diff --git a/keystoneauth1/access/access.py b/keystoneauth1/access/access.py index cf834fbf..de299e3e 100644 --- a/keystoneauth1/access/access.py +++ b/keystoneauth1/access/access.py @@ -329,6 +329,18 @@ class AccessInfo(object): """ raise NotImplementedError() + @property + def is_admin_project(self): + """Return true if the current project scope is the admin project. + + For backwards compatibility purposes if there is nothing specified in + the token we always assume we are in the admin project, so this will + default to True. + + :returns boolean + """ + raise NotImplementedError() + @property def audit_id(self): """Return the audit ID if present. @@ -536,6 +548,10 @@ class AccessInfoV2(AccessInfo): def is_federated(self): return False + @property + def is_admin_project(self): + return True + @property def audit_id(self): try: @@ -576,6 +592,10 @@ class AccessInfoV3(AccessInfo): def is_federated(self): return 'OS-FEDERATION' in self._user + @property + def is_admin_project(self): + return self._data.get('token', {}).get('is_admin_project', True) + @_missingproperty def expires(self): return utils.parse_isotime(self._data['token']['expires_at']) diff --git a/keystoneauth1/fixture/v3.py b/keystoneauth1/fixture/v3.py index f7cc3ebe..cd4a67fa 100644 --- a/keystoneauth1/fixture/v3.py +++ b/keystoneauth1/fixture/v3.py @@ -62,7 +62,8 @@ class Token(dict): project_domain_name=None, domain_id=None, domain_name=None, 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): + oauth_consumer_id=None, audit_id=None, audit_chain_id=None, + is_admin_project=None): super(Token, self).__init__() self.user_id = user_id or uuid.uuid4().hex @@ -117,6 +118,9 @@ class Token(dict): if audit_chain_id: self.audit_chain_id = audit_chain_id + if is_admin_project is not None: + self.is_admin_project = is_admin_project + @property def root(self): return self.setdefault('token', {}) @@ -335,6 +339,18 @@ class Token(dict): def role_names(self): return [r['name'] for r in self.root.get('roles', [])] + @property + def is_admin_project(self): + return self.root.get('is_admin_project') + + @is_admin_project.setter + def is_admin_project(self, value): + self.root['is_admin_project'] = value + + @is_admin_project.deleter + def is_admin_project(self): + self.root.pop('is_admin_project', None) + def validate(self): project = self.root.get('project') domain = self.root.get('domain') diff --git a/keystoneauth1/tests/unit/access/test_v2_access.py b/keystoneauth1/tests/unit/access/test_v2_access.py index 8f7bb503..aabef671 100644 --- a/keystoneauth1/tests/unit/access/test_v2_access.py +++ b/keystoneauth1/tests/unit/access/test_v2_access.py @@ -210,3 +210,9 @@ class AccessV2Test(utils.TestCase): self.assertIsInstance(auth_ref, access.AccessInfoV2) self.assertEqual({'kerberos': principal}, auth_ref.bind) + + def test_is_admin_project(self): + token = fixture.V2Token() + auth_ref = access.create(body=token) + self.assertIsInstance(auth_ref, access.AccessInfoV2) + self.assertIs(True, auth_ref.is_admin_project) diff --git a/keystoneauth1/tests/unit/access/test_v3_access.py b/keystoneauth1/tests/unit/access/test_v3_access.py index 7e9792c3..4054c2e8 100644 --- a/keystoneauth1/tests/unit/access/test_v3_access.py +++ b/keystoneauth1/tests/unit/access/test_v3_access.py @@ -195,3 +195,21 @@ class AccessV3Test(utils.TestCase): self.assertIsInstance(auth_ref, access.AccessInfoV3) self.assertEqual({'kerberos': principal}, auth_ref.bind) + + def test_is_admin_project_unset(self): + token = fixture.V3Token() + auth_ref = access.create(body=token) + self.assertIsInstance(auth_ref, access.AccessInfoV3) + self.assertIs(True, auth_ref.is_admin_project) + + def test_is_admin_project_true(self): + token = fixture.V3Token(is_admin_project=True) + auth_ref = access.create(body=token) + self.assertIsInstance(auth_ref, access.AccessInfoV3) + self.assertIs(True, auth_ref.is_admin_project) + + def test_is_admin_project_false(self): + token = fixture.V3Token(is_admin_project=False) + auth_ref = access.create(body=token) + self.assertIsInstance(auth_ref, access.AccessInfoV3) + self.assertIs(False, auth_ref.is_admin_project) diff --git a/keystoneauth1/tests/unit/test_fixtures.py b/keystoneauth1/tests/unit/test_fixtures.py index 0b533d00..55296594 100644 --- a/keystoneauth1/tests/unit/test_fixtures.py +++ b/keystoneauth1/tests/unit/test_fixtures.py @@ -297,3 +297,20 @@ class V3TokenTests(utils.TestCase): self.assertEqual({name1: data1, name2: data2}, token['token']['bind']) + + def test_is_admin_project(self): + token = fixture.V3Token() + self.assertIsNone(token.is_admin_project) + self.assertNotIn('is_admin_project', token['token']) + + token.is_admin_project = True + self.assertIs(True, token.is_admin_project) + self.assertIs(True, token['token']['is_admin_project']) + + token.is_admin_project = False + self.assertIs(False, token.is_admin_project) + self.assertIs(False, token['token']['is_admin_project']) + + del token.is_admin_project + self.assertIsNone(token.is_admin_project) + self.assertNotIn('is_admin_project', token['token'])