Do not fetch group assignments without groups

Without the change, the method fetched all assignments for a project
or domain, regardless of who has the assignment, user or group. This
led to situation when federated user without groups could scope a token
with other user's rules.

Return empty list of assignments if no groups were passed.

Closes-Bug: 1677723
Change-Id: I65f5be915bef2f979e70b043bde27064e970349d
(cherry picked from commit 2139639eea)
This commit is contained in:
Boris Bobrov 2017-04-25 14:36:12 +00:00 committed by Lance Bragstad
parent 02951abcd5
commit 955fd6ca37
2 changed files with 63 additions and 0 deletions

View File

@ -126,6 +126,11 @@ class Manager(manager.Manager):
def get_roles_for_groups(self, group_ids, project_id=None, domain_id=None):
"""Get a list of roles for this group on domain and/or project."""
# if no group ids were passed, there are no roles. Without this check,
# all assignments for the project or domain will be fetched,
# which is not what we want.
if not group_ids:
return []
if project_id is not None:
self.resource_api.get_project(project_id)
assignment_list = self.list_role_assignments(

View File

@ -1908,6 +1908,34 @@ class FederatedTokenTests(test_v3.RestfulTestCase, FederatedSetupMixin):
token_groups = token_resp['token']['user']['OS-FEDERATION']['groups']
self.assertEqual(0, len(token_groups))
def test_issue_scoped_token_no_groups(self):
"""Verify that token without groups cannot get scoped to project.
This test is required because of bug 1677723.
"""
# issue unscoped token with no groups
r = self._issue_unscoped_token(assertion='USER_NO_GROUPS_ASSERTION')
self.assertIsNotNone(r.headers.get('X-Subject-Token'))
token_resp = r.json_body
token_groups = token_resp['token']['user']['OS-FEDERATION']['groups']
self.assertEqual(0, len(token_groups))
unscoped_token = r.headers.get('X-Subject-Token')
# let admin get roles in a project
self.proj_employees
admin = unit.new_user_ref(CONF.identity.default_domain_id)
self.identity_api.create_user(admin)
self.assignment_api.create_grant(self.role_admin['id'],
user_id=admin['id'],
project_id=self.proj_employees['id'])
# try to scope the token. It should fail
scope = self._scope_request(
unscoped_token, 'project', self.proj_employees['id']
)
self.v3_create_token(
scope, expected_status=http_client.UNAUTHORIZED)
def test_issue_unscoped_token_malformed_environment(self):
"""Test whether non string objects are filtered out.
@ -3319,6 +3347,36 @@ class ShadowMappingTests(test_v3.RestfulTestCase, FederatedSetupMixin):
self.expected_results[project_name], roles[0]['name']
)
def test_user_gets_only_assigned_roles(self):
# in bug 1677723 user could get roles outside of what was assigned
# to them. This test verifies that this is no longer true.
# Authenticate once to create the projects
response = self._issue_unscoped_token()
self.assertValidMappedUser(response.json_body['token'])
unscoped_token = response.headers.get('X-Subject-Token')
# Assign admin role to newly-created project to another user
staging_project = self.resource_api.get_project_by_name(
'Staging', self.idp['domain_id']
)
admin = unit.new_user_ref(CONF.identity.default_domain_id)
self.identity_api.create_user(admin)
self.assignment_api.create_grant(self.role_admin['id'],
user_id=admin['id'],
project_id=staging_project['id'])
# Authenticate again with the federated user and verify roles
response = self._issue_unscoped_token()
self.assertValidMappedUser(response.json_body['token'])
unscoped_token = response.headers.get('X-Subject-Token')
scope = self._scope_request(
unscoped_token, 'project', staging_project['id']
)
response = self.v3_create_token(scope)
roles = response.json_body['token']['roles']
role_ids = [r['id'] for r in roles]
self.assertNotIn(self.role_admin['id'], role_ids)
class JsonHomeTests(test_v3.RestfulTestCase, test_v3.JsonHomeTestMixin):
JSON_HOME_DATA = {