Refactor auth_token token cache members to class
The token cache members are moved from AuthToken to their own class. Change-Id: Ibf00d39435fa7a6d9a92a9bdfacc3f1b07f890ef
This commit is contained in:
		@@ -545,20 +545,18 @@ class AuthProtocol(object):
 | 
				
			|||||||
        self.admin_password = self._conf_get('admin_password')
 | 
					        self.admin_password = self._conf_get('admin_password')
 | 
				
			||||||
        self.admin_tenant_name = self._conf_get('admin_tenant_name')
 | 
					        self.admin_tenant_name = self._conf_get('admin_tenant_name')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Token caching
 | 
					        memcache_security_strategy = (
 | 
				
			||||||
        self._cache_pool = None
 | 
					 | 
				
			||||||
        self._cache_initialized = False
 | 
					 | 
				
			||||||
        # memcache value treatment, ENCRYPT or MAC
 | 
					 | 
				
			||||||
        self._memcache_security_strategy = (
 | 
					 | 
				
			||||||
            self._conf_get('memcache_security_strategy'))
 | 
					            self._conf_get('memcache_security_strategy'))
 | 
				
			||||||
        if self._memcache_security_strategy is not None:
 | 
					
 | 
				
			||||||
            self._memcache_security_strategy = (
 | 
					        self._token_cache = TokenCache(
 | 
				
			||||||
                self._memcache_security_strategy.upper())
 | 
					            self.LOG,
 | 
				
			||||||
        self._memcache_secret_key = (
 | 
					            cache_time=int(self._conf_get('token_cache_time')),
 | 
				
			||||||
            self._conf_get('memcache_secret_key'))
 | 
					            hash_algorithms=self._conf_get('hash_algorithms'),
 | 
				
			||||||
        self._assert_valid_memcache_protection_config()
 | 
					            env_cache_name=self._conf_get('cache'),
 | 
				
			||||||
        # By default the token will be cached for 5 minutes
 | 
					            memcached_servers=self._conf_get('memcached_servers'),
 | 
				
			||||||
        self.token_cache_time = int(self._conf_get('token_cache_time'))
 | 
					            memcache_security_strategy=memcache_security_strategy,
 | 
				
			||||||
 | 
					            memcache_secret_key=self._conf_get('memcache_secret_key'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self._token_revocation_list = None
 | 
					        self._token_revocation_list = None
 | 
				
			||||||
        self._token_revocation_list_fetched_time = None
 | 
					        self._token_revocation_list_fetched_time = None
 | 
				
			||||||
        self.token_revocation_list_cache_timeout = datetime.timedelta(
 | 
					        self.token_revocation_list_cache_timeout = datetime.timedelta(
 | 
				
			||||||
@@ -576,22 +574,6 @@ class AuthProtocol(object):
 | 
				
			|||||||
        self.check_revocations_for_cached = self._conf_get(
 | 
					        self.check_revocations_for_cached = self._conf_get(
 | 
				
			||||||
            'check_revocations_for_cached')
 | 
					            'check_revocations_for_cached')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _assert_valid_memcache_protection_config(self):
 | 
					 | 
				
			||||||
        if self._memcache_security_strategy:
 | 
					 | 
				
			||||||
            if self._memcache_security_strategy not in ('MAC', 'ENCRYPT'):
 | 
					 | 
				
			||||||
                raise ConfigurationError('memcache_security_strategy must be '
 | 
					 | 
				
			||||||
                                         'ENCRYPT or MAC')
 | 
					 | 
				
			||||||
            if not self._memcache_secret_key:
 | 
					 | 
				
			||||||
                raise ConfigurationError('memcache_secret_key must be defined '
 | 
					 | 
				
			||||||
                                         'when a memcache_security_strategy '
 | 
					 | 
				
			||||||
                                         'is defined')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _init_cache(self, env):
 | 
					 | 
				
			||||||
        self._cache_pool = CachePool(
 | 
					 | 
				
			||||||
            env.get(self._conf_get('cache')),
 | 
					 | 
				
			||||||
            self._conf_get('memcached_servers'))
 | 
					 | 
				
			||||||
        self._cache_initialized = True
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _conf_get(self, name):
 | 
					    def _conf_get(self, name):
 | 
				
			||||||
        # try config from paste-deploy first
 | 
					        # try config from paste-deploy first
 | 
				
			||||||
        if name in self.conf:
 | 
					        if name in self.conf:
 | 
				
			||||||
@@ -665,9 +647,7 @@ class AuthProtocol(object):
 | 
				
			|||||||
        """
 | 
					        """
 | 
				
			||||||
        self.LOG.debug('Authenticating user token')
 | 
					        self.LOG.debug('Authenticating user token')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # initialize memcache if we haven't done so
 | 
					        self._token_cache.initialize(env)
 | 
				
			||||||
        if not self._cache_initialized:
 | 
					 | 
				
			||||||
            self._init_cache(env)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            self._remove_auth_headers(env)
 | 
					            self._remove_auth_headers(env)
 | 
				
			||||||
@@ -907,7 +887,7 @@ class AuthProtocol(object):
 | 
				
			|||||||
        token_id = None
 | 
					        token_id = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            token_ids, cached = self._check_user_token_cached(user_token)
 | 
					            token_ids, cached = self._token_cache.get(user_token)
 | 
				
			||||||
            token_id = token_ids[0]
 | 
					            token_id = token_ids[0]
 | 
				
			||||||
            if cached:
 | 
					            if cached:
 | 
				
			||||||
                data = cached
 | 
					                data = cached
 | 
				
			||||||
@@ -933,7 +913,7 @@ class AuthProtocol(object):
 | 
				
			|||||||
                data = self.verify_uuid_token(user_token, retry)
 | 
					                data = self.verify_uuid_token(user_token, retry)
 | 
				
			||||||
            expires = confirm_token_not_expired(data)
 | 
					            expires = confirm_token_not_expired(data)
 | 
				
			||||||
            self._confirm_token_bind(data, env)
 | 
					            self._confirm_token_bind(data, env)
 | 
				
			||||||
            self._cache_put(token_id, data, expires)
 | 
					            self._token_cache.store(token_id, data, expires)
 | 
				
			||||||
            return data
 | 
					            return data
 | 
				
			||||||
        except NetworkError:
 | 
					        except NetworkError:
 | 
				
			||||||
            self.LOG.debug('Token validation failure.', exc_info=True)
 | 
					            self.LOG.debug('Token validation failure.', exc_info=True)
 | 
				
			||||||
@@ -942,43 +922,10 @@ class AuthProtocol(object):
 | 
				
			|||||||
        except Exception:
 | 
					        except Exception:
 | 
				
			||||||
            self.LOG.debug('Token validation failure.', exc_info=True)
 | 
					            self.LOG.debug('Token validation failure.', exc_info=True)
 | 
				
			||||||
            if token_id:
 | 
					            if token_id:
 | 
				
			||||||
                self._cache_store_invalid(token_id)
 | 
					                self._token_cache.store_invalid(token_id)
 | 
				
			||||||
            self.LOG.warn('Authorization failed for token')
 | 
					            self.LOG.warn('Authorization failed for token')
 | 
				
			||||||
            raise InvalidUserToken('Token authorization failed')
 | 
					            raise InvalidUserToken('Token authorization failed')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _check_user_token_cached(self, user_token):
 | 
					 | 
				
			||||||
        """Check if the token is cached already.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Returns a tuple. The first element is a list of token IDs, where the
 | 
					 | 
				
			||||||
        first one is the preferred hash.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        The second element is the token data from the cache if the token was
 | 
					 | 
				
			||||||
        cached, otherwise ``None``.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        :raises InvalidUserToken: if the token is invalid
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if cms.is_asn1_token(user_token):
 | 
					 | 
				
			||||||
            # user_token is a PKI token that's not hashed.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            algos = self._conf_get('hash_algorithms')
 | 
					 | 
				
			||||||
            token_hashes = list(cms.cms_hash_token(user_token, mode=algo)
 | 
					 | 
				
			||||||
                                for algo in algos)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            for token_hash in token_hashes:
 | 
					 | 
				
			||||||
                cached = self._cache_get(token_hash)
 | 
					 | 
				
			||||||
                if cached:
 | 
					 | 
				
			||||||
                    return (token_hashes, cached)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            # The token wasn't found using any hash algorithm.
 | 
					 | 
				
			||||||
            return (token_hashes, None)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # user_token is either a UUID token or a hashed PKI token.
 | 
					 | 
				
			||||||
        token_id = user_token
 | 
					 | 
				
			||||||
        cached = self._cache_get(token_id)
 | 
					 | 
				
			||||||
        return ([token_id], cached)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _build_user_headers(self, token_info):
 | 
					    def _build_user_headers(self, token_info):
 | 
				
			||||||
        """Convert token object into headers.
 | 
					        """Convert token object into headers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1057,102 +1004,6 @@ class AuthProtocol(object):
 | 
				
			|||||||
        env_key = self._header_to_env_var(key)
 | 
					        env_key = self._header_to_env_var(key)
 | 
				
			||||||
        return env.get(env_key, default)
 | 
					        return env.get(env_key, default)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _cache_get(self, token_id):
 | 
					 | 
				
			||||||
        """Return token information from cache.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        If token is invalid raise InvalidUserToken
 | 
					 | 
				
			||||||
        return token only if fresh (not expired).
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if token_id:
 | 
					 | 
				
			||||||
            if self._memcache_security_strategy is None:
 | 
					 | 
				
			||||||
                key = CACHE_KEY_TEMPLATE % token_id
 | 
					 | 
				
			||||||
                with self._cache_pool.reserve() as cache:
 | 
					 | 
				
			||||||
                    serialized = cache.get(key)
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                secret_key = self._memcache_secret_key
 | 
					 | 
				
			||||||
                if isinstance(secret_key, six.string_types):
 | 
					 | 
				
			||||||
                    secret_key = secret_key.encode('utf-8')
 | 
					 | 
				
			||||||
                security_strategy = self._memcache_security_strategy
 | 
					 | 
				
			||||||
                if isinstance(security_strategy, six.string_types):
 | 
					 | 
				
			||||||
                    security_strategy = security_strategy.encode('utf-8')
 | 
					 | 
				
			||||||
                keys = memcache_crypt.derive_keys(
 | 
					 | 
				
			||||||
                    token_id,
 | 
					 | 
				
			||||||
                    secret_key,
 | 
					 | 
				
			||||||
                    security_strategy)
 | 
					 | 
				
			||||||
                cache_key = CACHE_KEY_TEMPLATE % (
 | 
					 | 
				
			||||||
                    memcache_crypt.get_cache_key(keys))
 | 
					 | 
				
			||||||
                with self._cache_pool.reserve() as cache:
 | 
					 | 
				
			||||||
                    raw_cached = cache.get(cache_key)
 | 
					 | 
				
			||||||
                try:
 | 
					 | 
				
			||||||
                    # unprotect_data will return None if raw_cached is None
 | 
					 | 
				
			||||||
                    serialized = memcache_crypt.unprotect_data(keys,
 | 
					 | 
				
			||||||
                                                               raw_cached)
 | 
					 | 
				
			||||||
                except Exception:
 | 
					 | 
				
			||||||
                    msg = 'Failed to decrypt/verify cache data'
 | 
					 | 
				
			||||||
                    self.LOG.exception(msg)
 | 
					 | 
				
			||||||
                    # this should have the same effect as data not
 | 
					 | 
				
			||||||
                    # found in cache
 | 
					 | 
				
			||||||
                    serialized = None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if serialized is None:
 | 
					 | 
				
			||||||
                return None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            # Note that 'invalid' and (data, expires) are the only
 | 
					 | 
				
			||||||
            # valid types of serialized cache entries, so there is not
 | 
					 | 
				
			||||||
            # a collision with jsonutils.loads(serialized) == None.
 | 
					 | 
				
			||||||
            if not isinstance(serialized, six.string_types):
 | 
					 | 
				
			||||||
                serialized = serialized.decode('utf-8')
 | 
					 | 
				
			||||||
            cached = jsonutils.loads(serialized)
 | 
					 | 
				
			||||||
            if cached == 'invalid':
 | 
					 | 
				
			||||||
                self.LOG.debug('Cached Token is marked unauthorized')
 | 
					 | 
				
			||||||
                raise InvalidUserToken('Token authorization failed')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            data, expires = cached
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            try:
 | 
					 | 
				
			||||||
                expires = timeutils.parse_isotime(expires)
 | 
					 | 
				
			||||||
            except ValueError:
 | 
					 | 
				
			||||||
                # Gracefully handle upgrade of expiration times from *nix
 | 
					 | 
				
			||||||
                # timestamps to ISO 8601 formatted dates by ignoring old cached
 | 
					 | 
				
			||||||
                # values.
 | 
					 | 
				
			||||||
                return
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            expires = timeutils.normalize_time(expires)
 | 
					 | 
				
			||||||
            utcnow = timeutils.utcnow()
 | 
					 | 
				
			||||||
            if utcnow < expires:
 | 
					 | 
				
			||||||
                self.LOG.debug('Returning cached token')
 | 
					 | 
				
			||||||
                return data
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                self.LOG.debug('Cached Token seems expired')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _cache_store(self, token_id, data):
 | 
					 | 
				
			||||||
        """Store value into memcache.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        data may be the string 'invalid' or a tuple like (data, expires)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        serialized_data = jsonutils.dumps(data)
 | 
					 | 
				
			||||||
        if isinstance(serialized_data, six.text_type):
 | 
					 | 
				
			||||||
            serialized_data = serialized_data.encode('utf-8')
 | 
					 | 
				
			||||||
        if self._memcache_security_strategy is None:
 | 
					 | 
				
			||||||
            cache_key = CACHE_KEY_TEMPLATE % token_id
 | 
					 | 
				
			||||||
            data_to_store = serialized_data
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            secret_key = self._memcache_secret_key
 | 
					 | 
				
			||||||
            if isinstance(secret_key, six.string_types):
 | 
					 | 
				
			||||||
                secret_key = secret_key.encode('utf-8')
 | 
					 | 
				
			||||||
            security_strategy = self._memcache_security_strategy
 | 
					 | 
				
			||||||
            if isinstance(security_strategy, six.string_types):
 | 
					 | 
				
			||||||
                security_strategy = security_strategy.encode('utf-8')
 | 
					 | 
				
			||||||
            keys = memcache_crypt.derive_keys(
 | 
					 | 
				
			||||||
                token_id, secret_key, security_strategy)
 | 
					 | 
				
			||||||
            cache_key = CACHE_KEY_TEMPLATE % memcache_crypt.get_cache_key(keys)
 | 
					 | 
				
			||||||
            data_to_store = memcache_crypt.protect_data(keys, serialized_data)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        with self._cache_pool.reserve() as cache:
 | 
					 | 
				
			||||||
            cache.set(cache_key, data_to_store, time=self.token_cache_time)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _invalid_user_token(self, msg=False):
 | 
					    def _invalid_user_token(self, msg=False):
 | 
				
			||||||
        # NOTE(jamielennox): use False as the default so that None is valid
 | 
					        # NOTE(jamielennox): use False as the default so that None is valid
 | 
				
			||||||
        if msg is False:
 | 
					        if msg is False:
 | 
				
			||||||
@@ -1224,21 +1075,6 @@ class AuthProtocol(object):
 | 
				
			|||||||
                               'identifier': identifier})
 | 
					                               'identifier': identifier})
 | 
				
			||||||
                self._invalid_user_token()
 | 
					                self._invalid_user_token()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _cache_put(self, token_id, data, expires):
 | 
					 | 
				
			||||||
        """Put token data into the cache.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Stores the parsed expire date in cache allowing
 | 
					 | 
				
			||||||
        quick check of token freshness on retrieval.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        """
 | 
					 | 
				
			||||||
        self.LOG.debug('Storing token in cache')
 | 
					 | 
				
			||||||
        self._cache_store(token_id, (data, expires))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _cache_store_invalid(self, token_id):
 | 
					 | 
				
			||||||
        """Store invalid token in cache."""
 | 
					 | 
				
			||||||
        self.LOG.debug('Marking token as unauthorized in cache')
 | 
					 | 
				
			||||||
        self._cache_store(token_id, 'invalid')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def verify_uuid_token(self, user_token, retry=True):
 | 
					    def verify_uuid_token(self, user_token, retry=True):
 | 
				
			||||||
        """Authenticate user token with keystone.
 | 
					        """Authenticate user token with keystone.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1507,6 +1343,210 @@ class CachePool(list):
 | 
				
			|||||||
            self.append(c)
 | 
					            self.append(c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TokenCache(object):
 | 
				
			||||||
 | 
					    """Encapsulates the auth_token token cache functionality.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auth_token caches tokens that it's seen so that when a token is re-used the
 | 
				
			||||||
 | 
					    middleware doesn't have to do a more expensive operation (like going to the
 | 
				
			||||||
 | 
					    identity server) to validate the token.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    initialize() must be called before calling the other methods.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Store a valid token in the cache using store(); mark a token as invalid in
 | 
				
			||||||
 | 
					    the cache using store_invalid().
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Check if a token is in the cache and retrieve it using get().
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _INVALID_INDICATOR = 'invalid'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, log, cache_time=None, hash_algorithms=None,
 | 
				
			||||||
 | 
					                 env_cache_name=None, memcached_servers=None,
 | 
				
			||||||
 | 
					                 memcache_security_strategy=None, memcache_secret_key=None):
 | 
				
			||||||
 | 
					        self.LOG = log
 | 
				
			||||||
 | 
					        self._cache_time = cache_time
 | 
				
			||||||
 | 
					        self._hash_algorithms = hash_algorithms
 | 
				
			||||||
 | 
					        self._env_cache_name = env_cache_name
 | 
				
			||||||
 | 
					        self._memcached_servers = memcached_servers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # memcache value treatment, ENCRYPT or MAC
 | 
				
			||||||
 | 
					        self._memcache_security_strategy = memcache_security_strategy
 | 
				
			||||||
 | 
					        if self._memcache_security_strategy is not None:
 | 
				
			||||||
 | 
					            self._memcache_security_strategy = (
 | 
				
			||||||
 | 
					                self._memcache_security_strategy.upper())
 | 
				
			||||||
 | 
					        self._memcache_secret_key = memcache_secret_key
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self._cache_pool = None
 | 
				
			||||||
 | 
					        self._initialized = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self._assert_valid_memcache_protection_config()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def initialize(self, env):
 | 
				
			||||||
 | 
					        if self._initialized:
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self._cache_pool = CachePool(env.get(self._env_cache_name),
 | 
				
			||||||
 | 
					                                     self._memcached_servers)
 | 
				
			||||||
 | 
					        self._initialized = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get(self, user_token):
 | 
				
			||||||
 | 
					        """Check if the token is cached already.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Returns a tuple. The first element is a list of token IDs, where the
 | 
				
			||||||
 | 
					        first one is the preferred hash.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        The second element is the token data from the cache if the token was
 | 
				
			||||||
 | 
					        cached, otherwise ``None``.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        :raises InvalidUserToken: if the token is invalid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if cms.is_asn1_token(user_token):
 | 
				
			||||||
 | 
					            # user_token is a PKI token that's not hashed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            token_hashes = list(cms.cms_hash_token(user_token, mode=algo)
 | 
				
			||||||
 | 
					                                for algo in self._hash_algorithms)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for token_hash in token_hashes:
 | 
				
			||||||
 | 
					                cached = self._cache_get(token_hash)
 | 
				
			||||||
 | 
					                if cached:
 | 
				
			||||||
 | 
					                    return (token_hashes, cached)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # The token wasn't found using any hash algorithm.
 | 
				
			||||||
 | 
					            return (token_hashes, None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # user_token is either a UUID token or a hashed PKI token.
 | 
				
			||||||
 | 
					        token_id = user_token
 | 
				
			||||||
 | 
					        cached = self._cache_get(token_id)
 | 
				
			||||||
 | 
					        return ([token_id], cached)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def store(self, token_id, data, expires):
 | 
				
			||||||
 | 
					        """Put token data into the cache.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Stores the parsed expire date in cache allowing
 | 
				
			||||||
 | 
					        quick check of token freshness on retrieval.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        self.LOG.debug('Storing token in cache')
 | 
				
			||||||
 | 
					        self._cache_store(token_id, (data, expires))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def store_invalid(self, token_id):
 | 
				
			||||||
 | 
					        """Store invalid token in cache."""
 | 
				
			||||||
 | 
					        self.LOG.debug('Marking token as unauthorized in cache')
 | 
				
			||||||
 | 
					        self._cache_store(token_id, self._INVALID_INDICATOR)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _assert_valid_memcache_protection_config(self):
 | 
				
			||||||
 | 
					        if self._memcache_security_strategy:
 | 
				
			||||||
 | 
					            if self._memcache_security_strategy not in ('MAC', 'ENCRYPT'):
 | 
				
			||||||
 | 
					                raise ConfigurationError('memcache_security_strategy must be '
 | 
				
			||||||
 | 
					                                         'ENCRYPT or MAC')
 | 
				
			||||||
 | 
					            if not self._memcache_secret_key:
 | 
				
			||||||
 | 
					                raise ConfigurationError('memcache_secret_key must be defined '
 | 
				
			||||||
 | 
					                                         'when a memcache_security_strategy '
 | 
				
			||||||
 | 
					                                         'is defined')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _cache_get(self, token_id):
 | 
				
			||||||
 | 
					        """Return token information from cache.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        If token is invalid raise InvalidUserToken
 | 
				
			||||||
 | 
					        return token only if fresh (not expired).
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if not token_id:
 | 
				
			||||||
 | 
					            # Nothing to do
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if self._memcache_security_strategy is None:
 | 
				
			||||||
 | 
					            key = CACHE_KEY_TEMPLATE % token_id
 | 
				
			||||||
 | 
					            with self._cache_pool.reserve() as cache:
 | 
				
			||||||
 | 
					                serialized = cache.get(key)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            secret_key = self._memcache_secret_key
 | 
				
			||||||
 | 
					            if isinstance(secret_key, six.string_types):
 | 
				
			||||||
 | 
					                secret_key = secret_key.encode('utf-8')
 | 
				
			||||||
 | 
					            security_strategy = self._memcache_security_strategy
 | 
				
			||||||
 | 
					            if isinstance(security_strategy, six.string_types):
 | 
				
			||||||
 | 
					                security_strategy = security_strategy.encode('utf-8')
 | 
				
			||||||
 | 
					            keys = memcache_crypt.derive_keys(
 | 
				
			||||||
 | 
					                token_id,
 | 
				
			||||||
 | 
					                secret_key,
 | 
				
			||||||
 | 
					                security_strategy)
 | 
				
			||||||
 | 
					            cache_key = CACHE_KEY_TEMPLATE % (
 | 
				
			||||||
 | 
					                memcache_crypt.get_cache_key(keys))
 | 
				
			||||||
 | 
					            with self._cache_pool.reserve() as cache:
 | 
				
			||||||
 | 
					                raw_cached = cache.get(cache_key)
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                # unprotect_data will return None if raw_cached is None
 | 
				
			||||||
 | 
					                serialized = memcache_crypt.unprotect_data(keys,
 | 
				
			||||||
 | 
					                                                           raw_cached)
 | 
				
			||||||
 | 
					            except Exception:
 | 
				
			||||||
 | 
					                msg = 'Failed to decrypt/verify cache data'
 | 
				
			||||||
 | 
					                self.LOG.exception(msg)
 | 
				
			||||||
 | 
					                # this should have the same effect as data not
 | 
				
			||||||
 | 
					                # found in cache
 | 
				
			||||||
 | 
					                serialized = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if serialized is None:
 | 
				
			||||||
 | 
					            return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Note that _INVALID_INDICATOR and (data, expires) are the only
 | 
				
			||||||
 | 
					        # valid types of serialized cache entries, so there is not
 | 
				
			||||||
 | 
					        # a collision with jsonutils.loads(serialized) == None.
 | 
				
			||||||
 | 
					        if not isinstance(serialized, six.string_types):
 | 
				
			||||||
 | 
					            serialized = serialized.decode('utf-8')
 | 
				
			||||||
 | 
					        cached = jsonutils.loads(serialized)
 | 
				
			||||||
 | 
					        if cached == self._INVALID_INDICATOR:
 | 
				
			||||||
 | 
					            self.LOG.debug('Cached Token is marked unauthorized')
 | 
				
			||||||
 | 
					            raise InvalidUserToken('Token authorization failed')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        data, expires = cached
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            expires = timeutils.parse_isotime(expires)
 | 
				
			||||||
 | 
					        except ValueError:
 | 
				
			||||||
 | 
					            # Gracefully handle upgrade of expiration times from *nix
 | 
				
			||||||
 | 
					            # timestamps to ISO 8601 formatted dates by ignoring old cached
 | 
				
			||||||
 | 
					            # values.
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expires = timeutils.normalize_time(expires)
 | 
				
			||||||
 | 
					        utcnow = timeutils.utcnow()
 | 
				
			||||||
 | 
					        if utcnow < expires:
 | 
				
			||||||
 | 
					            self.LOG.debug('Returning cached token')
 | 
				
			||||||
 | 
					            return data
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            self.LOG.debug('Cached Token seems expired')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _cache_store(self, token_id, data):
 | 
				
			||||||
 | 
					        """Store value into memcache.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        data may be _INVALID_INDICATOR or a tuple like (data, expires)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					        serialized_data = jsonutils.dumps(data)
 | 
				
			||||||
 | 
					        if isinstance(serialized_data, six.text_type):
 | 
				
			||||||
 | 
					            serialized_data = serialized_data.encode('utf-8')
 | 
				
			||||||
 | 
					        if self._memcache_security_strategy is None:
 | 
				
			||||||
 | 
					            cache_key = CACHE_KEY_TEMPLATE % token_id
 | 
				
			||||||
 | 
					            data_to_store = serialized_data
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            secret_key = self._memcache_secret_key
 | 
				
			||||||
 | 
					            if isinstance(secret_key, six.string_types):
 | 
				
			||||||
 | 
					                secret_key = secret_key.encode('utf-8')
 | 
				
			||||||
 | 
					            security_strategy = self._memcache_security_strategy
 | 
				
			||||||
 | 
					            if isinstance(security_strategy, six.string_types):
 | 
				
			||||||
 | 
					                security_strategy = security_strategy.encode('utf-8')
 | 
				
			||||||
 | 
					            keys = memcache_crypt.derive_keys(
 | 
				
			||||||
 | 
					                token_id, secret_key, security_strategy)
 | 
				
			||||||
 | 
					            cache_key = CACHE_KEY_TEMPLATE % memcache_crypt.get_cache_key(keys)
 | 
				
			||||||
 | 
					            data_to_store = memcache_crypt.protect_data(keys, serialized_data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        with self._cache_pool.reserve() as cache:
 | 
				
			||||||
 | 
					            cache.set(cache_key, data_to_store, time=self._cache_time)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def filter_factory(global_conf, **local_conf):
 | 
					def filter_factory(global_conf, **local_conf):
 | 
				
			||||||
    """Returns a WSGI filter app for use with paste.deploy."""
 | 
					    """Returns a WSGI filter app for use with paste.deploy."""
 | 
				
			||||||
    conf = global_conf.copy()
 | 
					    conf = global_conf.copy()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -378,8 +378,8 @@ class CachePoolTest(BaseAuthTokenMiddlewareTest):
 | 
				
			|||||||
            'cache': 'swift.cache'
 | 
					            'cache': 'swift.cache'
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        self.set_middleware(conf=conf)
 | 
					        self.set_middleware(conf=conf)
 | 
				
			||||||
        self.middleware._init_cache(env)
 | 
					        self.middleware._token_cache.initialize(env)
 | 
				
			||||||
        with self.middleware._cache_pool.reserve() as cache:
 | 
					        with self.middleware._token_cache._cache_pool.reserve() as cache:
 | 
				
			||||||
            self.assertEqual(cache, 'CACHE_TEST')
 | 
					            self.assertEqual(cache, 'CACHE_TEST')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_not_use_cache_from_env(self):
 | 
					    def test_not_use_cache_from_env(self):
 | 
				
			||||||
@@ -388,37 +388,40 @@ class CachePoolTest(BaseAuthTokenMiddlewareTest):
 | 
				
			|||||||
        """
 | 
					        """
 | 
				
			||||||
        self.set_middleware()
 | 
					        self.set_middleware()
 | 
				
			||||||
        env = {'swift.cache': 'CACHE_TEST'}
 | 
					        env = {'swift.cache': 'CACHE_TEST'}
 | 
				
			||||||
        self.middleware._init_cache(env)
 | 
					        self.middleware._token_cache.initialize(env)
 | 
				
			||||||
        with self.middleware._cache_pool.reserve() as cache:
 | 
					        with self.middleware._token_cache._cache_pool.reserve() as cache:
 | 
				
			||||||
            self.assertNotEqual(cache, 'CACHE_TEST')
 | 
					            self.assertNotEqual(cache, 'CACHE_TEST')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_multiple_context_managers_share_single_client(self):
 | 
					    def test_multiple_context_managers_share_single_client(self):
 | 
				
			||||||
        self.set_middleware()
 | 
					        self.set_middleware()
 | 
				
			||||||
 | 
					        token_cache = self.middleware._token_cache
 | 
				
			||||||
        env = {}
 | 
					        env = {}
 | 
				
			||||||
        self.middleware._init_cache(env)
 | 
					        token_cache.initialize(env)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        caches = []
 | 
					        caches = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        with self.middleware._cache_pool.reserve() as cache:
 | 
					        with token_cache._cache_pool.reserve() as cache:
 | 
				
			||||||
            caches.append(cache)
 | 
					            caches.append(cache)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        with self.middleware._cache_pool.reserve() as cache:
 | 
					        with token_cache._cache_pool.reserve() as cache:
 | 
				
			||||||
            caches.append(cache)
 | 
					            caches.append(cache)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertIs(caches[0], caches[1])
 | 
					        self.assertIs(caches[0], caches[1])
 | 
				
			||||||
        self.assertEqual(set(caches), set(self.middleware._cache_pool))
 | 
					        self.assertEqual(set(caches), set(token_cache._cache_pool))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_nested_context_managers_create_multiple_clients(self):
 | 
					    def test_nested_context_managers_create_multiple_clients(self):
 | 
				
			||||||
        self.set_middleware()
 | 
					        self.set_middleware()
 | 
				
			||||||
        env = {}
 | 
					        env = {}
 | 
				
			||||||
        self.middleware._init_cache(env)
 | 
					        self.middleware._token_cache.initialize(env)
 | 
				
			||||||
 | 
					        token_cache = self.middleware._token_cache
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        with self.middleware._cache_pool.reserve() as outer_cache:
 | 
					        with token_cache._cache_pool.reserve() as outer_cache:
 | 
				
			||||||
            with self.middleware._cache_pool.reserve() as inner_cache:
 | 
					            with token_cache._cache_pool.reserve() as inner_cache:
 | 
				
			||||||
                self.assertNotEqual(outer_cache, inner_cache)
 | 
					                self.assertNotEqual(outer_cache, inner_cache)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEqual(
 | 
					        self.assertEqual(
 | 
				
			||||||
            set([inner_cache, outer_cache]), set(self.middleware._cache_pool))
 | 
					            set([inner_cache, outer_cache]),
 | 
				
			||||||
 | 
					            set(token_cache._cache_pool))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GeneralAuthTokenMiddlewareTest(BaseAuthTokenMiddlewareTest,
 | 
					class GeneralAuthTokenMiddlewareTest(BaseAuthTokenMiddlewareTest,
 | 
				
			||||||
@@ -470,9 +473,10 @@ class GeneralAuthTokenMiddlewareTest(BaseAuthTokenMiddlewareTest,
 | 
				
			|||||||
        some_time_later = timeutils.utcnow() + datetime.timedelta(hours=4)
 | 
					        some_time_later = timeutils.utcnow() + datetime.timedelta(hours=4)
 | 
				
			||||||
        expires = timeutils.strtime(some_time_later)
 | 
					        expires = timeutils.strtime(some_time_later)
 | 
				
			||||||
        data = ('this_data', expires)
 | 
					        data = ('this_data', expires)
 | 
				
			||||||
        self.middleware._init_cache({})
 | 
					        token_cache = self.middleware._token_cache
 | 
				
			||||||
        self.middleware._cache_store(token, data)
 | 
					        token_cache.initialize({})
 | 
				
			||||||
        self.assertEqual(self.middleware._cache_get(token), data[0])
 | 
					        token_cache._cache_store(token, data)
 | 
				
			||||||
 | 
					        self.assertEqual(token_cache._cache_get(token), data[0])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @testtools.skipUnless(memcached_available(), 'memcached not available')
 | 
					    @testtools.skipUnless(memcached_available(), 'memcached not available')
 | 
				
			||||||
    def test_sign_cache_data(self):
 | 
					    def test_sign_cache_data(self):
 | 
				
			||||||
@@ -487,9 +491,10 @@ class GeneralAuthTokenMiddlewareTest(BaseAuthTokenMiddlewareTest,
 | 
				
			|||||||
        some_time_later = timeutils.utcnow() + datetime.timedelta(hours=4)
 | 
					        some_time_later = timeutils.utcnow() + datetime.timedelta(hours=4)
 | 
				
			||||||
        expires = timeutils.strtime(some_time_later)
 | 
					        expires = timeutils.strtime(some_time_later)
 | 
				
			||||||
        data = ('this_data', expires)
 | 
					        data = ('this_data', expires)
 | 
				
			||||||
        self.middleware._init_cache({})
 | 
					        token_cache = self.middleware._token_cache
 | 
				
			||||||
        self.middleware._cache_store(token, data)
 | 
					        token_cache.initialize({})
 | 
				
			||||||
        self.assertEqual(self.middleware._cache_get(token), data[0])
 | 
					        token_cache._cache_store(token, data)
 | 
				
			||||||
 | 
					        self.assertEqual(token_cache._cache_get(token), data[0])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @testtools.skipUnless(memcached_available(), 'memcached not available')
 | 
					    @testtools.skipUnless(memcached_available(), 'memcached not available')
 | 
				
			||||||
    def test_no_memcache_protection(self):
 | 
					    def test_no_memcache_protection(self):
 | 
				
			||||||
@@ -503,9 +508,10 @@ class GeneralAuthTokenMiddlewareTest(BaseAuthTokenMiddlewareTest,
 | 
				
			|||||||
        some_time_later = timeutils.utcnow() + datetime.timedelta(hours=4)
 | 
					        some_time_later = timeutils.utcnow() + datetime.timedelta(hours=4)
 | 
				
			||||||
        expires = timeutils.strtime(some_time_later)
 | 
					        expires = timeutils.strtime(some_time_later)
 | 
				
			||||||
        data = ('this_data', expires)
 | 
					        data = ('this_data', expires)
 | 
				
			||||||
        self.middleware._init_cache({})
 | 
					        token_cache = self.middleware._token_cache
 | 
				
			||||||
        self.middleware._cache_store(token, data)
 | 
					        token_cache.initialize({})
 | 
				
			||||||
        self.assertEqual(self.middleware._cache_get(token), data[0])
 | 
					        token_cache._cache_store(token, data)
 | 
				
			||||||
 | 
					        self.assertEqual(token_cache._cache_get(token), data[0])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_assert_valid_memcache_protection_config(self):
 | 
					    def test_assert_valid_memcache_protection_config(self):
 | 
				
			||||||
        # test missing memcache_secret_key
 | 
					        # test missing memcache_secret_key
 | 
				
			||||||
@@ -942,7 +948,7 @@ class CommonAuthTokenMiddlewareTest(object):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def _get_cached_token(self, token, mode='md5'):
 | 
					    def _get_cached_token(self, token, mode='md5'):
 | 
				
			||||||
        token_id = cms.cms_hash_token(token, mode=mode)
 | 
					        token_id = cms.cms_hash_token(token, mode=mode)
 | 
				
			||||||
        return self.middleware._cache_get(token_id)
 | 
					        return self.middleware._token_cache._cache_get(token_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_memcache(self):
 | 
					    def test_memcache(self):
 | 
				
			||||||
        # NOTE(jamielennox): it appears that httpretty can mess with the
 | 
					        # NOTE(jamielennox): it appears that httpretty can mess with the
 | 
				
			||||||
@@ -1866,11 +1872,11 @@ class TokenExpirationTest(BaseAuthTokenMiddlewareTest):
 | 
				
			|||||||
        token = 'mytoken'
 | 
					        token = 'mytoken'
 | 
				
			||||||
        data = 'this_data'
 | 
					        data = 'this_data'
 | 
				
			||||||
        self.set_middleware()
 | 
					        self.set_middleware()
 | 
				
			||||||
        self.middleware._init_cache({})
 | 
					        self.middleware._token_cache.initialize({})
 | 
				
			||||||
        some_time_later = timeutils.strtime(at=(self.now + self.delta))
 | 
					        some_time_later = timeutils.strtime(at=(self.now + self.delta))
 | 
				
			||||||
        expires = some_time_later
 | 
					        expires = some_time_later
 | 
				
			||||||
        self.middleware._cache_put(token, data, expires)
 | 
					        self.middleware._token_cache.store(token, data, expires)
 | 
				
			||||||
        self.assertEqual(self.middleware._cache_get(token), data)
 | 
					        self.assertEqual(self.middleware._token_cache._cache_get(token), data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_cached_token_not_expired_with_old_style_nix_timestamp(self):
 | 
					    def test_cached_token_not_expired_with_old_style_nix_timestamp(self):
 | 
				
			||||||
        """Ensure we cannot retrieve a token from the cache.
 | 
					        """Ensure we cannot retrieve a token from the cache.
 | 
				
			||||||
@@ -1882,44 +1888,45 @@ class TokenExpirationTest(BaseAuthTokenMiddlewareTest):
 | 
				
			|||||||
        token = 'mytoken'
 | 
					        token = 'mytoken'
 | 
				
			||||||
        data = 'this_data'
 | 
					        data = 'this_data'
 | 
				
			||||||
        self.set_middleware()
 | 
					        self.set_middleware()
 | 
				
			||||||
        self.middleware._init_cache({})
 | 
					        token_cache = self.middleware._token_cache
 | 
				
			||||||
 | 
					        token_cache.initialize({})
 | 
				
			||||||
        some_time_later = self.now + self.delta
 | 
					        some_time_later = self.now + self.delta
 | 
				
			||||||
        # Store a unix timestamp in the cache.
 | 
					        # Store a unix timestamp in the cache.
 | 
				
			||||||
        expires = calendar.timegm(some_time_later.timetuple())
 | 
					        expires = calendar.timegm(some_time_later.timetuple())
 | 
				
			||||||
        self.middleware._cache_put(token, data, expires)
 | 
					        token_cache.store(token, data, expires)
 | 
				
			||||||
        self.assertIsNone(self.middleware._cache_get(token))
 | 
					        self.assertIsNone(token_cache._cache_get(token))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_cached_token_expired(self):
 | 
					    def test_cached_token_expired(self):
 | 
				
			||||||
        token = 'mytoken'
 | 
					        token = 'mytoken'
 | 
				
			||||||
        data = 'this_data'
 | 
					        data = 'this_data'
 | 
				
			||||||
        self.set_middleware()
 | 
					        self.set_middleware()
 | 
				
			||||||
        self.middleware._init_cache({})
 | 
					        self.middleware._token_cache.initialize({})
 | 
				
			||||||
        some_time_earlier = timeutils.strtime(at=(self.now - self.delta))
 | 
					        some_time_earlier = timeutils.strtime(at=(self.now - self.delta))
 | 
				
			||||||
        expires = some_time_earlier
 | 
					        expires = some_time_earlier
 | 
				
			||||||
        self.middleware._cache_put(token, data, expires)
 | 
					        self.middleware._token_cache.store(token, data, expires)
 | 
				
			||||||
        self.assertIsNone(self.middleware._cache_get(token))
 | 
					        self.assertIsNone(self.middleware._token_cache._cache_get(token))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_cached_token_with_timezone_offset_not_expired(self):
 | 
					    def test_cached_token_with_timezone_offset_not_expired(self):
 | 
				
			||||||
        token = 'mytoken'
 | 
					        token = 'mytoken'
 | 
				
			||||||
        data = 'this_data'
 | 
					        data = 'this_data'
 | 
				
			||||||
        self.set_middleware()
 | 
					        self.set_middleware()
 | 
				
			||||||
        self.middleware._init_cache({})
 | 
					        self.middleware._token_cache.initialize({})
 | 
				
			||||||
        timezone_offset = datetime.timedelta(hours=2)
 | 
					        timezone_offset = datetime.timedelta(hours=2)
 | 
				
			||||||
        some_time_later = self.now - timezone_offset + self.delta
 | 
					        some_time_later = self.now - timezone_offset + self.delta
 | 
				
			||||||
        expires = timeutils.strtime(some_time_later) + '-02:00'
 | 
					        expires = timeutils.strtime(some_time_later) + '-02:00'
 | 
				
			||||||
        self.middleware._cache_put(token, data, expires)
 | 
					        self.middleware._token_cache.store(token, data, expires)
 | 
				
			||||||
        self.assertEqual(self.middleware._cache_get(token), data)
 | 
					        self.assertEqual(self.middleware._token_cache._cache_get(token), data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_cached_token_with_timezone_offset_expired(self):
 | 
					    def test_cached_token_with_timezone_offset_expired(self):
 | 
				
			||||||
        token = 'mytoken'
 | 
					        token = 'mytoken'
 | 
				
			||||||
        data = 'this_data'
 | 
					        data = 'this_data'
 | 
				
			||||||
        self.set_middleware()
 | 
					        self.set_middleware()
 | 
				
			||||||
        self.middleware._init_cache({})
 | 
					        self.middleware._token_cache.initialize({})
 | 
				
			||||||
        timezone_offset = datetime.timedelta(hours=2)
 | 
					        timezone_offset = datetime.timedelta(hours=2)
 | 
				
			||||||
        some_time_earlier = self.now - timezone_offset - self.delta
 | 
					        some_time_earlier = self.now - timezone_offset - self.delta
 | 
				
			||||||
        expires = timeutils.strtime(some_time_earlier) + '-02:00'
 | 
					        expires = timeutils.strtime(some_time_earlier) + '-02:00'
 | 
				
			||||||
        self.middleware._cache_put(token, data, expires)
 | 
					        self.middleware._token_cache.store(token, data, expires)
 | 
				
			||||||
        self.assertIsNone(self.middleware._cache_get(token))
 | 
					        self.assertIsNone(self.middleware._token_cache._cache_get(token))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CatalogConversionTests(BaseAuthTokenMiddlewareTest):
 | 
					class CatalogConversionTests(BaseAuthTokenMiddlewareTest):
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user