Fix implied roles in the application credentials

When user requests new application credentials without specifying roles
explicitly all current roles from the token are being used for that
(including implied roles).
When new application credentials are requested specifying a role that
implies another role (i.e. member) only that role is added into the
list. This is not what is expected, so change it by looping through
every requested role and add every implied role into the list if it is
not already there.

Related-Bug: https://bugs.launchpad.net/keystone/+bug/2030061

Change-Id: I452313ac7e1e6960748bcd1e667fb7c0076eb7a2
This commit is contained in:
gtema 2024-02-27 14:09:21 +01:00 committed by Dmitriy Rabotyagov
parent 1b78b57ec5
commit c3c6d9854c
2 changed files with 43 additions and 0 deletions

View File

@ -598,6 +598,19 @@ class UserAppCredListCreateResource(ks_flask.ResourceBase):
def _get_roles(self, app_cred_data, token):
if app_cred_data.get('roles'):
roles = self._normalize_role_list(app_cred_data['roles'])
# When "roles" passed into the application credentials creation
# we need to ensure also all implied roles are included similarly
# to how it behaves when no roles are passed and current user roles
# are being used.
# So loop over all roles implied by the current role and add it
# explicitly if not already there
for role in 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]:
roles.append(imp_role_obj)
# NOTE(cmurphy): The user is not allowed to add a role that is not
# in their token. This is to prevent trustees or application
# credential users from escallating their privileges to include

View File

@ -68,6 +68,36 @@ class ApplicationCredentialTestCase(test_v3.RestfulTestCase):
# But not the stored hash
self.assertNotIn('secret_hash', resp.json['application_credential'])
def test_create_application_credential_implied_role(self):
"""Test creation with implied roles.
Verify that implied roles are respected when user creates new
application credential specifying a role that implies some other
role
"""
implied_role = unit.new_role_ref(name='implied')
implied_role_id = implied_role['id']
PROVIDERS.role_api.create_role(implied_role_id, implied_role)
PROVIDERS.role_api.create_implied_role(self.role_id, implied_role_id)
with self.test_client() as c:
roles = [{'id': self.role_id}]
app_cred_body = self._app_cred_body(roles=roles)
token = self.get_scoped_token()
resp = c.post(
'/v3/users/%s/application_credentials' % self.user_id,
json=app_cred_body,
expected_status_code=http.client.CREATED,
headers={'X-Auth-Token': token})
# Create operation returns the secret
self.assertIn('secret', resp.json['application_credential'])
# But not the stored hash
self.assertNotIn('secret_hash', resp.json['application_credential'])
# Ensure implied role is also granted
self.assertIn(
implied_role_id,
[x['id'] for x in resp.json["application_credential"]["roles"]]
)
def test_create_application_credential_with_secret(self):
with self.test_client() as c:
secret = 'supersecuresecret'