32 lines
1.6 KiB
Diff
32 lines
1.6 KiB
Diff
# UNDF: UNDF-2026-000000132
|
|
--- a/keystone/api/users.py
|
|
+++ b/keystone/api/users.py
|
|
@@ -645,13 +645,17 @@ class UserResource(ks_flask.ResourceBase):
|
|
roles = self._normalize_role_list(app_cred_data['roles'])
|
|
- # loop over all roles implied by the current role and add it
|
|
- # explicitly if not already there
|
|
- for role in roles:
|
|
+ # Build a seen-set to deduplicate in O(1) instead of O(n) list scan.
|
|
+ seen_role_ids = {r['id'] for r in roles}
|
|
+ # Iterate over a snapshot so in-loop appends don't extend the loop.
|
|
+ for role in list(roles):
|
|
for implied_role in PROVIDERS.role_api.list_implied_roles(
|
|
role['id']
|
|
):
|
|
imp_role_obj = PROVIDERS.role_api.get_role(
|
|
implied_role['implied_role_id']
|
|
)
|
|
- if imp_role_obj['id'] not in [x['id'] for x in roles]:
|
|
+ if imp_role_obj['id'] not in seen_role_ids:
|
|
+ seen_role_ids.add(imp_role_obj['id'])
|
|
roles.append(imp_role_obj)
|
|
- # NOTE(cmurphy): The user is not allowed to add a role that is not
|
|
- # in their token.
|
|
- token_roles = [r['id'] for r in token.roles]
|
|
+ token_role_ids = {r['id'] for r in token.roles}
|
|
for role in roles:
|
|
- if role['id'] not in token_roles:
|
|
+ if role['id'] not in token_role_ids:
|
|
detail = _(
|
|
'Cannot create an application credential with '
|
|
'unassigned role'
|