From 45e2c0eb9b27aa8f61fab49909608ce4cd941333 Mon Sep 17 00:00:00 2001 From: lthievenaz-keeper Date: Thu, 27 Aug 2026 13:58:19 +0100 Subject: [PATCH 1/2] Add unsafe flag to ApplyMembership Add unsafe flag and manual documentation. Unsafe flag allows the apply-membership to remove yourself from the folders if set. --- keepercommander/importer/commands.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/keepercommander/importer/commands.py b/keepercommander/importer/commands.py index 32a54f7f5..c0280b9aa 100644 --- a/keepercommander/importer/commands.py +++ b/keepercommander/importer/commands.py @@ -135,6 +135,7 @@ def register_command_info(aliases, command_info): apply_membership_parser = argparse.ArgumentParser(prog='apply-membership', description='Loads shared folder membership from JSON file') apply_membership_parser.add_argument('--full-sync', dest='full_sync', action='store_true', help='Update and remove membership also.') +apply_membership_parser.add_argument('--unsafe', dest='unsafe', action='store_true', help='Combined with --full-sync. Will remove yourself from folders where you have no permission.') apply_membership_parser.add_argument('name', type=str, nargs='?', help='Input file name. "shared_folder_membership.json" if omitted.') apply_membership_parser.error = raise_parse_exception apply_membership_parser.exit = suppress_exit @@ -523,8 +524,9 @@ def execute(self, params, **kwargs): teams.append(obj) full_sync = kwargs.get('full_sync') is True + unsafe = kwargs.get('unsafe') is True if len(shared_folders) > 0: - imp_exp.import_user_permissions(params, shared_folders, full_sync) + imp_exp.import_user_permissions(params, shared_folders, full_sync, unsafe) if len(teams) > 0: imp_exp.import_teams(params, teams, full_sync) From fc9b3cc28480cfdcb851f09b0a990cb6a383d8ca Mon Sep 17 00:00:00 2001 From: lthievenaz-keeper Date: Thu, 27 Aug 2026 14:12:04 +0100 Subject: [PATCH 2/2] Support unsafe flag for ApplyMembership Currently, apply-membership --full-sync will remove folder permissions so that it matches the JSON file, however it won't remove yourself. Added --unsafe flag, which will allow removing yourself if you're not set on the folder permissions. This can be useful: - If the folder is only meant to be shared to your team and not you. - To reproduce enterprise-push behavior with shared folders at scale --- keepercommander/importer/imp_exp.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/keepercommander/importer/imp_exp.py b/keepercommander/importer/imp_exp.py index fcaa869dd..c42082f18 100644 --- a/keepercommander/importer/imp_exp.py +++ b/keepercommander/importer/imp_exp.py @@ -617,7 +617,7 @@ def import_teams(params, teams, full_sync=False): # type: (KeeperParams, List[ def import_user_permissions(params, shared_folders, - full_sync=False): # type: (KeeperParams, List[ImportSharedFolder], bool) -> None + full_sync=False, unsafe=False): # type: (KeeperParams, List[ImportSharedFolder], bool) -> None if not shared_folders: return @@ -654,7 +654,7 @@ def import_user_permissions(params, folders = [x for x in folders if x.uid in params.shared_folder_cache] if folders: - permissions = prepare_folder_permission(params, folders, full_sync) + permissions = prepare_folder_permission(params, folders, full_sync, unsafe) if permissions: teams_added = 0 users_added = 0 @@ -2536,7 +2536,7 @@ def prepare_record_link(params, records): return record_links -def prepare_folder_permission(params, folders, full_sync): +def prepare_folder_permission(params, folders, full_sync, unsafe=False): # type: (KeeperParams, List[ImportSharedFolder], bool) -> list """Prepare a list of API interactions for changes to folder permissions.""" shared_folder_lookup = {} @@ -2632,6 +2632,9 @@ def prepare_folder_permission(params, folders, full_sync): existing_users.update((x['username'] for x in shared_folder['users'])) if params.user in existing_users: existing_users.remove(params.user) + if unsafe: + # Set user to end of array to be removed last + existing_users.add(params.user) keep_teams = set() keep_users = set()