Merge "Expose bind data via AccessInfo"
This commit is contained in:
commit
1e7de85f53
@ -369,6 +369,22 @@ class AccessInfo(object):
|
|||||||
"""
|
"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def bind(self):
|
||||||
|
"""Information about external mechanisms the token is bound to.
|
||||||
|
|
||||||
|
If a token is bound to an external authentication mechanism it can only
|
||||||
|
be used in conjunction with that mechanism. For example if bound to a
|
||||||
|
kerberos principal it may only be accepted if there is also kerberos
|
||||||
|
authentication performed on the request.
|
||||||
|
|
||||||
|
:returns: A dictionary or None. The key will be the bind type the value
|
||||||
|
is a dictionary that is specific to the format of the bind
|
||||||
|
type. Returns None if there is no bind information in the
|
||||||
|
token.
|
||||||
|
"""
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
class AccessInfoV2(AccessInfo):
|
class AccessInfoV2(AccessInfo):
|
||||||
"""An object for encapsulating a raw v2 auth token from identity
|
"""An object for encapsulating a raw v2 auth token from identity
|
||||||
@ -386,7 +402,7 @@ class AccessInfoV2(AccessInfo):
|
|||||||
set_token = super(AccessInfoV2, self).auth_token
|
set_token = super(AccessInfoV2, self).auth_token
|
||||||
return set_token or self._data['access']['token']['id']
|
return set_token or self._data['access']['token']['id']
|
||||||
|
|
||||||
@_missingproperty
|
@property
|
||||||
def _token(self):
|
def _token(self):
|
||||||
return self._data['access']['token']
|
return self._data['access']['token']
|
||||||
|
|
||||||
@ -544,6 +560,10 @@ class AccessInfoV2(AccessInfo):
|
|||||||
def service_providers(self):
|
def service_providers(self):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@_missingproperty
|
||||||
|
def bind(self):
|
||||||
|
return self._token['bind']
|
||||||
|
|
||||||
|
|
||||||
class AccessInfoV3(AccessInfo):
|
class AccessInfoV3(AccessInfo):
|
||||||
"""An object for encapsulating a raw v3 auth token from identity
|
"""An object for encapsulating a raw v3 auth token from identity
|
||||||
@ -708,3 +728,7 @@ class AccessInfoV3(AccessInfo):
|
|||||||
service_providers.ServiceProviders.from_token(self._data))
|
service_providers.ServiceProviders.from_token(self._data))
|
||||||
|
|
||||||
return self._service_providers
|
return self._service_providers
|
||||||
|
|
||||||
|
@_missingproperty
|
||||||
|
def bind(self):
|
||||||
|
return self._data['token']['bind']
|
||||||
|
@ -242,3 +242,6 @@ class Token(dict):
|
|||||||
def set_trust(self, id=None, trustee_user_id=None):
|
def set_trust(self, id=None, trustee_user_id=None):
|
||||||
self.trust_id = id or uuid.uuid4().hex
|
self.trust_id = id or uuid.uuid4().hex
|
||||||
self.trustee_user_id = trustee_user_id or uuid.uuid4().hex
|
self.trustee_user_id = trustee_user_id or uuid.uuid4().hex
|
||||||
|
|
||||||
|
def set_bind(self, name, data):
|
||||||
|
self._token.setdefault('bind', {})[name] = data
|
||||||
|
@ -405,6 +405,9 @@ class Token(dict):
|
|||||||
_service_providers.append(sp)
|
_service_providers.append(sp)
|
||||||
return sp
|
return sp
|
||||||
|
|
||||||
|
def set_bind(self, name, data):
|
||||||
|
self.root.setdefault('bind', {})[name] = data
|
||||||
|
|
||||||
|
|
||||||
class V3FederationToken(Token):
|
class V3FederationToken(Token):
|
||||||
"""A V3 Keystone Federation token that can be used for testing.
|
"""A V3 Keystone Federation token that can be used for testing.
|
||||||
|
@ -55,6 +55,7 @@ class AccessV2Test(utils.TestCase):
|
|||||||
self.assertEqual(token.audit_id, auth_ref.audit_id)
|
self.assertEqual(token.audit_id, auth_ref.audit_id)
|
||||||
self.assertIsNone(auth_ref.audit_chain_id)
|
self.assertIsNone(auth_ref.audit_chain_id)
|
||||||
self.assertIsNone(token.audit_chain_id)
|
self.assertIsNone(token.audit_chain_id)
|
||||||
|
self.assertIsNone(auth_ref.bind)
|
||||||
|
|
||||||
def test_will_expire_soon(self):
|
def test_will_expire_soon(self):
|
||||||
token = fixture.V2Token()
|
token = fixture.V2Token()
|
||||||
@ -199,3 +200,13 @@ class AccessV2Test(utils.TestCase):
|
|||||||
self.assertEqual(user_id, auth_ref.trustee_user_id)
|
self.assertEqual(user_id, auth_ref.trustee_user_id)
|
||||||
|
|
||||||
self.assertEqual(trust_id, token['access']['trust']['id'])
|
self.assertEqual(trust_id, token['access']['trust']['id'])
|
||||||
|
|
||||||
|
def test_binding(self):
|
||||||
|
token = fixture.V2Token()
|
||||||
|
principal = uuid.uuid4().hex
|
||||||
|
token.set_bind('kerberos', principal)
|
||||||
|
|
||||||
|
auth_ref = access.create(body=token)
|
||||||
|
self.assertIsInstance(auth_ref, access.AccessInfoV2)
|
||||||
|
|
||||||
|
self.assertEqual({'kerberos': principal}, auth_ref.bind)
|
||||||
|
@ -62,6 +62,7 @@ class AccessV3Test(utils.TestCase):
|
|||||||
self.assertEqual(auth_ref.audit_id, token.audit_id)
|
self.assertEqual(auth_ref.audit_id, token.audit_id)
|
||||||
self.assertIsNone(auth_ref.audit_chain_id)
|
self.assertIsNone(auth_ref.audit_chain_id)
|
||||||
self.assertIsNone(token.audit_chain_id)
|
self.assertIsNone(token.audit_chain_id)
|
||||||
|
self.assertIsNone(auth_ref.bind)
|
||||||
|
|
||||||
def test_will_expire_soon(self):
|
def test_will_expire_soon(self):
|
||||||
expires = timeutils.utcnow() + datetime.timedelta(minutes=5)
|
expires = timeutils.utcnow() + datetime.timedelta(minutes=5)
|
||||||
@ -184,3 +185,13 @@ class AccessV3Test(utils.TestCase):
|
|||||||
token.set_project_scope()
|
token.set_project_scope()
|
||||||
auth_ref = access.create(body=token)
|
auth_ref = access.create(body=token)
|
||||||
self.assertFalse(auth_ref.is_federated)
|
self.assertFalse(auth_ref.is_federated)
|
||||||
|
|
||||||
|
def test_binding(self):
|
||||||
|
token = fixture.V3Token()
|
||||||
|
principal = uuid.uuid4().hex
|
||||||
|
token.set_bind('kerberos', principal)
|
||||||
|
|
||||||
|
auth_ref = access.create(body=token)
|
||||||
|
self.assertIsInstance(auth_ref, access.AccessInfoV3)
|
||||||
|
|
||||||
|
self.assertEqual({'kerberos': principal}, auth_ref.bind)
|
||||||
|
@ -109,6 +109,19 @@ class V2TokenTests(utils.TestCase):
|
|||||||
self.assertEqual(region, service['region'])
|
self.assertEqual(region, service['region'])
|
||||||
self.assertEqual(endpoint_id, service['id'])
|
self.assertEqual(endpoint_id, service['id'])
|
||||||
|
|
||||||
|
def test_token_bind(self):
|
||||||
|
name1 = uuid.uuid4().hex
|
||||||
|
data1 = uuid.uuid4().hex
|
||||||
|
name2 = uuid.uuid4().hex
|
||||||
|
data2 = {uuid.uuid4().hex: uuid.uuid4().hex}
|
||||||
|
|
||||||
|
token = fixture.V2Token()
|
||||||
|
token.set_bind(name1, data1)
|
||||||
|
token.set_bind(name2, data2)
|
||||||
|
|
||||||
|
self.assertEqual({name1: data1, name2: data2},
|
||||||
|
token['access']['token']['bind'])
|
||||||
|
|
||||||
|
|
||||||
class V3TokenTests(utils.TestCase):
|
class V3TokenTests(utils.TestCase):
|
||||||
|
|
||||||
@ -271,3 +284,16 @@ class V3TokenTests(utils.TestCase):
|
|||||||
self.assertEqual(ref_service_providers, token.service_providers)
|
self.assertEqual(ref_service_providers, token.service_providers)
|
||||||
self.assertEqual(ref_service_providers,
|
self.assertEqual(ref_service_providers,
|
||||||
token['token']['service_providers'])
|
token['token']['service_providers'])
|
||||||
|
|
||||||
|
def test_token_bind(self):
|
||||||
|
name1 = uuid.uuid4().hex
|
||||||
|
data1 = uuid.uuid4().hex
|
||||||
|
name2 = uuid.uuid4().hex
|
||||||
|
data2 = {uuid.uuid4().hex: uuid.uuid4().hex}
|
||||||
|
|
||||||
|
token = fixture.V3Token()
|
||||||
|
token.set_bind(name1, data1)
|
||||||
|
token.set_bind(name2, data2)
|
||||||
|
|
||||||
|
self.assertEqual({name1: data1, name2: data2},
|
||||||
|
token['token']['bind'])
|
||||||
|
Loading…
Reference in New Issue
Block a user