def _is_valid_token(self, token): """Verify the token is valid format and has not expired.""" current_time = timeutils.normalize_time(timeutils.utcnow()) try: # Get the data we need from the correct location (V2 and V3 tokens # differ in structure, Try V3 first, fall back to V2 second) token_data = token.get('token', token.get('access')) expires_at = token_data.get('expires_at', token_data.get('expires')) if not expires_at: expires_at = token_data['token']['expires'] expiry = timeutils.normalize_time( timeutils.parse_isotime(expires_at)) except Exception: LOG.exception( _LE('Unexpected error or malformed token ' 'determining token expiry: %s'), token) raise exception.TokenNotFound(_('Failed to validate token')) if current_time < expiry: self.check_revocation(token) # Token has not expired and has not been revoked. return None else: raise exception.TokenNotFound(_('Failed to validate token'))
def _validate_token_user(self): if self.trust_scoped: if self.user_id != self.trustee['id']: raise exception.Forbidden(_('User is not a trustee.')) try: PROVIDERS.resource_api.assert_domain_enabled( self.trustor['domain_id']) except AssertionError: raise exception.TokenNotFound(_('Trustor domain is disabled.')) try: PROVIDERS.resource_api.assert_domain_enabled( self.trustee['domain_id']) except AssertionError: raise exception.TokenNotFound(_('Trustee domain is disabled.')) try: PROVIDERS.identity_api.assert_user_enabled(self.trustor['id']) except AssertionError: raise exception.Forbidden(_('Trustor is disabled.')) if not self.user_domain.get('enabled'): msg = _('Unable to validate token because domain %(id)s is ' 'disabled') % { 'id': self.user_domain['id'] } LOG.warning(msg) raise exception.DomainNotFound(msg)
def get_token(self, token_id): if token_id is None: raise exception.TokenNotFound(token_id=token_id) with sql.session_for_read() as session: token_ref = session.query(TokenModel).get(token_id) if not token_ref or not token_ref.valid: raise exception.TokenNotFound(token_id=token_id) return token_ref.to_dict()
def get_token(self, token_id): if token_id is None: raise exception.TokenNotFound(token_id=token_id) session = sql.get_session() token_ref = session.query(TokenModel).get(token_id) if not token_ref or not token_ref.valid: raise exception.TokenNotFound(token_id=token_id) return token_ref.to_dict()
def get_token(self, token_id): try: token = self.db.get('token-%s' % token_id) except exception.NotFound: raise exception.TokenNotFound(token_id=token_id) if token['expires'] is None or token['expires'] > timeutils.utcnow(): return copy.deepcopy(token) else: raise exception.TokenNotFound(token_id=token_id)
def get_token(self, token_id): if token_id is None: raise exception.TokenNotFound(token_id='') ptk = self._prefix_token_id(token_id) token_ref = self.client.get(ptk) if token_ref is None: raise exception.TokenNotFound(token_id=token_id) return token_ref
def validate_token(self, token_id, window_seconds=0): if not token_id: raise exception.TokenNotFound(_('No token in the request')) try: token_ref = self._validate_token(token_id) self._is_valid_token(token_ref, window_seconds=window_seconds) return token_ref except exception.Unauthorized as e: LOG.debug('Unable to validate token: %s', e) raise exception.TokenNotFound(token_id=token_id)
def get_token(self, token_id): if token_id is None: raise exception.TokenNotFound(token_id=token_id) session = self.get_session() query = session.query(TokenModel) query = query.filter_by(id=self.token_to_key(token_id), valid=True) token_ref = query.first() now = datetime.datetime.utcnow() if token_ref and (not token_ref.expires or now < token_ref.expires): return token_ref.to_dict() else: raise exception.TokenNotFound(token_id=token_id)
def get_token(self, token_id): try: ref = self.db.get('token-%s' % token_id) except exception.NotFound: raise exception.TokenNotFound(token_id=token_id) now = timeutils.utcnow() expiry = ref['expires'] if expiry is None: raise exception.TokenNotFound(token_id=token_id) if expiry > now: return copy.deepcopy(ref) else: raise exception.TokenNotFound(token_id=token_id)
def validate_token(self, token_id, window_seconds=0, access_rules_support=None): if not token_id: raise exception.TokenNotFound(_('No token in the request')) try: token = self._validate_token(token_id) self._is_valid_token(token, window_seconds=window_seconds) self._validate_token_access_rules(token, access_rules_support) return token except exception.Unauthorized as e: LOG.debug('Unable to validate token: %s', e) raise exception.TokenNotFound(token_id=token_id)
def get_token(self, token_id): if token_id is None: raise exception.TokenNotFound(token_id=token_id) session = self.get_session() token_ref = session.query(TokenModel).get(token_id) now = datetime.datetime.utcnow() if not token_ref or not token_ref.valid: raise exception.TokenNotFound(token_id=token_id) if not token_ref.expires: raise exception.TokenNotFound(token_id=token_id) if now >= token_ref.expires: raise exception.TokenNotFound(token_id=token_id) return token_ref.to_dict()
def get_token(self, token_id): if token_id is None: raise exception.TokenNotFound(token_id=token_id) session = self.get_session() query = session.query(TokenModel) query = query.filter_by(id=token.unique_id(token_id), valid=True) token_ref = query.first() now = datetime.datetime.utcnow() if not token_ref: raise exception.TokenNotFound(token_id=token_id) if not token_ref.expires: raise exception.TokenNotFound(token_id=token_id) if now >= token_ref.expires: raise exception.TokenNotFound(token_id=token_id) return token_ref.to_dict()
def _populate_user(self, token_data, user_id, trust): if 'user' in token_data: # no need to repopulate user if it already exists return user_ref = PROVIDERS.identity_api.get_user(user_id) if CONF.trust.enabled and trust and 'OS-TRUST:trust' not in token_data: trustor_user_ref = (PROVIDERS.identity_api.get_user( trust['trustor_user_id'])) trustee_user_ref = (PROVIDERS.identity_api.get_user( trust['trustee_user_id'])) try: PROVIDERS.resource_api.assert_domain_enabled( trustor_user_ref['domain_id']) except AssertionError: raise exception.TokenNotFound(_('Trustor domain is disabled.')) try: PROVIDERS.resource_api.assert_domain_enabled( trustee_user_ref['domain_id']) except AssertionError: raise exception.TokenNotFound(_('Trustee domain is disabled.')) try: PROVIDERS.identity_api.assert_user_enabled( trust['trustor_user_id']) except AssertionError: raise exception.Forbidden(_('Trustor is disabled.')) if trust['impersonation']: user_ref = trustor_user_ref token_data['OS-TRUST:trust'] = ({ 'id': trust['id'], 'trustor_user': { 'id': trust['trustor_user_id'] }, 'trustee_user': { 'id': trust['trustee_user_id'] }, 'impersonation': trust['impersonation'] }) filtered_user = { 'id': user_ref['id'], 'name': user_ref['name'], 'domain': self._get_filtered_domain(user_ref['domain_id']), 'password_expires_at': user_ref['password_expires_at'] } token_data['user'] = filtered_user
def validate_v2_token(self, token_ref): """Validate a V2 formatted token. :param token_ref: reference describing the token to validate :returns: the token data :raises keystone.exception.TokenNotFound: if token format is invalid :raises keystone.exception.Unauthorized: if v3 token is used """ try: (user_id, methods, audit_ids, domain_id, project_id, trust_id, federated_info, created_at, expires_at) = self.token_formatter.validate_token(token_ref) except exception.ValidationError as e: raise exception.TokenNotFound(e) if trust_id or domain_id or federated_info: msg = _('This is not a v2.0 Fernet token. Use v3 for trust, ' 'domain, or federated tokens.') raise exception.Unauthorized(msg) v3_token_data = self.v3_token_data_helper.get_token_data( user_id, methods, project_id=project_id, expires=expires_at, issued_at=created_at, token=token_ref, include_catalog=False, audit_info=audit_ids) token_data = self.v2_token_data_helper.v3_to_v2_token(v3_token_data) token_data['access']['token']['id'] = token_ref return token_data
def delete_token(self, token_id): try: token_ref = self.get_token(token_id) self.db.delete('token-%s' % token_id) self.db.set('revoked-token-%s' % token_id, token_ref) except exception.NotFound: raise exception.TokenNotFound(token_id=token_id)
def get_token(self, token_id): try: ref = self.db.get('token-%s' % token_id) return copy.deepcopy(ref) except Exception: # On any issues here, Token is not found. raise exception.TokenNotFound(token_id=token_id)
def validate_non_persistent_token(self, token_id): try: (user_id, methods, audit_ids, domain_id, project_id, trust_id, federated_info, created_at, expires_at) = (self.token_formatter.validate_token(token_id)) except exception.ValidationError as e: raise exception.TokenNotFound(e) token_dict = None trust_ref = None if federated_info: # NOTE(lbragstad): We need to rebuild information about the # federated token as well as the federated token roles. This is # because when we validate a non-persistent token, we don't have a # token reference to pull the federated token information out of. # As a result, we have to extract it from the token itself and # rebuild the federated context. These private methods currently # live in the keystone.token.providers.fernet.Provider() class. token_dict = self._rebuild_federated_info(federated_info, user_id) if project_id or domain_id: self._rebuild_federated_token_roles(token_dict, federated_info, user_id, project_id, domain_id) if trust_id: trust_ref = self.trust_api.get_trust(trust_id) return self.v3_token_data_helper.get_token_data(user_id, method_names=methods, domain_id=domain_id, project_id=project_id, issued_at=created_at, expires=expires_at, trust=trust_ref, token=token_dict, audit_info=audit_ids)
def get_token(self, token_id): token = self.db.get('token-%s' % token_id) if (token and (token['expires'] is None or token['expires'] > datetime.datetime.utcnow())): return token else: raise exception.TokenNotFound(token_id=token_id)
def validate_v3_token(self, token_id): try: token_ref = self._verify_token(token_id) token_data = self._validate_v3_token_ref(token_ref) return token_data except (exception.ValidationError, exception.UserNotFound): raise exception.TokenNotFound(token_id)
def _is_valid_token(self, token): # Verify the token has not expired. current_time = timeutils.normalize_time(timeutils.utcnow()) try: # Get the data we need from the correct location (V2 and V3 tokens # differ in structure, Try V3 first, fall back to V2 second) token_data = token.get('token', token.get('access')) expires_at = token_data.get('expires_at', token_data.get('expires')) if not expires_at: expires_at = token_data['token']['expires'] expiry = timeutils.normalize_time( timeutils.parse_isotime(expires_at)) if current_time < expiry: # Token is has not expired and has not been revoked. return None except Exception: LOG.exception( _('Unexpected error or malformed token determining ' 'token expiry: %s') % token) # FIXME(morganfainberg): This error message needs to be updated to # reflect the token couldn't be found, but this change needs to wait # until Icehouse due to string freeze in Havana. This should be: # "Failed to find valid token" or something similar. raise exception.TokenNotFound(_('Failed to validate token'))
def _validate_v2_token_ref(self, token_ref): try: self._assert_default_domain(token_ref) # FIXME(gyee): performance or correctness? Should we return the # cached token or reconstruct it? Obviously if we are going with # the cached token, any role, project, or domain name changes # will not be reflected. One may argue that with PKI tokens, # we are essentially doing cached token validation anyway. # Lets go with the cached token strategy. Since token # management layer is now pluggable, one can always provide # their own implementation to suit their needs. token_data = token_ref.get('token_data') if (not token_data or self.get_token_version(token_data) != token.provider.V2): # token is created by old v2 logic metadata_ref = token_ref['metadata'] roles_ref = [] for role_id in metadata_ref.get('roles', []): roles_ref.append(self.assignment_api.get_role(role_id)) # Get a service catalog if possible # This is needed for on-behalf-of requests catalog_ref = None if token_ref.get('tenant'): catalog_ref = self.catalog_api.get_catalog( token_ref['user']['id'], token_ref['tenant']['id'], metadata_ref) token_data = self.v2_token_data_helper.format_token( token_ref, roles_ref, catalog_ref) return token_data except exception.ValidationError as e: LOG.exception(_('Failed to validate token')) raise exception.TokenNotFound(e)
def validate_v2_token(self, token_ref): try: self._assert_is_not_federation_token(token_ref) self._assert_default_domain(token_ref) # FIXME(gyee): performance or correctness? Should we return the # cached token or reconstruct it? Obviously if we are going with # the cached token, any role, project, or domain name changes # will not be reflected. One may argue that with PKI tokens, # we are essentially doing cached token validation anyway. # Lets go with the cached token strategy. Since token # management layer is now pluggable, one can always provide # their own implementation to suit their needs. token_data = token_ref.get('token_data') if (self.get_token_version(token_data) != token.provider.V2): # Validate the V3 token as V2 token_data = self.v2_token_data_helper.v3_to_v2_token( token_data) trust_id = token_data['access'].get('trust', {}).get('id') if trust_id: msg = ('Unable to validate trust-scoped tokens using version ' 'v2.0 API.') raise exception.Unauthorized(msg) return token_data except exception.ValidationError: LOG.exception(_LE('Failed to validate token')) token_id = token_ref['token_data']['access']['token']['id'] raise exception.TokenNotFound(token_id=token_id)
def validate_v3_token(self, token): """Validate a V3 formatted token. :param token: a string describing the token to validate :returns: the token data :raises keystone.exception.TokenNotFound: if token format version isn't supported """ try: (user_id, methods, audit_ids, domain_id, project_id, trust_id, federated_info, created_at, expires_at) = ( self.token_formatter.validate_token(token)) except exception.ValidationError as e: raise exception.TokenNotFound(e) token_dict = None trust_ref = None if federated_info: token_dict = self._rebuild_federated_info(federated_info, user_id) if trust_id: trust_ref = self.trust_api.get_trust(trust_id) return self.v3_token_data_helper.get_token_data( user_id, method_names=methods, domain_id=domain_id, project_id=project_id, issued_at=created_at, expires=expires_at, trust=trust_ref, token=token_dict, audit_info=audit_ids)
def check_revocation_v3(self, token): try: token_data = token['token'] except KeyError: raise exception.TokenNotFound(_('Failed to validate token')) token_values = self.revoke_api.model.build_token_values(token_data) self.revoke_api.check_token(token_values)
def delete_token(self, token_id): session = sql.get_session() with session.begin(): token_ref = session.query(TokenModel).get(token_id) if not token_ref or not token_ref.valid: raise exception.TokenNotFound(token_id=token_id) token_ref.valid = False
def _validate_token(self, token_id): if not token_id: raise exception.TokenNotFound(_('No token in the request')) if not self._needs_persistence: return self.driver.validate_v3_token(token_id) token_ref = self._persistence.get_token(token_id) version = self.driver.get_token_version(token_ref) if version == self.V3: try: return self.driver.validate_v3_token(token_ref) except exception.Unauthorized as e: LOG.debug('Unable to validate token: %s', e) raise exception.TokenNotFound(token_id=token_id) elif version == self.V2: return self.driver.validate_v2_token(token_ref) raise exception.UnsupportedTokenVersionException()
def get_token(self, token_id): session = self.get_session() token_ref = session.query(TokenModel).filter_by(id=token_id).first() now = datetime.datetime.utcnow() if token_ref and (not token_ref.expires or now < token_ref.expires): return token_ref.to_dict() else: raise exception.TokenNotFound(token_id=token_id)
def get_token(self, token_id): ptk = self._prefix_token_id(token_id) try: token_ref = self._get_key(ptk) except exception.NotFound: raise exception.TokenNotFound(token_id=token_id) return token_ref
def get(self, key): """Retrieves the value for a key or None.""" self.check_key(key) obj = self.cache.get(key) now = time.mktime(datetime.datetime.utcnow().timetuple()) if obj and (obj[1] == 0 or obj[1] > now): return obj[0] else: raise exception.TokenNotFound(token_id=key)
def check_revocation_v2(self, token): try: token_data = token['access'] except KeyError: raise exception.TokenNotFound(_('Failed to validate token')) token_values = self.revoke_api.model.build_token_values_v2( token_data, CONF.identity.default_domain_id) self.revoke_api.check_token(token_values)