diff --git a/keystone/identity/core.py b/keystone/identity/core.py index a0704f1..717da99 100644 --- a/keystone/identity/core.py +++ b/keystone/identity/core.py @@ -524,6 +524,17 @@ class RoleController(wsgi.Application): self.identity_api.add_user_to_tenant(context, tenant_id, user_id) self.identity_api.add_role_to_user_and_tenant( context, user_id, tenant_id, role_id) + + # invalidate all of the user's tokens + # TODO(dolph): ideally this would only revoke relevant tokens, if any + try: + for token_id in self.token_api.list_tokens(context, user_id): + self.token_api.delete_token(context, token_id) + except exception.NotImplemented: + # tokens remain valid for backends that can't list tokens for users + LOG.warning('User %s roles have changed, but existing tokens ' + 'remain valid' % user_id) + role_ref = self.identity_api.get_role(context, role_id) return {'role': role_ref} @@ -554,7 +565,16 @@ class RoleController(wsgi.Application): if not roles: self.identity_api.remove_user_from_tenant( context, tenant_id, user_id) - return + + # invalidate all of the user's tokens + # TODO(dolph): ideally this would only revoke relevant tokens, if any + try: + for token_id in self.token_api.list_tokens(context, user_id): + self.token_api.delete_token(context, token_id) + except exception.NotImplemented: + # tokens remain valid for backends that can't list tokens for users + LOG.warning('User %s roles have changed, but existing tokens ' + 'remain valid' % user_id) # COMPAT(diablo): CRUD extension def get_role_refs(self, context, user_id): @@ -596,6 +616,17 @@ class RoleController(wsgi.Application): self.identity_api.add_user_to_tenant(context, tenant_id, user_id) self.identity_api.add_role_to_user_and_tenant( context, user_id, tenant_id, role_id) + + # invalidate all of the user's tokens + # TODO(dolph): ideally this would only revoke relevant tokens, if any + try: + for token_id in self.token_api.list_tokens(context, user_id): + self.token_api.delete_token(context, token_id) + except exception.NotImplemented: + # tokens remain valid for backends that can't list tokens for users + LOG.warning('User %s roles have changed, but existing tokens ' + 'remain valid' % user_id) + role_ref = self.identity_api.get_role(context, role_id) return {'role': role_ref} @@ -623,3 +654,13 @@ class RoleController(wsgi.Application): if not roles: self.identity_api.remove_user_from_tenant( context, tenant_id, user_id) + + # invalidate all of the user's tokens + # TODO(dolph): ideally this would only revoke relevant tokens, if any + try: + for token_id in self.token_api.list_tokens(context, user_id): + self.token_api.delete_token(context, token_id) + except exception.NotImplemented: + # tokens remain valid for backends that can't list tokens for users + LOG.warning('User %s roles have changed, but existing tokens ' + 'remain valid' % user_id) diff --git a/tests/test_keystoneclient.py b/tests/test_keystoneclient.py index 0f6f628..53373e0 100644 --- a/tests/test_keystoneclient.py +++ b/tests/test_keystoneclient.py @@ -769,15 +769,15 @@ class KcMasterTestCase(CompatTestCase, KeystoneClientTests): def test_tenant_add_and_remove_user(self): client = self.get_client(admin=True) client.roles.add_user_role(tenant=self.tenant_baz['id'], - user=self.user_foo['id'], + user=self.user_two['id'], role=self.role_useless['id']) user_refs = client.tenants.list_users(tenant=self.tenant_baz['id']) - self.assert_(self.user_foo['id'] in [x.id for x in user_refs]) + self.assert_(self.user_two['id'] in [x.id for x in user_refs]) client.roles.remove_user_role(tenant=self.tenant_baz['id'], - user=self.user_foo['id'], + user=self.user_two['id'], role=self.role_useless['id']) user_refs = client.tenants.list_users(tenant=self.tenant_baz['id']) - self.assert_(self.user_foo['id'] not in [x.id for x in user_refs]) + self.assert_(self.user_two['id'] not in [x.id for x in user_refs]) def test_user_role_add_404(self): from keystoneclient import exceptions as client_exceptions @@ -890,16 +890,16 @@ class KcEssex3TestCase(CompatTestCase, KeystoneClientTests): def test_tenant_add_and_remove_user(self): client = self.get_client(admin=True) client.roles.add_user_to_tenant(tenant_id=self.tenant_baz['id'], - user_id=self.user_foo['id'], + user_id=self.user_two['id'], role_id=self.role_useless['id']) role_refs = client.roles.get_user_role_refs( - user_id=self.user_foo['id']) + user_id=self.user_two['id']) self.assert_(self.tenant_baz['id'] in [x.tenantId for x in role_refs]) # get the "role_refs" so we get the proper id, this is how the clients # do it roleref_refs = client.roles.get_user_role_refs( - user_id=self.user_foo['id']) + user_id=self.user_two['id']) for roleref_ref in roleref_refs: if (roleref_ref.roleId == self.role_useless['id'] and roleref_ref.tenantId == self.tenant_baz['id']): @@ -907,11 +907,11 @@ class KcEssex3TestCase(CompatTestCase, KeystoneClientTests): break client.roles.remove_user_from_tenant(tenant_id=self.tenant_baz['id'], - user_id=self.user_foo['id'], + user_id=self.user_two['id'], role_id=roleref_ref.id) role_refs = client.roles.get_user_role_refs( - user_id=self.user_foo['id']) + user_id=self.user_two['id']) self.assert_(self.tenant_baz['id'] not in [x.tenantId for x in role_refs])