From eee830f73b5900e3162f15b5762170f8458e577e Mon Sep 17 00:00:00 2001 From: Sergey Kolupaev Date: Thu, 30 Jul 2026 18:23:30 -0700 Subject: [PATCH 1/3] KEPM: Update policy evaluation status text --- keepercommander/commands/pedm/pedm_aram.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/keepercommander/commands/pedm/pedm_aram.py b/keepercommander/commands/pedm/pedm_aram.py index 302d47b44..b2ef09079 100644 --- a/keepercommander/commands/pedm/pedm_aram.py +++ b/keepercommander/commands/pedm/pedm_aram.py @@ -461,9 +461,9 @@ def execute(self, context: KeeperParams, **kwargs) -> Any: status_info = None if isinstance(status, int): if status == NotificationCenter_pb2.NotificationApprovalStatus.NAS_APPROVED: - status_info = '"Approved"' + status_info = 'Approved' elif status == NotificationCenter_pb2.NotificationApprovalStatus.NAS_DENIED: - status_info = '"Denied"' + status_info = 'Denied' if status_info: event['request_status'] = status_info if 'evaluation_status' in event: @@ -471,13 +471,19 @@ def execute(self, context: KeeperParams, **kwargs) -> Any: status_info = None if isinstance(status, int): if status == 1: - status_info = '"Allowed"' + status_info = 'Allowed' elif status == 2: - status_info = '"Denied"' + status_info = 'Denied' elif status == 3: - status_info = '"Denied - Failed MFA"' + status_info = 'Denied - Failed MFA' elif status == 4: - status_info = '"Denied - Failed Justification"' + status_info = 'Denied - Failed Justification' + elif status == 5: + status_info = 'Denied - Failed Approval' + elif status == 6: + status_info = 'Denied - Operator Approval' + elif status == 7: + status_info = 'Denied - Custom Controls' if status_info: event['evaluation_status'] = status_info if hash_fields: From 79206fcac78b6acfadc452fafa00756d5628f94e Mon Sep 17 00:00:00 2001 From: Sergey Kolupaev Date: Sat, 1 Aug 2026 20:30:57 -0700 Subject: [PATCH 2/3] get_enterprise_data_keys fails if managed node has no MANAGE_ROLE privilege --- keepercommander/enterprise.py | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/keepercommander/enterprise.py b/keepercommander/enterprise.py index 30ef9edf0..2613c579d 100644 --- a/keepercommander/enterprise.py +++ b/keepercommander/enterprise.py @@ -209,7 +209,10 @@ def load(self, params): # type: (KeeperParams) -> None if not rs.hasMore: break if proto.MANAGED_NODES in entities: - self.load_missing_role_keys(params) + try: + self.load_missing_role_keys(params) + except: + pass if not entities.isdisjoint([proto.MANAGED_NODES, proto.NODES, proto.ROLE_USERS]): if 'user_root_nodes' in params.enterprise: del params.enterprise['user_root_nodes'] @@ -222,15 +225,34 @@ def load_missing_role_keys(params): # type: (KeeperParams) -> None if 'managed_nodes' in params.enterprise: for mn in params.enterprise['managed_nodes']: nodes.add(mn['role_id']) + + enterprise_user_id = 0 + if len(nodes) > 0: + if 'users' in params.enterprise: + enterprise_user_id = next((x.get('enterprise_user_id') for x in params.enterprise['users'] if x.get('username') == params.user), 0) + if 'role_users' in params.enterprise: + role_users = {x.get('role_id') for x in params.enterprise['role_users'] if x.get('enterprise_user_id') == enterprise_user_id} + nodes.intersection_update(role_users) + if len(nodes) > 0: + if 'role_privileges' in params.enterprise: + user_node = next((x.get('enterprise_user_id') for x in params.enterprise['users'] if x.get('username') == params.user)) + roles_privileges = set() + for rp in params.enterprise['role_privileges']: + privilege = rp.get('privilege') + if privilege == 'manage_roles': + role_id = rp.get('role_id') + if role_id in nodes: + roles_privileges.add(role_id) + nodes.intersection_update(roles_privileges) if len(nodes) > 0: - roles = set() + role_keys = set() if 'role_keys' in params.enterprise: for rk in params.enterprise['role_keys']: - roles.add(rk['role_id']) + role_keys.add(rk['role_id']) if 'role_keys2' in params.enterprise: for rk in params.enterprise['role_keys2']: - roles.add(rk['role_id']) - nodes.difference_update(roles) + role_keys.add(rk['role_id']) + nodes.difference_update(role_keys) if len(nodes) > 0: rq = proto.GetEnterpriseDataKeysRequest() rq.roleId.extend(nodes) From 9bb7293a5faa2331b13ca48630793d01a03cc885 Mon Sep 17 00:00:00 2001 From: Sergey Kolupaev Date: Sat, 1 Aug 2026 20:31:45 -0700 Subject: [PATCH 3/3] Release 18.0.15 --- keepercommander/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/keepercommander/__init__.py b/keepercommander/__init__.py index 3610ed2cf..370cb4759 100644 --- a/keepercommander/__init__.py +++ b/keepercommander/__init__.py @@ -10,4 +10,4 @@ # Contact: commander@keepersecurity.com # -__version__ = '18.0.14' +__version__ = '18.0.15'