Break default auth plugin into file
Extract the default auth plugin into its own file. In future I'd like to move the whole auth loading process into this file - however I have some ideas for changing around how config works I'd like to do first. Change-Id: I90c2f9e55947a436374ff54465e15caffdf9925d Implements: bp refactor-extract-module
This commit is contained in:
parent
f950931484
commit
9ba567e32c
|
@ -179,8 +179,6 @@ from keystoneclient import access
|
|||
from keystoneclient import adapter
|
||||
from keystoneclient import auth
|
||||
from keystoneclient.auth.identity import base as base_identity
|
||||
from keystoneclient.auth.identity import v2
|
||||
from keystoneclient.auth import token_endpoint
|
||||
from keystoneclient.common import cms
|
||||
from keystoneclient import discover
|
||||
from keystoneclient import exceptions
|
||||
|
@ -192,6 +190,8 @@ import six
|
|||
from six.moves import urllib
|
||||
|
||||
from keystonemiddleware import _memcache_crypt as memcache_crypt
|
||||
from keystonemiddleware.auth_token import _auth
|
||||
from keystonemiddleware.auth_token import _base
|
||||
from keystonemiddleware.auth_token import _exceptions as exc
|
||||
from keystonemiddleware.auth_token import _revocations
|
||||
from keystonemiddleware.auth_token import _signing_dir
|
||||
|
@ -350,10 +350,8 @@ _OPTS = [
|
|||
' should be set to a single value for better performance.'),
|
||||
]
|
||||
|
||||
_AUTHTOKEN_GROUP = 'keystone_authtoken'
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(_OPTS, group=_AUTHTOKEN_GROUP)
|
||||
auth.register_conf_options(CONF, _AUTHTOKEN_GROUP)
|
||||
CONF.register_opts(_OPTS, group=_base.AUTHTOKEN_GROUP)
|
||||
|
||||
_LOG = logging.getLogger(__name__)
|
||||
|
||||
|
@ -460,7 +458,7 @@ def _conf_values_type_convert(conf):
|
|||
return {}
|
||||
|
||||
opt_types = {}
|
||||
for o in (_OPTS + _AuthTokenPlugin.get_options()):
|
||||
for o in (_OPTS + _auth.AuthTokenPlugin.get_options()):
|
||||
type_dest = (getattr(o, 'type', str), o.dest)
|
||||
opt_types[o.dest] = type_dest
|
||||
# Also add the deprecated name with the same type and dest.
|
||||
|
@ -498,161 +496,6 @@ class _MiniResp(object):
|
|||
self.headers.append(('Content-type', 'text/plain'))
|
||||
|
||||
|
||||
class _AuthTokenPlugin(auth.BaseAuthPlugin):
|
||||
|
||||
def __init__(self, auth_host, auth_port, auth_protocol, auth_admin_prefix,
|
||||
admin_user, admin_password, admin_tenant_name, admin_token,
|
||||
identity_uri, log):
|
||||
# NOTE(jamielennox): it does appear here that our default arguments
|
||||
# are backwards. We need to do it this way so that we can handle the
|
||||
# same deprecation strategy for CONF and the conf variable.
|
||||
if not identity_uri:
|
||||
log.warning(_LW('Configuring admin URI using auth fragments. '
|
||||
'This is deprecated, use \'identity_uri\''
|
||||
' instead.'))
|
||||
|
||||
if ':' in auth_host:
|
||||
# Note(dzyu) it is an IPv6 address, so it needs to be wrapped
|
||||
# with '[]' to generate a valid IPv6 URL, based on
|
||||
# http://www.ietf.org/rfc/rfc2732.txt
|
||||
auth_host = '[%s]' % auth_host
|
||||
|
||||
identity_uri = '%s://%s:%s' % (auth_protocol,
|
||||
auth_host,
|
||||
auth_port)
|
||||
|
||||
if auth_admin_prefix:
|
||||
identity_uri = '%s/%s' % (identity_uri,
|
||||
auth_admin_prefix.strip('/'))
|
||||
|
||||
self._identity_uri = identity_uri.rstrip('/')
|
||||
|
||||
# FIXME(jamielennox): Yes. This is wrong. We should be determining the
|
||||
# plugin to use based on a combination of discovery and inputs. Much
|
||||
# of this can be changed when we get keystoneclient 0.10. For now this
|
||||
# hardcoded path is EXACTLY the same as the original auth_token did.
|
||||
auth_url = '%s/v2.0' % self._identity_uri
|
||||
|
||||
if admin_token:
|
||||
log.warning(_LW(
|
||||
"The admin_token option in the auth_token middleware is "
|
||||
"deprecated and should not be used. The admin_user and "
|
||||
"admin_password options should be used instead. The "
|
||||
"admin_token option may be removed in a future release."))
|
||||
self._plugin = token_endpoint.Token(auth_url, admin_token)
|
||||
else:
|
||||
self._plugin = v2.Password(auth_url,
|
||||
username=admin_user,
|
||||
password=admin_password,
|
||||
tenant_name=admin_tenant_name)
|
||||
|
||||
self._LOG = log
|
||||
self._discover = None
|
||||
|
||||
def get_token(self, *args, **kwargs):
|
||||
return self._plugin.get_token(*args, **kwargs)
|
||||
|
||||
def get_endpoint(self, session, interface=None, version=None, **kwargs):
|
||||
"""Return an endpoint for the client.
|
||||
|
||||
There are no required keyword arguments to ``get_endpoint`` as a plugin
|
||||
implementation should use best effort with the information available to
|
||||
determine the endpoint.
|
||||
|
||||
:param session: The session object that the auth_plugin belongs to.
|
||||
:type session: keystoneclient.session.Session
|
||||
:param tuple version: The version number required for this endpoint.
|
||||
:param str interface: what visibility the endpoint should have.
|
||||
|
||||
:returns: The base URL that will be used to talk to the required
|
||||
service or None if not available.
|
||||
:rtype: string
|
||||
"""
|
||||
if interface == auth.AUTH_INTERFACE:
|
||||
return self._identity_uri
|
||||
|
||||
if not version:
|
||||
# NOTE(jamielennox): This plugin can only be used within auth_token
|
||||
# and auth_token will always provide version= with requests.
|
||||
return None
|
||||
|
||||
if not self._discover:
|
||||
self._discover = discover.Discover(session,
|
||||
auth_url=self._identity_uri,
|
||||
authenticated=False)
|
||||
|
||||
if not self._discover.url_for(version):
|
||||
# NOTE(jamielennox): The requested version is not supported by the
|
||||
# identity server.
|
||||
return None
|
||||
|
||||
# NOTE(jamielennox): for backwards compatibility here we don't
|
||||
# actually use the URL from discovery we hack it up instead. :(
|
||||
if version[0] == 2:
|
||||
return '%s/v2.0' % self._identity_uri
|
||||
elif version[0] == 3:
|
||||
return '%s/v3' % self._identity_uri
|
||||
|
||||
# NOTE(jamielennox): This plugin will only get called from auth_token
|
||||
# middleware. The middleware should never request a version that the
|
||||
# plugin doesn't know how to handle.
|
||||
msg = _('Invalid version asked for in auth_token plugin')
|
||||
raise NotImplementedError(msg)
|
||||
|
||||
def invalidate(self):
|
||||
return self._plugin.invalidate()
|
||||
|
||||
@classmethod
|
||||
def get_options(cls):
|
||||
options = super(_AuthTokenPlugin, cls).get_options()
|
||||
|
||||
options.extend([
|
||||
cfg.StrOpt('auth_admin_prefix',
|
||||
default='',
|
||||
help='Prefix to prepend at the beginning of the path. '
|
||||
'Deprecated, use identity_uri.'),
|
||||
cfg.StrOpt('auth_host',
|
||||
default='127.0.0.1',
|
||||
help='Host providing the admin Identity API endpoint. '
|
||||
'Deprecated, use identity_uri.'),
|
||||
cfg.IntOpt('auth_port',
|
||||
default=35357,
|
||||
help='Port of the admin Identity API endpoint. '
|
||||
'Deprecated, use identity_uri.'),
|
||||
cfg.StrOpt('auth_protocol',
|
||||
default='https',
|
||||
help='Protocol of the admin Identity API endpoint '
|
||||
'(http or https). Deprecated, use identity_uri.'),
|
||||
cfg.StrOpt('identity_uri',
|
||||
default=None,
|
||||
help='Complete admin Identity API endpoint. This '
|
||||
'should specify the unversioned root endpoint '
|
||||
'e.g. https://localhost:35357/'),
|
||||
cfg.StrOpt('admin_token',
|
||||
secret=True,
|
||||
help='This option is deprecated and may be removed in '
|
||||
'a future release. Single shared secret with the '
|
||||
'Keystone configuration used for bootstrapping a '
|
||||
'Keystone installation, or otherwise bypassing '
|
||||
'the normal authentication process. This option '
|
||||
'should not be used, use `admin_user` and '
|
||||
'`admin_password` instead.'),
|
||||
cfg.StrOpt('admin_user',
|
||||
help='Service username.'),
|
||||
cfg.StrOpt('admin_password',
|
||||
secret=True,
|
||||
help='Service user password.'),
|
||||
cfg.StrOpt('admin_tenant_name',
|
||||
default='admin',
|
||||
help='Service tenant name.'),
|
||||
])
|
||||
|
||||
return options
|
||||
|
||||
|
||||
_AuthTokenPlugin.register_conf_options(CONF, _AUTHTOKEN_GROUP)
|
||||
|
||||
|
||||
class _TokenData(object):
|
||||
"""An abstraction to show auth_token consumers some of the token contents.
|
||||
|
||||
|
@ -1354,7 +1197,7 @@ class AuthProtocol(object):
|
|||
# are accessible via _conf_get, however this doesn't work with the
|
||||
# plugin loading mechanisms. For using auth plugins we only support
|
||||
# configuring via the CONF file.
|
||||
auth_plugin = auth.load_from_conf_options(CONF, _AUTHTOKEN_GROUP)
|
||||
auth_plugin = auth.load_from_conf_options(CONF, _base.AUTHTOKEN_GROUP)
|
||||
|
||||
if not auth_plugin:
|
||||
# NOTE(jamielennox): Loading AuthTokenPlugin here should be
|
||||
|
@ -1362,7 +1205,7 @@ class AuthProtocol(object):
|
|||
# _AuthTokenPlugin.load_from_conf_options(CONF, GROUP) however
|
||||
# we can't do that because we have to use _conf_get to support
|
||||
# the paste.ini options.
|
||||
auth_plugin = _AuthTokenPlugin.load_from_options(
|
||||
auth_plugin = _auth.AuthTokenPlugin.load_from_options(
|
||||
auth_host=self._conf_get('auth_host'),
|
||||
auth_port=int(self._conf_get('auth_port')),
|
||||
auth_protocol=self._conf_get('auth_protocol'),
|
||||
|
@ -1501,7 +1344,7 @@ class _IdentityServer(object):
|
|||
# NOTE(jamielennox): This weird stripping of the prefix hack is
|
||||
# only relevant to the legacy case. We urljoin '/' to get just the
|
||||
# base URI as this is the original behaviour.
|
||||
if isinstance(self._adapter.auth, _AuthTokenPlugin):
|
||||
if isinstance(self._adapter.auth, _auth.AuthTokenPlugin):
|
||||
auth_uri = urllib.parse.urljoin(auth_uri, '/').rstrip('/')
|
||||
|
||||
return auth_uri
|
||||
|
|
|
@ -0,0 +1,181 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import logging
|
||||
|
||||
from keystoneclient import auth
|
||||
from keystoneclient.auth.identity import v2
|
||||
from keystoneclient.auth import token_endpoint
|
||||
from keystoneclient import discover
|
||||
from oslo_config import cfg
|
||||
|
||||
from keystonemiddleware.auth_token import _base
|
||||
from keystonemiddleware.i18n import _, _LW
|
||||
|
||||
|
||||
_LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AuthTokenPlugin(auth.BaseAuthPlugin):
|
||||
|
||||
def __init__(self, auth_host, auth_port, auth_protocol, auth_admin_prefix,
|
||||
admin_user, admin_password, admin_tenant_name, admin_token,
|
||||
identity_uri, log):
|
||||
# NOTE(jamielennox): it does appear here that our default arguments
|
||||
# are backwards. We need to do it this way so that we can handle the
|
||||
# same deprecation strategy for CONF and the conf variable.
|
||||
if not identity_uri:
|
||||
log.warning(_LW('Configuring admin URI using auth fragments. '
|
||||
'This is deprecated, use \'identity_uri\''
|
||||
' instead.'))
|
||||
|
||||
if ':' in auth_host:
|
||||
# Note(dzyu) it is an IPv6 address, so it needs to be wrapped
|
||||
# with '[]' to generate a valid IPv6 URL, based on
|
||||
# http://www.ietf.org/rfc/rfc2732.txt
|
||||
auth_host = '[%s]' % auth_host
|
||||
|
||||
identity_uri = '%s://%s:%s' % (auth_protocol,
|
||||
auth_host,
|
||||
auth_port)
|
||||
|
||||
if auth_admin_prefix:
|
||||
identity_uri = '%s/%s' % (identity_uri,
|
||||
auth_admin_prefix.strip('/'))
|
||||
|
||||
self._identity_uri = identity_uri.rstrip('/')
|
||||
|
||||
# FIXME(jamielennox): Yes. This is wrong. We should be determining the
|
||||
# plugin to use based on a combination of discovery and inputs. Much
|
||||
# of this can be changed when we get keystoneclient 0.10. For now this
|
||||
# hardcoded path is EXACTLY the same as the original auth_token did.
|
||||
auth_url = '%s/v2.0' % self._identity_uri
|
||||
|
||||
if admin_token:
|
||||
log.warning(_LW(
|
||||
"The admin_token option in the auth_token middleware is "
|
||||
"deprecated and should not be used. The admin_user and "
|
||||
"admin_password options should be used instead. The "
|
||||
"admin_token option may be removed in a future release."))
|
||||
self._plugin = token_endpoint.Token(auth_url, admin_token)
|
||||
else:
|
||||
self._plugin = v2.Password(auth_url,
|
||||
username=admin_user,
|
||||
password=admin_password,
|
||||
tenant_name=admin_tenant_name)
|
||||
|
||||
self._LOG = log
|
||||
self._discover = None
|
||||
|
||||
def get_token(self, *args, **kwargs):
|
||||
return self._plugin.get_token(*args, **kwargs)
|
||||
|
||||
def get_endpoint(self, session, interface=None, version=None, **kwargs):
|
||||
"""Return an endpoint for the client.
|
||||
|
||||
There are no required keyword arguments to ``get_endpoint`` as a plugin
|
||||
implementation should use best effort with the information available to
|
||||
determine the endpoint.
|
||||
|
||||
:param session: The session object that the auth_plugin belongs to.
|
||||
:type session: keystoneclient.session.Session
|
||||
:param tuple version: The version number required for this endpoint.
|
||||
:param str interface: what visibility the endpoint should have.
|
||||
|
||||
:returns: The base URL that will be used to talk to the required
|
||||
service or None if not available.
|
||||
:rtype: string
|
||||
"""
|
||||
if interface == auth.AUTH_INTERFACE:
|
||||
return self._identity_uri
|
||||
|
||||
if not version:
|
||||
# NOTE(jamielennox): This plugin can only be used within auth_token
|
||||
# and auth_token will always provide version= with requests.
|
||||
return None
|
||||
|
||||
if not self._discover:
|
||||
self._discover = discover.Discover(session,
|
||||
auth_url=self._identity_uri,
|
||||
authenticated=False)
|
||||
|
||||
if not self._discover.url_for(version):
|
||||
# NOTE(jamielennox): The requested version is not supported by the
|
||||
# identity server.
|
||||
return None
|
||||
|
||||
# NOTE(jamielennox): for backwards compatibility here we don't
|
||||
# actually use the URL from discovery we hack it up instead. :(
|
||||
if version[0] == 2:
|
||||
return '%s/v2.0' % self._identity_uri
|
||||
elif version[0] == 3:
|
||||
return '%s/v3' % self._identity_uri
|
||||
|
||||
# NOTE(jamielennox): This plugin will only get called from auth_token
|
||||
# middleware. The middleware should never request a version that the
|
||||
# plugin doesn't know how to handle.
|
||||
msg = _('Invalid version asked for in auth_token plugin')
|
||||
raise NotImplementedError(msg)
|
||||
|
||||
def invalidate(self):
|
||||
return self._plugin.invalidate()
|
||||
|
||||
@classmethod
|
||||
def get_options(cls):
|
||||
options = super(AuthTokenPlugin, cls).get_options()
|
||||
|
||||
options.extend([
|
||||
cfg.StrOpt('auth_admin_prefix',
|
||||
default='',
|
||||
help='Prefix to prepend at the beginning of the path. '
|
||||
'Deprecated, use identity_uri.'),
|
||||
cfg.StrOpt('auth_host',
|
||||
default='127.0.0.1',
|
||||
help='Host providing the admin Identity API endpoint. '
|
||||
'Deprecated, use identity_uri.'),
|
||||
cfg.IntOpt('auth_port',
|
||||
default=35357,
|
||||
help='Port of the admin Identity API endpoint. '
|
||||
'Deprecated, use identity_uri.'),
|
||||
cfg.StrOpt('auth_protocol',
|
||||
default='https',
|
||||
help='Protocol of the admin Identity API endpoint '
|
||||
'(http or https). Deprecated, use identity_uri.'),
|
||||
cfg.StrOpt('identity_uri',
|
||||
default=None,
|
||||
help='Complete admin Identity API endpoint. This '
|
||||
'should specify the unversioned root endpoint '
|
||||
'e.g. https://localhost:35357/'),
|
||||
cfg.StrOpt('admin_token',
|
||||
secret=True,
|
||||
help='This option is deprecated and may be removed in '
|
||||
'a future release. Single shared secret with the '
|
||||
'Keystone configuration used for bootstrapping a '
|
||||
'Keystone installation, or otherwise bypassing '
|
||||
'the normal authentication process. This option '
|
||||
'should not be used, use `admin_user` and '
|
||||
'`admin_password` instead.'),
|
||||
cfg.StrOpt('admin_user',
|
||||
help='Service username.'),
|
||||
cfg.StrOpt('admin_password',
|
||||
secret=True,
|
||||
help='Service user password.'),
|
||||
cfg.StrOpt('admin_tenant_name',
|
||||
default='admin',
|
||||
help='Service tenant name.'),
|
||||
])
|
||||
|
||||
return options
|
||||
|
||||
|
||||
auth.register_conf_options(cfg.CONF, _base.AUTHTOKEN_GROUP)
|
||||
AuthTokenPlugin.register_conf_options(cfg.CONF, _base.AUTHTOKEN_GROUP)
|
|
@ -0,0 +1,13 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
AUTHTOKEN_GROUP = 'keystone_authtoken'
|
|
@ -19,12 +19,13 @@ __all__ = [
|
|||
import copy
|
||||
|
||||
import keystonemiddleware.auth_token
|
||||
|
||||
from keystonemiddleware.auth_token import _auth
|
||||
from keystonemiddleware.auth_token import _base
|
||||
|
||||
auth_token_opts = [
|
||||
(keystonemiddleware.auth_token._AUTHTOKEN_GROUP,
|
||||
(_base.AUTHTOKEN_GROUP,
|
||||
keystonemiddleware.auth_token._OPTS +
|
||||
keystonemiddleware.auth_token._AuthTokenPlugin.get_options())
|
||||
_auth.AuthTokenPlugin.get_options())
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import logging
|
||||
import uuid
|
||||
|
||||
from keystoneclient import auth
|
||||
from keystoneclient import fixture
|
||||
from keystoneclient import session
|
||||
from requests_mock.contrib import fixture as rm_fixture
|
||||
import six
|
||||
import testtools
|
||||
|
||||
from keystonemiddleware.auth_token import _auth
|
||||
|
||||
|
||||
class DefaultAuthPluginTests(testtools.TestCase):
|
||||
|
||||
def new_plugin(self, auth_host=None, auth_port=None, auth_protocol=None,
|
||||
auth_admin_prefix=None, admin_user=None,
|
||||
admin_password=None, admin_tenant_name=None,
|
||||
admin_token=None, identity_uri=None, log=None):
|
||||
if not log:
|
||||
log = self.logger
|
||||
|
||||
return _auth.AuthTokenPlugin.load_from_options(
|
||||
auth_host=auth_host,
|
||||
auth_port=auth_port,
|
||||
auth_protocol=auth_protocol,
|
||||
auth_admin_prefix=auth_admin_prefix,
|
||||
admin_user=admin_user,
|
||||
admin_password=admin_password,
|
||||
admin_tenant_name=admin_tenant_name,
|
||||
admin_token=admin_token,
|
||||
identity_uri=identity_uri,
|
||||
log=log)
|
||||
|
||||
def setUp(self):
|
||||
super(DefaultAuthPluginTests, self).setUp()
|
||||
|
||||
self.stream = six.StringIO()
|
||||
self.logger = logging.getLogger(__name__)
|
||||
self.session = session.Session()
|
||||
self.requests = self.useFixture(rm_fixture.Fixture())
|
||||
|
||||
def test_auth_uri_from_fragments(self):
|
||||
auth_protocol = 'http'
|
||||
auth_host = 'testhost'
|
||||
auth_port = 8888
|
||||
auth_admin_prefix = 'admin'
|
||||
|
||||
expected = '%s://%s:%d/admin' % (auth_protocol, auth_host, auth_port)
|
||||
|
||||
plugin = self.new_plugin(auth_host=auth_host,
|
||||
auth_protocol=auth_protocol,
|
||||
auth_port=auth_port,
|
||||
auth_admin_prefix=auth_admin_prefix)
|
||||
|
||||
self.assertEqual(expected,
|
||||
plugin.get_endpoint(self.session,
|
||||
interface=auth.AUTH_INTERFACE))
|
||||
|
||||
def test_identity_uri_overrides_fragments(self):
|
||||
identity_uri = 'http://testhost:8888/admin'
|
||||
plugin = self.new_plugin(identity_uri=identity_uri,
|
||||
auth_host='anotherhost',
|
||||
auth_port=9999,
|
||||
auth_protocol='ftp')
|
||||
|
||||
self.assertEqual(identity_uri,
|
||||
plugin.get_endpoint(self.session,
|
||||
interface=auth.AUTH_INTERFACE))
|
||||
|
||||
def test_with_admin_token(self):
|
||||
token = uuid.uuid4().hex
|
||||
plugin = self.new_plugin(identity_uri='http://testhost:8888/admin',
|
||||
admin_token=token)
|
||||
self.assertEqual(token, plugin.get_token(self.session))
|
||||
|
||||
def test_with_user_pass(self):
|
||||
base_uri = 'http://testhost:8888/admin'
|
||||
token = fixture.V2Token()
|
||||
admin_tenant_name = uuid.uuid4().hex
|
||||
|
||||
self.requests.post(base_uri + '/v2.0/tokens',
|
||||
json=token)
|
||||
|
||||
plugin = self.new_plugin(identity_uri=base_uri,
|
||||
admin_user=uuid.uuid4().hex,
|
||||
admin_password=uuid.uuid4().hex,
|
||||
admin_tenant_name=admin_tenant_name)
|
||||
|
||||
self.assertEqual(token.token_id, plugin.get_token(self.session))
|
|
@ -43,6 +43,7 @@ import webob
|
|||
import webob.dec
|
||||
|
||||
from keystonemiddleware import auth_token
|
||||
from keystonemiddleware.auth_token import _base
|
||||
from keystonemiddleware.auth_token import _exceptions as exc
|
||||
from keystonemiddleware.auth_token import _revocations
|
||||
from keystonemiddleware.openstack.common import memorycache
|
||||
|
@ -2582,85 +2583,6 @@ class OtherTests(BaseAuthTokenMiddlewareTest):
|
|||
self._assert_auth_version('v10', (2, 0))
|
||||
|
||||
|
||||
class DefaultAuthPluginTests(testtools.TestCase):
|
||||
|
||||
def new_plugin(self, auth_host=None, auth_port=None, auth_protocol=None,
|
||||
auth_admin_prefix=None, admin_user=None,
|
||||
admin_password=None, admin_tenant_name=None,
|
||||
admin_token=None, identity_uri=None, log=None):
|
||||
if not log:
|
||||
log = self.logger
|
||||
|
||||
return auth_token._AuthTokenPlugin.load_from_options(
|
||||
auth_host=auth_host,
|
||||
auth_port=auth_port,
|
||||
auth_protocol=auth_protocol,
|
||||
auth_admin_prefix=auth_admin_prefix,
|
||||
admin_user=admin_user,
|
||||
admin_password=admin_password,
|
||||
admin_tenant_name=admin_tenant_name,
|
||||
admin_token=admin_token,
|
||||
identity_uri=identity_uri,
|
||||
log=log)
|
||||
|
||||
def setUp(self):
|
||||
super(DefaultAuthPluginTests, self).setUp()
|
||||
|
||||
self.stream = six.StringIO()
|
||||
self.logger = logging.getLogger(__name__)
|
||||
self.session = session.Session()
|
||||
self.requests = self.useFixture(rm_fixture.Fixture())
|
||||
|
||||
def test_auth_uri_from_fragments(self):
|
||||
auth_protocol = 'http'
|
||||
auth_host = 'testhost'
|
||||
auth_port = 8888
|
||||
auth_admin_prefix = 'admin'
|
||||
|
||||
expected = '%s://%s:%d/admin' % (auth_protocol, auth_host, auth_port)
|
||||
|
||||
plugin = self.new_plugin(auth_host=auth_host,
|
||||
auth_protocol=auth_protocol,
|
||||
auth_port=auth_port,
|
||||
auth_admin_prefix=auth_admin_prefix)
|
||||
|
||||
self.assertEqual(expected,
|
||||
plugin.get_endpoint(self.session,
|
||||
interface=auth.AUTH_INTERFACE))
|
||||
|
||||
def test_identity_uri_overrides_fragments(self):
|
||||
identity_uri = 'http://testhost:8888/admin'
|
||||
plugin = self.new_plugin(identity_uri=identity_uri,
|
||||
auth_host='anotherhost',
|
||||
auth_port=9999,
|
||||
auth_protocol='ftp')
|
||||
|
||||
self.assertEqual(identity_uri,
|
||||
plugin.get_endpoint(self.session,
|
||||
interface=auth.AUTH_INTERFACE))
|
||||
|
||||
def test_with_admin_token(self):
|
||||
token = uuid.uuid4().hex
|
||||
plugin = self.new_plugin(identity_uri='http://testhost:8888/admin',
|
||||
admin_token=token)
|
||||
self.assertEqual(token, plugin.get_token(self.session))
|
||||
|
||||
def test_with_user_pass(self):
|
||||
base_uri = 'http://testhost:8888/admin'
|
||||
token = fixture.V2Token()
|
||||
admin_tenant_name = uuid.uuid4().hex
|
||||
|
||||
self.requests.post(base_uri + '/v2.0/tokens',
|
||||
json=token)
|
||||
|
||||
plugin = self.new_plugin(identity_uri=base_uri,
|
||||
admin_user=uuid.uuid4().hex,
|
||||
admin_password=uuid.uuid4().hex,
|
||||
admin_tenant_name=admin_tenant_name)
|
||||
|
||||
self.assertEqual(token.token_id, plugin.get_token(self.session))
|
||||
|
||||
|
||||
class AuthProtocolLoadingTests(BaseAuthTokenMiddlewareTest):
|
||||
|
||||
AUTH_URL = 'http://auth.url/prefix'
|
||||
|
@ -2680,7 +2602,7 @@ class AuthProtocolLoadingTests(BaseAuthTokenMiddlewareTest):
|
|||
# the password options aren't set on config until loading time, but we
|
||||
# need them set so we can override the values for testing, so force it
|
||||
opts = auth.get_plugin_options('password')
|
||||
self.cfg.register_opts(opts, group=auth_token._AUTHTOKEN_GROUP)
|
||||
self.cfg.register_opts(opts, group=_base.AUTHTOKEN_GROUP)
|
||||
|
||||
project_id = uuid.uuid4().hex
|
||||
|
||||
|
@ -2691,7 +2613,7 @@ class AuthProtocolLoadingTests(BaseAuthTokenMiddlewareTest):
|
|||
auth_url=self.AUTH_URL,
|
||||
project_id=project_id,
|
||||
user_domain_id='userdomainid',
|
||||
group=auth_token._AUTHTOKEN_GROUP)
|
||||
group=_base.AUTHTOKEN_GROUP)
|
||||
|
||||
# admin_token is the token that the service will get back from auth
|
||||
admin_token_id = uuid.uuid4().hex
|
||||
|
@ -2739,7 +2661,7 @@ class AuthProtocolLoadingTests(BaseAuthTokenMiddlewareTest):
|
|||
|
||||
def test_invalid_plugin_fails_to_intialize(self):
|
||||
self.cfg.config(auth_plugin=uuid.uuid4().hex,
|
||||
group=auth_token._AUTHTOKEN_GROUP)
|
||||
group=_base.AUTHTOKEN_GROUP)
|
||||
|
||||
self.assertRaises(
|
||||
exceptions.NoMatchingPlugin,
|
||||
|
|
Loading…
Reference in New Issue