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
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import shutil
|
||||
import stat
|
||||
import yaml
|
||||
import time
|
||||
import re
|
||||
import string
|
||||
import random
|
||||
import socket
|
||||
import urlparse
|
||||
import errno
|
||||
|
@ -42,6 +42,10 @@ from moulinette.utils.log import getActionLogger
|
|||
|
||||
from yunohost.service import service_log
|
||||
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')
|
||||
|
||||
|
@ -333,8 +337,6 @@ def app_upgrade(auth, app=[], url=None, file=None):
|
|||
url -- Git url to fetch for upgrade
|
||||
|
||||
"""
|
||||
from yunohost.hook import hook_add, hook_remove, hook_exec
|
||||
|
||||
try:
|
||||
app_list()
|
||||
except MoulinetteError:
|
||||
|
@ -445,8 +447,6 @@ def app_install(auth, app, label=None, args=None):
|
|||
args -- Serialize arguments for app installation
|
||||
|
||||
"""
|
||||
from yunohost.hook import hook_add, hook_remove, hook_exec
|
||||
|
||||
# Fetch or extract sources
|
||||
try: os.listdir(install_tmp)
|
||||
except OSError: os.makedirs(install_tmp)
|
||||
|
@ -588,8 +588,6 @@ def app_remove(auth, app):
|
|||
app -- App(s) to delete
|
||||
|
||||
"""
|
||||
from yunohost.hook import hook_exec, hook_remove
|
||||
|
||||
if not _is_installed(app):
|
||||
raise MoulinetteError(errno.EINVAL,
|
||||
m18n.n('app_not_installed', app=app))
|
||||
|
@ -631,9 +629,6 @@ def app_addaccess(auth, apps, users=[]):
|
|||
apps
|
||||
|
||||
"""
|
||||
from yunohost.user import user_list, user_info
|
||||
from yunohost.hook import hook_callback
|
||||
|
||||
result = {}
|
||||
|
||||
if not users:
|
||||
|
@ -686,9 +681,6 @@ def app_removeaccess(auth, apps, users=[]):
|
|||
apps
|
||||
|
||||
"""
|
||||
from yunohost.user import user_list
|
||||
from yunohost.hook import hook_callback
|
||||
|
||||
result = {}
|
||||
|
||||
remove_all = False
|
||||
|
@ -736,8 +728,6 @@ def app_clearaccess(auth, apps):
|
|||
apps
|
||||
|
||||
"""
|
||||
from yunohost.hook import hook_callback
|
||||
|
||||
if not isinstance(apps, list): apps = [apps]
|
||||
|
||||
for app in apps:
|
||||
|
@ -788,8 +778,6 @@ def app_makedefault(auth, app, domain=None):
|
|||
domain
|
||||
|
||||
"""
|
||||
from yunohost.domain import domain_list
|
||||
|
||||
app_settings = _get_app_settings(app)
|
||||
app_domain = app_settings['domain']
|
||||
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
|
||||
|
||||
"""
|
||||
from yunohost.domain import domain_list
|
||||
|
||||
if "https://" == url[:8]:
|
||||
url = url[8:]
|
||||
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:
|
||||
main_domain = f.readline().rstrip()
|
||||
|
||||
|
@ -1404,11 +1387,11 @@ def _value_for_locale(values):
|
|||
if not isinstance(values, dict):
|
||||
return values
|
||||
|
||||
for lang in [m18n.locale, m18n.default_locale]:
|
||||
try:
|
||||
return _encode_string(values[lang])
|
||||
except KeyError:
|
||||
continue
|
||||
if m18n.locale in values:
|
||||
return _encode_string(values[m18n.locale])
|
||||
|
||||
if m18n.default_locale in values:
|
||||
return _encode_string(values[m18n.default_locale])
|
||||
|
||||
# Fallback to first value
|
||||
return _encode_string(values.values()[0])
|
||||
|
@ -1466,6 +1449,7 @@ def _check_manifest_requirements(manifest):
|
|||
pkgname=pkgname, version=version,
|
||||
spec=spec))
|
||||
|
||||
|
||||
def _parse_args_from_manifest(manifest, action, args={}, auth=None):
|
||||
"""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
|
||||
|
||||
"""
|
||||
from yunohost.domain import domain_list
|
||||
from yunohost.user import user_info
|
||||
|
||||
args_list = OrderedDict()
|
||||
try:
|
||||
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
|
||||
return args_list
|
||||
|
||||
|
||||
def _make_environment_dict(args_dict):
|
||||
"""
|
||||
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
|
||||
return env_dict
|
||||
|
||||
|
||||
def _parse_app_instance_name(app_instance_name):
|
||||
"""
|
||||
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
|
||||
return (appid, app_instance_nb)
|
||||
|
||||
|
||||
def is_true(arg):
|
||||
"""
|
||||
Convert a string into a boolean
|
||||
|
@ -1650,7 +1634,5 @@ def random_password(length=8):
|
|||
length -- The string length to generate
|
||||
|
||||
"""
|
||||
import string, random
|
||||
|
||||
char_set = string.ascii_uppercase + string.digits + string.ascii_lowercase
|
||||
return ''.join(random.sample(char_set, length))
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
"""
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import json
|
||||
import errno
|
||||
import time
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
""" License
|
||||
|
||||
Copyright (C) 2013 YunoHost
|
||||
Copyright (C) 2013-2016 YunoHost
|
||||
|
||||
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
|
||||
|
@ -24,20 +24,20 @@
|
|||
Manage domains
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import datetime
|
||||
import re
|
||||
import shutil
|
||||
import json
|
||||
import yaml
|
||||
import errno
|
||||
import shutil
|
||||
import requests
|
||||
from urllib import urlopen
|
||||
|
||||
from moulinette.core import MoulinetteError
|
||||
from moulinette.utils.log import getActionLogger
|
||||
|
||||
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')
|
||||
|
||||
|
@ -80,13 +80,9 @@ def domain_add(auth, domain, dyndns=False):
|
|||
dyndns -- Subscribe to DynDNS
|
||||
|
||||
"""
|
||||
from yunohost.hook import hook_callback
|
||||
|
||||
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']:
|
||||
raise MoulinetteError(errno.EEXIST, m18n.n('domain_exists'))
|
||||
|
||||
|
@ -94,7 +90,6 @@ def domain_add(auth, domain, dyndns=False):
|
|||
if dyndns:
|
||||
if len(domain.split('.')) < 3:
|
||||
raise MoulinetteError(errno.EINVAL, m18n.n('domain_dyndns_invalid'))
|
||||
from yunohost.dyndns import dyndns_subscribe
|
||||
|
||||
try:
|
||||
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:
|
||||
service_regen_conf(names=[
|
||||
'nginx', 'metronome', 'dnsmasq', 'rmilter'])
|
||||
os.system('yunohost app ssowatconf > /dev/null 2>&1')
|
||||
app_ssowatconf(auth)
|
||||
except IOError: pass
|
||||
except:
|
||||
# Force domain removal silently
|
||||
try: domain_remove(auth, domain, True)
|
||||
except: pass
|
||||
try:
|
||||
domain_remove(auth, domain, True)
|
||||
except:
|
||||
pass
|
||||
raise
|
||||
|
||||
hook_callback('post_domain_add', args=[domain])
|
||||
|
@ -182,8 +179,6 @@ def domain_remove(auth, domain, force=False):
|
|||
force -- Force the domain removal
|
||||
|
||||
"""
|
||||
from yunohost.hook import hook_callback
|
||||
|
||||
if not force and domain not in domain_list(auth)['domains']:
|
||||
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'))
|
||||
|
||||
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:
|
||||
raise MoulinetteError(errno.EIO, m18n.n('domain_deletion_failed'))
|
||||
|
||||
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])
|
||||
|
||||
|
@ -296,7 +291,7 @@ def get_public_ip(protocol=4):
|
|||
else:
|
||||
raise ValueError("invalid protocol version")
|
||||
try:
|
||||
return urlopen(url).read().strip()
|
||||
return requests.get(url).content.strip()
|
||||
except IOError:
|
||||
logger.debug('cannot retrieve public IPv%d' % protocol, exc_info=1)
|
||||
raise MoulinetteError(errno.ENETUNREACH,
|
||||
|
|
|
@ -40,6 +40,10 @@ from yunohost.domain import get_public_ip
|
|||
logger = getActionLogger('yunohost.dyndns')
|
||||
|
||||
|
||||
RE_DYNDNS_PRIVATE_KEY = re.compile(
|
||||
r'.*/K(?P<domain>[^\s\+]+)\.\+157.+\.private$'
|
||||
)
|
||||
|
||||
class IPRouteLine(object):
|
||||
""" Utility class to parse an ip route output line
|
||||
|
||||
|
@ -62,10 +66,6 @@ class IPRouteLine(object):
|
|||
for k, v in self.m.groupdict().items():
|
||||
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):
|
||||
"""
|
||||
|
@ -171,7 +171,7 @@ def dyndns_update(dyn_host="dyndns.yunohost.org", domain=None, key=None,
|
|||
if domain is None:
|
||||
# Retrieve the first registered domain
|
||||
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:
|
||||
continue
|
||||
_domain = match.group('domain')
|
||||
|
|
|
@ -36,7 +36,9 @@ except ImportError:
|
|||
from moulinette.core import MoulinetteError
|
||||
from moulinette.utils import process
|
||||
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'
|
||||
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']
|
||||
upnp = True
|
||||
if ipv4_only and ipv6_only:
|
||||
upnp = True # automatically disallow UPnP
|
||||
upnp = True # automatically disallow UPnP
|
||||
elif ipv4_only:
|
||||
ipvs = ['ipv4',]
|
||||
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']))
|
||||
|
||||
# Format returned dict
|
||||
ret = { "opened_ports": ports }
|
||||
ret = {"opened_ports": ports}
|
||||
if list_forwarded:
|
||||
# Combine TCP and UDP forwarded ports
|
||||
ret['forwarded_ports'] = sorted(
|
||||
|
@ -194,8 +196,6 @@ def firewall_reload(skip_upnp=False):
|
|||
skip_upnp -- Do not refresh port forwarding using UPnP
|
||||
|
||||
"""
|
||||
from yunohost.hook import hook_callback
|
||||
|
||||
reloaded = False
|
||||
errors = False
|
||||
|
||||
|
@ -224,8 +224,8 @@ def firewall_reload(skip_upnp=False):
|
|||
# Iterate over ports and add rule
|
||||
for protocol in ['TCP', 'UDP']:
|
||||
for port in firewall['ipv4'][protocol]:
|
||||
rules.append("iptables -A INPUT -p %s --dport %s -j ACCEPT" \
|
||||
% (protocol, process.quote(str(port))))
|
||||
rules.append("iptables -A INPUT -p %s --dport %s -j ACCEPT"
|
||||
% (protocol, process.quote(str(port))))
|
||||
rules += [
|
||||
"iptables -A INPUT -i lo -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
|
||||
for protocol in ['TCP', 'UDP']:
|
||||
for port in firewall['ipv6'][protocol]:
|
||||
rules.append("ip6tables -A INPUT -p %s --dport %s -j ACCEPT" \
|
||||
% (protocol, process.quote(str(port))))
|
||||
rules.append("ip6tables -A INPUT -p %s --dport %s -j ACCEPT"
|
||||
% (protocol, process.quote(str(port))))
|
||||
rules += [
|
||||
"ip6tables -A INPUT -i lo -j ACCEPT",
|
||||
"ip6tables -A INPUT -p icmpv6 -j ACCEPT",
|
||||
|
@ -308,13 +308,14 @@ def firewall_upnp(action='status', no_refresh=False):
|
|||
try:
|
||||
# Remove old cron job
|
||||
os.remove('/etc/cron.d/yunohost-firewall')
|
||||
except: pass
|
||||
except:
|
||||
pass
|
||||
action = 'status'
|
||||
no_refresh = False
|
||||
|
||||
if action == 'status' and no_refresh:
|
||||
# Only return current state
|
||||
return { 'enabled': enabled }
|
||||
return {'enabled': enabled}
|
||||
elif action == 'enable' or (enabled and action == 'status'):
|
||||
# Add cron job
|
||||
with open(upnp_cron_job, 'w+') as f:
|
||||
|
@ -330,7 +331,8 @@ def firewall_upnp(action='status', no_refresh=False):
|
|||
try:
|
||||
# Remove cron job
|
||||
os.remove(upnp_cron_job)
|
||||
except: pass
|
||||
except:
|
||||
pass
|
||||
enabled = False
|
||||
if action == 'status':
|
||||
no_refresh = True
|
||||
|
@ -364,7 +366,8 @@ def firewall_upnp(action='status', no_refresh=False):
|
|||
if upnpc.getspecificportmapping(port, protocol):
|
||||
try:
|
||||
upnpc.deleteportmapping(port, protocol)
|
||||
except: pass
|
||||
except:
|
||||
pass
|
||||
if not enabled:
|
||||
continue
|
||||
try:
|
||||
|
@ -403,7 +406,7 @@ def firewall_upnp(action='status', no_refresh=False):
|
|||
|
||||
if action == 'enable' and not enabled:
|
||||
raise MoulinetteError(errno.ENXIO, m18n.n('upnp_port_open_failed'))
|
||||
return { 'enabled': enabled }
|
||||
return {'enabled': enabled}
|
||||
|
||||
|
||||
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
|
||||
one if it's not defined.
|
||||
"""
|
||||
from moulinette.utils.text import searchf
|
||||
try:
|
||||
m = searchf(r'^Port[ \t]+([0-9]+)$',
|
||||
'/etc/ssh/sshd_config', count=-1)
|
||||
|
@ -444,12 +446,14 @@ def _get_ssh_port(default=22):
|
|||
pass
|
||||
return default
|
||||
|
||||
|
||||
def _update_firewall_file(rules):
|
||||
"""Make a backup and write new rules to firewall file"""
|
||||
os.system("cp {0} {0}.old".format(firewall_file))
|
||||
with open(firewall_file, 'w') as f:
|
||||
yaml.safe_dump(rules, f, default_flow_style=False)
|
||||
|
||||
|
||||
def _on_rule_command_error(returncode, cmd, output):
|
||||
"""Callback for rules commands error"""
|
||||
# Log error and continue commands execution
|
||||
|
|
|
@ -24,15 +24,12 @@
|
|||
Manage hooks
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import json
|
||||
import errno
|
||||
import subprocess
|
||||
from glob import iglob
|
||||
|
||||
from moulinette.core import MoulinetteError
|
||||
from moulinette.utils import log
|
||||
from moulinette.utils.process import call_async_output
|
||||
|
||||
hook_folder = '/usr/share/yunohost/hooks/'
|
||||
custom_hook_folder = '/etc/yunohost/hooks.d/'
|
||||
|
@ -52,14 +49,16 @@ def hook_add(app, file):
|
|||
path, filename = os.path.split(file)
|
||||
priority, action = _extract_filename_parts(filename)
|
||||
|
||||
try: os.listdir(custom_hook_folder + action)
|
||||
except OSError: os.makedirs(custom_hook_folder + action)
|
||||
try:
|
||||
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('chown -hR admin: %s' % hook_folder)
|
||||
|
||||
return { 'hook': finalpath }
|
||||
return {'hook': finalpath}
|
||||
|
||||
|
||||
def hook_remove(app):
|
||||
|
@ -74,8 +73,9 @@ def hook_remove(app):
|
|||
for action in os.listdir(custom_hook_folder):
|
||||
for script in os.listdir(custom_hook_folder + action):
|
||||
if script.endswith(app):
|
||||
os.remove(custom_hook_folder + action +'/'+ script)
|
||||
except OSError: pass
|
||||
os.remove(custom_hook_folder + action + '/' + script)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
||||
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):
|
||||
# Use the priority as key and a dict of hooks names
|
||||
# with their info as value
|
||||
value = { 'path': path }
|
||||
value = {'path': path}
|
||||
try:
|
||||
d[priority][name] = value
|
||||
except KeyError:
|
||||
d[priority] = { name: value }
|
||||
d[priority] = {name: value}
|
||||
else:
|
||||
def _append_hook(d, priority, name, path):
|
||||
# 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:
|
||||
h['path'] = path
|
||||
return
|
||||
l.append({ 'priority': priority, 'path': path })
|
||||
l.append({'priority': priority, 'path': path})
|
||||
d[name] = l
|
||||
else:
|
||||
if list_by == 'name':
|
||||
result = set()
|
||||
|
||||
def _append_hook(d, priority, name, path):
|
||||
# Add only the 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",
|
||||
action, custom_hook_folder)
|
||||
|
||||
return { 'hooks': result }
|
||||
return {'hooks': result}
|
||||
|
||||
|
||||
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
|
||||
|
||||
"""
|
||||
result = { 'succeed': {}, 'failed': {} }
|
||||
result = {'succeed': {}, 'failed': {}}
|
||||
hooks_dict = {}
|
||||
|
||||
# Retrieve hooks
|
||||
|
@ -258,7 +259,7 @@ def hook_callback(action, hooks=[], args=None, no_trace=False, chdir=None,
|
|||
for h in hl:
|
||||
# Update hooks 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
|
||||
if not hooks_dict:
|
||||
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
|
||||
|
||||
"""
|
||||
from moulinette.utils.process import call_async_output
|
||||
from yunohost.app import _value_for_locale
|
||||
|
||||
# Validate hook path
|
||||
if path[0] != '/':
|
||||
path = os.path.realpath(path)
|
||||
|
|
|
@ -35,12 +35,15 @@ import errno
|
|||
import os
|
||||
import dns.resolver
|
||||
import cPickle as pickle
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime
|
||||
|
||||
from moulinette.core import MoulinetteError
|
||||
from moulinette.utils.log import getActionLogger
|
||||
|
||||
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')
|
||||
|
||||
|
@ -406,9 +409,6 @@ def monitor_enable(no_stats=False):
|
|||
no_stats -- Disable monitoring statistics
|
||||
|
||||
"""
|
||||
from yunohost.service import (service_status, service_enable,
|
||||
service_start)
|
||||
|
||||
glances = service_status('glances')
|
||||
if glances['status'] != 'running':
|
||||
service_start('glances')
|
||||
|
@ -433,9 +433,6 @@ def monitor_disable():
|
|||
Disable server monitoring
|
||||
|
||||
"""
|
||||
from yunohost.service import (service_status, service_disable,
|
||||
service_stop)
|
||||
|
||||
glances = service_status('glances')
|
||||
if glances['status'] != 'inactive':
|
||||
service_stop('glances')
|
||||
|
@ -467,8 +464,6 @@ def _get_glances_api():
|
|||
else:
|
||||
return p
|
||||
|
||||
from yunohost.service import service_status
|
||||
|
||||
if service_status('glances')['status'] != 'running':
|
||||
raise MoulinetteError(errno.EPERM, m18n.n('monitor_not_enabled'))
|
||||
raise MoulinetteError(errno.EIO, m18n.n('monitor_glances_con_failed'))
|
||||
|
@ -722,22 +717,26 @@ def _append_to_stats(stats, monitor, statics=[]):
|
|||
statics = [statics]
|
||||
|
||||
# Appending function
|
||||
def _append(s, m, st):
|
||||
for k, v in m.items():
|
||||
if k in st:
|
||||
s[k] = v
|
||||
elif isinstance(v, dict):
|
||||
if k not in s:
|
||||
s[k] = {}
|
||||
s[k] = _append(s[k], v, st)
|
||||
def _append(_stats, _monitor, _statics):
|
||||
for key, value in _monitor.items():
|
||||
if key in _statics:
|
||||
_stats[key] = value
|
||||
|
||||
elif isinstance(value, dict):
|
||||
if key not in _stats:
|
||||
_stats[key] = {}
|
||||
_stats[key] = _append(_stats[key], value, _statics)
|
||||
|
||||
else:
|
||||
if k not in s:
|
||||
s[k] = []
|
||||
if isinstance(v, list):
|
||||
s[k].extend(v)
|
||||
if key not in _stats:
|
||||
_stats[key] = []
|
||||
|
||||
if isinstance(value, list):
|
||||
_stats[key].extend(value)
|
||||
else:
|
||||
s[k].append(v)
|
||||
return s
|
||||
_stats[key].append(value)
|
||||
|
||||
return _stats
|
||||
|
||||
stats = _append(stats, monitor, statics)
|
||||
return stats
|
||||
|
|
|
@ -36,7 +36,7 @@ from difflib import unified_diff
|
|||
from moulinette.core import MoulinetteError
|
||||
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'
|
||||
|
|
|
@ -24,10 +24,7 @@
|
|||
Specific tools
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import yaml
|
||||
import re
|
||||
import getpass
|
||||
import requests
|
||||
import json
|
||||
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.domain import domain_add, domain_list, get_public_ip
|
||||
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.monitor import monitor_disk, monitor_network, monitor_system
|
||||
from yunohost.monitor import monitor_disk, monitor_system
|
||||
from yunohost.utils.packages import ynh_packages_version
|
||||
|
||||
apps_setting_path= '/etc/yunohost/apps/'
|
||||
apps_setting_path = '/etc/yunohost/apps/'
|
||||
|
||||
logger = getActionLogger('yunohost.tools')
|
||||
|
||||
|
@ -62,12 +59,16 @@ def tools_ldapinit(auth):
|
|||
ldap_map = yaml.load(f)
|
||||
|
||||
for rdn, attr_dict in ldap_map['parents'].items():
|
||||
try: auth.add(rdn, attr_dict)
|
||||
except: pass
|
||||
try:
|
||||
auth.add(rdn, attr_dict)
|
||||
except:
|
||||
pass
|
||||
|
||||
for rdn, attr_dict in ldap_map['children'].items():
|
||||
try: auth.add(rdn, attr_dict)
|
||||
except: pass
|
||||
try:
|
||||
auth.add(rdn, attr_dict)
|
||||
except:
|
||||
pass
|
||||
|
||||
admin_dict = {
|
||||
'cn': 'admin',
|
||||
|
@ -118,7 +119,7 @@ def tools_maindomain(auth, old_domain=None, new_domain=None, dyndns=False):
|
|||
old_domain = f.readline().rstrip()
|
||||
|
||||
if not new_domain:
|
||||
return { 'current_main_domain': old_domain }
|
||||
return {'current_main_domain': old_domain}
|
||||
|
||||
if not new_domain:
|
||||
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 = [
|
||||
'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,
|
||||
]
|
||||
|
||||
|
@ -146,14 +147,15 @@ def tools_maindomain(auth, old_domain=None, new_domain=None, dyndns=False):
|
|||
pass
|
||||
else:
|
||||
dyndomains = json.loads(r.text)
|
||||
dyndomain = '.'.join(new_domain.split('.')[1:])
|
||||
dyndomain = '.'.join(new_domain.split('.')[1:])
|
||||
if dyndomain in dyndomains:
|
||||
dyndns_subscribe(domain=new_domain)
|
||||
|
||||
try:
|
||||
with open('/etc/yunohost/installed', 'r') as f:
|
||||
service_regen_conf()
|
||||
except IOError: pass
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
logger.success(m18n.n('maindomain_changed'))
|
||||
|
||||
|
@ -181,7 +183,7 @@ def tools_postinstall(domain, password, ignore_dyndns=False):
|
|||
pass
|
||||
else:
|
||||
dyndomains = json.loads(r.text)
|
||||
dyndomain = '.'.join(domain.split('.')[1:])
|
||||
dyndomain = '.'.join(domain.split('.')[1:])
|
||||
if dyndomain in dyndomains:
|
||||
if requests.get('https://dyndns.yunohost.org/test/%s' % domain).status_code == 200:
|
||||
dyndns = True
|
||||
|
@ -195,7 +197,7 @@ def tools_postinstall(domain, password, ignore_dyndns=False):
|
|||
auth = init_authenticator(('ldap', 'default'),
|
||||
{'uri': "ldap://localhost:389",
|
||||
'base_dn': "dc=yunohost,dc=org",
|
||||
'user_rdn': "cn=admin" })
|
||||
'user_rdn': "cn=admin"})
|
||||
auth.authenticate('yunohost')
|
||||
|
||||
# Initialize LDAP for YunoHost
|
||||
|
@ -212,8 +214,10 @@ def tools_postinstall(domain, password, ignore_dyndns=False):
|
|||
]
|
||||
|
||||
for folder in folders_to_create:
|
||||
try: os.listdir(folder)
|
||||
except OSError: os.makedirs(folder)
|
||||
try:
|
||||
os.listdir(folder)
|
||||
except OSError:
|
||||
os.makedirs(folder)
|
||||
|
||||
# Change folders permissions
|
||||
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:
|
||||
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:
|
||||
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'
|
||||
command_list = [
|
||||
'echo "01" > %s/serial' % ssl_dir,
|
||||
'rm %s/index.txt' % ssl_dir,
|
||||
'touch %s/index.txt' % ssl_dir,
|
||||
'rm %s/index.txt' % ssl_dir,
|
||||
'touch %s/index.txt' % 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),
|
||||
'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()
|
||||
except MoulinetteError:
|
||||
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)
|
||||
new_app_dict = app_info(original_app_id, raw=True)
|
||||
for app_id in os.listdir(apps_setting_path):
|
||||
if '__' in app_id:
|
||||
original_app_id = app_id[:app_id.index('__')]
|
||||
else:
|
||||
original_app_id = app_id
|
||||
|
||||
# Custom app
|
||||
if new_app_dict is None or 'lastUpdate' not in new_app_dict or 'git' not in new_app_dict:
|
||||
continue
|
||||
current_app_dict = app_info(app_id, raw=True)
|
||||
new_app_dict = app_info(original_app_id, raw=True)
|
||||
|
||||
if (new_app_dict['lastUpdate'] > current_app_dict['lastUpdate']) \
|
||||
or ('update_time' not in current_app_dict['settings'] \
|
||||
and (new_app_dict['lastUpdate'] > current_app_dict['settings']['install_time'])) \
|
||||
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']
|
||||
})
|
||||
# Custom app
|
||||
if new_app_dict is None or 'lastUpdate' not in new_app_dict or 'git' not in new_app_dict:
|
||||
continue
|
||||
|
||||
if (new_app_dict['lastUpdate'] > current_app_dict['lastUpdate']) \
|
||||
or ('update_time' not in current_app_dict['settings'] \
|
||||
and (new_app_dict['lastUpdate'] > current_app_dict['settings']['install_time'])) \
|
||||
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:
|
||||
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):
|
||||
|
@ -381,7 +384,7 @@ def tools_upgrade(auth, ignore_apps=False, ignore_packages=False):
|
|||
# ... and set a hourly cron up to upgrade critical packages
|
||||
if critical_upgrades:
|
||||
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:
|
||||
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
|
||||
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):
|
||||
|
@ -422,7 +425,7 @@ def tools_diagnosis(auth, private=False):
|
|||
Return global info about current yunohost instance to help debugging
|
||||
|
||||
"""
|
||||
diagnosis = OrderedDict();
|
||||
diagnosis = OrderedDict()
|
||||
|
||||
# Debian release
|
||||
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)
|
||||
else:
|
||||
diagnosis['system']['memory'] = {
|
||||
'ram' : '%s (%s free)' % (system['memory']['ram']['total'], system['memory']['ram']['free']),
|
||||
'swap' : '%s (%s free)' % (system['memory']['swap']['total'], system['memory']['swap']['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']),
|
||||
}
|
||||
|
||||
# Services status
|
||||
|
|
|
@ -30,12 +30,17 @@ import string
|
|||
import json
|
||||
import errno
|
||||
import subprocess
|
||||
import math
|
||||
import re
|
||||
import pwd
|
||||
|
||||
from moulinette.core import MoulinetteError
|
||||
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')
|
||||
|
||||
|
||||
|
@ -50,12 +55,12 @@ def user_list(auth, fields=None, filter=None, limit=None, offset=None):
|
|||
fields -- fields to fetch
|
||||
|
||||
"""
|
||||
user_attrs = { 'uid': 'username',
|
||||
'cn': 'fullname',
|
||||
'mail': 'mail',
|
||||
'maildrop': 'mail-forward',
|
||||
'mailuserquota': 'mailbox-quota' }
|
||||
attrs = [ 'uid' ]
|
||||
user_attrs = {'uid': 'username',
|
||||
'cn': 'fullname',
|
||||
'mail': 'mail',
|
||||
'maildrop': 'mail-forward',
|
||||
'mailuserquota': 'mailbox-quota'}
|
||||
attrs = ['uid']
|
||||
users = {}
|
||||
|
||||
# Set default arguments values
|
||||
|
@ -74,12 +79,12 @@ def user_list(auth, fields=None, filter=None, limit=None, offset=None):
|
|||
raise MoulinetteError(errno.EINVAL,
|
||||
m18n.n('field_invalid', attr))
|
||||
else:
|
||||
attrs = [ 'uid', 'cn', 'mail', 'mailuserquota' ]
|
||||
attrs = ['uid', 'cn', 'mail', 'mailuserquota']
|
||||
|
||||
result = auth.search('ou=users,dc=yunohost,dc=org', filter, attrs)
|
||||
|
||||
if len(result) > offset and limit > 0:
|
||||
for user in result[offset:offset+limit]:
|
||||
for user in result[offset:offset + limit]:
|
||||
entry = {}
|
||||
for attr, values in user.items():
|
||||
try:
|
||||
|
@ -88,7 +93,7 @@ def user_list(auth, fields=None, filter=None, limit=None, offset=None):
|
|||
pass
|
||||
uid = entry[user_attrs['uid']]
|
||||
users[uid] = entry
|
||||
return { 'users' : users }
|
||||
return {'users': users}
|
||||
|
||||
|
||||
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
|
||||
|
||||
"""
|
||||
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
|
||||
auth.validate_uniqueness({
|
||||
'uid' : username,
|
||||
'mail' : mail
|
||||
'uid': username,
|
||||
'mail': mail
|
||||
})
|
||||
|
||||
# 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'))
|
||||
|
||||
# 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,
|
||||
m18n.n('mail_domain_unknown',
|
||||
domain=mail[mail.find('@')+1:]))
|
||||
domain=mail[mail.find('@') + 1:]))
|
||||
|
||||
# Get random UID/GID
|
||||
uid_check = gid_check = 0
|
||||
|
@ -141,7 +141,7 @@ def user_create(auth, username, firstname, lastname, mail, password,
|
|||
fullname = '%s %s' % (firstname, lastname)
|
||||
rdn = 'uid=%s,ou=users' % username
|
||||
char_set = string.ascii_uppercase + string.digits
|
||||
salt = ''.join(random.sample(char_set,8))
|
||||
salt = ''.join(random.sample(char_set, 8))
|
||||
salt = '$1$' + salt + '$'
|
||||
user_pwd = '{CRYPT}' + crypt.crypt(str(password), salt)
|
||||
attr_dict = {
|
||||
|
@ -166,12 +166,12 @@ def user_create(auth, username, firstname, lastname, mail, password,
|
|||
with open('/etc/yunohost/current_host') as f:
|
||||
main_domain = f.readline().rstrip()
|
||||
aliases = [
|
||||
'root@'+ main_domain,
|
||||
'admin@'+ main_domain,
|
||||
'webmaster@'+ main_domain,
|
||||
'postmaster@'+ main_domain,
|
||||
'root@' + main_domain,
|
||||
'admin@' + main_domain,
|
||||
'webmaster@' + 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
|
||||
try:
|
||||
|
@ -184,8 +184,8 @@ def user_create(auth, username, firstname, lastname, mail, password,
|
|||
with open('/etc/ssowat/conf.json.persistent', 'w+') as f:
|
||||
json.dump(ssowat_conf, f, sort_keys=True, indent=4)
|
||||
|
||||
except IOError: pass
|
||||
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
if auth.add(rdn, attr_dict):
|
||||
# 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
|
||||
memberlist = auth.search(filter='cn=sftpusers', attrs=['memberUid'])[0]['memberUid']
|
||||
memberlist.append(username)
|
||||
if auth.update('cn=sftpusers,ou=groups', { 'memberUid': memberlist }):
|
||||
if auth.update('cn=sftpusers,ou=groups', {'memberUid': memberlist}):
|
||||
try:
|
||||
# Attempt to create user home folder
|
||||
subprocess.check_call(
|
||||
|
@ -204,12 +204,12 @@ def user_create(auth, username, firstname, lastname, mail, password,
|
|||
logger.warning(m18n.n('user_home_creation_failed'),
|
||||
exc_info=1)
|
||||
app_ssowatconf(auth)
|
||||
#TODO: Send a welcome mail to user
|
||||
# TODO: Send a welcome mail to user
|
||||
logger.success(m18n.n('user_created'))
|
||||
hook_callback('post_user_create',
|
||||
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'))
|
||||
|
||||
|
@ -223,18 +223,17 @@ def user_delete(auth, username, purge=False):
|
|||
purge
|
||||
|
||||
"""
|
||||
from yunohost.app import app_ssowatconf
|
||||
from yunohost.hook import hook_callback
|
||||
|
||||
if auth.remove('uid=%s,ou=users' % username):
|
||||
# Invalidate passwd to take user deletion into account
|
||||
subprocess.call(['nscd', '-i', 'passwd'])
|
||||
|
||||
# Update SFTP user group
|
||||
memberlist = auth.search(filter='cn=sftpusers', attrs=['memberUid'])[0]['memberUid']
|
||||
try: memberlist.remove(username)
|
||||
except: pass
|
||||
if auth.update('cn=sftpusers,ou=groups', { 'memberUid': memberlist }):
|
||||
try:
|
||||
memberlist.remove(username)
|
||||
except:
|
||||
pass
|
||||
if auth.update('cn=sftpusers,ou=groups', {'memberUid': memberlist}):
|
||||
if purge:
|
||||
subprocess.call(['rm', '-rf', '/home/{0}'.format(username)])
|
||||
else:
|
||||
|
@ -265,9 +264,6 @@ def user_update(auth, username, firstname=None, lastname=None, mail=None,
|
|||
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']
|
||||
new_attr_dict = {}
|
||||
domains = domain_list(auth)['domains']
|
||||
|
@ -280,11 +276,11 @@ def user_update(auth, username, firstname=None, lastname=None, mail=None,
|
|||
|
||||
# Get modifications from arguments
|
||||
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]
|
||||
|
||||
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
|
||||
|
||||
if lastname and firstname:
|
||||
|
@ -292,34 +288,34 @@ def user_update(auth, username, firstname=None, lastname=None, mail=None,
|
|||
|
||||
if change_password:
|
||||
char_set = string.ascii_uppercase + string.digits
|
||||
salt = ''.join(random.sample(char_set,8))
|
||||
salt = ''.join(random.sample(char_set, 8))
|
||||
salt = '$1$' + salt + '$'
|
||||
new_attr_dict['userPassword'] = '{CRYPT}' + crypt.crypt(str(change_password), salt)
|
||||
|
||||
if mail:
|
||||
auth.validate_uniqueness({ 'mail': mail })
|
||||
if mail[mail.find('@')+1:] not in domains:
|
||||
auth.validate_uniqueness({'mail': mail})
|
||||
if mail[mail.find('@') + 1:] not in domains:
|
||||
raise MoulinetteError(errno.EINVAL,
|
||||
m18n.n('mail_domain_unknown',
|
||||
domain=mail[mail.find('@')+1:]))
|
||||
domain=mail[mail.find('@') + 1:]))
|
||||
del user['mail'][0]
|
||||
new_attr_dict['mail'] = [mail] + user['mail']
|
||||
|
||||
if add_mailalias:
|
||||
if not isinstance(add_mailalias, list):
|
||||
add_mailalias = [ add_mailalias ]
|
||||
add_mailalias = [add_mailalias]
|
||||
for mail in add_mailalias:
|
||||
auth.validate_uniqueness({ 'mail': mail })
|
||||
if mail[mail.find('@')+1:] not in domains:
|
||||
auth.validate_uniqueness({'mail': mail})
|
||||
if mail[mail.find('@') + 1:] not in domains:
|
||||
raise MoulinetteError(errno.EINVAL,
|
||||
m18n.n('mail_domain_unknown',
|
||||
domain=mail[mail.find('@')+1:]))
|
||||
domain=mail[mail.find('@') + 1:]))
|
||||
user['mail'].append(mail)
|
||||
new_attr_dict['mail'] = user['mail']
|
||||
|
||||
if remove_mailalias:
|
||||
if not isinstance(remove_mailalias, list):
|
||||
remove_mailalias = [ remove_mailalias ]
|
||||
remove_mailalias = [remove_mailalias]
|
||||
for mail in remove_mailalias:
|
||||
if len(user['mail']) > 1 and mail in user['mail'][1:]:
|
||||
user['mail'].remove(mail)
|
||||
|
@ -330,7 +326,7 @@ def user_update(auth, username, firstname=None, lastname=None, mail=None,
|
|||
|
||||
if add_mailforward:
|
||||
if not isinstance(add_mailforward, list):
|
||||
add_mailforward = [ add_mailforward ]
|
||||
add_mailforward = [add_mailforward]
|
||||
for mail in add_mailforward:
|
||||
if mail in user['maildrop'][1:]:
|
||||
continue
|
||||
|
@ -339,7 +335,7 @@ def user_update(auth, username, firstname=None, lastname=None, mail=None,
|
|||
|
||||
if remove_mailforward:
|
||||
if not isinstance(remove_mailforward, list):
|
||||
remove_mailforward = [ remove_mailforward ]
|
||||
remove_mailforward = [remove_mailforward]
|
||||
for mail in remove_mailforward:
|
||||
if len(user['maildrop']) > 1 and mail in user['maildrop'][1:]:
|
||||
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
|
||||
|
||||
if auth.update('uid=%s,ou=users' % username, new_attr_dict):
|
||||
logger.success(m18n.n('user_updated'))
|
||||
app_ssowatconf(auth)
|
||||
return user_info(auth, username)
|
||||
logger.success(m18n.n('user_updated'))
|
||||
app_ssowatconf(auth)
|
||||
return user_info(auth, username)
|
||||
else:
|
||||
raise MoulinetteError(169, m18n.n('user_update_failed'))
|
||||
raise MoulinetteError(169, m18n.n('user_update_failed'))
|
||||
|
||||
|
||||
def user_info(auth, username):
|
||||
|
@ -372,9 +368,9 @@ def user_info(auth, username):
|
|||
]
|
||||
|
||||
if len(username.split('@')) is 2:
|
||||
filter = 'mail='+ username
|
||||
filter = 'mail=' + username
|
||||
else:
|
||||
filter = 'uid='+ username
|
||||
filter = 'uid=' + username
|
||||
|
||||
result = auth.search('ou=users,dc=yunohost,dc=org', filter, user_attrs)
|
||||
|
||||
|
@ -398,28 +394,31 @@ def user_info(auth, username):
|
|||
result_dict['mail-forward'] = user['maildrop'][1:]
|
||||
|
||||
if 'mailuserquota' in user:
|
||||
if user['mailuserquota'][0] != '0':
|
||||
cmd = 'doveadm -f flow quota get -u %s' % user['uid'][0]
|
||||
userquota = subprocess.check_output(cmd,stderr=subprocess.STDOUT,
|
||||
shell=True)
|
||||
quotavalue = re.findall(r'\d+', userquota)
|
||||
result = '%s (%s%s)' % ( _convertSize(eval(quotavalue[0])),
|
||||
quotavalue[2], '%')
|
||||
result_dict['mailbox-quota'] = {
|
||||
'limit' : user['mailuserquota'][0],
|
||||
'use' : result
|
||||
}
|
||||
if user['mailuserquota'][0] != '0':
|
||||
cmd = 'doveadm -f flow quota get -u %s' % user['uid'][0]
|
||||
userquota = subprocess.check_output(cmd, stderr=subprocess.STDOUT,
|
||||
shell=True)
|
||||
quotavalue = re.findall(r'\d+', userquota)
|
||||
result = '%s (%s%s)' % (_convertSize(eval(quotavalue[0])),
|
||||
quotavalue[2], '%')
|
||||
result_dict['mailbox-quota'] = {
|
||||
'limit': user['mailuserquota'][0],
|
||||
'use': result
|
||||
}
|
||||
else:
|
||||
result_dict['mailbox-quota'] = m18n.n('unlimit')
|
||||
|
||||
result_dict['mailbox-quota'] = m18n.n('unlimit')
|
||||
|
||||
if result:
|
||||
return result_dict
|
||||
else:
|
||||
raise MoulinetteError(167, m18n.n('user_info_failed'))
|
||||
|
||||
|
||||
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:
|
||||
return "%3.1f%s%s" % (num, unit, suffix)
|
||||
|
||||
num /= 1024.0
|
||||
|
||||
return "%.1f%s%s" % (num, 'Yi', suffix)
|
||||
|
|
Loading…
Add table
Reference in a new issue