summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2014-09-15 03:44:33 +0000
committerGerrit Code Review <review@openstack.org>2014-09-15 03:44:33 +0000
commit766840fc004cf0e14c4c4761af24139410015483 (patch)
treefbbb2aa6b7958b2913060271785fcbd5407d63de
parent44ab927fe7798ba3f4cd1717b5e087edcbb1795b (diff)
parentd26c81df440c0d1306c1aaf1c001fa6f7df37115 (diff)
downloadkeystonemiddleware-766840fc004cf0e14c4c4761af24139410015483.tar.gz
Merge "Create an Auth Plugin to pass to users"
-rw-r--r--doc/source/conf.py5
-rw-r--r--keystonemiddleware/auth_token.py45
-rw-r--r--keystonemiddleware/tests/test_auth_token_middleware.py20
3 files changed, 65 insertions, 5 deletions
diff --git a/doc/source/conf.py b/doc/source/conf.py
index 19c81d6..069382b 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -231,6 +231,7 @@ latex_documents = [
# If false, no module index is generated.
#latex_use_modindex = True
+keystoneclient = 'http://docs.openstack.org/developer/python-keystoneclient/'
-# Example configuration for intersphinx: refer to the Python standard library.
-#intersphinx_mapping = {'python': ('http://docs.python.org/', None)}
+intersphinx_mapping = {'keystoneclient': (keystoneclient, None),
+ }
diff --git a/keystonemiddleware/auth_token.py b/keystonemiddleware/auth_token.py
index c446345..328172e 100644
--- a/keystonemiddleware/auth_token.py
+++ b/keystonemiddleware/auth_token.py
@@ -143,6 +143,11 @@ keystone.token_info
Keystone token validation call, as well as basic information about
the tenant and user.
+keystone.token_auth
+ A keystoneclient auth plugin that may be used with a
+ :py:class:`keystoneclient.session.Session`. This plugin will load the
+ authentication data provided to auth_token middleware.
+
"""
import contextlib
@@ -154,6 +159,7 @@ import tempfile
import time
from keystoneclient import access
+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
@@ -479,6 +485,38 @@ class _MiniResp(object):
self.headers.append(('Content-type', 'text/plain'))
+class _UserAuthPlugin(base_identity.BaseIdentityPlugin):
+ """The incoming authentication credentials.
+
+ A plugin that represents the incoming user credentials. This can be
+ consumed by applications.
+
+ This object is not expected to be constructed directly by users. It is
+ created and passed by auth_token middleware and then can be used as the
+ authentication plugin when communicating via a session.
+ """
+
+ def __init__(self, user_token, auth_ref):
+ # FIXME(jamielennox): set reauthenticate=False here when keystoneclient
+ # 0.11 is released to prevent trying to refetch authentication.
+ super(_UserAuthPlugin, self).__init__()
+ self._user_token = user_token
+ self._stored_auth_ref = auth_ref
+
+ def get_token(self, session, **kwargs):
+ # NOTE(jamielennox): This is needed partially because the AccessInfo
+ # factory is so bad that we don't always get the correct token data.
+ # Override and always return the token that was provided in the req.
+ return self._user_token
+
+ def get_auth_ref(self, session, **kwargs):
+ # NOTE(jamielennox): We can't go out and fetch this auth_ref, we've
+ # got it already so always return it. In the event it tries to
+ # re-authenticate it will get the same old auth_ref which is not
+ # perfect, but the best we can do for now.
+ return self._stored_auth_ref
+
+
class AuthProtocol(object):
"""Auth Middleware that handles authenticating client calls."""
@@ -600,8 +638,10 @@ class AuthProtocol(object):
self._remove_auth_headers(env)
user_token = self._get_user_token_from_header(env)
token_info = self._validate_user_token(user_token, env)
+ auth_ref = access.AccessInfo.factory(body=token_info)
env['keystone.token_info'] = token_info
- user_headers = self._build_user_headers(token_info)
+ env['keystone.token_auth'] = _UserAuthPlugin(user_token, auth_ref)
+ user_headers = self._build_user_headers(auth_ref, token_info)
self._add_headers(env, user_headers)
return self._call_app(env, start_response)
@@ -755,7 +795,7 @@ class AuthProtocol(object):
self._LOG.warn('Authorization failed for token')
raise InvalidUserToken('Token authorization failed')
- def _build_user_headers(self, token_info):
+ def _build_user_headers(self, auth_ref, token_info):
"""Convert token object into headers.
Build headers that represent authenticated user - see main
@@ -765,7 +805,6 @@ class AuthProtocol(object):
:raise InvalidUserToken when unable to parse token object
"""
- auth_ref = access.AccessInfo.factory(body=token_info)
roles = ','.join(auth_ref.role_names)
if _token_is_v2(token_info) and not auth_ref.project_id:
diff --git a/keystonemiddleware/tests/test_auth_token_middleware.py b/keystonemiddleware/tests/test_auth_token_middleware.py
index 29f199e..bd3bf8b 100644
--- a/keystonemiddleware/tests/test_auth_token_middleware.py
+++ b/keystonemiddleware/tests/test_auth_token_middleware.py
@@ -30,6 +30,7 @@ from keystoneclient import access
from keystoneclient.common import cms
from keystoneclient import exceptions
from keystoneclient import fixture
+from keystoneclient import session
import mock
import testresources
import testtools
@@ -1296,6 +1297,25 @@ class CommonAuthTokenMiddlewareTest(object):
# Assert that the token wasn't cached again.
self.assertThat(1, matchers.Equals(cache.set.call_count))
+ def test_auth_plugin(self):
+ httpretty.register_uri(httpretty.GET,
+ self.examples.SERVICE_URL,
+ body=VERSION_LIST_v3,
+ status_code=300)
+
+ req = webob.Request.blank('/')
+ req.headers['X-Auth-Token'] = self.token_dict['uuid_token_default']
+ body = self.middleware(req.environ, self.start_fake_response)
+ self.assertEqual(200, self.response_status)
+ self.assertEqual([FakeApp.SUCCESS], body)
+
+ token_auth = req.environ['keystone.token_auth']
+ endpoint_filter = {'service_type': self.examples.SERVICE_TYPE,
+ 'version': 3}
+
+ url = token_auth.get_endpoint(session.Session(), **endpoint_filter)
+ self.assertEqual('%s/v3' % BASE_URI, url)
+
class V2CertDownloadMiddlewareTest(BaseAuthTokenMiddlewareTest,
testresources.ResourcedTestCase):