mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Merge 9f383970b7
into ec887626b5
This commit is contained in:
commit
1c41c5e442
10 changed files with 214 additions and 235 deletions
|
@ -24,13 +24,13 @@
|
||||||
Manage apps
|
Manage apps
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
import json
|
import json
|
||||||
import shutil
|
import shutil
|
||||||
import stat
|
|
||||||
import yaml
|
import yaml
|
||||||
import time
|
import time
|
||||||
import re
|
import re
|
||||||
|
import string
|
||||||
|
import random
|
||||||
import socket
|
import socket
|
||||||
import urlparse
|
import urlparse
|
||||||
import errno
|
import errno
|
||||||
|
@ -42,6 +42,10 @@ from moulinette.utils.log import getActionLogger
|
||||||
|
|
||||||
from yunohost.service import service_log
|
from yunohost.service import service_log
|
||||||
from yunohost.utils import packages
|
from yunohost.utils import packages
|
||||||
|
from yunohost.hook import hook_add, hook_remove, hook_exec, hook_callback
|
||||||
|
from yunohost.user import user_list, user_info
|
||||||
|
from yunohost.domain import domain_list
|
||||||
|
|
||||||
|
|
||||||
logger = getActionLogger('yunohost.app')
|
logger = getActionLogger('yunohost.app')
|
||||||
|
|
||||||
|
@ -333,8 +337,6 @@ def app_upgrade(auth, app=[], url=None, file=None):
|
||||||
url -- Git url to fetch for upgrade
|
url -- Git url to fetch for upgrade
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from yunohost.hook import hook_add, hook_remove, hook_exec
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
app_list()
|
app_list()
|
||||||
except MoulinetteError:
|
except MoulinetteError:
|
||||||
|
@ -445,8 +447,6 @@ def app_install(auth, app, label=None, args=None):
|
||||||
args -- Serialize arguments for app installation
|
args -- Serialize arguments for app installation
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from yunohost.hook import hook_add, hook_remove, hook_exec
|
|
||||||
|
|
||||||
# Fetch or extract sources
|
# Fetch or extract sources
|
||||||
try: os.listdir(install_tmp)
|
try: os.listdir(install_tmp)
|
||||||
except OSError: os.makedirs(install_tmp)
|
except OSError: os.makedirs(install_tmp)
|
||||||
|
@ -588,8 +588,6 @@ def app_remove(auth, app):
|
||||||
app -- App(s) to delete
|
app -- App(s) to delete
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from yunohost.hook import hook_exec, hook_remove
|
|
||||||
|
|
||||||
if not _is_installed(app):
|
if not _is_installed(app):
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise MoulinetteError(errno.EINVAL,
|
||||||
m18n.n('app_not_installed', app=app))
|
m18n.n('app_not_installed', app=app))
|
||||||
|
@ -631,9 +629,6 @@ def app_addaccess(auth, apps, users=[]):
|
||||||
apps
|
apps
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from yunohost.user import user_list, user_info
|
|
||||||
from yunohost.hook import hook_callback
|
|
||||||
|
|
||||||
result = {}
|
result = {}
|
||||||
|
|
||||||
if not users:
|
if not users:
|
||||||
|
@ -686,9 +681,6 @@ def app_removeaccess(auth, apps, users=[]):
|
||||||
apps
|
apps
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from yunohost.user import user_list
|
|
||||||
from yunohost.hook import hook_callback
|
|
||||||
|
|
||||||
result = {}
|
result = {}
|
||||||
|
|
||||||
remove_all = False
|
remove_all = False
|
||||||
|
@ -736,8 +728,6 @@ def app_clearaccess(auth, apps):
|
||||||
apps
|
apps
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from yunohost.hook import hook_callback
|
|
||||||
|
|
||||||
if not isinstance(apps, list): apps = [apps]
|
if not isinstance(apps, list): apps = [apps]
|
||||||
|
|
||||||
for app in apps:
|
for app in apps:
|
||||||
|
@ -788,8 +778,6 @@ def app_makedefault(auth, app, domain=None):
|
||||||
domain
|
domain
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from yunohost.domain import domain_list
|
|
||||||
|
|
||||||
app_settings = _get_app_settings(app)
|
app_settings = _get_app_settings(app)
|
||||||
app_domain = app_settings['domain']
|
app_domain = app_settings['domain']
|
||||||
app_path = app_settings['path']
|
app_path = app_settings['path']
|
||||||
|
@ -881,8 +869,6 @@ def app_checkurl(auth, url, app=None):
|
||||||
app -- Write domain & path to app settings for further checks
|
app -- Write domain & path to app settings for further checks
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from yunohost.domain import domain_list
|
|
||||||
|
|
||||||
if "https://" == url[:8]:
|
if "https://" == url[:8]:
|
||||||
url = url[8:]
|
url = url[8:]
|
||||||
elif "http://" == url[:7]:
|
elif "http://" == url[:7]:
|
||||||
|
@ -965,9 +951,6 @@ def app_ssowatconf(auth):
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from yunohost.domain import domain_list
|
|
||||||
from yunohost.user import user_list
|
|
||||||
|
|
||||||
with open('/etc/yunohost/current_host', 'r') as f:
|
with open('/etc/yunohost/current_host', 'r') as f:
|
||||||
main_domain = f.readline().rstrip()
|
main_domain = f.readline().rstrip()
|
||||||
|
|
||||||
|
@ -1404,11 +1387,11 @@ def _value_for_locale(values):
|
||||||
if not isinstance(values, dict):
|
if not isinstance(values, dict):
|
||||||
return values
|
return values
|
||||||
|
|
||||||
for lang in [m18n.locale, m18n.default_locale]:
|
if m18n.locale in values:
|
||||||
try:
|
return _encode_string(values[m18n.locale])
|
||||||
return _encode_string(values[lang])
|
|
||||||
except KeyError:
|
if m18n.default_locale in values:
|
||||||
continue
|
return _encode_string(values[m18n.default_locale])
|
||||||
|
|
||||||
# Fallback to first value
|
# Fallback to first value
|
||||||
return _encode_string(values.values()[0])
|
return _encode_string(values.values()[0])
|
||||||
|
@ -1466,6 +1449,7 @@ def _check_manifest_requirements(manifest):
|
||||||
pkgname=pkgname, version=version,
|
pkgname=pkgname, version=version,
|
||||||
spec=spec))
|
spec=spec))
|
||||||
|
|
||||||
|
|
||||||
def _parse_args_from_manifest(manifest, action, args={}, auth=None):
|
def _parse_args_from_manifest(manifest, action, args={}, auth=None):
|
||||||
"""Parse arguments needed for an action from the manifest
|
"""Parse arguments needed for an action from the manifest
|
||||||
|
|
||||||
|
@ -1480,9 +1464,6 @@ def _parse_args_from_manifest(manifest, action, args={}, auth=None):
|
||||||
args -- A dictionnary of arguments to parse
|
args -- A dictionnary of arguments to parse
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from yunohost.domain import domain_list
|
|
||||||
from yunohost.user import user_info
|
|
||||||
|
|
||||||
args_list = OrderedDict()
|
args_list = OrderedDict()
|
||||||
try:
|
try:
|
||||||
action_args = manifest['arguments'][action]
|
action_args = manifest['arguments'][action]
|
||||||
|
@ -1577,6 +1558,7 @@ def _parse_args_from_manifest(manifest, action, args={}, auth=None):
|
||||||
args_list[arg_name] = arg_value
|
args_list[arg_name] = arg_value
|
||||||
return args_list
|
return args_list
|
||||||
|
|
||||||
|
|
||||||
def _make_environment_dict(args_dict):
|
def _make_environment_dict(args_dict):
|
||||||
"""
|
"""
|
||||||
Convert a dictionnary containing manifest arguments
|
Convert a dictionnary containing manifest arguments
|
||||||
|
@ -1591,6 +1573,7 @@ def _make_environment_dict(args_dict):
|
||||||
env_dict[ "YNH_APP_ARG_%s" % arg_name.upper() ] = arg_value
|
env_dict[ "YNH_APP_ARG_%s" % arg_name.upper() ] = arg_value
|
||||||
return env_dict
|
return env_dict
|
||||||
|
|
||||||
|
|
||||||
def _parse_app_instance_name(app_instance_name):
|
def _parse_app_instance_name(app_instance_name):
|
||||||
"""
|
"""
|
||||||
Parse a Yunohost app instance name and extracts the original appid
|
Parse a Yunohost app instance name and extracts the original appid
|
||||||
|
@ -1618,6 +1601,7 @@ def _parse_app_instance_name(app_instance_name):
|
||||||
app_instance_nb = int(match.groupdict().get('appinstancenb')) if match.groupdict().get('appinstancenb') is not None else 1
|
app_instance_nb = int(match.groupdict().get('appinstancenb')) if match.groupdict().get('appinstancenb') is not None else 1
|
||||||
return (appid, app_instance_nb)
|
return (appid, app_instance_nb)
|
||||||
|
|
||||||
|
|
||||||
def is_true(arg):
|
def is_true(arg):
|
||||||
"""
|
"""
|
||||||
Convert a string into a boolean
|
Convert a string into a boolean
|
||||||
|
@ -1650,7 +1634,5 @@ def random_password(length=8):
|
||||||
length -- The string length to generate
|
length -- The string length to generate
|
||||||
|
|
||||||
"""
|
"""
|
||||||
import string, random
|
|
||||||
|
|
||||||
char_set = string.ascii_uppercase + string.digits + string.ascii_lowercase
|
char_set = string.ascii_uppercase + string.digits + string.ascii_lowercase
|
||||||
return ''.join(random.sample(char_set, length))
|
return ''.join(random.sample(char_set, length))
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import sys
|
|
||||||
import json
|
import json
|
||||||
import errno
|
import errno
|
||||||
import time
|
import time
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
""" License
|
""" License
|
||||||
|
|
||||||
Copyright (C) 2013 YunoHost
|
Copyright (C) 2013-2016 YunoHost
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Affero General Public License as published
|
it under the terms of the GNU Affero General Public License as published
|
||||||
|
@ -24,20 +24,20 @@
|
||||||
Manage domains
|
Manage domains
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
import datetime
|
|
||||||
import re
|
import re
|
||||||
import shutil
|
|
||||||
import json
|
import json
|
||||||
import yaml
|
import yaml
|
||||||
import errno
|
import errno
|
||||||
|
import shutil
|
||||||
import requests
|
import requests
|
||||||
from urllib import urlopen
|
|
||||||
|
|
||||||
from moulinette.core import MoulinetteError
|
from moulinette.core import MoulinetteError
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
|
|
||||||
from yunohost.service import service_regen_conf
|
from yunohost.service import service_regen_conf
|
||||||
|
from yunohost.hook import hook_callback
|
||||||
|
from yunohost.dyndns import dyndns_subscribe
|
||||||
|
from yunohost.app import app_ssowatconf
|
||||||
|
|
||||||
logger = getActionLogger('yunohost.domain')
|
logger = getActionLogger('yunohost.domain')
|
||||||
|
|
||||||
|
@ -80,13 +80,9 @@ def domain_add(auth, domain, dyndns=False):
|
||||||
dyndns -- Subscribe to DynDNS
|
dyndns -- Subscribe to DynDNS
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from yunohost.hook import hook_callback
|
|
||||||
|
|
||||||
attr_dict = { 'objectClass' : ['mailDomain', 'top'] }
|
attr_dict = { 'objectClass' : ['mailDomain', 'top'] }
|
||||||
|
|
||||||
now = datetime.datetime.now()
|
|
||||||
timestamp = str(now.year) + str(now.month) + str(now.day)
|
|
||||||
|
|
||||||
if domain in domain_list(auth)['domains']:
|
if domain in domain_list(auth)['domains']:
|
||||||
raise MoulinetteError(errno.EEXIST, m18n.n('domain_exists'))
|
raise MoulinetteError(errno.EEXIST, m18n.n('domain_exists'))
|
||||||
|
|
||||||
|
@ -94,7 +90,6 @@ def domain_add(auth, domain, dyndns=False):
|
||||||
if dyndns:
|
if dyndns:
|
||||||
if len(domain.split('.')) < 3:
|
if len(domain.split('.')) < 3:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('domain_dyndns_invalid'))
|
raise MoulinetteError(errno.EINVAL, m18n.n('domain_dyndns_invalid'))
|
||||||
from yunohost.dyndns import dyndns_subscribe
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
r = requests.get('https://dyndns.yunohost.org/domains')
|
r = requests.get('https://dyndns.yunohost.org/domains')
|
||||||
|
@ -160,12 +155,14 @@ def domain_add(auth, domain, dyndns=False):
|
||||||
with open('/etc/yunohost/installed', 'r') as f:
|
with open('/etc/yunohost/installed', 'r') as f:
|
||||||
service_regen_conf(names=[
|
service_regen_conf(names=[
|
||||||
'nginx', 'metronome', 'dnsmasq', 'rmilter'])
|
'nginx', 'metronome', 'dnsmasq', 'rmilter'])
|
||||||
os.system('yunohost app ssowatconf > /dev/null 2>&1')
|
app_ssowatconf(auth)
|
||||||
except IOError: pass
|
except IOError: pass
|
||||||
except:
|
except:
|
||||||
# Force domain removal silently
|
# Force domain removal silently
|
||||||
try: domain_remove(auth, domain, True)
|
try:
|
||||||
except: pass
|
domain_remove(auth, domain, True)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
raise
|
raise
|
||||||
|
|
||||||
hook_callback('post_domain_add', args=[domain])
|
hook_callback('post_domain_add', args=[domain])
|
||||||
|
@ -182,8 +179,6 @@ def domain_remove(auth, domain, force=False):
|
||||||
force -- Force the domain removal
|
force -- Force the domain removal
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from yunohost.hook import hook_callback
|
|
||||||
|
|
||||||
if not force and domain not in domain_list(auth)['domains']:
|
if not force and domain not in domain_list(auth)['domains']:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('domain_unknown'))
|
raise MoulinetteError(errno.EINVAL, m18n.n('domain_unknown'))
|
||||||
|
|
||||||
|
@ -200,12 +195,12 @@ def domain_remove(auth, domain, force=False):
|
||||||
m18n.n('domain_uninstall_app_first'))
|
m18n.n('domain_uninstall_app_first'))
|
||||||
|
|
||||||
if auth.remove('virtualdomain=' + domain + ',ou=domains') or force:
|
if auth.remove('virtualdomain=' + domain + ',ou=domains') or force:
|
||||||
os.system('rm -rf /etc/yunohost/certs/%s' % domain)
|
shutil.rmtree('/etc/yunohost/certs/%s' % domain)
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(errno.EIO, m18n.n('domain_deletion_failed'))
|
raise MoulinetteError(errno.EIO, m18n.n('domain_deletion_failed'))
|
||||||
|
|
||||||
service_regen_conf(names=['nginx', 'metronome', 'dnsmasq'])
|
service_regen_conf(names=['nginx', 'metronome', 'dnsmasq'])
|
||||||
os.system('yunohost app ssowatconf > /dev/null 2>&1')
|
app_ssowatconf(auth)
|
||||||
|
|
||||||
hook_callback('post_domain_remove', args=[domain])
|
hook_callback('post_domain_remove', args=[domain])
|
||||||
|
|
||||||
|
@ -296,7 +291,7 @@ def get_public_ip(protocol=4):
|
||||||
else:
|
else:
|
||||||
raise ValueError("invalid protocol version")
|
raise ValueError("invalid protocol version")
|
||||||
try:
|
try:
|
||||||
return urlopen(url).read().strip()
|
return requests.get(url).content.strip()
|
||||||
except IOError:
|
except IOError:
|
||||||
logger.debug('cannot retrieve public IPv%d' % protocol, exc_info=1)
|
logger.debug('cannot retrieve public IPv%d' % protocol, exc_info=1)
|
||||||
raise MoulinetteError(errno.ENETUNREACH,
|
raise MoulinetteError(errno.ENETUNREACH,
|
||||||
|
|
|
@ -40,6 +40,10 @@ from yunohost.domain import get_public_ip
|
||||||
logger = getActionLogger('yunohost.dyndns')
|
logger = getActionLogger('yunohost.dyndns')
|
||||||
|
|
||||||
|
|
||||||
|
RE_DYNDNS_PRIVATE_KEY = re.compile(
|
||||||
|
r'.*/K(?P<domain>[^\s\+]+)\.\+157.+\.private$'
|
||||||
|
)
|
||||||
|
|
||||||
class IPRouteLine(object):
|
class IPRouteLine(object):
|
||||||
""" Utility class to parse an ip route output line
|
""" Utility class to parse an ip route output line
|
||||||
|
|
||||||
|
@ -62,10 +66,6 @@ class IPRouteLine(object):
|
||||||
for k, v in self.m.groupdict().items():
|
for k, v in self.m.groupdict().items():
|
||||||
setattr(self, k, v)
|
setattr(self, k, v)
|
||||||
|
|
||||||
re_dyndns_private_key = re.compile(
|
|
||||||
r'.*/K(?P<domain>[^\s\+]+)\.\+157.+\.private$'
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def dyndns_subscribe(subscribe_host="dyndns.yunohost.org", domain=None, key=None):
|
def dyndns_subscribe(subscribe_host="dyndns.yunohost.org", domain=None, key=None):
|
||||||
"""
|
"""
|
||||||
|
@ -171,7 +171,7 @@ def dyndns_update(dyn_host="dyndns.yunohost.org", domain=None, key=None,
|
||||||
if domain is None:
|
if domain is None:
|
||||||
# Retrieve the first registered domain
|
# Retrieve the first registered domain
|
||||||
for path in glob.iglob('/etc/yunohost/dyndns/K*.private'):
|
for path in glob.iglob('/etc/yunohost/dyndns/K*.private'):
|
||||||
match = re_dyndns_private_key.match(path)
|
match = RE_DYNDNS_PRIVATE_KEY.match(path)
|
||||||
if not match:
|
if not match:
|
||||||
continue
|
continue
|
||||||
_domain = match.group('domain')
|
_domain = match.group('domain')
|
||||||
|
|
|
@ -36,7 +36,9 @@ except ImportError:
|
||||||
from moulinette.core import MoulinetteError
|
from moulinette.core import MoulinetteError
|
||||||
from moulinette.utils import process
|
from moulinette.utils import process
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
from moulinette.utils.text import prependlines
|
from moulinette.utils.text import prependlines, searchf
|
||||||
|
|
||||||
|
from yunohost.hook import hook_callback
|
||||||
|
|
||||||
firewall_file = '/etc/yunohost/firewall.yml'
|
firewall_file = '/etc/yunohost/firewall.yml'
|
||||||
upnp_cron_job = '/etc/cron.d/yunohost-firewall-upnp'
|
upnp_cron_job = '/etc/cron.d/yunohost-firewall-upnp'
|
||||||
|
@ -123,7 +125,7 @@ def firewall_disallow(protocol, port, ipv4_only=False, ipv6_only=False,
|
||||||
ipvs = ['ipv4', 'ipv6']
|
ipvs = ['ipv4', 'ipv6']
|
||||||
upnp = True
|
upnp = True
|
||||||
if ipv4_only and ipv6_only:
|
if ipv4_only and ipv6_only:
|
||||||
upnp = True # automatically disallow UPnP
|
upnp = True # automatically disallow UPnP
|
||||||
elif ipv4_only:
|
elif ipv4_only:
|
||||||
ipvs = ['ipv4',]
|
ipvs = ['ipv4',]
|
||||||
upnp = upnp_only
|
upnp = upnp_only
|
||||||
|
@ -178,7 +180,7 @@ def firewall_list(raw=False, by_ip_version=False, list_forwarded=False):
|
||||||
ports = sorted(set(ports['ipv4']) | set(ports['ipv6']))
|
ports = sorted(set(ports['ipv4']) | set(ports['ipv6']))
|
||||||
|
|
||||||
# Format returned dict
|
# Format returned dict
|
||||||
ret = { "opened_ports": ports }
|
ret = {"opened_ports": ports}
|
||||||
if list_forwarded:
|
if list_forwarded:
|
||||||
# Combine TCP and UDP forwarded ports
|
# Combine TCP and UDP forwarded ports
|
||||||
ret['forwarded_ports'] = sorted(
|
ret['forwarded_ports'] = sorted(
|
||||||
|
@ -194,8 +196,6 @@ def firewall_reload(skip_upnp=False):
|
||||||
skip_upnp -- Do not refresh port forwarding using UPnP
|
skip_upnp -- Do not refresh port forwarding using UPnP
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from yunohost.hook import hook_callback
|
|
||||||
|
|
||||||
reloaded = False
|
reloaded = False
|
||||||
errors = False
|
errors = False
|
||||||
|
|
||||||
|
@ -224,8 +224,8 @@ def firewall_reload(skip_upnp=False):
|
||||||
# Iterate over ports and add rule
|
# Iterate over ports and add rule
|
||||||
for protocol in ['TCP', 'UDP']:
|
for protocol in ['TCP', 'UDP']:
|
||||||
for port in firewall['ipv4'][protocol]:
|
for port in firewall['ipv4'][protocol]:
|
||||||
rules.append("iptables -A INPUT -p %s --dport %s -j ACCEPT" \
|
rules.append("iptables -A INPUT -p %s --dport %s -j ACCEPT"
|
||||||
% (protocol, process.quote(str(port))))
|
% (protocol, process.quote(str(port))))
|
||||||
rules += [
|
rules += [
|
||||||
"iptables -A INPUT -i lo -j ACCEPT",
|
"iptables -A INPUT -i lo -j ACCEPT",
|
||||||
"iptables -A INPUT -p icmp -j ACCEPT",
|
"iptables -A INPUT -p icmp -j ACCEPT",
|
||||||
|
@ -253,8 +253,8 @@ def firewall_reload(skip_upnp=False):
|
||||||
# Iterate over ports and add rule
|
# Iterate over ports and add rule
|
||||||
for protocol in ['TCP', 'UDP']:
|
for protocol in ['TCP', 'UDP']:
|
||||||
for port in firewall['ipv6'][protocol]:
|
for port in firewall['ipv6'][protocol]:
|
||||||
rules.append("ip6tables -A INPUT -p %s --dport %s -j ACCEPT" \
|
rules.append("ip6tables -A INPUT -p %s --dport %s -j ACCEPT"
|
||||||
% (protocol, process.quote(str(port))))
|
% (protocol, process.quote(str(port))))
|
||||||
rules += [
|
rules += [
|
||||||
"ip6tables -A INPUT -i lo -j ACCEPT",
|
"ip6tables -A INPUT -i lo -j ACCEPT",
|
||||||
"ip6tables -A INPUT -p icmpv6 -j ACCEPT",
|
"ip6tables -A INPUT -p icmpv6 -j ACCEPT",
|
||||||
|
@ -308,13 +308,14 @@ def firewall_upnp(action='status', no_refresh=False):
|
||||||
try:
|
try:
|
||||||
# Remove old cron job
|
# Remove old cron job
|
||||||
os.remove('/etc/cron.d/yunohost-firewall')
|
os.remove('/etc/cron.d/yunohost-firewall')
|
||||||
except: pass
|
except:
|
||||||
|
pass
|
||||||
action = 'status'
|
action = 'status'
|
||||||
no_refresh = False
|
no_refresh = False
|
||||||
|
|
||||||
if action == 'status' and no_refresh:
|
if action == 'status' and no_refresh:
|
||||||
# Only return current state
|
# Only return current state
|
||||||
return { 'enabled': enabled }
|
return {'enabled': enabled}
|
||||||
elif action == 'enable' or (enabled and action == 'status'):
|
elif action == 'enable' or (enabled and action == 'status'):
|
||||||
# Add cron job
|
# Add cron job
|
||||||
with open(upnp_cron_job, 'w+') as f:
|
with open(upnp_cron_job, 'w+') as f:
|
||||||
|
@ -330,7 +331,8 @@ def firewall_upnp(action='status', no_refresh=False):
|
||||||
try:
|
try:
|
||||||
# Remove cron job
|
# Remove cron job
|
||||||
os.remove(upnp_cron_job)
|
os.remove(upnp_cron_job)
|
||||||
except: pass
|
except:
|
||||||
|
pass
|
||||||
enabled = False
|
enabled = False
|
||||||
if action == 'status':
|
if action == 'status':
|
||||||
no_refresh = True
|
no_refresh = True
|
||||||
|
@ -364,7 +366,8 @@ def firewall_upnp(action='status', no_refresh=False):
|
||||||
if upnpc.getspecificportmapping(port, protocol):
|
if upnpc.getspecificportmapping(port, protocol):
|
||||||
try:
|
try:
|
||||||
upnpc.deleteportmapping(port, protocol)
|
upnpc.deleteportmapping(port, protocol)
|
||||||
except: pass
|
except:
|
||||||
|
pass
|
||||||
if not enabled:
|
if not enabled:
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
|
@ -403,7 +406,7 @@ def firewall_upnp(action='status', no_refresh=False):
|
||||||
|
|
||||||
if action == 'enable' and not enabled:
|
if action == 'enable' and not enabled:
|
||||||
raise MoulinetteError(errno.ENXIO, m18n.n('upnp_port_open_failed'))
|
raise MoulinetteError(errno.ENXIO, m18n.n('upnp_port_open_failed'))
|
||||||
return { 'enabled': enabled }
|
return {'enabled': enabled}
|
||||||
|
|
||||||
|
|
||||||
def firewall_stop():
|
def firewall_stop():
|
||||||
|
@ -434,7 +437,6 @@ def _get_ssh_port(default=22):
|
||||||
Retrieve the SSH port from the sshd_config file or used the default
|
Retrieve the SSH port from the sshd_config file or used the default
|
||||||
one if it's not defined.
|
one if it's not defined.
|
||||||
"""
|
"""
|
||||||
from moulinette.utils.text import searchf
|
|
||||||
try:
|
try:
|
||||||
m = searchf(r'^Port[ \t]+([0-9]+)$',
|
m = searchf(r'^Port[ \t]+([0-9]+)$',
|
||||||
'/etc/ssh/sshd_config', count=-1)
|
'/etc/ssh/sshd_config', count=-1)
|
||||||
|
@ -444,12 +446,14 @@ def _get_ssh_port(default=22):
|
||||||
pass
|
pass
|
||||||
return default
|
return default
|
||||||
|
|
||||||
|
|
||||||
def _update_firewall_file(rules):
|
def _update_firewall_file(rules):
|
||||||
"""Make a backup and write new rules to firewall file"""
|
"""Make a backup and write new rules to firewall file"""
|
||||||
os.system("cp {0} {0}.old".format(firewall_file))
|
os.system("cp {0} {0}.old".format(firewall_file))
|
||||||
with open(firewall_file, 'w') as f:
|
with open(firewall_file, 'w') as f:
|
||||||
yaml.safe_dump(rules, f, default_flow_style=False)
|
yaml.safe_dump(rules, f, default_flow_style=False)
|
||||||
|
|
||||||
|
|
||||||
def _on_rule_command_error(returncode, cmd, output):
|
def _on_rule_command_error(returncode, cmd, output):
|
||||||
"""Callback for rules commands error"""
|
"""Callback for rules commands error"""
|
||||||
# Log error and continue commands execution
|
# Log error and continue commands execution
|
||||||
|
|
|
@ -24,15 +24,12 @@
|
||||||
Manage hooks
|
Manage hooks
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
import re
|
|
||||||
import json
|
|
||||||
import errno
|
import errno
|
||||||
import subprocess
|
|
||||||
from glob import iglob
|
from glob import iglob
|
||||||
|
|
||||||
from moulinette.core import MoulinetteError
|
from moulinette.core import MoulinetteError
|
||||||
from moulinette.utils import log
|
from moulinette.utils import log
|
||||||
|
from moulinette.utils.process import call_async_output
|
||||||
|
|
||||||
hook_folder = '/usr/share/yunohost/hooks/'
|
hook_folder = '/usr/share/yunohost/hooks/'
|
||||||
custom_hook_folder = '/etc/yunohost/hooks.d/'
|
custom_hook_folder = '/etc/yunohost/hooks.d/'
|
||||||
|
@ -52,14 +49,16 @@ def hook_add(app, file):
|
||||||
path, filename = os.path.split(file)
|
path, filename = os.path.split(file)
|
||||||
priority, action = _extract_filename_parts(filename)
|
priority, action = _extract_filename_parts(filename)
|
||||||
|
|
||||||
try: os.listdir(custom_hook_folder + action)
|
try:
|
||||||
except OSError: os.makedirs(custom_hook_folder + action)
|
os.listdir(custom_hook_folder + action)
|
||||||
|
except OSError:
|
||||||
|
os.makedirs(custom_hook_folder + action)
|
||||||
|
|
||||||
finalpath = custom_hook_folder + action +'/'+ priority +'-'+ app
|
finalpath = custom_hook_folder + action + '/' + priority + '-' + app
|
||||||
os.system('cp %s %s' % (file, finalpath))
|
os.system('cp %s %s' % (file, finalpath))
|
||||||
os.system('chown -hR admin: %s' % hook_folder)
|
os.system('chown -hR admin: %s' % hook_folder)
|
||||||
|
|
||||||
return { 'hook': finalpath }
|
return {'hook': finalpath}
|
||||||
|
|
||||||
|
|
||||||
def hook_remove(app):
|
def hook_remove(app):
|
||||||
|
@ -74,8 +73,9 @@ def hook_remove(app):
|
||||||
for action in os.listdir(custom_hook_folder):
|
for action in os.listdir(custom_hook_folder):
|
||||||
for script in os.listdir(custom_hook_folder + action):
|
for script in os.listdir(custom_hook_folder + action):
|
||||||
if script.endswith(app):
|
if script.endswith(app):
|
||||||
os.remove(custom_hook_folder + action +'/'+ script)
|
os.remove(custom_hook_folder + action + '/' + script)
|
||||||
except OSError: pass
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def hook_info(action, name):
|
def hook_info(action, name):
|
||||||
|
@ -136,11 +136,11 @@ def hook_list(action, list_by='name', show_info=False):
|
||||||
def _append_hook(d, priority, name, path):
|
def _append_hook(d, priority, name, path):
|
||||||
# Use the priority as key and a dict of hooks names
|
# Use the priority as key and a dict of hooks names
|
||||||
# with their info as value
|
# with their info as value
|
||||||
value = { 'path': path }
|
value = {'path': path}
|
||||||
try:
|
try:
|
||||||
d[priority][name] = value
|
d[priority][name] = value
|
||||||
except KeyError:
|
except KeyError:
|
||||||
d[priority] = { name: value }
|
d[priority] = {name: value}
|
||||||
else:
|
else:
|
||||||
def _append_hook(d, priority, name, path):
|
def _append_hook(d, priority, name, path):
|
||||||
# Use the priority as key and the name as value
|
# Use the priority as key and the name as value
|
||||||
|
@ -162,11 +162,12 @@ def hook_list(action, list_by='name', show_info=False):
|
||||||
if h['path'] != path:
|
if h['path'] != path:
|
||||||
h['path'] = path
|
h['path'] = path
|
||||||
return
|
return
|
||||||
l.append({ 'priority': priority, 'path': path })
|
l.append({'priority': priority, 'path': path})
|
||||||
d[name] = l
|
d[name] = l
|
||||||
else:
|
else:
|
||||||
if list_by == 'name':
|
if list_by == 'name':
|
||||||
result = set()
|
result = set()
|
||||||
|
|
||||||
def _append_hook(d, priority, name, path):
|
def _append_hook(d, priority, name, path):
|
||||||
# Add only the name
|
# Add only the name
|
||||||
d.add(name)
|
d.add(name)
|
||||||
|
@ -204,7 +205,7 @@ def hook_list(action, list_by='name', show_info=False):
|
||||||
logger.debug("custom hook folder not found for action '%s' in %s",
|
logger.debug("custom hook folder not found for action '%s' in %s",
|
||||||
action, custom_hook_folder)
|
action, custom_hook_folder)
|
||||||
|
|
||||||
return { 'hooks': result }
|
return {'hooks': result}
|
||||||
|
|
||||||
|
|
||||||
def hook_callback(action, hooks=[], args=None, no_trace=False, chdir=None,
|
def hook_callback(action, hooks=[], args=None, no_trace=False, chdir=None,
|
||||||
|
@ -226,7 +227,7 @@ def hook_callback(action, hooks=[], args=None, no_trace=False, chdir=None,
|
||||||
(name, priority, path, succeed) as arguments
|
(name, priority, path, succeed) as arguments
|
||||||
|
|
||||||
"""
|
"""
|
||||||
result = { 'succeed': {}, 'failed': {} }
|
result = {'succeed': {}, 'failed': {}}
|
||||||
hooks_dict = {}
|
hooks_dict = {}
|
||||||
|
|
||||||
# Retrieve hooks
|
# Retrieve hooks
|
||||||
|
@ -258,7 +259,7 @@ def hook_callback(action, hooks=[], args=None, no_trace=False, chdir=None,
|
||||||
for h in hl:
|
for h in hl:
|
||||||
# Update hooks dict
|
# Update hooks dict
|
||||||
d = hooks_dict.get(h['priority'], dict())
|
d = hooks_dict.get(h['priority'], dict())
|
||||||
d.update({ n: { 'path': h['path'] }})
|
d.update({n: {'path': h['path']}})
|
||||||
hooks_dict[h['priority']] = d
|
hooks_dict[h['priority']] = d
|
||||||
if not hooks_dict:
|
if not hooks_dict:
|
||||||
return result
|
return result
|
||||||
|
@ -308,9 +309,6 @@ def hook_exec(path, args=None, raise_on_error=False, no_trace=False,
|
||||||
env -- Dictionnary of environment variables to export
|
env -- Dictionnary of environment variables to export
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from moulinette.utils.process import call_async_output
|
|
||||||
from yunohost.app import _value_for_locale
|
|
||||||
|
|
||||||
# Validate hook path
|
# Validate hook path
|
||||||
if path[0] != '/':
|
if path[0] != '/':
|
||||||
path = os.path.realpath(path)
|
path = os.path.realpath(path)
|
||||||
|
|
|
@ -35,12 +35,15 @@ import errno
|
||||||
import os
|
import os
|
||||||
import dns.resolver
|
import dns.resolver
|
||||||
import cPickle as pickle
|
import cPickle as pickle
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime
|
||||||
|
|
||||||
from moulinette.core import MoulinetteError
|
from moulinette.core import MoulinetteError
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
|
|
||||||
from yunohost.domain import get_public_ip
|
from yunohost.domain import get_public_ip
|
||||||
|
from yunohost.service import (service_status, service_enable,
|
||||||
|
service_start, service_disable, service_stop)
|
||||||
|
|
||||||
|
|
||||||
logger = getActionLogger('yunohost.monitor')
|
logger = getActionLogger('yunohost.monitor')
|
||||||
|
|
||||||
|
@ -406,9 +409,6 @@ def monitor_enable(no_stats=False):
|
||||||
no_stats -- Disable monitoring statistics
|
no_stats -- Disable monitoring statistics
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from yunohost.service import (service_status, service_enable,
|
|
||||||
service_start)
|
|
||||||
|
|
||||||
glances = service_status('glances')
|
glances = service_status('glances')
|
||||||
if glances['status'] != 'running':
|
if glances['status'] != 'running':
|
||||||
service_start('glances')
|
service_start('glances')
|
||||||
|
@ -433,9 +433,6 @@ def monitor_disable():
|
||||||
Disable server monitoring
|
Disable server monitoring
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from yunohost.service import (service_status, service_disable,
|
|
||||||
service_stop)
|
|
||||||
|
|
||||||
glances = service_status('glances')
|
glances = service_status('glances')
|
||||||
if glances['status'] != 'inactive':
|
if glances['status'] != 'inactive':
|
||||||
service_stop('glances')
|
service_stop('glances')
|
||||||
|
@ -467,8 +464,6 @@ def _get_glances_api():
|
||||||
else:
|
else:
|
||||||
return p
|
return p
|
||||||
|
|
||||||
from yunohost.service import service_status
|
|
||||||
|
|
||||||
if service_status('glances')['status'] != 'running':
|
if service_status('glances')['status'] != 'running':
|
||||||
raise MoulinetteError(errno.EPERM, m18n.n('monitor_not_enabled'))
|
raise MoulinetteError(errno.EPERM, m18n.n('monitor_not_enabled'))
|
||||||
raise MoulinetteError(errno.EIO, m18n.n('monitor_glances_con_failed'))
|
raise MoulinetteError(errno.EIO, m18n.n('monitor_glances_con_failed'))
|
||||||
|
@ -722,22 +717,26 @@ def _append_to_stats(stats, monitor, statics=[]):
|
||||||
statics = [statics]
|
statics = [statics]
|
||||||
|
|
||||||
# Appending function
|
# Appending function
|
||||||
def _append(s, m, st):
|
def _append(_stats, _monitor, _statics):
|
||||||
for k, v in m.items():
|
for key, value in _monitor.items():
|
||||||
if k in st:
|
if key in _statics:
|
||||||
s[k] = v
|
_stats[key] = value
|
||||||
elif isinstance(v, dict):
|
|
||||||
if k not in s:
|
elif isinstance(value, dict):
|
||||||
s[k] = {}
|
if key not in _stats:
|
||||||
s[k] = _append(s[k], v, st)
|
_stats[key] = {}
|
||||||
|
_stats[key] = _append(_stats[key], value, _statics)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if k not in s:
|
if key not in _stats:
|
||||||
s[k] = []
|
_stats[key] = []
|
||||||
if isinstance(v, list):
|
|
||||||
s[k].extend(v)
|
if isinstance(value, list):
|
||||||
|
_stats[key].extend(value)
|
||||||
else:
|
else:
|
||||||
s[k].append(v)
|
_stats[key].append(value)
|
||||||
return s
|
|
||||||
|
return _stats
|
||||||
|
|
||||||
stats = _append(stats, monitor, statics)
|
stats = _append(stats, monitor, statics)
|
||||||
return stats
|
return stats
|
||||||
|
|
|
@ -36,7 +36,7 @@ from difflib import unified_diff
|
||||||
from moulinette.core import MoulinetteError
|
from moulinette.core import MoulinetteError
|
||||||
from moulinette.utils import log, filesystem
|
from moulinette.utils import log, filesystem
|
||||||
|
|
||||||
from yunohost.hook import hook_list, hook_callback
|
from yunohost.hook import hook_callback
|
||||||
|
|
||||||
|
|
||||||
base_conf_path = '/home/yunohost.conf'
|
base_conf_path = '/home/yunohost.conf'
|
||||||
|
|
|
@ -24,10 +24,7 @@
|
||||||
Specific tools
|
Specific tools
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
import yaml
|
import yaml
|
||||||
import re
|
|
||||||
import getpass
|
|
||||||
import requests
|
import requests
|
||||||
import json
|
import json
|
||||||
import errno
|
import errno
|
||||||
|
@ -42,12 +39,12 @@ from moulinette.utils.log import getActionLogger
|
||||||
from yunohost.app import app_fetchlist, app_info, app_upgrade, app_ssowatconf, app_list
|
from yunohost.app import app_fetchlist, app_info, app_upgrade, app_ssowatconf, app_list
|
||||||
from yunohost.domain import domain_add, domain_list, get_public_ip
|
from yunohost.domain import domain_add, domain_list, get_public_ip
|
||||||
from yunohost.dyndns import dyndns_subscribe
|
from yunohost.dyndns import dyndns_subscribe
|
||||||
from yunohost.firewall import firewall_upnp, firewall_reload
|
from yunohost.firewall import firewall_upnp
|
||||||
from yunohost.service import service_status, service_regen_conf, service_log
|
from yunohost.service import service_status, service_regen_conf, service_log
|
||||||
from yunohost.monitor import monitor_disk, monitor_network, monitor_system
|
from yunohost.monitor import monitor_disk, monitor_system
|
||||||
from yunohost.utils.packages import ynh_packages_version
|
from yunohost.utils.packages import ynh_packages_version
|
||||||
|
|
||||||
apps_setting_path= '/etc/yunohost/apps/'
|
apps_setting_path = '/etc/yunohost/apps/'
|
||||||
|
|
||||||
logger = getActionLogger('yunohost.tools')
|
logger = getActionLogger('yunohost.tools')
|
||||||
|
|
||||||
|
@ -62,12 +59,16 @@ def tools_ldapinit(auth):
|
||||||
ldap_map = yaml.load(f)
|
ldap_map = yaml.load(f)
|
||||||
|
|
||||||
for rdn, attr_dict in ldap_map['parents'].items():
|
for rdn, attr_dict in ldap_map['parents'].items():
|
||||||
try: auth.add(rdn, attr_dict)
|
try:
|
||||||
except: pass
|
auth.add(rdn, attr_dict)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
for rdn, attr_dict in ldap_map['children'].items():
|
for rdn, attr_dict in ldap_map['children'].items():
|
||||||
try: auth.add(rdn, attr_dict)
|
try:
|
||||||
except: pass
|
auth.add(rdn, attr_dict)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
admin_dict = {
|
admin_dict = {
|
||||||
'cn': 'admin',
|
'cn': 'admin',
|
||||||
|
@ -118,7 +119,7 @@ def tools_maindomain(auth, old_domain=None, new_domain=None, dyndns=False):
|
||||||
old_domain = f.readline().rstrip()
|
old_domain = f.readline().rstrip()
|
||||||
|
|
||||||
if not new_domain:
|
if not new_domain:
|
||||||
return { 'current_main_domain': old_domain }
|
return {'current_main_domain': old_domain}
|
||||||
|
|
||||||
if not new_domain:
|
if not new_domain:
|
||||||
raise MoulinetteError(errno.EINVAL, m18n.n('new_domain_required'))
|
raise MoulinetteError(errno.EINVAL, m18n.n('new_domain_required'))
|
||||||
|
@ -130,7 +131,7 @@ def tools_maindomain(auth, old_domain=None, new_domain=None, dyndns=False):
|
||||||
|
|
||||||
command_list = [
|
command_list = [
|
||||||
'ln -s /etc/yunohost/certs/%s/key.pem /etc/ssl/private/yunohost_key.pem' % new_domain,
|
'ln -s /etc/yunohost/certs/%s/key.pem /etc/ssl/private/yunohost_key.pem' % new_domain,
|
||||||
'ln -s /etc/yunohost/certs/%s/crt.pem /etc/ssl/certs/yunohost_crt.pem' % new_domain,
|
'ln -s /etc/yunohost/certs/%s/crt.pem /etc/ssl/certs/yunohost_crt.pem' % new_domain,
|
||||||
'echo %s > /etc/yunohost/current_host' % new_domain,
|
'echo %s > /etc/yunohost/current_host' % new_domain,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -146,14 +147,15 @@ def tools_maindomain(auth, old_domain=None, new_domain=None, dyndns=False):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
dyndomains = json.loads(r.text)
|
dyndomains = json.loads(r.text)
|
||||||
dyndomain = '.'.join(new_domain.split('.')[1:])
|
dyndomain = '.'.join(new_domain.split('.')[1:])
|
||||||
if dyndomain in dyndomains:
|
if dyndomain in dyndomains:
|
||||||
dyndns_subscribe(domain=new_domain)
|
dyndns_subscribe(domain=new_domain)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open('/etc/yunohost/installed', 'r') as f:
|
with open('/etc/yunohost/installed', 'r') as f:
|
||||||
service_regen_conf()
|
service_regen_conf()
|
||||||
except IOError: pass
|
except IOError:
|
||||||
|
pass
|
||||||
|
|
||||||
logger.success(m18n.n('maindomain_changed'))
|
logger.success(m18n.n('maindomain_changed'))
|
||||||
|
|
||||||
|
@ -181,7 +183,7 @@ def tools_postinstall(domain, password, ignore_dyndns=False):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
dyndomains = json.loads(r.text)
|
dyndomains = json.loads(r.text)
|
||||||
dyndomain = '.'.join(domain.split('.')[1:])
|
dyndomain = '.'.join(domain.split('.')[1:])
|
||||||
if dyndomain in dyndomains:
|
if dyndomain in dyndomains:
|
||||||
if requests.get('https://dyndns.yunohost.org/test/%s' % domain).status_code == 200:
|
if requests.get('https://dyndns.yunohost.org/test/%s' % domain).status_code == 200:
|
||||||
dyndns = True
|
dyndns = True
|
||||||
|
@ -195,7 +197,7 @@ def tools_postinstall(domain, password, ignore_dyndns=False):
|
||||||
auth = init_authenticator(('ldap', 'default'),
|
auth = init_authenticator(('ldap', 'default'),
|
||||||
{'uri': "ldap://localhost:389",
|
{'uri': "ldap://localhost:389",
|
||||||
'base_dn': "dc=yunohost,dc=org",
|
'base_dn': "dc=yunohost,dc=org",
|
||||||
'user_rdn': "cn=admin" })
|
'user_rdn': "cn=admin"})
|
||||||
auth.authenticate('yunohost')
|
auth.authenticate('yunohost')
|
||||||
|
|
||||||
# Initialize LDAP for YunoHost
|
# Initialize LDAP for YunoHost
|
||||||
|
@ -212,8 +214,10 @@ def tools_postinstall(domain, password, ignore_dyndns=False):
|
||||||
]
|
]
|
||||||
|
|
||||||
for folder in folders_to_create:
|
for folder in folders_to_create:
|
||||||
try: os.listdir(folder)
|
try:
|
||||||
except OSError: os.makedirs(folder)
|
os.listdir(folder)
|
||||||
|
except OSError:
|
||||||
|
os.makedirs(folder)
|
||||||
|
|
||||||
# Change folders permissions
|
# Change folders permissions
|
||||||
os.system('chmod 755 /home/yunohost.app')
|
os.system('chmod 755 /home/yunohost.app')
|
||||||
|
@ -232,7 +236,7 @@ def tools_postinstall(domain, password, ignore_dyndns=False):
|
||||||
if 'redirected_urls' not in ssowat_conf:
|
if 'redirected_urls' not in ssowat_conf:
|
||||||
ssowat_conf['redirected_urls'] = {}
|
ssowat_conf['redirected_urls'] = {}
|
||||||
|
|
||||||
ssowat_conf['redirected_urls']['/'] = domain +'/yunohost/admin'
|
ssowat_conf['redirected_urls']['/'] = domain + '/yunohost/admin'
|
||||||
|
|
||||||
with open('/etc/ssowat/conf.json.persistent', 'w+') as f:
|
with open('/etc/ssowat/conf.json.persistent', 'w+') as f:
|
||||||
json.dump(ssowat_conf, f, sort_keys=True, indent=4)
|
json.dump(ssowat_conf, f, sort_keys=True, indent=4)
|
||||||
|
@ -244,8 +248,8 @@ def tools_postinstall(domain, password, ignore_dyndns=False):
|
||||||
ssl_dir = '/usr/share/yunohost/yunohost-config/ssl/yunoCA'
|
ssl_dir = '/usr/share/yunohost/yunohost-config/ssl/yunoCA'
|
||||||
command_list = [
|
command_list = [
|
||||||
'echo "01" > %s/serial' % ssl_dir,
|
'echo "01" > %s/serial' % ssl_dir,
|
||||||
'rm %s/index.txt' % ssl_dir,
|
'rm %s/index.txt' % ssl_dir,
|
||||||
'touch %s/index.txt' % ssl_dir,
|
'touch %s/index.txt' % ssl_dir,
|
||||||
'cp %s/openssl.cnf %s/openssl.ca.cnf' % (ssl_dir, ssl_dir),
|
'cp %s/openssl.cnf %s/openssl.ca.cnf' % (ssl_dir, ssl_dir),
|
||||||
'sed -i "s/yunohost.org/%s/g" %s/openssl.ca.cnf ' % (domain, ssl_dir),
|
'sed -i "s/yunohost.org/%s/g" %s/openssl.ca.cnf ' % (domain, ssl_dir),
|
||||||
'openssl req -x509 -new -config %s/openssl.ca.cnf -days 3650 -out %s/ca/cacert.pem -keyout %s/ca/cakey.pem -nodes -batch' % (ssl_dir, ssl_dir, ssl_dir),
|
'openssl req -x509 -new -config %s/openssl.ca.cnf -days 3650 -out %s/ca/cacert.pem -keyout %s/ca/cakey.pem -nodes -batch' % (ssl_dir, ssl_dir, ssl_dir),
|
||||||
|
@ -317,35 +321,34 @@ def tools_update(ignore_apps=False, ignore_packages=False):
|
||||||
app_fetchlist()
|
app_fetchlist()
|
||||||
except MoulinetteError:
|
except MoulinetteError:
|
||||||
pass
|
pass
|
||||||
app_list = os.listdir(apps_setting_path)
|
|
||||||
if len(app_list) > 0:
|
|
||||||
for app_id in app_list:
|
|
||||||
if '__' in app_id:
|
|
||||||
original_app_id = app_id[:app_id.index('__')]
|
|
||||||
else:
|
|
||||||
original_app_id = app_id
|
|
||||||
|
|
||||||
current_app_dict = app_info(app_id, raw=True)
|
for app_id in os.listdir(apps_setting_path):
|
||||||
new_app_dict = app_info(original_app_id, raw=True)
|
if '__' in app_id:
|
||||||
|
original_app_id = app_id[:app_id.index('__')]
|
||||||
|
else:
|
||||||
|
original_app_id = app_id
|
||||||
|
|
||||||
# Custom app
|
current_app_dict = app_info(app_id, raw=True)
|
||||||
if new_app_dict is None or 'lastUpdate' not in new_app_dict or 'git' not in new_app_dict:
|
new_app_dict = app_info(original_app_id, raw=True)
|
||||||
continue
|
|
||||||
|
|
||||||
if (new_app_dict['lastUpdate'] > current_app_dict['lastUpdate']) \
|
# Custom app
|
||||||
or ('update_time' not in current_app_dict['settings'] \
|
if new_app_dict is None or 'lastUpdate' not in new_app_dict or 'git' not in new_app_dict:
|
||||||
and (new_app_dict['lastUpdate'] > current_app_dict['settings']['install_time'])) \
|
continue
|
||||||
or ('update_time' in current_app_dict['settings'] \
|
|
||||||
and (new_app_dict['lastUpdate'] > current_app_dict['settings']['update_time'])):
|
if (new_app_dict['lastUpdate'] > current_app_dict['lastUpdate']) \
|
||||||
apps.append({
|
or ('update_time' not in current_app_dict['settings'] \
|
||||||
'id': app_id,
|
and (new_app_dict['lastUpdate'] > current_app_dict['settings']['install_time'])) \
|
||||||
'label': current_app_dict['settings']['label']
|
or ('update_time' in current_app_dict['settings'] \
|
||||||
})
|
and (new_app_dict['lastUpdate'] > current_app_dict['settings']['update_time'])):
|
||||||
|
apps.append({
|
||||||
|
'id': app_id,
|
||||||
|
'label': current_app_dict['settings']['label']
|
||||||
|
})
|
||||||
|
|
||||||
if len(apps) == 0 and len(packages) == 0:
|
if len(apps) == 0 and len(packages) == 0:
|
||||||
logger.info(m18n.n('packages_no_upgrade'))
|
logger.info(m18n.n('packages_no_upgrade'))
|
||||||
|
|
||||||
return { 'packages': packages, 'apps': apps }
|
return {'packages': packages, 'apps': apps}
|
||||||
|
|
||||||
|
|
||||||
def tools_upgrade(auth, ignore_apps=False, ignore_packages=False):
|
def tools_upgrade(auth, ignore_apps=False, ignore_packages=False):
|
||||||
|
@ -381,7 +384,7 @@ def tools_upgrade(auth, ignore_apps=False, ignore_packages=False):
|
||||||
# ... and set a hourly cron up to upgrade critical packages
|
# ... and set a hourly cron up to upgrade critical packages
|
||||||
if critical_upgrades:
|
if critical_upgrades:
|
||||||
logger.info(m18n.n('packages_upgrade_critical_later',
|
logger.info(m18n.n('packages_upgrade_critical_later',
|
||||||
packages=', '.join(critical_upgrades)))
|
packages=', '.join(critical_upgrades)))
|
||||||
with open('/etc/cron.d/yunohost-upgrade', 'w+') as f:
|
with open('/etc/cron.d/yunohost-upgrade', 'w+') as f:
|
||||||
f.write('00 * * * * root PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin apt-get install %s -y && rm -f /etc/cron.d/yunohost-upgrade\n' % ' '.join(critical_upgrades))
|
f.write('00 * * * * root PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin apt-get install %s -y && rm -f /etc/cron.d/yunohost-upgrade\n' % ' '.join(critical_upgrades))
|
||||||
|
|
||||||
|
@ -414,7 +417,7 @@ def tools_upgrade(auth, ignore_apps=False, ignore_packages=False):
|
||||||
|
|
||||||
# Return API logs if it is an API call
|
# Return API logs if it is an API call
|
||||||
if is_api:
|
if is_api:
|
||||||
return { "log": service_log('yunohost-api', number="100").values()[0] }
|
return {"log": service_log('yunohost-api', number="100").values()[0]}
|
||||||
|
|
||||||
|
|
||||||
def tools_diagnosis(auth, private=False):
|
def tools_diagnosis(auth, private=False):
|
||||||
|
@ -422,7 +425,7 @@ def tools_diagnosis(auth, private=False):
|
||||||
Return global info about current yunohost instance to help debugging
|
Return global info about current yunohost instance to help debugging
|
||||||
|
|
||||||
"""
|
"""
|
||||||
diagnosis = OrderedDict();
|
diagnosis = OrderedDict()
|
||||||
|
|
||||||
# Debian release
|
# Debian release
|
||||||
try:
|
try:
|
||||||
|
@ -466,8 +469,8 @@ def tools_diagnosis(auth, private=False):
|
||||||
logger.warning(m18n.n('diagnosis_monitor_system_error', error=format(e)), exc_info=1)
|
logger.warning(m18n.n('diagnosis_monitor_system_error', error=format(e)), exc_info=1)
|
||||||
else:
|
else:
|
||||||
diagnosis['system']['memory'] = {
|
diagnosis['system']['memory'] = {
|
||||||
'ram' : '%s (%s free)' % (system['memory']['ram']['total'], system['memory']['ram']['free']),
|
'ram': '%s (%s free)' % (system['memory']['ram']['total'], system['memory']['ram']['free']),
|
||||||
'swap' : '%s (%s free)' % (system['memory']['swap']['total'], system['memory']['swap']['free']),
|
'swap': '%s (%s free)' % (system['memory']['swap']['total'], system['memory']['swap']['free']),
|
||||||
}
|
}
|
||||||
|
|
||||||
# Services status
|
# Services status
|
||||||
|
|
|
@ -30,12 +30,17 @@ import string
|
||||||
import json
|
import json
|
||||||
import errno
|
import errno
|
||||||
import subprocess
|
import subprocess
|
||||||
import math
|
|
||||||
import re
|
import re
|
||||||
|
import pwd
|
||||||
|
|
||||||
from moulinette.core import MoulinetteError
|
from moulinette.core import MoulinetteError
|
||||||
from moulinette.utils.log import getActionLogger
|
from moulinette.utils.log import getActionLogger
|
||||||
|
|
||||||
|
from yunohost.domain import domain_list
|
||||||
|
from yunohost.hook import hook_callback
|
||||||
|
from yunohost.app import app_ssowatconf
|
||||||
|
|
||||||
|
|
||||||
logger = getActionLogger('yunohost.user')
|
logger = getActionLogger('yunohost.user')
|
||||||
|
|
||||||
|
|
||||||
|
@ -50,12 +55,12 @@ def user_list(auth, fields=None, filter=None, limit=None, offset=None):
|
||||||
fields -- fields to fetch
|
fields -- fields to fetch
|
||||||
|
|
||||||
"""
|
"""
|
||||||
user_attrs = { 'uid': 'username',
|
user_attrs = {'uid': 'username',
|
||||||
'cn': 'fullname',
|
'cn': 'fullname',
|
||||||
'mail': 'mail',
|
'mail': 'mail',
|
||||||
'maildrop': 'mail-forward',
|
'maildrop': 'mail-forward',
|
||||||
'mailuserquota': 'mailbox-quota' }
|
'mailuserquota': 'mailbox-quota'}
|
||||||
attrs = [ 'uid' ]
|
attrs = ['uid']
|
||||||
users = {}
|
users = {}
|
||||||
|
|
||||||
# Set default arguments values
|
# Set default arguments values
|
||||||
|
@ -74,12 +79,12 @@ def user_list(auth, fields=None, filter=None, limit=None, offset=None):
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise MoulinetteError(errno.EINVAL,
|
||||||
m18n.n('field_invalid', attr))
|
m18n.n('field_invalid', attr))
|
||||||
else:
|
else:
|
||||||
attrs = [ 'uid', 'cn', 'mail', 'mailuserquota' ]
|
attrs = ['uid', 'cn', 'mail', 'mailuserquota']
|
||||||
|
|
||||||
result = auth.search('ou=users,dc=yunohost,dc=org', filter, attrs)
|
result = auth.search('ou=users,dc=yunohost,dc=org', filter, attrs)
|
||||||
|
|
||||||
if len(result) > offset and limit > 0:
|
if len(result) > offset and limit > 0:
|
||||||
for user in result[offset:offset+limit]:
|
for user in result[offset:offset + limit]:
|
||||||
entry = {}
|
entry = {}
|
||||||
for attr, values in user.items():
|
for attr, values in user.items():
|
||||||
try:
|
try:
|
||||||
|
@ -88,7 +93,7 @@ def user_list(auth, fields=None, filter=None, limit=None, offset=None):
|
||||||
pass
|
pass
|
||||||
uid = entry[user_attrs['uid']]
|
uid = entry[user_attrs['uid']]
|
||||||
users[uid] = entry
|
users[uid] = entry
|
||||||
return { 'users' : users }
|
return {'users': users}
|
||||||
|
|
||||||
|
|
||||||
def user_create(auth, username, firstname, lastname, mail, password,
|
def user_create(auth, username, firstname, lastname, mail, password,
|
||||||
|
@ -105,15 +110,10 @@ def user_create(auth, username, firstname, lastname, mail, password,
|
||||||
mailbox_quota -- Mailbox size quota
|
mailbox_quota -- Mailbox size quota
|
||||||
|
|
||||||
"""
|
"""
|
||||||
import pwd
|
|
||||||
from yunohost.domain import domain_list
|
|
||||||
from yunohost.hook import hook_callback
|
|
||||||
from yunohost.app import app_ssowatconf
|
|
||||||
|
|
||||||
# Validate uniqueness of username and mail in LDAP
|
# Validate uniqueness of username and mail in LDAP
|
||||||
auth.validate_uniqueness({
|
auth.validate_uniqueness({
|
||||||
'uid' : username,
|
'uid': username,
|
||||||
'mail' : mail
|
'mail': mail
|
||||||
})
|
})
|
||||||
|
|
||||||
# Validate uniqueness of username in system users
|
# Validate uniqueness of username in system users
|
||||||
|
@ -125,10 +125,10 @@ def user_create(auth, username, firstname, lastname, mail, password,
|
||||||
raise MoulinetteError(errno.EEXIST, m18n.n('system_username_exists'))
|
raise MoulinetteError(errno.EEXIST, m18n.n('system_username_exists'))
|
||||||
|
|
||||||
# Check that the mail domain exists
|
# Check that the mail domain exists
|
||||||
if mail[mail.find('@')+1:] not in domain_list(auth)['domains']:
|
if mail[mail.find('@') + 1:] not in domain_list(auth)['domains']:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise MoulinetteError(errno.EINVAL,
|
||||||
m18n.n('mail_domain_unknown',
|
m18n.n('mail_domain_unknown',
|
||||||
domain=mail[mail.find('@')+1:]))
|
domain=mail[mail.find('@') + 1:]))
|
||||||
|
|
||||||
# Get random UID/GID
|
# Get random UID/GID
|
||||||
uid_check = gid_check = 0
|
uid_check = gid_check = 0
|
||||||
|
@ -141,7 +141,7 @@ def user_create(auth, username, firstname, lastname, mail, password,
|
||||||
fullname = '%s %s' % (firstname, lastname)
|
fullname = '%s %s' % (firstname, lastname)
|
||||||
rdn = 'uid=%s,ou=users' % username
|
rdn = 'uid=%s,ou=users' % username
|
||||||
char_set = string.ascii_uppercase + string.digits
|
char_set = string.ascii_uppercase + string.digits
|
||||||
salt = ''.join(random.sample(char_set,8))
|
salt = ''.join(random.sample(char_set, 8))
|
||||||
salt = '$1$' + salt + '$'
|
salt = '$1$' + salt + '$'
|
||||||
user_pwd = '{CRYPT}' + crypt.crypt(str(password), salt)
|
user_pwd = '{CRYPT}' + crypt.crypt(str(password), salt)
|
||||||
attr_dict = {
|
attr_dict = {
|
||||||
|
@ -166,12 +166,12 @@ def user_create(auth, username, firstname, lastname, mail, password,
|
||||||
with open('/etc/yunohost/current_host') as f:
|
with open('/etc/yunohost/current_host') as f:
|
||||||
main_domain = f.readline().rstrip()
|
main_domain = f.readline().rstrip()
|
||||||
aliases = [
|
aliases = [
|
||||||
'root@'+ main_domain,
|
'root@' + main_domain,
|
||||||
'admin@'+ main_domain,
|
'admin@' + main_domain,
|
||||||
'webmaster@'+ main_domain,
|
'webmaster@' + main_domain,
|
||||||
'postmaster@'+ main_domain,
|
'postmaster@' + main_domain,
|
||||||
]
|
]
|
||||||
attr_dict['mail'] = [ attr_dict['mail'] ] + aliases
|
attr_dict['mail'] = [attr_dict['mail']] + aliases
|
||||||
|
|
||||||
# If exists, remove the redirection from the SSO
|
# If exists, remove the redirection from the SSO
|
||||||
try:
|
try:
|
||||||
|
@ -184,8 +184,8 @@ def user_create(auth, username, firstname, lastname, mail, password,
|
||||||
with open('/etc/ssowat/conf.json.persistent', 'w+') as f:
|
with open('/etc/ssowat/conf.json.persistent', 'w+') as f:
|
||||||
json.dump(ssowat_conf, f, sort_keys=True, indent=4)
|
json.dump(ssowat_conf, f, sort_keys=True, indent=4)
|
||||||
|
|
||||||
except IOError: pass
|
except IOError:
|
||||||
|
pass
|
||||||
|
|
||||||
if auth.add(rdn, attr_dict):
|
if auth.add(rdn, attr_dict):
|
||||||
# Invalidate passwd to take user creation into account
|
# Invalidate passwd to take user creation into account
|
||||||
|
@ -194,7 +194,7 @@ def user_create(auth, username, firstname, lastname, mail, password,
|
||||||
# Update SFTP user group
|
# Update SFTP user group
|
||||||
memberlist = auth.search(filter='cn=sftpusers', attrs=['memberUid'])[0]['memberUid']
|
memberlist = auth.search(filter='cn=sftpusers', attrs=['memberUid'])[0]['memberUid']
|
||||||
memberlist.append(username)
|
memberlist.append(username)
|
||||||
if auth.update('cn=sftpusers,ou=groups', { 'memberUid': memberlist }):
|
if auth.update('cn=sftpusers,ou=groups', {'memberUid': memberlist}):
|
||||||
try:
|
try:
|
||||||
# Attempt to create user home folder
|
# Attempt to create user home folder
|
||||||
subprocess.check_call(
|
subprocess.check_call(
|
||||||
|
@ -204,12 +204,12 @@ def user_create(auth, username, firstname, lastname, mail, password,
|
||||||
logger.warning(m18n.n('user_home_creation_failed'),
|
logger.warning(m18n.n('user_home_creation_failed'),
|
||||||
exc_info=1)
|
exc_info=1)
|
||||||
app_ssowatconf(auth)
|
app_ssowatconf(auth)
|
||||||
#TODO: Send a welcome mail to user
|
# TODO: Send a welcome mail to user
|
||||||
logger.success(m18n.n('user_created'))
|
logger.success(m18n.n('user_created'))
|
||||||
hook_callback('post_user_create',
|
hook_callback('post_user_create',
|
||||||
args=[username, mail, password, firstname, lastname])
|
args=[username, mail, password, firstname, lastname])
|
||||||
|
|
||||||
return { 'fullname' : fullname, 'username' : username, 'mail' : mail }
|
return {'fullname': fullname, 'username': username, 'mail': mail}
|
||||||
|
|
||||||
raise MoulinetteError(169, m18n.n('user_creation_failed'))
|
raise MoulinetteError(169, m18n.n('user_creation_failed'))
|
||||||
|
|
||||||
|
@ -223,18 +223,17 @@ def user_delete(auth, username, purge=False):
|
||||||
purge
|
purge
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from yunohost.app import app_ssowatconf
|
|
||||||
from yunohost.hook import hook_callback
|
|
||||||
|
|
||||||
if auth.remove('uid=%s,ou=users' % username):
|
if auth.remove('uid=%s,ou=users' % username):
|
||||||
# Invalidate passwd to take user deletion into account
|
# Invalidate passwd to take user deletion into account
|
||||||
subprocess.call(['nscd', '-i', 'passwd'])
|
subprocess.call(['nscd', '-i', 'passwd'])
|
||||||
|
|
||||||
# Update SFTP user group
|
# Update SFTP user group
|
||||||
memberlist = auth.search(filter='cn=sftpusers', attrs=['memberUid'])[0]['memberUid']
|
memberlist = auth.search(filter='cn=sftpusers', attrs=['memberUid'])[0]['memberUid']
|
||||||
try: memberlist.remove(username)
|
try:
|
||||||
except: pass
|
memberlist.remove(username)
|
||||||
if auth.update('cn=sftpusers,ou=groups', { 'memberUid': memberlist }):
|
except:
|
||||||
|
pass
|
||||||
|
if auth.update('cn=sftpusers,ou=groups', {'memberUid': memberlist}):
|
||||||
if purge:
|
if purge:
|
||||||
subprocess.call(['rm', '-rf', '/home/{0}'.format(username)])
|
subprocess.call(['rm', '-rf', '/home/{0}'.format(username)])
|
||||||
else:
|
else:
|
||||||
|
@ -265,9 +264,6 @@ def user_update(auth, username, firstname=None, lastname=None, mail=None,
|
||||||
remove_mailalias -- Mail aliases to remove
|
remove_mailalias -- Mail aliases to remove
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from yunohost.domain import domain_list
|
|
||||||
from yunohost.app import app_ssowatconf
|
|
||||||
|
|
||||||
attrs_to_fetch = ['givenName', 'sn', 'mail', 'maildrop']
|
attrs_to_fetch = ['givenName', 'sn', 'mail', 'maildrop']
|
||||||
new_attr_dict = {}
|
new_attr_dict = {}
|
||||||
domains = domain_list(auth)['domains']
|
domains = domain_list(auth)['domains']
|
||||||
|
@ -280,11 +276,11 @@ def user_update(auth, username, firstname=None, lastname=None, mail=None,
|
||||||
|
|
||||||
# Get modifications from arguments
|
# Get modifications from arguments
|
||||||
if firstname:
|
if firstname:
|
||||||
new_attr_dict['givenName'] = firstname # TODO: Validate
|
new_attr_dict['givenName'] = firstname # TODO: Validate
|
||||||
new_attr_dict['cn'] = new_attr_dict['displayName'] = firstname + ' ' + user['sn'][0]
|
new_attr_dict['cn'] = new_attr_dict['displayName'] = firstname + ' ' + user['sn'][0]
|
||||||
|
|
||||||
if lastname:
|
if lastname:
|
||||||
new_attr_dict['sn'] = lastname # TODO: Validate
|
new_attr_dict['sn'] = lastname # TODO: Validate
|
||||||
new_attr_dict['cn'] = new_attr_dict['displayName'] = user['givenName'][0] + ' ' + lastname
|
new_attr_dict['cn'] = new_attr_dict['displayName'] = user['givenName'][0] + ' ' + lastname
|
||||||
|
|
||||||
if lastname and firstname:
|
if lastname and firstname:
|
||||||
|
@ -292,34 +288,34 @@ def user_update(auth, username, firstname=None, lastname=None, mail=None,
|
||||||
|
|
||||||
if change_password:
|
if change_password:
|
||||||
char_set = string.ascii_uppercase + string.digits
|
char_set = string.ascii_uppercase + string.digits
|
||||||
salt = ''.join(random.sample(char_set,8))
|
salt = ''.join(random.sample(char_set, 8))
|
||||||
salt = '$1$' + salt + '$'
|
salt = '$1$' + salt + '$'
|
||||||
new_attr_dict['userPassword'] = '{CRYPT}' + crypt.crypt(str(change_password), salt)
|
new_attr_dict['userPassword'] = '{CRYPT}' + crypt.crypt(str(change_password), salt)
|
||||||
|
|
||||||
if mail:
|
if mail:
|
||||||
auth.validate_uniqueness({ 'mail': mail })
|
auth.validate_uniqueness({'mail': mail})
|
||||||
if mail[mail.find('@')+1:] not in domains:
|
if mail[mail.find('@') + 1:] not in domains:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise MoulinetteError(errno.EINVAL,
|
||||||
m18n.n('mail_domain_unknown',
|
m18n.n('mail_domain_unknown',
|
||||||
domain=mail[mail.find('@')+1:]))
|
domain=mail[mail.find('@') + 1:]))
|
||||||
del user['mail'][0]
|
del user['mail'][0]
|
||||||
new_attr_dict['mail'] = [mail] + user['mail']
|
new_attr_dict['mail'] = [mail] + user['mail']
|
||||||
|
|
||||||
if add_mailalias:
|
if add_mailalias:
|
||||||
if not isinstance(add_mailalias, list):
|
if not isinstance(add_mailalias, list):
|
||||||
add_mailalias = [ add_mailalias ]
|
add_mailalias = [add_mailalias]
|
||||||
for mail in add_mailalias:
|
for mail in add_mailalias:
|
||||||
auth.validate_uniqueness({ 'mail': mail })
|
auth.validate_uniqueness({'mail': mail})
|
||||||
if mail[mail.find('@')+1:] not in domains:
|
if mail[mail.find('@') + 1:] not in domains:
|
||||||
raise MoulinetteError(errno.EINVAL,
|
raise MoulinetteError(errno.EINVAL,
|
||||||
m18n.n('mail_domain_unknown',
|
m18n.n('mail_domain_unknown',
|
||||||
domain=mail[mail.find('@')+1:]))
|
domain=mail[mail.find('@') + 1:]))
|
||||||
user['mail'].append(mail)
|
user['mail'].append(mail)
|
||||||
new_attr_dict['mail'] = user['mail']
|
new_attr_dict['mail'] = user['mail']
|
||||||
|
|
||||||
if remove_mailalias:
|
if remove_mailalias:
|
||||||
if not isinstance(remove_mailalias, list):
|
if not isinstance(remove_mailalias, list):
|
||||||
remove_mailalias = [ remove_mailalias ]
|
remove_mailalias = [remove_mailalias]
|
||||||
for mail in remove_mailalias:
|
for mail in remove_mailalias:
|
||||||
if len(user['mail']) > 1 and mail in user['mail'][1:]:
|
if len(user['mail']) > 1 and mail in user['mail'][1:]:
|
||||||
user['mail'].remove(mail)
|
user['mail'].remove(mail)
|
||||||
|
@ -330,7 +326,7 @@ def user_update(auth, username, firstname=None, lastname=None, mail=None,
|
||||||
|
|
||||||
if add_mailforward:
|
if add_mailforward:
|
||||||
if not isinstance(add_mailforward, list):
|
if not isinstance(add_mailforward, list):
|
||||||
add_mailforward = [ add_mailforward ]
|
add_mailforward = [add_mailforward]
|
||||||
for mail in add_mailforward:
|
for mail in add_mailforward:
|
||||||
if mail in user['maildrop'][1:]:
|
if mail in user['maildrop'][1:]:
|
||||||
continue
|
continue
|
||||||
|
@ -339,7 +335,7 @@ def user_update(auth, username, firstname=None, lastname=None, mail=None,
|
||||||
|
|
||||||
if remove_mailforward:
|
if remove_mailforward:
|
||||||
if not isinstance(remove_mailforward, list):
|
if not isinstance(remove_mailforward, list):
|
||||||
remove_mailforward = [ remove_mailforward ]
|
remove_mailforward = [remove_mailforward]
|
||||||
for mail in remove_mailforward:
|
for mail in remove_mailforward:
|
||||||
if len(user['maildrop']) > 1 and mail in user['maildrop'][1:]:
|
if len(user['maildrop']) > 1 and mail in user['maildrop'][1:]:
|
||||||
user['maildrop'].remove(mail)
|
user['maildrop'].remove(mail)
|
||||||
|
@ -352,11 +348,11 @@ def user_update(auth, username, firstname=None, lastname=None, mail=None,
|
||||||
new_attr_dict['mailuserquota'] = mailbox_quota
|
new_attr_dict['mailuserquota'] = mailbox_quota
|
||||||
|
|
||||||
if auth.update('uid=%s,ou=users' % username, new_attr_dict):
|
if auth.update('uid=%s,ou=users' % username, new_attr_dict):
|
||||||
logger.success(m18n.n('user_updated'))
|
logger.success(m18n.n('user_updated'))
|
||||||
app_ssowatconf(auth)
|
app_ssowatconf(auth)
|
||||||
return user_info(auth, username)
|
return user_info(auth, username)
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(169, m18n.n('user_update_failed'))
|
raise MoulinetteError(169, m18n.n('user_update_failed'))
|
||||||
|
|
||||||
|
|
||||||
def user_info(auth, username):
|
def user_info(auth, username):
|
||||||
|
@ -372,9 +368,9 @@ def user_info(auth, username):
|
||||||
]
|
]
|
||||||
|
|
||||||
if len(username.split('@')) is 2:
|
if len(username.split('@')) is 2:
|
||||||
filter = 'mail='+ username
|
filter = 'mail=' + username
|
||||||
else:
|
else:
|
||||||
filter = 'uid='+ username
|
filter = 'uid=' + username
|
||||||
|
|
||||||
result = auth.search('ou=users,dc=yunohost,dc=org', filter, user_attrs)
|
result = auth.search('ou=users,dc=yunohost,dc=org', filter, user_attrs)
|
||||||
|
|
||||||
|
@ -399,27 +395,30 @@ def user_info(auth, username):
|
||||||
|
|
||||||
if 'mailuserquota' in user:
|
if 'mailuserquota' in user:
|
||||||
if user['mailuserquota'][0] != '0':
|
if user['mailuserquota'][0] != '0':
|
||||||
cmd = 'doveadm -f flow quota get -u %s' % user['uid'][0]
|
cmd = 'doveadm -f flow quota get -u %s' % user['uid'][0]
|
||||||
userquota = subprocess.check_output(cmd,stderr=subprocess.STDOUT,
|
userquota = subprocess.check_output(cmd, stderr=subprocess.STDOUT,
|
||||||
shell=True)
|
shell=True)
|
||||||
quotavalue = re.findall(r'\d+', userquota)
|
quotavalue = re.findall(r'\d+', userquota)
|
||||||
result = '%s (%s%s)' % ( _convertSize(eval(quotavalue[0])),
|
result = '%s (%s%s)' % (_convertSize(eval(quotavalue[0])),
|
||||||
quotavalue[2], '%')
|
quotavalue[2], '%')
|
||||||
result_dict['mailbox-quota'] = {
|
result_dict['mailbox-quota'] = {
|
||||||
'limit' : user['mailuserquota'][0],
|
'limit': user['mailuserquota'][0],
|
||||||
'use' : result
|
'use': result
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
result_dict['mailbox-quota'] = m18n.n('unlimit')
|
result_dict['mailbox-quota'] = m18n.n('unlimit')
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
return result_dict
|
return result_dict
|
||||||
else:
|
else:
|
||||||
raise MoulinetteError(167, m18n.n('user_info_failed'))
|
raise MoulinetteError(167, m18n.n('user_info_failed'))
|
||||||
|
|
||||||
|
|
||||||
def _convertSize(num, suffix=''):
|
def _convertSize(num, suffix=''):
|
||||||
for unit in ['K','M','G','T','P','E','Z']:
|
for unit in ['K', 'M', 'G', 'T', 'P', 'E', 'Z']:
|
||||||
if abs(num) < 1024.0:
|
if abs(num) < 1024.0:
|
||||||
return "%3.1f%s%s" % (num, unit, suffix)
|
return "%3.1f%s%s" % (num, unit, suffix)
|
||||||
|
|
||||||
num /= 1024.0
|
num /= 1024.0
|
||||||
|
|
||||||
return "%.1f%s%s" % (num, 'Yi', suffix)
|
return "%.1f%s%s" % (num, 'Yi', suffix)
|
||||||
|
|
Loading…
Add table
Reference in a new issue