Sync up with latest keystoneclient changes
Change-Id: I895534b2d30dec8e38461e07ebf03ea8f466dad9
This commit is contained in:
parent
8ba7650d02
commit
40ae1ffeaa
@ -18,7 +18,7 @@ Session object
|
||||
provides an HTTP request method. The transport is also to be used by
|
||||
the authenticator if needed.
|
||||
* authenticator - An authenticator derived from
|
||||
``openstack.auth.base.BaseAuthenticator`` that provides get_token and
|
||||
``openstack.auth.base.BaseAuthPlugin`` that provides get_token and
|
||||
get_endpoint methods for the session.
|
||||
|
||||
All the other methods of the session accept the following parameters:
|
||||
|
@ -33,7 +33,7 @@ from openstack.auth import base
|
||||
from openstack.auth.identity import authenticator
|
||||
|
||||
|
||||
class TestAuthenticator(base.BaseAuthenticator):
|
||||
class TestAuthenticator(base.BaseAuthPlugin):
|
||||
def __init__(self, token, endpoint):
|
||||
super(TestAuthenticator, self).__init__()
|
||||
self.token = token
|
||||
|
@ -16,7 +16,7 @@ import six
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class BaseAuthenticator(object):
|
||||
class BaseAuthPlugin(object):
|
||||
"""The basic structure of an authenticator."""
|
||||
|
||||
@abc.abstractmethod
|
||||
@ -54,3 +54,18 @@ class BaseAuthenticator(object):
|
||||
:returns string: The base URL that will be used to talk to the
|
||||
required service or None if not available.
|
||||
"""
|
||||
|
||||
def invalidate(self):
|
||||
"""Invalidate the current authentication data.
|
||||
|
||||
This should result in fetching a new token on next call.
|
||||
|
||||
A plugin may be invalidated if an Unauthorized HTTP response is
|
||||
returned to indicate that the token may have been revoked or is
|
||||
otherwise now invalid.
|
||||
|
||||
:returns bool: True if there was something that the plugin did to
|
||||
invalidate. This means that it makes sense to try again.
|
||||
If nothing happens returns False to indicate give up.
|
||||
"""
|
||||
return False
|
||||
|
@ -18,15 +18,16 @@ from openstack.auth import base
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class BaseIdentityPlugin(base.BaseAuthenticator):
|
||||
class BaseIdentityPlugin(base.BaseAuthPlugin):
|
||||
|
||||
# Consider a token valid if it does not expire for this many seconds
|
||||
BEST_BEFORE_SECONDS = 1
|
||||
|
||||
def __init__(self, auth_url=None):
|
||||
def __init__(self, auth_url=None, reauthenticate=True):
|
||||
super(BaseIdentityPlugin, self).__init__()
|
||||
self.auth_url = auth_url
|
||||
self.access_info = None
|
||||
self.reauthenticate = reauthenticate
|
||||
|
||||
@abc.abstractmethod
|
||||
def authorize(self, transport, **kwargs):
|
||||
@ -52,6 +53,28 @@ class BaseIdentityPlugin(base.BaseAuthenticator):
|
||||
"""
|
||||
return self.get_access(transport).auth_token
|
||||
|
||||
def _needs_reauthenticate(self):
|
||||
"""Return if the existing token needs to be re-authenticated.
|
||||
|
||||
The token should be refreshed if it is about to expire.
|
||||
|
||||
:returns: True if the plugin should fetch a new token. False otherwise.
|
||||
"""
|
||||
if not self.access_info:
|
||||
# authentication was never fetched.
|
||||
return True
|
||||
|
||||
if not self.reauthenticate:
|
||||
# don't re-authenticate if it has been disallowed.
|
||||
return False
|
||||
|
||||
if self.access_info.will_expire_soon(self.BEST_BEFORE_SECONDS):
|
||||
# if it's about to expire we should re-authenticate now.
|
||||
return True
|
||||
|
||||
# otherwise it's fine and use the existing one.
|
||||
return False
|
||||
|
||||
def get_access(self, transport):
|
||||
"""Fetch or return a current AccessInfo object.
|
||||
|
||||
@ -62,12 +85,27 @@ class BaseIdentityPlugin(base.BaseAuthenticator):
|
||||
|
||||
:returns AccessInfo: Valid AccessInfo
|
||||
"""
|
||||
if (not self.access_info or
|
||||
self.access_info.will_expire_soon(self.BEST_BEFORE_SECONDS)):
|
||||
if self._needs_reauthenticate():
|
||||
self.access_info = self.authorize(transport)
|
||||
|
||||
return self.access_info
|
||||
|
||||
def invalidate(self):
|
||||
"""Invalidate the current authentication data.
|
||||
|
||||
This should result in fetching a new token on next call.
|
||||
|
||||
A plugin may be invalidated if an Unauthorized HTTP response is
|
||||
returned to indicate that the token may have been revoked or is
|
||||
otherwise now invalid.
|
||||
|
||||
:returns bool: True if there was something that the plugin did to
|
||||
invalidate. This means that it makes sense to try again.
|
||||
If nothing happens returns False to indicate give up.
|
||||
"""
|
||||
self.access_info = None
|
||||
return True
|
||||
|
||||
def get_endpoint(self, transport, service, **kwargs):
|
||||
"""Return a valid endpoint for a service.
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
# under the License.
|
||||
|
||||
import abc
|
||||
import logging
|
||||
|
||||
import six
|
||||
|
||||
@ -20,21 +21,29 @@ from openstack.auth import access
|
||||
from openstack.auth.identity import base
|
||||
from openstack import exceptions
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class Auth(base.BaseIdentityPlugin):
|
||||
|
||||
def __init__(self, auth_url,
|
||||
trust_id=None,
|
||||
tenant_id=None,
|
||||
tenant_name=None):
|
||||
tenant_name=None,
|
||||
reauthenticate=True):
|
||||
"""Construct an Identity V2 Authentication Plugin.
|
||||
|
||||
:param string auth_url: Identity service endpoint for authorization.
|
||||
:param string trust_id: Trust ID for trust scoping.
|
||||
:param string tenant_id: Tenant ID for project scoping.
|
||||
:param string tenant_name: Tenant name for project scoping.
|
||||
:param bool reauthenticate: Allow fetching a new token if the current
|
||||
one is going to expire.
|
||||
(optional) default True
|
||||
"""
|
||||
super(Auth, self).__init__(auth_url=auth_url)
|
||||
super(Auth, self).__init__(auth_url=auth_url,
|
||||
reauthenticate=reauthenticate)
|
||||
|
||||
self.trust_id = trust_id
|
||||
self.tenant_id = tenant_id
|
||||
@ -42,7 +51,7 @@ class Auth(base.BaseIdentityPlugin):
|
||||
|
||||
def authorize(self, transport, **kwargs):
|
||||
headers = {'Accept': 'application/json'}
|
||||
url = self.auth_url + '/tokens'
|
||||
url = self.auth_url.rstrip('/') + '/tokens'
|
||||
params = {'auth': self.get_auth_data(headers)}
|
||||
|
||||
if self.tenant_id:
|
||||
@ -52,6 +61,7 @@ class Auth(base.BaseIdentityPlugin):
|
||||
if self.trust_id:
|
||||
params['auth']['trust_id'] = self.trust_id
|
||||
|
||||
_logger.debug('Making authentication request to %s', url)
|
||||
resp = transport.post(url, json=params, headers=headers)
|
||||
|
||||
try:
|
||||
@ -73,20 +83,38 @@ class Auth(base.BaseIdentityPlugin):
|
||||
|
||||
class Password(Auth):
|
||||
|
||||
def __init__(self, auth_url, username, password, **kwargs):
|
||||
def __init__(self, auth_url, username=None, password=None, user_id=None,
|
||||
**kwargs):
|
||||
"""A plugin for authenticating with a username and password.
|
||||
|
||||
A username or user_id must be provided.
|
||||
|
||||
:param string auth_url: Identity service endpoint for authorization.
|
||||
:param string username: Username for authentication.
|
||||
:param string password: Password for authentication.
|
||||
:param string user_id: User ID for authentication.
|
||||
|
||||
:raises TypeError: if a user_id or username is not provided.
|
||||
"""
|
||||
super(Password, self).__init__(auth_url, **kwargs)
|
||||
|
||||
if not (user_id or username):
|
||||
msg = 'You need to specify either a username or user_id'
|
||||
raise TypeError(msg)
|
||||
|
||||
self.user_id = user_id
|
||||
self.username = username
|
||||
self.password = password
|
||||
|
||||
def get_auth_data(self, headers=None):
|
||||
return {'passwordCredentials': {'username': self.username,
|
||||
'password': self.password}}
|
||||
auth = {'password': self.password}
|
||||
|
||||
if self.username:
|
||||
auth['username'] = self.username
|
||||
elif self.user_id:
|
||||
auth['userId'] = self.user_id
|
||||
|
||||
return {'passwordCredentials': auth}
|
||||
|
||||
|
||||
class Token(Auth):
|
||||
|
@ -33,7 +33,8 @@ class Auth(base.BaseIdentityPlugin):
|
||||
project_id=None,
|
||||
project_name=None,
|
||||
project_domain_id=None,
|
||||
project_domain_name=None):
|
||||
project_domain_name=None,
|
||||
reauthenticate=True):
|
||||
"""Construct an Identity V3 Authentication Plugin.
|
||||
|
||||
:param string auth_url: Identity service endpoint for authentication.
|
||||
@ -45,9 +46,13 @@ class Auth(base.BaseIdentityPlugin):
|
||||
:param string project_name: Project name for project scoping.
|
||||
:param string project_domain_id: Project's domain ID for project.
|
||||
:param string project_domain_name: Project's domain name for project.
|
||||
:param bool reauthenticate: Allow fetching a new token if the current
|
||||
one is going to expire.
|
||||
(optional) default True
|
||||
"""
|
||||
|
||||
super(Auth, self).__init__(auth_url=auth_url)
|
||||
super(Auth, self).__init__(auth_url=auth_url,
|
||||
reauthenticate=reauthenticate)
|
||||
|
||||
self.auth_methods = auth_methods
|
||||
self.trust_id = trust_id
|
||||
@ -104,6 +109,7 @@ class Auth(base.BaseIdentityPlugin):
|
||||
elif self.trust_id:
|
||||
body['auth']['scope'] = {'OS-TRUST:trust': {'id': self.trust_id}}
|
||||
|
||||
_logger.debug('Making authentication request to %s', self.token_url)
|
||||
resp = transport.post(self.token_url, json=body, headers=headers)
|
||||
|
||||
try:
|
||||
|
Loading…
Reference in New Issue
Block a user