diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 7813dee58..f27a10abd 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -38,12 +38,12 @@ from collections import OrderedDict from datetime import datetime from moulinette import msignals, m18n, msettings -from yunohost.utils.error import YunohostError from moulinette.utils.log import getActionLogger from moulinette.utils.filesystem import read_json from yunohost.service import service_log, service_status, _run_service_command from yunohost.utils import packages +from yunohost.utils.error import YunohostError from yunohost.log import is_unit_operation, OperationLogger logger = getActionLogger('yunohost.app') @@ -437,7 +437,7 @@ def app_map(app=None, raw=False, user=None): @is_unit_operation() -def app_change_url(operation_logger, auth, app, domain, path): +def app_change_url(operation_logger, app, domain, path): """ Modify the URL at which an application is installed. @@ -468,7 +468,7 @@ def app_change_url(operation_logger, auth, app, domain, path): raise YunohostError("app_change_url_identical_domains", domain=domain, path=path) # Check the url is available - conflicts = _get_conflicting_apps(auth, domain, path, ignore_app=app) + conflicts = _get_conflicting_apps(domain, path, ignore_app=app) if conflicts: apps = [] for path, app_id, app_label in conflicts: @@ -484,7 +484,7 @@ def app_change_url(operation_logger, auth, app, domain, path): # Retrieve arguments list for change_url script # TODO: Allow to specify arguments - args_odict = _parse_args_from_manifest(manifest, 'change_url', auth=auth) + args_odict = _parse_args_from_manifest(manifest, 'change_url') args_list = args_odict.values() args_list.append(app) @@ -538,7 +538,7 @@ def app_change_url(operation_logger, auth, app, domain, path): app_setting(app, 'domain', value=domain) app_setting(app, 'path', value=path) - app_ssowatconf(auth) + app_ssowatconf() # avoid common mistakes if _run_service_command("reload", "nginx") == False: @@ -557,7 +557,7 @@ def app_change_url(operation_logger, auth, app, domain, path): hook_callback('post_app_change_url', args=args_list, env=env_dict) -def app_upgrade(auth, app=[], url=None, file=None): +def app_upgrade(app=[], url=None, file=None): """ Upgrade app @@ -633,7 +633,7 @@ def app_upgrade(auth, app=[], url=None, file=None): # Retrieve arguments list for upgrade script # TODO: Allow to specify arguments - args_odict = _parse_args_from_manifest(manifest, 'upgrade', auth=auth) + args_odict = _parse_args_from_manifest(manifest, 'upgrade') args_list = args_odict.values() args_list.append(app_instance_name) @@ -693,7 +693,7 @@ def app_upgrade(auth, app=[], url=None, file=None): if not_upgraded_apps: raise YunohostError('app_not_upgraded', apps=', '.join(not_upgraded_apps)) - app_ssowatconf(auth) + app_ssowatconf() logger.success(m18n.n('upgrade_complete')) @@ -703,7 +703,7 @@ def app_upgrade(auth, app=[], url=None, file=None): @is_unit_operation() -def app_install(operation_logger, auth, app, label=None, args=None, no_remove_on_failure=False, force=False): +def app_install(operation_logger, app, label=None, args=None, no_remove_on_failure=False, force=False): """ Install apps @@ -795,7 +795,7 @@ def app_install(operation_logger, auth, app, label=None, args=None, no_remove_on # Retrieve arguments list for install script args_dict = {} if not args else \ dict(urlparse.parse_qsl(args, keep_blank_values=True)) - args_odict = _parse_args_from_manifest(manifest, 'install', args=args_dict, auth=auth) + args_odict = _parse_args_from_manifest(manifest, 'install', args=args_dict) args_list = args_odict.values() args_list.append(app_instance_name) @@ -887,7 +887,7 @@ def app_install(operation_logger, auth, app, label=None, args=None, no_remove_on shutil.rmtree(app_setting_path) shutil.rmtree(extracted_app_folder) - app_ssowatconf(auth) + app_ssowatconf() if packages.dpkg_is_broken(): logger.error(m18n.n("this_action_broke_dpkg")) @@ -914,7 +914,7 @@ def app_install(operation_logger, auth, app, label=None, args=None, no_remove_on os.system('chown -R root: %s' % app_setting_path) os.system('chown -R admin: %s/scripts' % app_setting_path) - app_ssowatconf(auth) + app_ssowatconf() logger.success(m18n.n('installation_complete')) @@ -922,7 +922,7 @@ def app_install(operation_logger, auth, app, label=None, args=None, no_remove_on @is_unit_operation() -def app_remove(operation_logger, auth, app): +def app_remove(operation_logger, app): """ Remove app @@ -974,13 +974,13 @@ def app_remove(operation_logger, auth, app): shutil.rmtree(app_setting_path) shutil.rmtree('/tmp/yunohost_remove') hook_remove(app) - app_ssowatconf(auth) + app_ssowatconf() if packages.dpkg_is_broken(): raise YunohostError("this_action_broke_dpkg") -def app_addaccess(auth, apps, users=[]): +def app_addaccess(apps, users=[]): """ Grant access right to users (everyone by default) @@ -995,7 +995,7 @@ def app_addaccess(auth, apps, users=[]): result = {} if not users: - users = user_list(auth)['users'].keys() + users = user_list()['users'].keys() elif not isinstance(users, list): users = [users, ] if not isinstance(apps, list): @@ -1025,7 +1025,7 @@ def app_addaccess(auth, apps, users=[]): for allowed_user in users: if allowed_user not in allowed_users: try: - user_info(auth, allowed_user) + user_info(allowed_user) except YunohostError: logger.warning(m18n.n('user_unknown', user=allowed_user)) continue @@ -1041,12 +1041,12 @@ def app_addaccess(auth, apps, users=[]): result[app] = allowed_users - app_ssowatconf(auth) + app_ssowatconf() return {'allowed_users': result} -def app_removeaccess(auth, apps, users=[]): +def app_removeaccess(apps, users=[]): """ Revoke access right to users (everyone by default) @@ -1088,7 +1088,7 @@ def app_removeaccess(auth, apps, users=[]): if allowed_user not in users: allowed_users.add(allowed_user) else: - for allowed_user in user_list(auth)['users'].keys(): + for allowed_user in user_list()['users'].keys(): if allowed_user not in users: allowed_users.add(allowed_user) @@ -1102,12 +1102,12 @@ def app_removeaccess(auth, apps, users=[]): operation_logger.success() - app_ssowatconf(auth) + app_ssowatconf() return {'allowed_users': result} -def app_clearaccess(auth, apps): +def app_clearaccess(apps): """ Reset access rights for the app @@ -1140,7 +1140,7 @@ def app_clearaccess(auth, apps): operation_logger.success() - app_ssowatconf(auth) + app_ssowatconf() def app_debug(app): @@ -1167,7 +1167,7 @@ def app_debug(app): @is_unit_operation() -def app_makedefault(operation_logger, auth, app, domain=None): +def app_makedefault(operation_logger, app, domain=None): """ Redirect domain root to an app @@ -1185,7 +1185,7 @@ def app_makedefault(operation_logger, auth, app, domain=None): if domain is None: domain = app_domain operation_logger.related_to.append(('domain', domain)) - elif domain not in domain_list(auth)['domains']: + elif domain not in domain_list()['domains']: raise YunohostError('domain_unknown') operation_logger.start() @@ -1264,7 +1264,7 @@ def app_checkport(port): raise YunohostError('port_unavailable', port=int(port)) -def app_register_url(auth, app, domain, path): +def app_register_url(app, domain, path): """ Book/register a web path for a given app @@ -1290,7 +1290,7 @@ def app_register_url(auth, app, domain, path): raise YunohostError('app_already_installed_cant_change_url') # Check the url is available - conflicts = _get_conflicting_apps(auth, domain, path) + conflicts = _get_conflicting_apps(domain, path) if conflicts: apps = [] for path, app_id, app_label in conflicts: @@ -1307,7 +1307,7 @@ def app_register_url(auth, app, domain, path): app_setting(app, 'path', value=path) -def app_checkurl(auth, url, app=None): +def app_checkurl(url, app=None): """ Check availability of a web path @@ -1337,7 +1337,7 @@ def app_checkurl(auth, url, app=None): apps_map = app_map(raw=True) - if domain not in domain_list(auth)['domains']: + if domain not in domain_list()['domains']: raise YunohostError('domain_unknown') if domain in apps_map: @@ -1394,7 +1394,7 @@ def app_initdb(user, password=None, db=None, sql=None): logger.success(m18n.n('mysql_db_initialized')) -def app_ssowatconf(auth): +def app_ssowatconf(): """ Regenerate SSOwat configuration file @@ -1404,7 +1404,7 @@ def app_ssowatconf(auth): from yunohost.user import user_list main_domain = _get_maindomain() - domains = domain_list(auth)['domains'] + domains = domain_list()['domains'] skipped_urls = [] skipped_regex = [] @@ -1481,7 +1481,7 @@ def app_ssowatconf(auth): 'redirected_urls': redirected_urls, 'redirected_regex': redirected_regex, 'users': {username: app_map(user=username) - for username in user_list(auth)['users'].keys()}, + for username in user_list()['users'].keys()}, } with open('/etc/ssowat/conf.json', 'w+') as f: @@ -1490,14 +1490,14 @@ def app_ssowatconf(auth): logger.success(m18n.n('ssowat_conf_generated')) -def app_change_label(auth, app, new_label): +def app_change_label(app, new_label): installed = _is_installed(app) if not installed: raise YunohostError('app_not_installed', app=app) app_setting(app, "label", value=new_label) - app_ssowatconf(auth) + app_ssowatconf() # actions todo list: @@ -2143,7 +2143,7 @@ def _check_manifest_requirements(manifest, app_instance_name): spec=spec, app=app_instance_name) -def _parse_args_from_manifest(manifest, action, args={}, auth=None): +def _parse_args_from_manifest(manifest, action, args={}): """Parse arguments needed for an action from the manifest Retrieve specified arguments for the action from the manifest, and parse @@ -2162,10 +2162,10 @@ def _parse_args_from_manifest(manifest, action, args={}, auth=None): return OrderedDict() action_args = manifest['arguments'][action] - return _parse_action_args_in_yunohost_format(args, action_args, auth) + return _parse_action_args_in_yunohost_format(args, action_args) -def _parse_args_for_action(action, args={}, auth=None): +def _parse_args_for_action(action, args={}): """Parse arguments needed for an action from the actions list Retrieve specified arguments for the action from the manifest, and parse @@ -2186,10 +2186,10 @@ def _parse_args_for_action(action, args={}, auth=None): action_args = action['arguments'] - return _parse_action_args_in_yunohost_format(args, action_args, auth) + return _parse_action_args_in_yunohost_format(args, action_args) -def _parse_action_args_in_yunohost_format(args, action_args, auth=None): +def _parse_action_args_in_yunohost_format(args, action_args): """Parse arguments store in either manifest.json or actions.json """ from yunohost.domain import (domain_list, _get_maindomain, @@ -2242,12 +2242,12 @@ def _parse_action_args_in_yunohost_format(args, action_args, auth=None): arg_default = _get_maindomain() ask_string += ' (default: {0})'.format(arg_default) msignals.display(m18n.n('domains_available')) - for domain in domain_list(auth)['domains']: + for domain in domain_list()['domains']: msignals.display("- {}".format(domain)) elif arg_type == 'user': msignals.display(m18n.n('users_available')) - for user in user_list(auth)['users'].keys(): + for user in user_list()['users'].keys(): msignals.display("- {}".format(user)) elif arg_type == 'password': @@ -2283,11 +2283,11 @@ def _parse_action_args_in_yunohost_format(args, action_args, auth=None): # Validate argument type if arg_type == 'domain': - if arg_value not in domain_list(auth)['domains']: + if arg_value not in domain_list()['domains']: raise YunohostError('app_argument_invalid', name=arg_name, error=m18n.n('domain_unknown')) elif arg_type == 'user': try: - user_info(auth, arg_value) + user_info(arg_value) except YunohostError as e: raise YunohostError('app_argument_invalid', name=arg_name, error=e) elif arg_type == 'app': @@ -2328,7 +2328,7 @@ def _parse_action_args_in_yunohost_format(args, action_args, auth=None): domain, path = _normalize_domain_path(domain, path) # Check the url is available - conflicts = _get_conflicting_apps(auth, domain, path) + conflicts = _get_conflicting_apps(domain, path) if conflicts: apps = [] for path, app_id, app_label in conflicts: diff --git a/src/yunohost/backup.py b/src/yunohost/backup.py index 82a778491..9a87015c0 100644 --- a/src/yunohost/backup.py +++ b/src/yunohost/backup.py @@ -2090,7 +2090,7 @@ def backup_create(name=None, description=None, methods=[], } -def backup_restore(auth, name, system=[], apps=[], force=False): +def backup_restore(name, system=[], apps=[], force=False): """ Restore from a local backup archive diff --git a/src/yunohost/certificate.py b/src/yunohost/certificate.py index d7e8c0157..4235d522d 100644 --- a/src/yunohost/certificate.py +++ b/src/yunohost/certificate.py @@ -86,7 +86,7 @@ DNS_RESOLVERS = [ # -def certificate_status(auth, domain_list, full=False): +def certificate_status(domain_list, full=False): """ Print the status of certificate for given domains (all by default) @@ -99,10 +99,10 @@ def certificate_status(auth, domain_list, full=False): # If no domains given, consider all yunohost domains if domain_list == []: - domain_list = yunohost.domain.domain_list(auth)['domains'] + domain_list = yunohost.domain.domain_list()['domains'] # Else, validate that yunohost knows the domains given else: - yunohost_domains_list = yunohost.domain.domain_list(auth)['domains'] + yunohost_domains_list = yunohost.domain.domain_list()['domains'] for domain in domain_list: # Is it in Yunohost domain list? if domain not in yunohost_domains_list: @@ -126,7 +126,7 @@ def certificate_status(auth, domain_list, full=False): return {"certificates": certificates} -def certificate_install(auth, domain_list, force=False, no_checks=False, self_signed=False, staging=False): +def certificate_install(domain_list, force=False, no_checks=False, self_signed=False, staging=False): """ Install a Let's Encrypt certificate for given domains (all by default) @@ -142,7 +142,7 @@ def certificate_install(auth, domain_list, force=False, no_checks=False, self_si _certificate_install_selfsigned(domain_list, force) else: _certificate_install_letsencrypt( - auth, domain_list, force, no_checks, staging) + domain_list, force, no_checks, staging) def _certificate_install_selfsigned(domain_list, force=False): @@ -237,7 +237,7 @@ def _certificate_install_selfsigned(domain_list, force=False): operation_logger.error(msg) -def _certificate_install_letsencrypt(auth, domain_list, force=False, no_checks=False, staging=False): +def _certificate_install_letsencrypt(domain_list, force=False, no_checks=False, staging=False): import yunohost.domain if not os.path.exists(ACCOUNT_KEY_FILE): @@ -246,7 +246,7 @@ def _certificate_install_letsencrypt(auth, domain_list, force=False, no_checks=F # If no domains given, consider all yunohost domains with self-signed # certificates if domain_list == []: - for domain in yunohost.domain.domain_list(auth)['domains']: + for domain in yunohost.domain.domain_list()['domains']: status = _get_status(domain) if status["CA_type"]["code"] != "self-signed": @@ -257,7 +257,7 @@ def _certificate_install_letsencrypt(auth, domain_list, force=False, no_checks=F # Else, validate that yunohost knows the domains given else: for domain in domain_list: - yunohost_domains_list = yunohost.domain.domain_list(auth)['domains'] + yunohost_domains_list = yunohost.domain.domain_list()['domains'] if domain not in yunohost_domains_list: raise YunohostError('certmanager_domain_unknown', domain=domain) @@ -285,7 +285,7 @@ def _certificate_install_letsencrypt(auth, domain_list, force=False, no_checks=F operation_logger.start() - _configure_for_acme_challenge(auth, domain) + _configure_for_acme_challenge(domain) _fetch_and_enable_new_certificate(domain, staging, no_checks=no_checks) _install_cron(no_checks=no_checks) @@ -300,7 +300,7 @@ def _certificate_install_letsencrypt(auth, domain_list, force=False, no_checks=F operation_logger.error(msg) -def certificate_renew(auth, domain_list, force=False, no_checks=False, email=False, staging=False): +def certificate_renew(domain_list, force=False, no_checks=False, email=False, staging=False): """ Renew Let's Encrypt certificate for given domains (all by default) @@ -317,7 +317,7 @@ def certificate_renew(auth, domain_list, force=False, no_checks=False, email=Fal # If no domains given, consider all yunohost domains with Let's Encrypt # certificates if domain_list == []: - for domain in yunohost.domain.domain_list(auth)['domains']: + for domain in yunohost.domain.domain_list()['domains']: # Does it have a Let's Encrypt cert? status = _get_status(domain) @@ -344,7 +344,7 @@ def certificate_renew(auth, domain_list, force=False, no_checks=False, email=Fal for domain in domain_list: # Is it in Yunohost dmomain list? - if domain not in yunohost.domain.domain_list(auth)['domains']: + if domain not in yunohost.domain.domain_list()['domains']: raise YunohostError('certmanager_domain_unknown', domain=domain) status = _get_status(domain) @@ -468,7 +468,7 @@ Subject: %s smtp.quit() -def _configure_for_acme_challenge(auth, domain): +def _configure_for_acme_challenge(domain): nginx_conf_folder = "/etc/nginx/conf.d/%s.d" % domain nginx_conf_file = "%s/000-acmechallenge.conf" % nginx_conf_folder @@ -511,7 +511,7 @@ location ^~ '/.well-known/acme-challenge/' # any clean function already implemented in yunohost to do this though) _run_service_command("reload", "nginx") - app_ssowatconf(auth) + app_ssowatconf() def _check_acme_challenge_configuration(domain): diff --git a/src/yunohost/domain.py b/src/yunohost/domain.py index a39f45a0e..42a4881ba 100644 --- a/src/yunohost/domain.py +++ b/src/yunohost/domain.py @@ -42,7 +42,7 @@ from yunohost.hook import hook_callback logger = getActionLogger('yunohost.domain') -def domain_list(auth): +def domain_list(): """ List domains @@ -52,10 +52,12 @@ def domain_list(auth): limit -- Maximum number of domain fetched """ + from yunohost.utils.ldap import _get_ldap_interface + + ldap = _get_ldap_interface() + result = ldap.search('ou=domains,dc=yunohost,dc=org', 'virtualdomain=*', ['virtualdomain']) + result_list = [] - - result = auth.search('ou=domains,dc=yunohost,dc=org', 'virtualdomain=*', ['virtualdomain']) - for domain in result: result_list.append(domain['virtualdomain'][0]) @@ -63,7 +65,7 @@ def domain_list(auth): @is_unit_operation() -def domain_add(operation_logger, auth, domain, dyndns=False): +def domain_add(operation_logger, domain, dyndns=False): """ Create a custom domain @@ -74,9 +76,12 @@ def domain_add(operation_logger, auth, domain, dyndns=False): """ from yunohost.hook import hook_callback from yunohost.app import app_ssowatconf + from yunohost.utils.ldap import _get_ldap_interface + + ldap = _get_ldap_interface() try: - auth.validate_uniqueness({'virtualdomain': domain}) + ldap.validate_uniqueness({'virtualdomain': domain}) except MoulinetteError: raise YunohostError('domain_exists') @@ -107,18 +112,18 @@ def domain_add(operation_logger, auth, domain, dyndns=False): 'virtualdomain': domain, } - if not auth.add('virtualdomain=%s,ou=domains' % domain, attr_dict): + if not ldap.add('virtualdomain=%s,ou=domains' % domain, attr_dict): raise YunohostError('domain_creation_failed') # Don't regen these conf if we're still in postinstall if os.path.exists('/etc/yunohost/installed'): regen_conf(names=['nginx', 'metronome', 'dnsmasq', 'postfix', 'rspamd']) - app_ssowatconf(auth) + app_ssowatconf() except Exception: # Force domain removal silently try: - domain_remove(auth, domain, True) + domain_remove(domain, True) except: pass raise @@ -129,7 +134,7 @@ def domain_add(operation_logger, auth, domain, dyndns=False): @is_unit_operation() -def domain_remove(operation_logger, auth, domain, force=False): +def domain_remove(operation_logger, domain, force=False): """ Delete domains @@ -140,8 +145,9 @@ def domain_remove(operation_logger, auth, domain, force=False): """ from yunohost.hook import hook_callback from yunohost.app import app_ssowatconf + from yunohost.utils.ldap import _get_ldap_interface - if not force and domain not in domain_list(auth)['domains']: + if not force and domain not in domain_list()['domains']: raise YunohostError('domain_unknown') # Check domain is not the main domain @@ -160,13 +166,14 @@ def domain_remove(operation_logger, auth, domain, force=False): raise YunohostError('domain_uninstall_app_first') operation_logger.start() - if auth.remove('virtualdomain=' + domain + ',ou=domains') or force: + ldap = _get_ldap_interface() + if ldap.remove('virtualdomain=' + domain + ',ou=domains') or force: os.system('rm -rf /etc/yunohost/certs/%s' % domain) else: raise YunohostError('domain_deletion_failed') regen_conf(names=['nginx', 'metronome', 'dnsmasq', 'postfix']) - app_ssowatconf(auth) + app_ssowatconf() hook_callback('post_domain_remove', args=[domain]) @@ -222,19 +229,19 @@ def domain_dns_conf(domain, ttl=None): return result -def domain_cert_status(auth, domain_list, full=False): - return yunohost.certificate.certificate_status(auth, domain_list, full) +def domain_cert_status(domain_list, full=False): + return yunohost.certificate.certificate_status(domain_list, full) -def domain_cert_install(auth, domain_list, force=False, no_checks=False, self_signed=False, staging=False): - return yunohost.certificate.certificate_install(auth, domain_list, force, no_checks, self_signed, staging) +def domain_cert_install(domain_list, force=False, no_checks=False, self_signed=False, staging=False): + return yunohost.certificate.certificate_install(domain_list, force, no_checks, self_signed, staging) -def domain_cert_renew(auth, domain_list, force=False, no_checks=False, email=False, staging=False): - return yunohost.certificate.certificate_renew(auth, domain_list, force, no_checks, email, staging) +def domain_cert_renew(domain_list, force=False, no_checks=False, email=False, staging=False): + return yunohost.certificate.certificate_renew(domain_list, force, no_checks, email, staging) -def _get_conflicting_apps(auth, domain, path, ignore_app=None): +def _get_conflicting_apps(domain, path, ignore_app=None): """ Return a list of all conflicting apps with a domain/path (it can be empty) @@ -247,7 +254,7 @@ def _get_conflicting_apps(auth, domain, path, ignore_app=None): domain, path = _normalize_domain_path(domain, path) # Abort if domain is unknown - if domain not in domain_list(auth)['domains']: + if domain not in domain_list()['domains']: raise YunohostError('domain_unknown') # This import cannot be put on top of file because it would create a @@ -274,7 +281,7 @@ def _get_conflicting_apps(auth, domain, path, ignore_app=None): return conflicts -def domain_url_available(auth, domain, path): +def domain_url_available(domain, path): """ Check availability of a web path @@ -283,7 +290,7 @@ def domain_url_available(auth, domain, path): path -- The path to check (e.g. /coffee) """ - return len(_get_conflicting_apps(auth, domain, path)) == 0 + return len(_get_conflicting_apps(domain, path)) == 0 def _get_maindomain(): diff --git a/src/yunohost/log.py b/src/yunohost/log.py index e576ae536..3620ac990 100644 --- a/src/yunohost/log.py +++ b/src/yunohost/log.py @@ -208,7 +208,7 @@ def log_display(path, number=50, share=False): def is_unit_operation(entities=['app', 'domain', 'service', 'user'], - exclude=['auth', 'password'], operation_key=None): + exclude=['password'], operation_key=None): """ Configure quickly a unit operation @@ -222,9 +222,8 @@ def is_unit_operation(entities=['app', 'domain', 'service', 'user'], (argname, entity_type) instead of just put the entity type. exclude Remove some arguments from the context. By default, arguments - called 'password' and 'auth' are removed. If an argument is an object, you - need to exclude it or create manually the unit operation without this - decorator. + called 'password' are removed. If an argument is an object, you need to + exclude it or create manually the unit operation without this decorator. operation_key A key to describe the unit operation log used to create the filename and search a translation. Please ensure that this key prefixed by diff --git a/src/yunohost/ssh.py b/src/yunohost/ssh.py index b4ac31dbb..f0110b34e 100644 --- a/src/yunohost/ssh.py +++ b/src/yunohost/ssh.py @@ -11,7 +11,7 @@ from moulinette.utils.filesystem import read_file, write_to_file, chown, chmod, SSHD_CONFIG_PATH = "/etc/ssh/sshd_config" -def user_ssh_allow(auth, username): +def user_ssh_allow(username): """ Allow YunoHost user connect as ssh. @@ -20,17 +20,19 @@ def user_ssh_allow(auth, username): """ # TODO it would be good to support different kind of shells - if not _get_user_for_ssh(auth, username): + if not _get_user_for_ssh(username): raise YunohostError('user_unknown', user=username) - auth.update('uid=%s,ou=users' % username, {'loginShell': '/bin/bash'}) + from yunohost.utils.ldap import _get_ldap_interface + ldap = _get_ldap_interface() + ldap.update('uid=%s,ou=users' % username, {'loginShell': '/bin/bash'}) # Somehow this is needed otherwise the PAM thing doesn't forget about the # old loginShell value ? subprocess.call(['nscd', '-i', 'passwd']) -def user_ssh_disallow(auth, username): +def user_ssh_disallow(username): """ Disallow YunoHost user connect as ssh. @@ -39,18 +41,20 @@ def user_ssh_disallow(auth, username): """ # TODO it would be good to support different kind of shells - if not _get_user_for_ssh(auth, username): + if not _get_user_for_ssh(username): raise YunohostError('user_unknown', user=username) - auth.update('uid=%s,ou=users' % username, {'loginShell': '/bin/false'}) + from yunohost.utils.ldap import _get_ldap_interface + ldap = _get_ldap_interface() + ldap.update('uid=%s,ou=users' % username, {'loginShell': '/bin/false'}) # Somehow this is needed otherwise the PAM thing doesn't forget about the # old loginShell value ? subprocess.call(['nscd', '-i', 'passwd']) -def user_ssh_list_keys(auth, username): - user = _get_user_for_ssh(auth, username, ["homeDirectory"]) +def user_ssh_list_keys(username): + user = _get_user_for_ssh(username, ["homeDirectory"]) if not user: raise Exception("User with username '%s' doesn't exists" % username) @@ -82,8 +86,8 @@ def user_ssh_list_keys(auth, username): return {"keys": keys} -def user_ssh_add_key(auth, username, key, comment): - user = _get_user_for_ssh(auth, username, ["homeDirectory", "uid"]) +def user_ssh_add_key(username, key, comment): + user = _get_user_for_ssh(username, ["homeDirectory", "uid"]) if not user: raise Exception("User with username '%s' doesn't exists" % username) @@ -116,8 +120,8 @@ def user_ssh_add_key(auth, username, key, comment): write_to_file(authorized_keys_file, authorized_keys_content) -def user_ssh_remove_key(auth, username, key): - user = _get_user_for_ssh(auth, username, ["homeDirectory", "uid"]) +def user_ssh_remove_key(username, key): + user = _get_user_for_ssh(username, ["homeDirectory", "uid"]) if not user: raise Exception("User with username '%s' doesn't exists" % username) @@ -148,8 +152,8 @@ def user_ssh_remove_key(auth, username, key): # -def _get_user_for_ssh(auth, username, attrs=None): - def ssh_root_login_status(auth): +def _get_user_for_ssh(username, attrs=None): + def ssh_root_login_status(): # XXX temporary placed here for when the ssh_root commands are integrated # extracted from https://github.com/YunoHost/yunohost/pull/345 # XXX should we support all the options? @@ -172,7 +176,7 @@ def _get_user_for_ssh(auth, username, attrs=None): 'username': 'root', 'fullname': '', 'mail': '', - 'ssh_allowed': ssh_root_login_status(auth)["PermitRootLogin"], + 'ssh_allowed': ssh_root_login_status()["PermitRootLogin"], 'shell': root_unix.pw_shell, 'home_path': root_unix.pw_dir, } @@ -189,7 +193,9 @@ def _get_user_for_ssh(auth, username, attrs=None): } # TODO escape input using https://www.python-ldap.org/doc/html/ldap-filter.html - user = auth.search('ou=users,dc=yunohost,dc=org', + from yunohost.utils.ldap import _get_ldap_interface + ldap = _get_ldap_interface() + user = ldap.search('ou=users,dc=yunohost,dc=org', '(&(objectclass=person)(uid=%s))' % username, attrs) diff --git a/src/yunohost/tools.py b/src/yunohost/tools.py index a3b6bc8cd..572328392 100644 --- a/src/yunohost/tools.py +++ b/src/yunohost/tools.py @@ -111,10 +111,9 @@ def tools_ldapinit(): raise YunohostError('installation_failed') logger.success(m18n.n('ldap_initialized')) - return auth -def tools_adminpw(auth, new_password, check_strength=True): +def tools_adminpw(new_password, check_strength=True): """ Change admin password @@ -136,8 +135,11 @@ def tools_adminpw(auth, new_password, check_strength=True): new_hash = _hash_user_password(new_password) + from yunohost.utils.ldap import _get_ldap_interface + ldap = _get_ldap_interface() + try: - auth.update("cn=admin", {"userPassword": new_hash, }) + ldap.update("cn=admin", {"userPassword": new_hash, }) except: logger.exception('unable to change admin password') raise YunohostError('admin_password_change_failed') @@ -161,7 +163,7 @@ def tools_adminpw(auth, new_password, check_strength=True): @is_unit_operation() -def tools_maindomain(operation_logger, auth, new_domain=None): +def tools_maindomain(operation_logger, new_domain=None): """ Check the current main domain, or change it @@ -175,7 +177,7 @@ def tools_maindomain(operation_logger, auth, new_domain=None): return {'current_main_domain': _get_maindomain()} # Check domain exists - if new_domain not in domain_list(auth)['domains']: + if new_domain not in domain_list()['domains']: raise YunohostError('domain_unknown') operation_logger.related_to.append(('domain', new_domain)) @@ -204,7 +206,7 @@ def tools_maindomain(operation_logger, auth, new_domain=None): _set_hostname(new_domain) # Generate SSOwat configuration file - app_ssowatconf(auth) + app_ssowatconf() # Regen configurations try: @@ -331,7 +333,7 @@ def tools_postinstall(operation_logger, domain, password, ignore_dyndns=False, # Initialize LDAP for YunoHost # TODO: Improve this part by integrate ldapinit into conf_regen hook - auth = tools_ldapinit() + tools_ldapinit() # Create required folders folders_to_create = [ @@ -405,11 +407,11 @@ def tools_postinstall(operation_logger, domain, password, ignore_dyndns=False, # New domain config regen_conf(['nsswitch'], force=True) - domain_add(auth, domain, dyndns) - tools_maindomain(auth, domain) + domain_add(domain, dyndns) + tools_maindomain(domain) # Change LDAP admin password - tools_adminpw(auth, password, check_strength=not force_password) + tools_adminpw(password, check_strength=not force_password) # Enable UPnP silently and reload firewall firewall_upnp('enable', no_refresh=True) @@ -573,7 +575,7 @@ def _dump_sources_list(): @is_unit_operation() -def tools_upgrade(operation_logger, auth, ignore_apps=False, ignore_packages=False): +def tools_upgrade(operation_logger, ignore_apps=False, ignore_packages=False): """ Update apps & package cache, then display changelog @@ -645,7 +647,7 @@ def tools_upgrade(operation_logger, auth, ignore_apps=False, ignore_packages=Fal if not ignore_apps: try: - app_upgrade(auth) + app_upgrade() except Exception as e: failure = True logger.warning('unable to upgrade apps: %s' % str(e)) @@ -659,7 +661,7 @@ def tools_upgrade(operation_logger, auth, ignore_apps=False, ignore_packages=Fal return {"log": service_log('yunohost-api', number="100").values()[0]} -def tools_diagnosis(auth, private=False): +def tools_diagnosis(private=False): """ Return global info about current yunohost instance to help debugging @@ -754,7 +756,7 @@ def tools_diagnosis(auth, private=False): diagnosis['private']['public_ip']['IPv6'] = get_public_ip(6) # Domains - diagnosis['private']['domains'] = domain_list(auth)['domains'] + diagnosis['private']['domains'] = domain_list()['domains'] diagnosis['private']['regen_conf'] = regen_conf(with_diff=True, dry_run=True) @@ -1078,18 +1080,21 @@ def tools_migrations_state(): return read_json(MIGRATIONS_STATE_PATH) -def tools_shell(auth, command=None): +def tools_shell(command=None): """ Launch an (i)python shell in the YunoHost context. This is entirely aim for development. """ + from yunohost.utils.ldap import _get_ldap_interface + ldap = _get_ldap_interface() + if command: exec(command) return - logger.warn("The \033[1;34mauth\033[0m is available in this context") + logger.warn("The \033[1;34mldap\033[0m interface is available in this context") try: from IPython import embed embed() diff --git a/src/yunohost/user.py b/src/yunohost/user.py index a38f0b4c5..db0d80ce3 100644 --- a/src/yunohost/user.py +++ b/src/yunohost/user.py @@ -41,7 +41,7 @@ from yunohost.log import is_unit_operation logger = getActionLogger('yunohost.user') -def user_list(auth, fields=None): +def user_list(fields=None): """ List users @@ -52,6 +52,8 @@ def user_list(auth, fields=None): fields -- fields to fetch """ + from yunohost.utils.ldap import _get_ldap_interface + user_attrs = { 'uid': 'username', 'cn': 'fullname', @@ -75,7 +77,8 @@ def user_list(auth, fields=None): else: attrs = ['uid', 'cn', 'mail', 'mailuserquota', 'loginShell'] - result = auth.search('ou=users,dc=yunohost,dc=org', + ldap = _get_ldap_interface() + result = ldap.search('ou=users,dc=yunohost,dc=org', '(&(objectclass=person)(!(uid=root))(!(uid=nobody)))', attrs) @@ -98,7 +101,7 @@ def user_list(auth, fields=None): @is_unit_operation([('username', 'user')]) -def user_create(operation_logger, auth, username, firstname, lastname, mail, password, +def user_create(operation_logger, username, firstname, lastname, mail, password, mailbox_quota="0"): """ Create user @@ -116,12 +119,15 @@ def user_create(operation_logger, auth, username, firstname, lastname, mail, pas from yunohost.hook import hook_callback from yunohost.app import app_ssowatconf from yunohost.utils.password import assert_password_is_strong_enough + from yunohost.utils.ldap import _get_ldap_interface # Ensure sufficiently complex password assert_password_is_strong_enough("user", password) + ldap = _get_ldap_interface() + # Validate uniqueness of username and mail in LDAP - auth.validate_uniqueness({ + ldap.validate_uniqueness({ 'uid': username, 'mail': mail }) @@ -143,7 +149,7 @@ def user_create(operation_logger, auth, username, firstname, lastname, mail, pas raise YunohostError('mail_unavailable') # Check that the mail domain exists - if mail.split("@")[1] not in domain_list(auth)['domains']: + if mail.split("@")[1] not in domain_list()['domains']: raise YunohostError('mail_domain_unknown', domain=mail.split("@")[1]) operation_logger.start() @@ -177,7 +183,7 @@ def user_create(operation_logger, auth, username, firstname, lastname, mail, pas } # If it is the first user, add some aliases - if not auth.search(base='ou=users,dc=yunohost,dc=org', filter='uid=*'): + if not ldap.search(base='ou=users,dc=yunohost,dc=org', filter='uid=*'): attr_dict['mail'] = [attr_dict['mail']] + aliases # If exists, remove the redirection from the SSO @@ -197,14 +203,14 @@ def user_create(operation_logger, auth, username, firstname, lastname, mail, pas except IOError as e: raise YunohostError('ssowat_persistent_conf_write_error', error=e.strerror) - if auth.add('uid=%s,ou=users' % username, attr_dict): + if ldap.add('uid=%s,ou=users' % username, attr_dict): # Invalidate passwd to take user creation into account subprocess.call(['nscd', '-i', 'passwd']) # Update SFTP user group - memberlist = auth.search(filter='cn=sftpusers', attrs=['memberUid'])[0]['memberUid'] + memberlist = ldap.search(filter='cn=sftpusers', attrs=['memberUid'])[0]['memberUid'] memberlist.append(username) - if auth.update('cn=sftpusers,ou=groups', {'memberUid': memberlist}): + if ldap.update('cn=sftpusers,ou=groups', {'memberUid': memberlist}): try: # Attempt to create user home folder subprocess.check_call( @@ -213,7 +219,7 @@ def user_create(operation_logger, auth, username, firstname, lastname, mail, pas if not os.path.isdir('/home/{0}'.format(username)): logger.warning(m18n.n('user_home_creation_failed'), exc_info=1) - app_ssowatconf(auth) + app_ssowatconf() # TODO: Send a welcome mail to user logger.success(m18n.n('user_created')) hook_callback('post_user_create', @@ -225,7 +231,7 @@ def user_create(operation_logger, auth, username, firstname, lastname, mail, pas @is_unit_operation([('username', 'user')]) -def user_delete(operation_logger, auth, username, purge=False): +def user_delete(operation_logger, username, purge=False): """ Delete user @@ -236,34 +242,37 @@ def user_delete(operation_logger, auth, username, purge=False): """ from yunohost.app import app_ssowatconf from yunohost.hook import hook_callback + from yunohost.utils.ldap import _get_ldap_interface operation_logger.start() - if auth.remove('uid=%s,ou=users' % username): + + ldap = _get_ldap_interface() + if ldap.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'] + memberlist = ldap.search(filter='cn=sftpusers', attrs=['memberUid'])[0]['memberUid'] try: memberlist.remove(username) except: pass - if auth.update('cn=sftpusers,ou=groups', {'memberUid': memberlist}): + if ldap.update('cn=sftpusers,ou=groups', {'memberUid': memberlist}): if purge: subprocess.call(['rm', '-rf', '/home/{0}'.format(username)]) subprocess.call(['rm', '-rf', '/var/mail/{0}'.format(username)]) else: raise YunohostError('user_deletion_failed') - app_ssowatconf(auth) + app_ssowatconf() hook_callback('post_user_delete', args=[username, purge]) logger.success(m18n.n('user_deleted')) -@is_unit_operation([('username', 'user')], exclude=['auth', 'change_password']) -def user_update(operation_logger, auth, username, firstname=None, lastname=None, mail=None, +@is_unit_operation([('username', 'user')], exclude=['change_password']) +def user_update(operation_logger, username, firstname=None, lastname=None, mail=None, change_password=None, add_mailforward=None, remove_mailforward=None, add_mailalias=None, remove_mailalias=None, mailbox_quota=None): """ @@ -284,13 +293,15 @@ def user_update(operation_logger, auth, username, firstname=None, lastname=None, from yunohost.domain import domain_list, _get_maindomain from yunohost.app import app_ssowatconf from yunohost.utils.password import assert_password_is_strong_enough + from yunohost.utils.ldap import _get_ldap_interface + ldap = _get_ldap_interface() attrs_to_fetch = ['givenName', 'sn', 'mail', 'maildrop'] new_attr_dict = {} - domains = domain_list(auth)['domains'] + domains = domain_list()['domains'] # Populate user informations - result = auth.search(base='ou=users,dc=yunohost,dc=org', filter='uid=' + username, attrs=attrs_to_fetch) + result = ldap.search(base='ou=users,dc=yunohost,dc=org', filter='uid=' + username, attrs=attrs_to_fetch) if not result: raise YunohostError('user_unknown', user=username) user = result[0] @@ -321,7 +332,7 @@ def user_update(operation_logger, auth, username, firstname=None, lastname=None, 'webmaster@' + main_domain, 'postmaster@' + main_domain, ] - auth.validate_uniqueness({'mail': mail}) + ldap.validate_uniqueness({'mail': mail}) if mail[mail.find('@') + 1:] not in domains: raise YunohostError('mail_domain_unknown', domain=mail[mail.find('@') + 1:]) if mail in aliases: @@ -334,7 +345,7 @@ def user_update(operation_logger, auth, username, firstname=None, lastname=None, if not isinstance(add_mailalias, list): add_mailalias = [add_mailalias] for mail in add_mailalias: - auth.validate_uniqueness({'mail': mail}) + ldap.validate_uniqueness({'mail': mail}) if mail[mail.find('@') + 1:] not in domains: raise YunohostError('mail_domain_unknown', domain=mail[mail.find('@') + 1:]) user['mail'].append(mail) @@ -374,15 +385,15 @@ def user_update(operation_logger, auth, username, firstname=None, lastname=None, operation_logger.start() - if auth.update('uid=%s,ou=users' % username, new_attr_dict): + if ldap.update('uid=%s,ou=users' % username, new_attr_dict): logger.success(m18n.n('user_updated')) - app_ssowatconf(auth) - return user_info(auth, username) + app_ssowatconf() + return user_info(username) else: raise YunohostError('user_update_failed') -def user_info(auth, username): +def user_info(username): """ Get user informations @@ -390,6 +401,10 @@ def user_info(auth, username): username -- Username or mail to get informations """ + from yunohost.utils.ldap import _get_ldap_interface + + ldap = _get_ldap_interface() + user_attrs = [ 'cn', 'mail', 'uid', 'maildrop', 'givenName', 'sn', 'mailuserquota' ] @@ -399,7 +414,7 @@ def user_info(auth, username): else: filter = 'uid=' + username - result = auth.search('ou=users,dc=yunohost,dc=org', filter, user_attrs) + result = ldap.search('ou=users,dc=yunohost,dc=org', filter, user_attrs) if result: user = result[0] @@ -469,24 +484,24 @@ def user_info(auth, username): import yunohost.ssh -def user_ssh_allow(auth, username): - return yunohost.ssh.user_ssh_allow(auth, username) +def user_ssh_allow(username): + return yunohost.ssh.user_ssh_allow(username) -def user_ssh_disallow(auth, username): - return yunohost.ssh.user_ssh_disallow(auth, username) +def user_ssh_disallow(username): + return yunohost.ssh.user_ssh_disallow(username) -def user_ssh_list_keys(auth, username): - return yunohost.ssh.user_ssh_list_keys(auth, username) +def user_ssh_list_keys(username): + return yunohost.ssh.user_ssh_list_keys(username) -def user_ssh_add_key(auth, username, key, comment): - return yunohost.ssh.user_ssh_add_key(auth, username, key, comment) +def user_ssh_add_key(username, key, comment): + return yunohost.ssh.user_ssh_add_key(username, key, comment) -def user_ssh_remove_key(auth, username, key): - return yunohost.ssh.user_ssh_remove_key(auth, username, key) +def user_ssh_remove_key(username, key): + return yunohost.ssh.user_ssh_remove_key(username, key) # # End SSH subcategory