summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYogeshwar Srikrishnan <yoga80@yahoo.com>2011-09-20 14:54:53 -0500
committerDolph Mathews <dolph.mathews@gmail.com>2011-09-21 12:02:53 -0500
commit64ce8c8a3b4a1e747c114ca50e3a05e65f36759d (patch)
treef13a305b0e45d349ae10899f26698e9e88c65986
parent012b2125fb121f44a1786bbd21f60568c74be367 (diff)
Added support for HEAD /tokens/{token_id}
Changed POST /tokens response container from 'auth' to 'access' Change-Id: Ibb8cf43948bce0de08cdbdb0619c4d640ced56cd
-rw-r--r--keystone/content/admin/identityadminguide.pdfbin269587 -> 269594 bytes
-rw-r--r--keystone/content/service/identitydevguide.pdfbin269587 -> 269594 bytes
-rw-r--r--keystone/controllers/auth.py18
-rw-r--r--keystone/frontends/legacy_token_auth.py4
-rwxr-xr-xkeystone/logic/service.py10
-rwxr-xr-xkeystone/logic/types/auth.py8
-rwxr-xr-xkeystone/middleware/auth_token.py8
-rwxr-xr-xkeystone/middleware/swift_auth.py8
-rwxr-xr-xkeystone/routers/admin.py3
-rw-r--r--keystone/test/functional/common.py22
-rw-r--r--keystone/test/functional/test_auth.py8
-rwxr-xr-xkeystone/test/functional/test_authentication.py8
-rw-r--r--keystone/test/functional/test_issue_85.py2
-rwxr-xr-xkeystone/test/functional/test_tenants.py4
-rwxr-xr-xkeystone/test/functional/test_token.py31
-rwxr-xr-xkeystone/test/unit/test_ec2_authn.py2
-rwxr-xr-xkeystone/utils.py2
17 files changed, 97 insertions, 41 deletions
diff --git a/keystone/content/admin/identityadminguide.pdf b/keystone/content/admin/identityadminguide.pdf
index 3a1c5b3d..5d412368 100644
--- a/keystone/content/admin/identityadminguide.pdf
+++ b/keystone/content/admin/identityadminguide.pdf
Binary files differ
diff --git a/keystone/content/service/identitydevguide.pdf b/keystone/content/service/identitydevguide.pdf
index 3a1c5b3d..5d412368 100644
--- a/keystone/content/service/identitydevguide.pdf
+++ b/keystone/content/service/identitydevguide.pdf
Binary files differ
diff --git a/keystone/controllers/auth.py b/keystone/controllers/auth.py
index bd30afb6..b8d3a8bb 100644
--- a/keystone/controllers/auth.py
+++ b/keystone/controllers/auth.py
@@ -24,14 +24,22 @@ class AuthController(wsgi.Controller):
return utils.send_result(200, req,
config.SERVICE.authenticate_ec2(creds))
+ def _validate_token(self, req, token_id):
+ """Validates the token, and that it belongs to the specified tenant"""
+ belongs_to = req.GET.get('belongsTo')
+ return config.SERVICE.validate_token(
+ utils.get_auth_token(req), token_id, belongs_to)
+
@utils.wrap_error
def validate_token(self, req, token_id):
- belongs_to = req.GET.get("belongsTo", None)
+ result = self._validate_token(req, token_id)
+ return utils.send_result(200, req, result)
- rval = config.SERVICE.validate_token(
- utils.get_auth_token(req), token_id, belongs_to)
-
- return utils.send_result(200, req, rval)
+ @utils.wrap_error
+ def check_token(self, req, token_id):
+ """Validates the token, but only returns a status code (HEAD)"""
+ self._validate_token(req, token_id)
+ return utils.send_result(200, req)
@utils.wrap_error
def delete_token(self, req, token_id):
diff --git a/keystone/frontends/legacy_token_auth.py b/keystone/frontends/legacy_token_auth.py
index fb5f65f0..7fe83d79 100644
--- a/keystone/frontends/legacy_token_auth.py
+++ b/keystone/frontends/legacy_token_auth.py
@@ -85,8 +85,8 @@ class AuthProtocol(object):
def __transform_headers(self, content):
"""Transform Keystone auth to legacy headers"""
headers = {}
- if "auth" in content:
- auth = content["auth"]
+ if "access" in content:
+ auth = content["access"]
if "token" in auth:
headers["X-Auth-Token"] = auth["token"]["id"]
if "serviceCatalog" in auth:
diff --git a/keystone/logic/service.py b/keystone/logic/service.py
index dba9c564..fce5b420 100755
--- a/keystone/logic/service.py
+++ b/keystone/logic/service.py
@@ -123,11 +123,17 @@ class IdentityService(object):
if not api.TOKEN.get(token_id):
raise fault.UnauthorizedFault("Bad token, please reauthenticate")
-
(token, user) = self.__validate_token(token_id, belongs_to)
-
return self.__get_validate_data(token, user)
+ def check_token(self, admin_token, token_id, belongs_to=None):
+ self.__validate_service_or_keystone_admin_token(admin_token)
+
+ if not api.TOKEN.get(token_id):
+ raise fault.UnauthorizedFault("Bad token, please reauthenticate")
+
+ self.__validate_token(token_id, belongs_to)
+
def revoke_token(self, admin_token, token_id):
self.__validate_admin_token(admin_token)
diff --git a/keystone/logic/types/auth.py b/keystone/logic/types/auth.py
index 5fff98df..edc94200 100755
--- a/keystone/logic/types/auth.py
+++ b/keystone/logic/types/auth.py
@@ -226,7 +226,7 @@ class AuthData(object):
self.__convert_baseurls_to_dict()
def to_xml(self):
- dom = etree.Element("auth",
+ dom = etree.Element("access",
xmlns="http://docs.openstack.org/identity/api/v2.0")
token = etree.Element("token",
expires=self.token.expires.isoformat())
@@ -245,8 +245,8 @@ class AuthData(object):
base_url_item = getattr(base_url, url_kind + "_url")
if base_url_item:
endpoint.set(url_kind + "URL", base_url_item.\
- replace('%tenant_id%', self.token.tenant_id)
- if self.token.tenant_id else base_url_item)
+ replace('%tenant_id%', str(self.token.tenant_id))
+ if self.token.tenant_id else base_url_item)
service.append(endpoint)
service_catalog.append(service)
dom.append(service_catalog)
@@ -283,7 +283,7 @@ class AuthData(object):
service_catalog[key] = endpoints
auth["serviceCatalog"] = service_catalog
ret = {}
- ret["auth"] = auth
+ ret["access"] = auth
return json.dumps(ret)
diff --git a/keystone/middleware/auth_token.py b/keystone/middleware/auth_token.py
index e0e993d8..b766966e 100755
--- a/keystone/middleware/auth_token.py
+++ b/keystone/middleware/auth_token.py
@@ -279,18 +279,18 @@ class AuthProtocol(object):
token_info = json.loads(data)
roles = []
- role_refs = token_info["auth"]["user"]["roleRefs"]
+ role_refs = token_info["access"]["user"]["roleRefs"]
if role_refs != None:
for role_ref in role_refs:
roles.append(role_ref["roleId"])
try:
- tenant = token_info['auth']['token']['tenantId']
+ tenant = token_info['access']['token']['tenantId']
except:
tenant = None
if not tenant:
- tenant = token_info['auth']['user']['tenantId']
- verified_claims = {'user': token_info['auth']['user']['username'],
+ tenant = token_info['access']['user']['tenantId']
+ verified_claims = {'user': token_info['access']['user']['username'],
'tenant': tenant,
'roles': roles}
return verified_claims
diff --git a/keystone/middleware/swift_auth.py b/keystone/middleware/swift_auth.py
index f92b2d76..ff498b12 100755
--- a/keystone/middleware/swift_auth.py
+++ b/keystone/middleware/swift_auth.py
@@ -212,19 +212,19 @@ class AuthProtocol(object):
identity_info = json.loads(data)
roles = []
- role_refs = identity_info["auth"]["user"]["roleRefs"]
+ role_refs = identity_info["access"]["user"]["roleRefs"]
if role_refs is not None:
for role_ref in role_refs:
roles.append(role_ref["roleId"])
try:
- tenant = identity_info['auth']['token']['tenantId']
+ tenant = identity_info['access']['token']['tenantId']
except:
tenant = None
if not tenant:
- tenant = identity_info['auth']['user']['tenantId']
+ tenant = identity_info['access']['user']['tenantId']
# TODO(Ziad): add groups back in
- identity = {'user': identity_info['auth']['user']['username'],
+ identity = {'user': identity_info['access']['user']['username'],
'tenant': tenant,
'roles': roles}
diff --git a/keystone/routers/admin.py b/keystone/routers/admin.py
index bf804388..d63304f9 100755
--- a/keystone/routers/admin.py
+++ b/keystone/routers/admin.py
@@ -47,6 +47,9 @@ class AdminApi(wsgi.Router):
action="validate_token",
conditions=dict(method=["GET"]))
mapper.connect("/tokens/{token_id}", controller=auth_controller,
+ action="check_token",
+ conditions=dict(method=["HEAD"]))
+ mapper.connect("/tokens/{token_id}", controller=auth_controller,
action="delete_token",
conditions=dict(method=["DELETE"]))
diff --git a/keystone/test/functional/common.py b/keystone/test/functional/common.py
index 1cc1615a..c408905a 100644
--- a/keystone/test/functional/common.py
+++ b/keystone/test/functional/common.py
@@ -107,10 +107,11 @@ class RestfulTestCase(HttpTestCase):
def _decode_response_body(self, response):
"""Detects response body type, and attempts to decode it"""
- if 'application/json' in response.getheader('Content-Type', ''):
- response.json = self._decode_json(response.body)
- elif 'application/xml' in response.getheader('Content-Type', ''):
- response.xml = self._decode_xml(response.body)
+ if response.body != None and response.body.strip():
+ if 'application/json' in response.getheader('Content-Type', ''):
+ response.json = self._decode_json(response.body)
+ elif 'application/xml' in response.getheader('Content-Type', ''):
+ response.xml = self._decode_xml(response.body)
return response
@staticmethod
@@ -186,6 +187,16 @@ class ApiTestCase(RestfulTestCase):
return self.admin_request(method='GET',
path='/tokens/%s?belongsTo=%s' % (token_id, tenant_id), **kwargs)
+ def check_token(self, token_id, **kwargs):
+ """HEAD /tokens/{token_id}"""
+ return self.admin_request(method='HEAD',
+ path='/tokens/%s' % (token_id,), **kwargs)
+
+ def check_token_belongs_to(self, token_id, tenant_id, **kwargs):
+ """HEAD /tokens/{token_id}?belongsTo={tenant_id}"""
+ return self.admin_request(method='HEAD',
+ path='/tokens/%s?belongsTo=%s' % (token_id, tenant_id), **kwargs)
+
def delete_token(self, token_id, **kwargs):
"""DELETE /tokens/{token_id}"""
return self.admin_request(method='DELETE',
@@ -453,7 +464,7 @@ class FunctionalTestCase(ApiTestCase):
"""Prepare keystone for system tests"""
# Authenticate as admin user to establish admin_token
self.admin_token = self.authenticate(self.admin_username,
- self.admin_password).json['auth']['token']['id']
+ self.admin_password).json['access']['token']['id']
self.admin_user_id = self.fetch_user_by_name('admin').\
json['users']['values'][0]['id']
@@ -467,7 +478,6 @@ class FunctionalTestCase(ApiTestCase):
"passwordCredentials": {
"username": user_name,
"password": user_password}}}
-
if tenant_id:
data["auth"]["tenantId"] = tenant_id
diff --git a/keystone/test/functional/test_auth.py b/keystone/test/functional/test_auth.py
index d192959c..c2d70296 100644
--- a/keystone/test/functional/test_auth.py
+++ b/keystone/test/functional/test_auth.py
@@ -15,8 +15,8 @@ class TestAdminAuthentication(common.FunctionalTestCase):
r = self.authenticate(self.admin_username, self.admin_password)
# Assert we get back a token with an expiration date
- self.assertTrue(r.json['auth']['token']['id'])
- self.assertTrue(r.json['auth']['token']['expires'])
+ self.assertTrue(r.json['access']['token']['id'])
+ self.assertTrue(r.json['access']['token']['expires'])
class TestAdminAuthenticationNegative(common.FunctionalTestCase):
@@ -32,7 +32,7 @@ class TestAdminAuthenticationNegative(common.FunctionalTestCase):
# Replace our admin_token with a mere service token
self.admin_token = self.authenticate(user['name'], user['password']).\
- json['auth']['token']['id']
+ json['access']['token']['id']
# Try creating another user using the wrong token
self.create_user(assert_status=401)
@@ -57,7 +57,7 @@ class TestServiceAuthentication(common.FunctionalTestCase):
'passwordCredentials': {
'username': self.user['name'],
'password': self.user['password']}}}).\
- json['auth']['token']['id']
+ json['access']['token']['id']
# In the real world, the service user would then pass his/her token
# to some service that depends on keystone, which would then need to
diff --git a/keystone/test/functional/test_authentication.py b/keystone/test/functional/test_authentication.py
index 485477ea..d860db91 100755
--- a/keystone/test/functional/test_authentication.py
+++ b/keystone/test/functional/test_authentication.py
@@ -43,8 +43,8 @@ class AuthenticationTest(common.FunctionalTestCase):
r = self.authenticate(self.user['name'], self.user['password'],
self.tenant['id'], assert_status=200)
- self.assertIsNotNone(r.json['auth']['token'])
- self.assertIsNotNone(r.json['auth']['serviceCatalog'])
+ self.assertIsNotNone(r.json['access']['token'])
+ self.assertIsNotNone(r.json['access']['serviceCatalog'])
def test_authorize_xml(self):
data = ('<?xml version="1.0" encoding="UTF-8"?> '
@@ -55,7 +55,7 @@ class AuthenticationTest(common.FunctionalTestCase):
self.user['name'], self.user['password'])
r = self.post_token(as_xml=data, assert_status=200)
- self.assertEquals(r.xml.tag, '{%s}auth' % self.xmlns)
+ self.assertEquals(r.xml.tag, '{%s}access' % self.xmlns)
serviceCatalog = r.xml.find('{%s}serviceCatalog' % self.xmlns)
self.assertIsNotNone(serviceCatalog)
@@ -79,7 +79,7 @@ class AuthenticationTest(common.FunctionalTestCase):
"passwordCredentials": {
"username-field-completely-wrong": self.user['name'],
"password": self.user['password']},
- "tenantId": self.tenant['id']}}
+ "tenantId": self.tenant['id']}}
self.post_token(as_json=data, assert_status=400)
def test_authorize_user_wrong_xml(self):
diff --git a/keystone/test/functional/test_issue_85.py b/keystone/test/functional/test_issue_85.py
index d52aa892..0244a40a 100644
--- a/keystone/test/functional/test_issue_85.py
+++ b/keystone/test/functional/test_issue_85.py
@@ -16,7 +16,7 @@ class TestIssue85(common.FunctionalTestCase):
# Authenticate as user to get a token *for a specific tenant*
user_token = self.authenticate(user['name'], user['password'],
- tenant['id']).json['auth']['token']['id']
+ tenant['id']).json['access']['token']['id']
# Validate and check that token belongs to tenant
tenantid = self.get_token(user_token).\
diff --git a/keystone/test/functional/test_tenants.py b/keystone/test/functional/test_tenants.py
index 8f51fe6d..d3d197d9 100755
--- a/keystone/test/functional/test_tenants.py
+++ b/keystone/test/functional/test_tenants.py
@@ -128,7 +128,7 @@ class GetTenantsTest(TenantTest):
user = self.create_user_with_known_password(tenant_id=tenant['id']).\
json['user']
token = self.authenticate(user['name'], user['password'],
- tenant['id']).json['auth']['token']
+ tenant['id']).json['access']['token']
self.service_token = token['id']
tenants = self.service_request(method='GET', path='/tenants',
assert_status=200).json['tenants']['values']
@@ -140,7 +140,7 @@ class GetTenantsTest(TenantTest):
user = self.create_user_with_known_password(tenant_id=tenant['id']).\
json['user']
token = self.authenticate(user['name'], user['password'],
- tenant['id']).json['auth']['token']
+ tenant['id']).json['access']['token']
self.service_token = token['id']
r = self.service_request(method='GET', path='/tenants',
diff --git a/keystone/test/functional/test_token.py b/keystone/test/functional/test_token.py
index 14000139..a96bd111 100755
--- a/keystone/test/functional/test_token.py
+++ b/keystone/test/functional/test_token.py
@@ -30,7 +30,7 @@ class ValidateToken(common.FunctionalTestCase):
self.role_ref = self.grant_role_to_user(self.user['id'],
self.role['id'], self.tenant['id']).json['role']
self.token = self.authenticate(self.user['name'],
- self.user['password'], self.tenant['id']).json['auth']['token']
+ self.user['password'], self.tenant['id']).json['access']['token']
def test_validate_token_true(self):
r = self.get_token_belongsto(self.token['id'], self.tenant['id'],
@@ -85,5 +85,34 @@ class ValidateToken(common.FunctionalTestCase):
'Accept': 'application/xml'})
+class CheckToken(common.FunctionalTestCase):
+ def setUp(self, *args, **kwargs):
+ super(CheckToken, self).setUp(*args, **kwargs)
+ self.tenant = self.create_tenant().json['tenant']
+ self.user = self.create_user_with_known_password(
+ tenant_id=self.tenant['id']).json['user']
+ self.token = self.authenticate(self.user['name'],
+ self.user['password'], self.tenant['id']).json['access']['token']
+
+ def test_validate_token_true(self):
+ self.check_token_belongs_to(self.token['id'], self.tenant['id'],
+ assert_status=200)
+
+ def test_validate_token_true_using_service_token(self):
+ self.admin_token = self.service_admin_token
+ self.check_token_belongs_to(self.token['id'], self.tenant['id'],
+ assert_status=200)
+
+ def test_validate_token_expired(self):
+ self.check_token(self.expired_admin_token, assert_status=403)
+
+ def test_validate_token_expired_xml(self):
+ self.check_token(self.expired_admin_token, assert_status=403, headers={
+ 'Accept': 'application/xml'})
+
+ def test_validate_token_invalid(self):
+ self.check_token(common.unique_str(), assert_status=401)
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/keystone/test/unit/test_ec2_authn.py b/keystone/test/unit/test_ec2_authn.py
index 2593a38f..c85d274a 100755
--- a/keystone/test/unit/test_ec2_authn.py
+++ b/keystone/test/unit/test_ec2_authn.py
@@ -68,7 +68,7 @@ class EC2AuthnMethods(base.ServiceAPITest):
self.get_response()
expected = {
- u'auth': {
+ u'access': {
u'serviceCatalog': {},
u'token': {
u'expires': self.expires.strftime("%Y-%m-%dT%H:%M:%S.%f"),
diff --git a/keystone/utils.py b/keystone/utils.py
index 1dbd3fc4..b9e95cd2 100755
--- a/keystone/utils.py
+++ b/keystone/utils.py
@@ -106,7 +106,7 @@ def send_error(code, req, result):
return resp
-def send_result(code, req, result):
+def send_result(code, req, result=None):
content = None
resp = Response()