def build_token_values(token_data): token_values = { 'expires_at': timeutils.normalize_time( timeutils.parse_isotime(token_data['expires_at'])), 'issued_at': timeutils.normalize_time( timeutils.parse_isotime(token_data['issued_at'])) } user = token_data.get('user') if user is not None: token_values['user_id'] = user['id'] token_values['identity_domain_id'] = user['domain']['id'] else: token_values['user_id'] = None token_values['identity_domain_id'] = None project = token_data.get('project', token_data.get('tenant')) if project is not None: token_values['project_id'] = project['id'] token_values['assignment_domain_id'] = project['domain']['id'] else: token_values['project_id'] = None token_values['assignment_domain_id'] = None role_list = [] roles = token_data.get('roles') if roles is not None: for role in roles: role_list.append(role['id']) token_values['roles'] = role_list trust = token_data.get('OS-TRUST:trust') if trust is None: token_values['trust_id'] = None token_values['trustor_id'] = None token_values['trustee_id'] = None else: token_values['trust_id'] = trust['id'] token_values['trustor_id'] = trust['trustor_user']['id'] token_values['trustee_id'] = trust['trustee_user']['id'] oauth1 = token_data.get('OS-OAUTH1') if oauth1 is None: token_values['consumer_id'] = None token_values['access_token_id'] = None else: token_values['consumer_id'] = oauth1['consumer_id'] token_values['access_token_id'] = oauth1['access_token_id'] return token_values
def build_token_values(token_data): token_values = { 'expires_at': timeutils.normalize_time( timeutils.parse_isotime(token_data['expires_at'])), 'issued_at': timeutils.normalize_time( timeutils.parse_isotime(token_data['issued_at']))} user = token_data.get('user') if user is not None: token_values['user_id'] = user['id'] token_values['identity_domain_id'] = user['domain']['id'] else: token_values['user_id'] = None token_values['identity_domain_id'] = None project = token_data.get('project', token_data.get('tenant')) if project is not None: token_values['project_id'] = project['id'] token_values['assignment_domain_id'] = project['domain']['id'] else: token_values['project_id'] = None token_values['assignment_domain_id'] = None role_list = [] roles = token_data.get('roles') if roles is not None: for role in roles: role_list.append(role['id']) token_values['roles'] = role_list trust = token_data.get('OS-TRUST:trust') if trust is None: token_values['trust_id'] = None token_values['trustor_id'] = None token_values['trustee_id'] = None else: token_values['trust_id'] = trust['id'] token_values['trustor_id'] = trust['trustor_user']['id'] token_values['trustee_id'] = trust['trustee_user']['id'] oauth1 = token_data.get('OS-OAUTH1') if oauth1 is None: token_values['consumer_id'] = None token_values['access_token_id'] = None else: token_values['consumer_id'] = oauth1['consumer_id'] token_values['access_token_id'] = oauth1['access_token_id'] return token_values
def _request_admin_token(self): """Retrieve new token as admin user from keystone. :return token id upon success :raises ServerError when unable to communicate with keystone """ params = { 'auth': { 'passwordCredentials': { 'username': self.admin_user, 'password': self.admin_password, }, 'tenantName': self.admin_tenant_name, } } response, data = self._json_request('POST', '/v2.0/tokens', body=params) try: token = data['access']['token']['id'] expiry = data['access']['token']['expires'] assert token assert expiry datetime_expiry = timeutils.parse_isotime(expiry) return (token, timeutils.normalize_time(datetime_expiry)) except (AssertionError, KeyError): LOG.warn("Unexpected response from keystone service: %s", data) raise ServiceError('invalid json response') except (ValueError): LOG.warn("Unable to parse expiration time from token: %s", data) raise ServiceError('invalid json response')
def _request_admin_token(self): """Retrieve new token as admin user from keystone. :return token id upon success :raises ServerError when unable to communicate with keystone """ params = { "auth": { "passwordCredentials": {"username": self.admin_user, "password": self.admin_password}, "tenantName": self.admin_tenant_name, } } response, data = self._json_request("POST", "/v2.0/tokens", body=params) try: token = data["access"]["token"]["id"] expiry = data["access"]["token"]["expires"] assert token assert expiry datetime_expiry = timeutils.parse_isotime(expiry) return (token, timeutils.normalize_time(datetime_expiry)) except (AssertionError, KeyError): self.LOG.warn("Unexpected response from keystone service: %s", data) raise ServiceError("invalid json response") except (ValueError): self.LOG.warn("Unable to parse expiration time from token: %s", data) raise ServiceError("invalid json response")
def _cache_get(self, token_id, ignore_expires=False): """Return token information from cache. If token is invalid raise InvalidUserToken return token only if fresh (not expired). """ if self._cache and token_id: if self._memcache_security_strategy is None: key = CACHE_KEY_TEMPLATE % token_id serialized = self._cache.get(key) else: keys = memcache_crypt.derive_keys( token_id, self._memcache_secret_key, self._memcache_security_strategy) cache_key = CACHE_KEY_TEMPLATE % ( memcache_crypt.get_cache_key(keys)) raw_cached = self._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. cached = jsonutils.loads(serialized) if cached == 'invalid': self.LOG.debug('Cached Token %s is marked unauthorized', token_id) 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 ignore_expires or utcnow < expires: self.LOG.debug('Returning cached token %s', token_id) return data else: self.LOG.debug('Cached Token %s seems expired', token_id)
def _cache_get(self, token_id, ignore_expires=False): """Return token information from cache. If token is invalid raise InvalidUserToken return token only if fresh (not expired). """ if self._cache and token_id: if self._memcache_security_strategy is None: key = CACHE_KEY_TEMPLATE % token_id serialized = self._cache.get(key) else: keys = memcache_crypt.derive_keys( token_id, self._memcache_secret_key, self._memcache_security_strategy) cache_key = CACHE_KEY_TEMPLATE % ( memcache_crypt.get_cache_key(keys)) raw_cached = self._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. cached = jsonutils.loads(serialized) if cached == 'invalid': self.LOG.debug('Cached Token %s is marked unauthorized', token_id) 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 ignore_expires or utcnow < expires: self.LOG.debug('Returning cached token %s', token_id) return data else: self.LOG.debug('Cached Token %s seems expired', token_id)
def build_token_values_v2(access, default_domain_id): token_data = access['token'] token_values = { 'expires_at': timeutils.normalize_time(timeutils.parse_isotime( token_data['expires'])), 'issued_at': timeutils.normalize_time( timeutils.parse_isotime(token_data['issued_at'])) } token_values['user_id'] = access.get('user', {}).get('id') project = token_data.get('tenant') if project is not None: token_values['project_id'] = project['id'] else: token_values['project_id'] = None token_values['identity_domain_id'] = default_domain_id token_values['assignment_domain_id'] = default_domain_id trust = token_data.get('trust') if trust is None: token_values['trust_id'] = None token_values['trustor_id'] = None token_values['trustee_id'] = None else: token_values['trust_id'] = trust['id'] token_values['trustor_id'] = trust['trustor_id'] token_values['trustee_id'] = trust['trustee_id'] token_values['consumer_id'] = None token_values['access_token_id'] = None role_list = [] # Roles are by ID in metadata and by name in the user section roles = access.get('metadata', {}).get('roles', []) for role in roles: role_list.append(role) token_values['roles'] = role_list return token_values
def will_expire_soon(self, stale_duration=None): """Determines if expiration is about to occur. :return: boolean : true if expiration is within the given duration """ stale_duration = STALE_TOKEN_DURATION if stale_duration is None else stale_duration norm_expires = timeutils.normalize_time(self.expires) # (gyee) should we move auth_token.will_expire_soon() to timeutils # instead of duplicating code here? soon = timeutils.utcnow() + datetime.timedelta(seconds=stale_duration) return norm_expires < soon
def build_token_values_v2(access, default_domain_id): token_data = access['token'] token_values = { 'expires_at': timeutils.normalize_time( timeutils.parse_isotime(token_data['expires'])), 'issued_at': timeutils.normalize_time( timeutils.parse_isotime(token_data['issued_at']))} token_values['user_id'] = access.get('user', {}).get('id') project = token_data.get('tenant') if project is not None: token_values['project_id'] = project['id'] else: token_values['project_id'] = None token_values['identity_domain_id'] = default_domain_id token_values['assignment_domain_id'] = default_domain_id trust = token_data.get('trust') if trust is None: token_values['trust_id'] = None token_values['trustor_id'] = None token_values['trustee_id'] = None else: token_values['trust_id'] = trust['id'] token_values['trustor_id'] = trust['trustor_id'] token_values['trustee_id'] = trust['trustee_id'] token_values['consumer_id'] = None token_values['access_token_id'] = None role_list = [] # Roles are by ID in metadata and by name in the user section roles = access.get('metadata', {}).get('roles', []) for role in roles: role_list.append(role) token_values['roles'] = role_list return token_values
def will_expire_soon(self, stale_duration=None): """ Determines if expiration is about to occur. :return: boolean : true if expiration is within the given duration """ stale_duration = stale_duration or TALE_TOKEN_DURATION norm_expires = timeutils.normalize_time(self.expires) # (gyee) should we move auth_token.will_expire_soon() to timeutils # instead of duplicating code here? soon = (timeutils.utcnow() + datetime.timedelta(seconds=stale_duration)) return norm_expires < soon
def confirm_token_not_expired(data): if not data: raise InvalidUserToken('Token authorization failed') if _token_is_v2(data): timestamp = data['access']['token']['expires'] elif _token_is_v3(data): timestamp = data['token']['expires_at'] else: raise InvalidUserToken('Token authorization failed') expires = timeutils.parse_isotime(timestamp) expires = timeutils.normalize_time(expires) utcnow = timeutils.utcnow() if utcnow >= expires: raise InvalidUserToken('Token authorization failed') return timeutils.isotime(at=expires, subsecond=True)