From 288d6b6b4781f53f11edf1760de04ebf2ba2864c Mon Sep 17 00:00:00 2001 From: selfhoster1312 Date: Fri, 10 May 2024 19:31:05 +0200 Subject: [PATCH] Add users_remove bulk operation --- src/tests/test_sso_and_portalapi.py | 6 ++--- src/user.py | 39 +++++++++++++++++++++++++---- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/tests/test_sso_and_portalapi.py b/src/tests/test_sso_and_portalapi.py index 78e1cb278..35eec594a 100644 --- a/src/tests/test_sso_and_portalapi.py +++ b/src/tests/test_sso_and_portalapi.py @@ -7,7 +7,7 @@ import os from .conftest import message, raiseYunohostError, get_test_apps_dir from yunohost.domain import _get_maindomain, domain_add, domain_remove, domain_list, domains_add, domains_remove -from yunohost.user import user_create, user_list, user_delete, User, users_add +from yunohost.user import user_create, user_list, user_delete, User, users_add, users_remove from yunohost.authenticators.ldap_ynhuser import Authenticator, SESSION_FOLDER, short_hash from yunohost.app import app_install, app_remove, app_setting, app_ssowatconf, app_change_url from yunohost.permission import user_permission_list, user_permission_update @@ -63,8 +63,8 @@ def setup_module(module): def teardown_module(module): userlist = user_list()["users"] - for user in [ "alice", "bob" ]: - if user in userlist: user_delete(user) + users = [ user for user in [ "alice", "bob" ] if user in userlist ] + users_remove(users) app_remove("hellopy") diff --git a/src/user.py b/src/user.py index c30b550a3..843124c94 100644 --- a/src/user.py +++ b/src/user.py @@ -146,6 +146,28 @@ def shellexists(shell): """Check if the provided shell exists and is executable.""" return os.path.isfile(shell) and os.access(shell, os.X_OK) +# Used in tests to create many users at once. +# The permissions are synchronized at the end of the entire operation. +@is_unit_operation() +def users_remove( + operation_logger, + users: List[str], +): + + for username in users: + user_delete(username, do_regen_conf=False) + + from yunohost.permission import permission_sync_to_user + permission_sync_to_user() + + # Invalidate passwd to take user deletion into account + subprocess.call(["nscd", "-i", "passwd"]) + + from yunohost.hook import hook_callback + for username in users: + hook_callback("post_user_delete", args=[username, False]) + logger.success(m18n.n("user_deleted")) + # Used in tests to create many users at once. # The permissions are synchronized at the end of the entire operation. @is_unit_operation() @@ -360,7 +382,7 @@ def user_create( @is_unit_operation([("username", "user")]) -def user_delete(operation_logger, username, purge=False, from_import=False): +def user_delete(operation_logger, username, purge=False, from_import=False, do_regen_conf=True): from yunohost.hook import hook_callback from yunohost.utils.ldap import _get_ldap_interface from yunohost.authenticators.ldap_ynhuser import Authenticator as PortalAuth @@ -372,7 +394,6 @@ def user_delete(operation_logger, username, purge=False, from_import=False): if not from_import: operation_logger.start() - user_group_update("all_users", remove=username, force=True, sync_perm=False) for group, infos in user_group_list()["groups"].items(): if group == "all_users": continue @@ -385,7 +406,14 @@ def user_delete(operation_logger, username, purge=False, from_import=False): # epic bug happened somewhere else and only a partial removal was # performed...) if username in user_group_list()["groups"].keys(): - user_group_delete(username, force=True, sync_perm=True) + user_group_delete(username, force=True, sync_perm=False) + + PortalAuth.invalidate_all_sessions_for_user(username) + AdminAuth.invalidate_all_sessions_for_user(username) + + # Apparently ldap.remove uid removes from group all_users, but unless we have test we + # can't be too sure... so leave it here until we have tests for this! + user_group_update("all_users", remove=username, force=True, sync_perm=do_regen_conf) ldap = _get_ldap_interface() try: @@ -393,8 +421,9 @@ def user_delete(operation_logger, username, purge=False, from_import=False): except Exception as e: raise YunohostError("user_deletion_failed", user=username, error=e) - PortalAuth.invalidate_all_sessions_for_user(username) - AdminAuth.invalidate_all_sessions_for_user(username) + if not do_regen_conf: + return + # Invalidate passwd to take user deletion into account subprocess.call(["nscd", "-i", "passwd"])