Add is_domain to keystoneauth token

This patch allows keystoneauth to handle the v3 project scoped token
'is_domain' flag, that represents whether the scoped project acts as a
domain.

Follow on patches will build on this to create policy rules to execute
domain scoped token operations with project tokens.

Change-Id: I28bea2aa1e1ab299eba1dfa9f0a8451a7846a5d5
Partially-Implements: add-isdomain-to-token
Depends-On: Ic0bd0c6cf2c47680063752820a067cf40d47b184
This commit is contained in:
Clenimar Sousa 2016-02-19 11:23:22 -03:00 committed by Clenimar Filemon
parent c43d9dc75b
commit b1f1e50a0d
4 changed files with 108 additions and 3 deletions

View File

@ -397,6 +397,14 @@ class AccessInfo(object):
"""
raise NotImplementedError()
@property
def project_is_domain(self):
"""Return if a project act as a domain.
:returns: bool
"""
raise NotImplementedError()
class AccessInfoV2(AccessInfo):
"""An object for encapsulating raw v2 auth token from identity service."""
@ -528,6 +536,10 @@ class AccessInfoV2(AccessInfo):
except KeyError:
pass
@property
def project_is_domain(self):
return False
@property
def project_domain_id(self):
return None
@ -658,6 +670,10 @@ class AccessInfoV3(AccessInfo):
def project_id(self):
return self._project['id']
@_missingproperty
def project_is_domain(self):
return self._data['token']['is_domain']
@_missingproperty
def project_domain_id(self):
return self._project['domain']['id']

View File

@ -63,7 +63,7 @@ class Token(dict):
trust_id=None, trust_impersonation=None, trustee_user_id=None,
trustor_user_id=None, oauth_access_token_id=None,
oauth_consumer_id=None, audit_id=None, audit_chain_id=None,
is_admin_project=None):
is_admin_project=None, project_is_domain=None):
super(Token, self).__init__()
self.user_id = user_id or uuid.uuid4().hex
@ -99,7 +99,8 @@ class Token(dict):
self.set_project_scope(id=project_id,
name=project_name,
domain_id=project_domain_id,
domain_name=project_domain_name)
domain_name=project_domain_name,
is_domain=project_is_domain)
if domain_id or domain_name:
self.set_domain_scope(id=domain_id, name=domain_name)
@ -213,6 +214,14 @@ class Token(dict):
def project_id(self, value):
self.root.setdefault('project', {})['id'] = value
@property
def project_is_domain(self):
return self.root.get('is_domain')
@project_is_domain.setter
def project_is_domain(self, value):
self.root['is_domain'] = value
@property
def project_name(self):
return self.root.get('project', {}).get('name')
@ -390,12 +399,15 @@ class Token(dict):
return service
def set_project_scope(self, id=None, name=None, domain_id=None,
domain_name=None):
domain_name=None, is_domain=None):
self.project_id = id or uuid.uuid4().hex
self.project_name = name or uuid.uuid4().hex
self.project_domain_id = domain_id or uuid.uuid4().hex
self.project_domain_name = domain_name or uuid.uuid4().hex
if is_domain is not None:
self.project_is_domain = is_domain
def set_domain_scope(self, id=None, name=None):
self.domain_id = id or uuid.uuid4().hex
self.domain_name = name or uuid.uuid4().hex

View File

@ -44,6 +44,7 @@ class AccessV3Test(utils.TestCase):
self.assertFalse(auth_ref.domain_scoped)
self.assertFalse(auth_ref.project_scoped)
self.assertIsNone(auth_ref.project_is_domain)
self.assertEqual(token.user_domain_id, auth_ref.user_domain_id)
self.assertEqual(token.user_domain_name, auth_ref.user_domain_name)
@ -110,6 +111,7 @@ class AccessV3Test(utils.TestCase):
self.assertTrue(auth_ref.domain_scoped)
self.assertFalse(auth_ref.project_scoped)
self.assertIsNone(auth_ref.project_is_domain)
self.assertEqual(token.audit_id, auth_ref.audit_id)
self.assertEqual(token.audit_chain_id, auth_ref.audit_chain_id)
@ -155,6 +157,53 @@ class AccessV3Test(utils.TestCase):
self.assertFalse(auth_ref.domain_scoped)
self.assertTrue(auth_ref.project_scoped)
self.assertIsNone(auth_ref.project_is_domain)
self.assertEqual(token.audit_id, auth_ref.audit_id)
self.assertEqual(token.audit_chain_id, auth_ref.audit_chain_id)
def test_building_project_as_domain_scoped_accessinfo(self):
token = fixture.V3Token()
token.set_project_scope(is_domain=True)
service = token.add_service(type='identity')
service.add_standard_endpoints(public='http://url')
token_id = uuid.uuid4().hex
auth_ref = access.create(body=token, auth_token=token_id)
self.assertIn('methods', auth_ref._data['token'])
self.assertIn('catalog', auth_ref._data['token'])
self.assertTrue(auth_ref.has_service_catalog())
self.assertTrue(auth_ref._data['token']['catalog'])
self.assertEqual(token_id, auth_ref.auth_token)
self.assertEqual(token.user_name, auth_ref.username)
self.assertEqual(token.user_id, auth_ref.user_id)
self.assertEqual(token.role_ids, auth_ref.role_ids)
self.assertEqual(token.role_names, auth_ref.role_names)
self.assertIsNone(auth_ref.domain_name)
self.assertIsNone(auth_ref.domain_id)
self.assertEqual(token.project_name, auth_ref.project_name)
self.assertEqual(token.project_id, auth_ref.project_id)
self.assertEqual(auth_ref.tenant_name, auth_ref.project_name)
self.assertEqual(auth_ref.tenant_id, auth_ref.project_id)
self.assertEqual(token.project_domain_id, auth_ref.project_domain_id)
self.assertEqual(token.project_domain_name,
auth_ref.project_domain_name)
self.assertEqual(token.user_domain_id, auth_ref.user_domain_id)
self.assertEqual(token.user_domain_name, auth_ref.user_domain_name)
self.assertFalse(auth_ref.domain_scoped)
self.assertTrue(auth_ref.project_scoped)
self.assertTrue(auth_ref.project_is_domain)
self.assertEqual(token.audit_id, auth_ref.audit_id)
self.assertEqual(token.audit_chain_id, auth_ref.audit_chain_id)

View File

@ -164,6 +164,34 @@ class V3TokenTests(utils.TestCase):
self.assertEqual(project_name, token.project_name)
self.assertEqual(project_name, token['token']['project']['name'])
self.assertIsNone(token.get('token', {}).get('is_domain'))
project_domain = token['token']['project']['domain']
self.assertEqual(project_domain_id, token.project_domain_id)
self.assertEqual(project_domain_id, project_domain['id'])
self.assertEqual(project_domain_name, token.project_domain_name)
self.assertEqual(project_domain_name, project_domain['name'])
def test_project_as_domain_scoped(self):
project_id = uuid.uuid4().hex
project_name = uuid.uuid4().hex
project_domain_id = uuid.uuid4().hex
project_domain_name = uuid.uuid4().hex
project_is_domain = True
token = fixture.V3Token(project_id=project_id,
project_name=project_name,
project_domain_id=project_domain_id,
project_domain_name=project_domain_name,
project_is_domain=project_is_domain)
self.assertEqual(project_id, token.project_id)
self.assertEqual(project_id, token['token']['project']['id'])
self.assertEqual(project_name, token.project_name)
self.assertEqual(project_name, token['token']['project']['name'])
self.assertEqual(project_is_domain, token['token']['is_domain'])
project_domain = token['token']['project']['domain']
self.assertEqual(project_domain_id, token.project_domain_id)