diff options
author | Dolph Mathews <dolph.mathews@gmail.com> | 2013-06-03 14:21:36 -0500 |
---|---|---|
committer | Dolph Mathews <dolph.mathews@gmail.com> | 2013-06-03 14:24:49 -0500 |
commit | 132ff6d85e02acdce7483c2848686676cb4f14a0 (patch) | |
tree | 8664e53c7485f5f78200e72436976f6d54dd389f | |
parent | cd349711bc6210bf35952c5f71bb92ab7676bd2d (diff) | |
download | keystone-132ff6d85e02acdce7483c2848686676cb4f14a0.tar.gz keystone-132ff6d85e02acdce7483c2848686676cb4f14a0.tar.xz keystone-132ff6d85e02acdce7483c2848686676cb4f14a0.zip |
Maintain tokens after role assignments (bug 1170186)
Change-Id: Iacd2d9e09be4ab3d6a3c5acf4074e4af7e300602
-rw-r--r-- | keystone/identity/controllers.py | 9 | ||||
-rw-r--r-- | tests/test_content_types.py | 36 | ||||
-rw-r--r-- | tests/test_v3_auth.py | 60 |
3 files changed, 75 insertions, 30 deletions
diff --git a/keystone/identity/controllers.py b/keystone/identity/controllers.py index 3e60272d..b2dae337 100644 --- a/keystone/identity/controllers.py +++ b/keystone/identity/controllers.py @@ -308,7 +308,6 @@ class Role(controller.V2Controller): self.identity_api.add_role_to_user_and_project( context, user_id, tenant_id, role_id) - self._delete_tokens_for_user(context, user_id) role_ref = self.identity_api.get_role(context, role_id) return {'role': role_ref} @@ -766,14 +765,6 @@ class RoleV3(controller.V3Controller): self.identity_api.create_grant( context, role_id, user_id, group_id, domain_id, project_id) - # So that existing tokens don't stop the use of this grant - # delete any tokens for this user or, in the case of a group, - # tokens from all the uses who are members of this group. - if user_id: - self._delete_tokens_for_user(context, user_id) - else: - self._delete_tokens_for_group(context, group_id) - @controller.protected def list_grants(self, context, user_id=None, group_id=None, domain_id=None, project_id=None): diff --git a/tests/test_content_types.py b/tests/test_content_types.py index e5bdc56a..d4cc1d81 100644 --- a/tests/test_content_types.py +++ b/tests/test_content_types.py @@ -214,23 +214,35 @@ class RestfulTestCase(test.TestCase): def admin_request(self, **kwargs): return self._request(app=self.admin_app, **kwargs) + def _get_token(self, body): + """Convenience method so that we can test authenticated requests.""" + r = self.public_request(method='POST', path='/v2.0/tokens', body=body) + return self._get_token_id(r) + + def get_unscoped_token(self): + """Convenience method so that we can test authenticated requests.""" + return self._get_token({ + 'auth': { + 'passwordCredentials': { + 'username': self.user_foo['name'], + 'password': self.user_foo['password'], + }, + }, + }) + def get_scoped_token(self, tenant_id=None): """Convenience method so that we can test authenticated requests.""" if not tenant_id: tenant_id = self.tenant_bar['id'] - r = self.public_request( - method='POST', - path='/v2.0/tokens', - body={ - 'auth': { - 'passwordCredentials': { - 'username': self.user_foo['name'], - 'password': self.user_foo['password'], - }, - 'tenantId': tenant_id, + return self._get_token({ + 'auth': { + 'passwordCredentials': { + 'username': self.user_foo['name'], + 'password': self.user_foo['password'], }, - }) - return self._get_token_id(r) + 'tenantId': tenant_id, + }, + }) def _get_token_id(self, r): """Helper method to return a token ID from a response. diff --git a/tests/test_v3_auth.py b/tests/test_v3_auth.py index 1ee3719d..dd39f96a 100644 --- a/tests/test_v3_auth.py +++ b/tests/test_v3_auth.py @@ -490,6 +490,48 @@ class TestTokenRevoking(test_v3.RestfulTestCase): group_id=self.group1['id'], project_id=self.projectA['id']) + def test_unscoped_token_remains_valid_after_role_assignment(self): + r = self.post( + '/auth/tokens', + body=self.build_authentication_request( + user_id=self.user1['id'], + password=self.user1['password'])) + unscoped_token = r.headers.get('X-Subject-Token') + + r = self.post( + '/auth/tokens', + body=self.build_authentication_request( + token=unscoped_token, + project_id=self.projectA['id'])) + scoped_token = r.headers.get('X-Subject-Token') + + # confirm both tokens are valid + self.head('/auth/tokens', + headers={'X-Subject-Token': unscoped_token}, + expected_status=204) + self.head('/auth/tokens', + headers={'X-Subject-Token': scoped_token}, + expected_status=204) + + # create a new role + role = self.new_role_ref() + self.identity_api.create_role(role['id'], role) + + # assign a new role + self.put( + '/projects/%(project_id)s/users/%(user_id)s/roles/%(role_id)s' % { + 'project_id': self.projectA['id'], + 'user_id': self.user1['id'], + 'role_id': role['id']}) + + # both tokens should remain valid + self.head('/auth/tokens', + headers={'X-Subject-Token': unscoped_token}, + expected_status=204) + self.head('/auth/tokens', + headers={'X-Subject-Token': scoped_token}, + expected_status=204) + def test_deleting_user_grant_revokes_token(self): """Test deleting a user grant revokes token. @@ -521,13 +563,13 @@ class TestTokenRevoking(test_v3.RestfulTestCase): headers={'X-Subject-Token': token}, expected_status=401) - def test_creating_user_grant_revokes_token(self): - """Test creating a user grant revokes token. + def test_domain_user_role_assignment_maintains_token(self): + """Test user-domain role assignment maintains existing token. Test Plan: - Get a token for user1, scoped to ProjectA - Create a grant for user1 on DomainB - - Check token is no longer valid + - Check token is still valid """ auth_data = self.build_authentication_request( @@ -540,7 +582,7 @@ class TestTokenRevoking(test_v3.RestfulTestCase): self.head('/auth/tokens', headers={'X-Subject-Token': token}, expected_status=204) - # Delete the grant, which should invalidate the token + # Assign a role, which should not affect the token grant_url = ( '/domains/%(domain_id)s/users/%(user_id)s/' 'roles/%(role_id)s' % { @@ -550,7 +592,7 @@ class TestTokenRevoking(test_v3.RestfulTestCase): self.put(grant_url) self.head('/auth/tokens', headers={'X-Subject-Token': token}, - expected_status=401) + expected_status=204) def test_deleting_group_grant_revokes_tokens(self): """Test deleting a group grant revokes tokens. @@ -613,13 +655,13 @@ class TestTokenRevoking(test_v3.RestfulTestCase): headers={'X-Subject-Token': token3}, expected_status=204) - def test_creating_group_grant_revokes_token(self): - """Test creating a group grant revokes token. + def test_domain_group_role_assignment_maintains_token(self): + """Test domain-group role assignment maintains existing token. Test Plan: - Get a token for user1, scoped to ProjectA - Create a grant for group1 on DomainB - - Check token is no longer valid + - Check token is still longer valid """ auth_data = self.build_authentication_request( @@ -642,7 +684,7 @@ class TestTokenRevoking(test_v3.RestfulTestCase): self.put(grant_url) self.head('/auth/tokens', headers={'X-Subject-Token': token}, - expected_status=401) + expected_status=204) def test_group_membership_changes_revokes_token(self): """Test add/removal to/from group revokes token. |