Allow requesting an unscoped Token
The keystone server understands that specifying unscoped in the scope section of an auth request means that it should ignore the default_project_id of a user and return an unscoped token. This is the client side change to allow requesting these tokens via an auth plugin. Change-Id: Iba5ebcea0bf0d8e5a31d552977276fc03e536c67 Implements: bp explicit-unscoped
This commit is contained in:
parent
19b3fd648e
commit
91e67141bc
|
@ -112,9 +112,13 @@ class Auth(BaseAuth):
|
|||
is going to expire. (optional) default True
|
||||
:param bool include_catalog: Include the service catalog in the returned
|
||||
token. (optional) default True.
|
||||
:param bool unscoped: Force the return of an unscoped token. This will make
|
||||
the keystone server return an unscoped token even if
|
||||
a default_project_id is set for this user.
|
||||
"""
|
||||
|
||||
def __init__(self, auth_url, auth_methods, **kwargs):
|
||||
self.unscoped = kwargs.pop('unscoped', False)
|
||||
super(Auth, self).__init__(auth_url=auth_url, **kwargs)
|
||||
self.auth_methods = auth_methods
|
||||
|
||||
|
@ -138,12 +142,13 @@ class Auth(BaseAuth):
|
|||
|
||||
mutual_exclusion = [bool(self.domain_id or self.domain_name),
|
||||
bool(self.project_id or self.project_name),
|
||||
bool(self.trust_id)]
|
||||
bool(self.trust_id),
|
||||
bool(self.unscoped)]
|
||||
|
||||
if sum(mutual_exclusion) > 1:
|
||||
raise exceptions.AuthorizationFailure(
|
||||
_('Authentication cannot be scoped to multiple targets. Pick '
|
||||
'one of: project, domain or trust'))
|
||||
'one of: project, domain, trust or unscoped'))
|
||||
|
||||
if self.domain_id:
|
||||
body['auth']['scope'] = {'domain': {'id': self.domain_id}}
|
||||
|
@ -161,6 +166,8 @@ class Auth(BaseAuth):
|
|||
scope['project']['domain'] = {'name': self.project_domain_name}
|
||||
elif self.trust_id:
|
||||
body['auth']['scope'] = {'OS-TRUST:trust': {'id': self.trust_id}}
|
||||
elif self.unscoped:
|
||||
body['auth']['scope'] = {'unscoped': {}}
|
||||
|
||||
# NOTE(jamielennox): we add nocatalog here rather than in token_url
|
||||
# directly as some federation plugins require the base token_url
|
||||
|
|
|
@ -496,3 +496,38 @@ class V3IdentityPlugin(utils.TestCase):
|
|||
self.assertIs(v3.AuthMethod, v3_base.AuthMethod)
|
||||
self.assertIs(v3.AuthConstructor, v3_base.AuthConstructor)
|
||||
self.assertIs(v3.Auth, v3_base.Auth)
|
||||
|
||||
def test_unscoped_request(self):
|
||||
token = fixture.V3Token()
|
||||
self.stub_auth(json=token)
|
||||
password = uuid.uuid4().hex
|
||||
|
||||
a = v3.Password(self.TEST_URL,
|
||||
user_id=token.user_id,
|
||||
password=password,
|
||||
unscoped=True)
|
||||
s = session.Session()
|
||||
|
||||
auth_ref = a.get_access(s)
|
||||
|
||||
self.assertFalse(auth_ref.scoped)
|
||||
body = self.requests_mock.last_request.json()
|
||||
|
||||
ident = body['auth']['identity']
|
||||
|
||||
self.assertEqual(['password'], ident['methods'])
|
||||
self.assertEqual(token.user_id, ident['password']['user']['id'])
|
||||
self.assertEqual(password, ident['password']['user']['password'])
|
||||
|
||||
self.assertEqual({}, body['auth']['scope']['unscoped'])
|
||||
|
||||
def test_unscoped_with_scope_data(self):
|
||||
a = v3.Password(self.TEST_URL,
|
||||
user_id=uuid.uuid4().hex,
|
||||
password=uuid.uuid4().hex,
|
||||
unscoped=True,
|
||||
project_id=uuid.uuid4().hex)
|
||||
|
||||
s = session.Session()
|
||||
|
||||
self.assertRaises(exceptions.AuthorizationFailure, a.get_auth_ref, s)
|
||||
|
|
Loading…
Reference in New Issue