diff --git a/keystone/service.py b/keystone/service.py index 05cca4e600..8e1f056e77 100644 --- a/keystone/service.py +++ b/keystone/service.py @@ -32,6 +32,10 @@ class AdminRouter(wsgi.ComposingRouter): controller=auth_controller, action='validate_token', conditions=dict(method=['GET'])) + mapper.connect('/tokens/{token_id}', + controller=auth_controller, + action='delete_token', + conditions=dict(method=['DELETE'])) mapper.connect('/tokens/{token_id}/endpoints', controller=auth_controller, action='endpoints', @@ -255,6 +259,14 @@ class TokenController(wsgi.Application): roles_ref.append(self.identity_api.get_role(context, role_id)) return self._format_token(token_ref, roles_ref) + def delete_token(self, context, token_id): + """Delete a token, effectively invalidating it for authz.""" + # TODO(termie): this stuff should probably be moved to middleware + self.assert_admin(context) + + token_ref = self.token_api.delete_token(context=context, + token_id=token_id) + def endpoints(self, context, token_id): """Return service catalog endpoints.""" token_ref = self.token_api.get_token(context=context, diff --git a/tests/test_cli.py b/tests/test_cli.py index 5d06d49185..bd4ead735b 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -59,6 +59,9 @@ class CliMasterTestCase(test_keystoneclient.KcMasterTestCase): def test_authenticate_token_tenant_name(self): raise nose.exc.SkipTest('N/A') + def test_authenticate_and_delete_token(self): + raise nose.exc.SkipTest('N/A') + def test_tenant_create_update_and_delete(self): raise nose.exc.SkipTest('cli does not support booleans yet') diff --git a/tests/test_keystoneclient.py b/tests/test_keystoneclient.py index 1cda1bc620..a32a3b143c 100644 --- a/tests/test_keystoneclient.py +++ b/tests/test_keystoneclient.py @@ -122,6 +122,22 @@ class KeystoneClientTests(object): token_client = self._client(token=token, tenant_name='BAR') tenants = token_client.tenants.list() self.assertEquals(tenants[0].id, self.tenant_bar['id']) + self.assertEquals(tenants[0].id, self.tenant_bar['id']) + + def test_authenticate_and_delete_token(self): + client = self.get_client() + token = client.auth_token + token_client = self._client(token=token) + tenants = token_client.tenants.list() + self.assertEquals(tenants[0].id, self.tenant_bar['id']) + + client.tokens.delete(token_client.auth_token) + + # FIXME(dolph): this should raise unauthorized + # from keystoneclient import exceptions as client_exceptions + # with self.assertRaises(client_exceptions.Unauthorized): + with self.assertRaises(Exception): + token_client.tenants.list() # TODO(termie): I'm not really sure that this is testing much def test_endpoints(self): @@ -460,3 +476,6 @@ class KcEssex3TestCase(CompatTestCase, KeystoneClientTests): client = self.get_client() roles = client.roles.get_user_role_refs(user_id='foo') self.assertTrue(len(roles) > 0) + + def test_authenticate_and_delete_token(self): + raise nose.exc.SkipTest('N/A')