From 33a13b7dcd82ee926a707bf1cc7f87ae2b90c98e Mon Sep 17 00:00:00 2001 From: Dolph Mathews Date: Tue, 21 Feb 2012 16:38:40 -0600 Subject: Add HEAD /tokens/{token_id} (bug 933587) Also addresses bug 928045 by returning 204 No Content for null content bodies. Change-Id: Icd4b8b5f6c29c074cb014c301fe86cd917f6663e --- keystone/common/wsgi.py | 9 ++++++--- keystone/service.py | 35 +++++++++++++++++++++++++++++++---- tests/test_content_types.py | 5 ++--- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/keystone/common/wsgi.py b/keystone/common/wsgi.py index 496288e5..d5976339 100644 --- a/keystone/common/wsgi.py +++ b/keystone/common/wsgi.py @@ -182,7 +182,9 @@ class Application(BaseApplication): logging.warning(e) return render_exception(e) - if result is None or type(result) is str or type(result) is unicode: + if result is None: + return render_response(status=(204, 'No Content')) + elif isinstance(result, basestring): return result elif isinstance(result, webob.Response): return result @@ -458,13 +460,14 @@ class ExtensionRouter(Router): return _factory -def render_response(body, status=(200, 'OK'), headers=None): +def render_response(body=None, status=(200, 'OK'), headers=None): """Forms a WSGI response""" resp = webob.Response() resp.status = '%s %s' % status resp.headerlist = headers or [('Content-Type', 'application/json')] - resp.body = json.dumps(body) + if body is not None: + resp.body = json.dumps(body) return resp diff --git a/keystone/service.py b/keystone/service.py index b0bfd10c..359ba8e4 100644 --- a/keystone/service.py +++ b/keystone/service.py @@ -44,6 +44,10 @@ class AdminRouter(wsgi.ComposingRouter): controller=auth_controller, action='validate_token', conditions=dict(method=['GET'])) + mapper.connect('/tokens/{token_id}', + controller=auth_controller, + action='validate_token_head', + conditions=dict(method=['HEAD'])) mapper.connect('/tokens/{token_id}', controller=auth_controller, action='delete_token', @@ -316,11 +320,10 @@ class TokenController(wsgi.Application): logging.debug('TOKEN_REF %s', token_ref) return self._format_authenticate(token_ref, roles_ref, catalog_ref) - # admin only - def validate_token(self, context, token_id, belongs_to=None): - """Check that a token is valid. + def _get_token_ref(self, context, token_id, belongs_to=None): + """Returns a token if a valid one exists. - Optionally, also ensure that it is owned by a specific tenant. + Optionally, limited to a token owned by a specific tenant. """ # TODO(termie): this stuff should probably be moved to middleware @@ -332,6 +335,30 @@ class TokenController(wsgi.Application): if belongs_to: assert token_ref['tenant']['id'] == belongs_to + return token_ref + + # admin only + def validate_token_head(self, context, token_id, belongs_to=None): + """Check that a token is valid. + + Optionally, also ensure that it is owned by a specific tenant. + + Identical to ``validate_token``, except does not return a response. + + """ + assert self._get_token_ref(context, token_id, belongs_to) + + # admin only + def validate_token(self, context, token_id, belongs_to=None): + """Check that a token is valid. + + Optionally, also ensure that it is owned by a specific tenant. + + Returns metadata about the token along any associated roles. + + """ + token_ref = self._get_token_ref(context, token_id, belongs_to) + # TODO(termie): optimize this call at some point and put it into the # the return for metadata # fill out the roles in the metadata diff --git a/tests/test_content_types.py b/tests/test_content_types.py index 016ffa9a..d2dd51e1 100644 --- a/tests/test_content_types.py +++ b/tests/test_content_types.py @@ -313,13 +313,12 @@ class CoreApiTests(object): sake of completely covering the core API. """ - raise nose.exc.SkipTest('Blocked by bug 933587') - token = self.get_scoped_token() self.admin_request(method='HEAD', path='/v2.0/tokens/%(token_id)s' % { 'token_id': token, }, - token=token) + token=token, + expected_status=204) def test_endpoints(self): raise nose.exc.SkipTest('Blocked by bug 933555') -- cgit