Merge "Separate exceptions into their own file"

This commit is contained in:
Jenkins 2015-02-25 00:55:31 +00:00 committed by Gerrit Code Review
commit 4b6fb39fd1
4 changed files with 100 additions and 79 deletions

View File

@ -195,6 +195,7 @@ import six
from six.moves import urllib
from keystonemiddleware import _memcache_crypt as memcache_crypt
from keystonemiddleware.auth_token import _exceptions as exc
from keystonemiddleware.i18n import _, _LC, _LE, _LI, _LW
from keystonemiddleware.openstack.common import memorycache
@ -396,13 +397,13 @@ def _token_is_v3(token_info):
def _get_token_expiration(data):
if not data:
raise InvalidToken(_('Token authorization failed'))
raise exc.InvalidToken(_('Token authorization failed'))
if _token_is_v2(data):
return data['access']['token']['expires']
elif _token_is_v3(data):
return data['token']['expires_at']
else:
raise InvalidToken(_('Token authorization failed'))
raise exc.InvalidToken(_('Token authorization failed'))
def _confirm_token_not_expired(expires):
@ -410,7 +411,7 @@ def _confirm_token_not_expired(expires):
expires = timeutils.normalize_time(expires)
utcnow = timeutils.utcnow()
if utcnow >= expires:
raise InvalidToken(_('Token authorization failed'))
raise exc.InvalidToken(_('Token authorization failed'))
def _v3_to_v2_catalog(catalog):
@ -478,29 +479,13 @@ def _conf_values_type_convert(conf):
# This option is not known to auth_token.
pass
except ValueError as e:
raise ConfigurationError(
raise exc.ConfigurationError(
_('Unable to convert the value of %(key)s option into correct '
'type: %(ex)s') % {'key': k, 'ex': e})
opts[dest] = v
return opts
class InvalidToken(Exception):
pass
class ServiceError(Exception):
pass
class ConfigurationError(Exception):
pass
class RevocationListError(Exception):
pass
class _MiniResp(object):
def __init__(self, error_message, env, headers=[]):
# The HEAD method is unique: it must never return a body, even if
@ -931,7 +916,7 @@ class AuthProtocol(object):
user_headers = self._build_user_headers(user_auth_ref,
user_token_info)
self._add_headers(env, user_headers)
except InvalidToken:
except exc.InvalidToken:
if self._delay_auth_decision:
self._LOG.info(
_LI('Invalid user token - deferring reject '
@ -953,7 +938,7 @@ class AuthProtocol(object):
auth_token=serv_token)
serv_headers = self._build_service_headers(serv_token_info)
self._add_headers(env, serv_headers)
except InvalidToken:
except exc.InvalidToken:
# Delayed auth not currently supported for service tokens.
# (Can be implemented if a use case is found.)
self._LOG.info(
@ -963,7 +948,7 @@ class AuthProtocol(object):
env['keystone.token_auth'] = _UserAuthPlugin(user_auth_ref,
serv_auth_ref)
except ServiceError as e:
except exc.ServiceError as e:
self._LOG.critical(_LC('Unable to obtain admin token: %s'), e)
return self._do_503_error(env, start_response)
@ -1014,7 +999,7 @@ class AuthProtocol(object):
:param env: wsgi request environment
:returns: token id
:raises InvalidToken: if no token is provided in request
:raises exc.InvalidToken: if no token is provided in request
"""
token = self._get_header(env, 'X-Auth-Token',
@ -1026,7 +1011,7 @@ class AuthProtocol(object):
self._LOG.warn(_LW('Unable to find authentication token'
' in headers'))
self._LOG.debug('Headers: %s', env)
raise InvalidToken(_('Unable to find token in headers'))
raise exc.InvalidToken(_('Unable to find token in headers'))
def _get_service_token_from_header(self, env):
"""Get service token id from request.
@ -1062,7 +1047,7 @@ class AuthProtocol(object):
:param env: wsgi environment
:param retry: Ignored, as it is not longer relevant
:returns: uncrypted body of the token if the token is valid
:raises InvalidToken: if token is rejected
:raises exc.InvalidToken: if token is rejected
"""
token_id = None
@ -1096,7 +1081,7 @@ class AuthProtocol(object):
except exceptions.CertificateConfigError:
self._LOG.warn(_LW('Fetch certificate config failed, '
'fallback to online validation.'))
except RevocationListError:
except exc.RevocationListError:
self._LOG.warn(_LW('Fetch revocation list failed, '
'fallback to online validation.'))
@ -1115,15 +1100,15 @@ class AuthProtocol(object):
except (exceptions.ConnectionRefused, exceptions.RequestTimeout):
self._LOG.debug('Token validation failure.', exc_info=True)
self._LOG.warn(_LW('Authorization failed for token'))
raise InvalidToken(_('Token authorization failed'))
except ServiceError:
raise exc.InvalidToken(_('Token authorization failed'))
except exc.ServiceError:
raise
except Exception:
self._LOG.debug('Token validation failure.', exc_info=True)
if token_id:
self._token_cache.store_invalid(token_id)
self._LOG.warn(_LW('Authorization failed for token'))
raise InvalidToken(_('Token authorization failed'))
raise exc.InvalidToken(_('Token authorization failed'))
def _build_user_headers(self, auth_ref, token_info):
"""Convert token object into headers.
@ -1133,13 +1118,13 @@ class AuthProtocol(object):
:param token_info: token object returned by identity
server on authentication
:raises InvalidToken: when unable to parse token object
:raises exc.InvalidToken: when unable to parse token object
"""
roles = ','.join(auth_ref.role_names)
if _token_is_v2(token_info) and not auth_ref.project_id:
raise InvalidToken(_('Unable to determine tenancy.'))
raise exc.InvalidToken(_('Unable to determine tenancy.'))
rval = {
'X-Identity-Status': 'Confirmed',
@ -1170,13 +1155,13 @@ class AuthProtocol(object):
:param token_info: token object returned by identity
server on authentication
:raises InvalidToken: when unable to parse token object
:raises exc.InvalidToken: when unable to parse token object
"""
auth_ref = access.AccessInfo.factory(body=token_info)
if _token_is_v2(token_info) and not auth_ref.project_id:
raise InvalidToken(_('Unable to determine service tenancy.'))
raise exc.InvalidToken(_('Unable to determine service tenancy.'))
roles = ','.join(auth_ref.role_names)
rval = {
@ -1223,7 +1208,7 @@ class AuthProtocol(object):
if msg is False:
msg = _('Token authorization failed')
raise InvalidToken(msg)
raise exc.InvalidToken(msg)
def _confirm_token_bind(self, data, env):
bind_mode = self._conf_get('enforce_token_bind')
@ -1340,7 +1325,7 @@ class AuthProtocol(object):
return verified
# TypeError If the signed_text is not zlib compressed
except TypeError:
raise InvalidToken(signed_text)
raise exc.InvalidToken(signed_text)
def _fetch_signing_cert(self):
self._signing_directory.write_file(
@ -1562,7 +1547,7 @@ class _IdentityServer(object):
', '.join(versions))
msg = _('No compatible apis supported by server')
raise ServiceError(msg)
raise exc.ServiceError(msg)
def verify_token(self, user_token, retry=True):
"""Authenticate user token with identity server.
@ -1572,8 +1557,8 @@ class _IdentityServer(object):
user authentication when an indeterminate
response is received. Optional.
:returns: token object received from identity server on success
:raises InvalidToken: if token is rejected
:raises ServiceError: if unable to authenticate token
:raises exc.InvalidToken: if token is rejected
:raises exc.ServiceError: if unable to authenticate token
"""
user_token = _safe_quote(user_token)
@ -1598,7 +1583,7 @@ class _IdentityServer(object):
if response.status_code == 200:
return data
raise InvalidToken()
raise exc.InvalidToken()
def fetch_revocation_list(self):
try:
@ -1607,14 +1592,14 @@ class _IdentityServer(object):
authenticated=True,
endpoint_filter={'version': (2, 0)})
except exceptions.HTTPError as e:
raise RevocationListError(_('Failed to fetch token revocation '
'list: %d') % e.http_status)
msg = _('Failed to fetch token revocation list: %d')
raise exc.RevocationListError(msg % e.http_status)
if response.status_code != 200:
raise RevocationListError(_('Unable to fetch token revocation '
'list.'))
msg = _('Unable to fetch token revocation list.')
raise exc.RevocationListError(msg)
if 'signed' not in data:
raise RevocationListError(_('Revocation list improperly '
'formatted.'))
msg = _('Revocation list improperly formatted.')
raise exc.RevocationListError(msg)
return data['signed']
def fetch_signing_cert(self):
@ -1792,7 +1777,7 @@ class _Revocations(object):
def check(self, token_ids):
if self._any_revoked(token_ids):
self._log.debug('Token is marked as having been revoked')
raise InvalidToken(_('Token has been revoked'))
raise exc.InvalidToken(_('Token has been revoked'))
class _SigningDirectory(object):
@ -1839,7 +1824,7 @@ class _SigningDirectory(object):
def _verify_signing_dir(self):
if os.path.isdir(self._directory_name):
if not os.access(self._directory_name, os.W_OK):
raise ConfigurationError(
raise exc.ConfigurationError(
_('unable to access signing_dir %s') %
self._directory_name)
uid = os.getuid()
@ -1935,7 +1920,7 @@ class _TokenCache(object):
The second element is the token data from the cache if the token was
cached, otherwise ``None``.
:raises InvalidToken: if the token is invalid
:raises exc.InvalidToken: if the token is invalid
"""
@ -2028,7 +2013,7 @@ class _TokenCache(object):
def _cache_get(self, token_id):
"""Return token information from cache.
If token is invalid raise InvalidToken
If token is invalid raise exc.InvalidToken
return token only if fresh (not expired).
"""
@ -2054,7 +2039,7 @@ class _TokenCache(object):
cached = jsonutils.loads(data)
if cached == self._INVALID_INDICATOR:
self._LOG.debug('Cached Token is marked unauthorized')
raise InvalidToken(_('Token authorization failed'))
raise exc.InvalidToken(_('Token authorization failed'))
data, expires = cached
@ -2073,7 +2058,7 @@ class _TokenCache(object):
return data
else:
self._LOG.debug('Cached Token seems expired')
raise InvalidToken(_('Token authorization failed'))
raise exc.InvalidToken(_('Token authorization failed'))
def _cache_store(self, token_id, data):
"""Store value into memcache.
@ -2105,12 +2090,12 @@ class _SecureTokenCache(_TokenCache):
security_strategy = security_strategy.upper()
if security_strategy not in ('MAC', 'ENCRYPT'):
raise ConfigurationError(_('memcache_security_strategy must be '
'ENCRYPT or MAC'))
msg = _('memcache_security_strategy must be ENCRYPT or MAC')
raise exc.ConfigurationError(msg)
if not secret_key:
raise ConfigurationError(_('memcache_secret_key must be defined '
'when a memcache_security_strategy '
'is defined'))
msg = _('memcache_secret_key must be defined when a '
'memcache_security_strategy is defined')
raise exc.ConfigurationError(msg)
if isinstance(security_strategy, six.string_types):
security_strategy = security_strategy.encode('utf-8')
@ -2175,3 +2160,10 @@ if __name__ == '__main__':
server = simple_server.make_server('', 8000, app)
print('Serving on port 8000 (Ctrl+C to end)...')
server.serve_forever()
# NOTE(jamielennox): Maintained here for public API compatibility.
InvalidToken = exc.InvalidToken
ServiceError = exc.ServiceError
ConfigurationError = exc.ConfigurationError
RevocationListError = exc.RevocationListError

View File

@ -0,0 +1,27 @@
# 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.
class InvalidToken(Exception):
pass
class ServiceError(Exception):
pass
class ConfigurationError(Exception):
pass
class RevocationListError(Exception):
pass

View File

@ -43,6 +43,7 @@ import webob
import webob.dec
from keystonemiddleware import auth_token
from keystonemiddleware.auth_token import _exceptions as exc
from keystonemiddleware.openstack.common import memorycache
from keystonemiddleware.tests import client_fixtures
from keystonemiddleware.tests import utils
@ -562,35 +563,35 @@ class GeneralAuthTokenMiddlewareTest(BaseAuthTokenMiddlewareTest,
'memcached_servers': ','.join(MEMCACHED_SERVERS),
'memcache_security_strategy': 'Encrypt'
}
self.assertRaises(auth_token.ConfigurationError, self.set_middleware,
self.assertRaises(exc.ConfigurationError, self.set_middleware,
conf=conf)
# test invalue memcache_security_strategy
conf = {
'memcached_servers': ','.join(MEMCACHED_SERVERS),
'memcache_security_strategy': 'whatever'
}
self.assertRaises(auth_token.ConfigurationError, self.set_middleware,
self.assertRaises(exc.ConfigurationError, self.set_middleware,
conf=conf)
# test missing memcache_secret_key
conf = {
'memcached_servers': ','.join(MEMCACHED_SERVERS),
'memcache_security_strategy': 'mac'
}
self.assertRaises(auth_token.ConfigurationError, self.set_middleware,
self.assertRaises(exc.ConfigurationError, self.set_middleware,
conf=conf)
conf = {
'memcached_servers': ','.join(MEMCACHED_SERVERS),
'memcache_security_strategy': 'Encrypt',
'memcache_secret_key': ''
}
self.assertRaises(auth_token.ConfigurationError, self.set_middleware,
self.assertRaises(exc.ConfigurationError, self.set_middleware,
conf=conf)
conf = {
'memcached_servers': ','.join(MEMCACHED_SERVERS),
'memcache_security_strategy': 'mAc',
'memcache_secret_key': ''
}
self.assertRaises(auth_token.ConfigurationError, self.set_middleware,
self.assertRaises(exc.ConfigurationError, self.set_middleware,
conf=conf)
def test_config_revocation_cache_timeout(self):
@ -630,7 +631,7 @@ class GeneralAuthTokenMiddlewareTest(BaseAuthTokenMiddlewareTest,
conf = {
'include_service_catalog': '123',
}
self.assertRaises(auth_token.ConfigurationError,
self.assertRaises(exc.ConfigurationError,
auth_token.AuthProtocol, self.fake_app, conf)
@ -844,7 +845,7 @@ class CommonAuthTokenMiddlewareTest(object):
def test_verify_signed_token_raises_exception_for_revoked_token(self):
self.middleware._revocations._list = (
self.get_revocation_list_json())
self.assertRaises(auth_token.InvalidToken,
self.assertRaises(exc.InvalidToken,
self.middleware._verify_signed_token,
self.token_dict['revoked_token'],
[self.token_dict['revoked_token_hash']])
@ -854,7 +855,7 @@ class CommonAuthTokenMiddlewareTest(object):
self.set_middleware()
self.middleware._revocations._list = (
self.get_revocation_list_json(mode='sha256'))
self.assertRaises(auth_token.InvalidToken,
self.assertRaises(exc.InvalidToken,
self.middleware._verify_signed_token,
self.token_dict['revoked_token'],
[self.token_dict['revoked_token_hash_sha256'],
@ -863,7 +864,7 @@ class CommonAuthTokenMiddlewareTest(object):
def test_verify_signed_token_raises_exception_for_revoked_pkiz_token(self):
self.middleware._revocations._list = (
self.examples.REVOKED_TOKEN_PKIZ_LIST_JSON)
self.assertRaises(auth_token.InvalidToken,
self.assertRaises(exc.InvalidToken,
self.middleware._verify_pkiz_token,
self.token_dict['revoked_token_pkiz'],
[self.token_dict['revoked_token_pkiz_hash']])
@ -960,7 +961,7 @@ class CommonAuthTokenMiddlewareTest(object):
def test_invalid_revocation_list_raises_error(self):
self.requests.get('%s/v2.0/tokens/revoked' % BASE_URI, json={})
self.assertRaises(auth_token.RevocationListError,
self.assertRaises(exc.RevocationListError,
self.middleware._revocations._fetch)
def test_fetch_revocation_list(self):
@ -1019,7 +1020,7 @@ class CommonAuthTokenMiddlewareTest(object):
self.middleware._LOG = FakeLog()
self.middleware._delay_auth_decision = False
self.assertRaises(auth_token.InvalidToken,
self.assertRaises(exc.InvalidToken,
self.middleware._get_user_token_from_header, {})
self.assertIsNotNone(self.middleware._LOG.msg)
self.assertIsNotNone(self.middleware._LOG.debugmsg)
@ -1067,7 +1068,7 @@ class CommonAuthTokenMiddlewareTest(object):
token = 'invalid-token'
req.headers['X-Auth-Token'] = token
self.middleware(req.environ, self.start_fake_response)
self.assertRaises(auth_token.InvalidToken,
self.assertRaises(exc.InvalidToken,
self._get_cached_token, token)
def _test_memcache_set_invalid_signed(self, hash_algorithms=None,
@ -1079,7 +1080,7 @@ class CommonAuthTokenMiddlewareTest(object):
self.conf['hash_algorithms'] = ','.join(hash_algorithms)
self.set_middleware()
self.middleware(req.environ, self.start_fake_response)
self.assertRaises(auth_token.InvalidToken,
self.assertRaises(exc.InvalidToken,
self._get_cached_token, token, mode=exp_mode)
def test_memcache_set_invalid_signed(self):
@ -1994,13 +1995,13 @@ class TokenExpirationTest(BaseAuthTokenMiddlewareTest):
def test_no_data(self):
data = {}
self.assertRaises(auth_token.InvalidToken,
self.assertRaises(exc.InvalidToken,
auth_token._get_token_expiration,
data)
def test_bad_data(self):
data = {'my_happy_token_dict': 'woo'}
self.assertRaises(auth_token.InvalidToken,
self.assertRaises(exc.InvalidToken,
auth_token._get_token_expiration,
data)
@ -2018,7 +2019,7 @@ class TokenExpirationTest(BaseAuthTokenMiddlewareTest):
def test_v2_token_expired(self):
data = self.create_v2_token_fixture(expires=self.one_hour_ago)
expires = auth_token._get_token_expiration(data)
self.assertRaises(auth_token.InvalidToken,
self.assertRaises(exc.InvalidToken,
auth_token._confirm_token_not_expired,
expires)
@ -2035,7 +2036,7 @@ class TokenExpirationTest(BaseAuthTokenMiddlewareTest):
data = self.create_v2_token_fixture(
expires='1999-12-31T19:05:10Z')
expires = auth_token._get_token_expiration(data)
self.assertRaises(auth_token.InvalidToken,
self.assertRaises(exc.InvalidToken,
auth_token._confirm_token_not_expired,
expires)
@ -2053,7 +2054,7 @@ class TokenExpirationTest(BaseAuthTokenMiddlewareTest):
def test_v3_token_expired(self):
data = self.create_v3_token_fixture(expires=self.one_hour_ago)
expires = auth_token._get_token_expiration(data)
self.assertRaises(auth_token.InvalidToken,
self.assertRaises(exc.InvalidToken,
auth_token._confirm_token_not_expired,
expires)
@ -2071,7 +2072,7 @@ class TokenExpirationTest(BaseAuthTokenMiddlewareTest):
data = self.create_v3_token_fixture(
expires='1999-12-31T19:05:10Z')
expires = auth_token._get_token_expiration(data)
self.assertRaises(auth_token.InvalidToken,
self.assertRaises(exc.InvalidToken,
auth_token._confirm_token_not_expired,
expires)
@ -2112,7 +2113,7 @@ class TokenExpirationTest(BaseAuthTokenMiddlewareTest):
expires = some_time_earlier
self.middleware._token_cache.store(token, data, expires)
self.assertThat(lambda: self.middleware._token_cache._cache_get(token),
matchers.raises(auth_token.InvalidToken))
matchers.raises(exc.InvalidToken))
def test_cached_token_with_timezone_offset_not_expired(self):
token = 'mytoken'
@ -2135,7 +2136,7 @@ class TokenExpirationTest(BaseAuthTokenMiddlewareTest):
expires = timeutils.strtime(some_time_earlier) + '-02:00'
self.middleware._token_cache.store(token, data, expires)
self.assertThat(lambda: self.middleware._token_cache._cache_get(token),
matchers.raises(auth_token.InvalidToken))
matchers.raises(exc.InvalidToken))
class CatalogConversionTests(BaseAuthTokenMiddlewareTest):

View File

@ -23,6 +23,7 @@ import mock
import testtools
from keystonemiddleware import auth_token
from keystonemiddleware.auth_token import _exceptions as exc
class RevocationsTests(testtools.TestCase):
@ -61,7 +62,7 @@ class RevocationsTests(testtools.TestCase):
token_id = uuid.uuid4().hex
revoked_tokens = [token_id]
token_ids = [token_id]
self.assertRaises(auth_token.InvalidToken,
self.assertRaises(exc.InvalidToken,
self._check_with_list, revoked_tokens, token_ids)