def _get_project_id_from_auth(self, context, auth): """Extract tenant information from auth dict. Returns a valid tenant_id if it exists, or None if not specified. """ tenant_id = auth.get('tenantId', None) if tenant_id and len(tenant_id) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='tenantId', size=CONF.max_param_size) tenant_name = auth.get('tenantName', None) if tenant_name and len(tenant_name) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='tenantName', size=CONF.max_param_size) if tenant_name: try: tenant_ref = self.identity_api.get_project_by_name( context=context, tenant_name=tenant_name, domain_id=DEFAULT_DOMAIN_ID) tenant_id = tenant_ref['id'] except exception.ProjectNotFound as e: raise exception.Unauthorized(e) return tenant_id
def _get_project_id_from_auth(self, auth): """Extract and normalize project information from auth dict. :param auth: Dictionary representing the authentication request. :returns: A string representing the project in the authentication request. If project scope isn't present in the request None is returned. """ project_id = auth.get('tenantId') project_name = auth.get('tenantName') if project_id: if len(project_id) > CONF.max_param_size: raise exception.ValidationSizeError( attribute='tenantId', size=CONF.max_param_size ) elif project_name: if len(project_name) > CONF.max_param_size: raise exception.ValidationSizeError( attribute='tenantName', size=CONF.max_param_size ) if (CONF.resource.project_name_url_safe == 'strict' and utils.is_not_url_safe(project_name)): msg = _('Tenant name cannot contain reserved characters.') raise exception.Unauthorized(message=msg) try: project_id = self.resource_api.get_project_by_name( project_name, CONF.identity.default_domain_id )['id'] except exception.ProjectNotFound as e: raise exception.Unauthorized(e) else: project_id = None return project_id
def _get_project_id_from_auth(self, auth): """Extract tenant information from auth dict. Returns a valid tenant_id if it exists, or None if not specified. """ tenant_id = auth.get('tenantId') if tenant_id and len(tenant_id) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='tenantId', size=CONF.max_param_size) tenant_name = auth.get('tenantName') if tenant_name and len(tenant_name) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='tenantName', size=CONF.max_param_size) if tenant_name: if (CONF.resource.project_name_url_safe == 'strict' and utils.is_not_url_safe(tenant_name)): msg = _('Tenant name cannot contain reserved characters.') raise exception.Unauthorized(message=msg) try: tenant_ref = self.resource_api.get_project_by_name( tenant_name, CONF.identity.default_domain_id) tenant_id = tenant_ref['id'] except exception.ProjectNotFound as e: raise exception.Unauthorized(e) return tenant_id
def _authenticate_local(self, context, auth): """Try to authenticate against the identity backend. Returns auth_token_data, (user_ref, tenant_ref, metadata_ref) """ if 'passwordCredentials' not in auth: raise exception.ValidationError( attribute='passwordCredentials', target='auth') if "password" not in auth['passwordCredentials']: raise exception.ValidationError( attribute='password', target='passwordCredentials') password = auth['passwordCredentials']['password'] if password and len(password) > CONF.identity.max_password_length: raise exception.ValidationSizeError( attribute='password', size=CONF.identity.max_password_length) if (not auth['passwordCredentials'].get("userId") and not auth['passwordCredentials'].get("username")): raise exception.ValidationError( attribute='username or userId', target='passwordCredentials') user_id = auth['passwordCredentials'].get('userId') if user_id and len(user_id) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='userId', size=CONF.max_param_size) username = auth['passwordCredentials'].get('username', '') if username: if len(username) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='username', size=CONF.max_param_size) try: user_ref = self.identity_api.get_user_by_name( username, CONF.identity.default_domain_id) user_id = user_ref['id'] except exception.UserNotFound as e: raise exception.Unauthorized(e) try: user_ref = self.identity_api.authenticate( context, user_id=user_id, password=password) except AssertionError as e: raise exception.Unauthorized(e.args[0]) metadata_ref = {} tenant_id = self._get_project_id_from_auth(auth) tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref( user_id, tenant_id) expiry = provider.default_expire_time() bind = None audit_id = None return (user_ref, tenant_ref, metadata_ref, expiry, bind, audit_id)
def _authenticate_local(self, context, auth): """Try to authenticate against the identity backend. Returns auth_token_data, (user_ref, tenant_ref, metadata_ref) """ if 'passwordCredentials' not in auth: raise exception.ValidationError( attribute='passwordCredentials', target='auth') if "password" not in auth['passwordCredentials']: raise exception.ValidationError( attribute='password', target='passwordCredentials') password = auth['passwordCredentials']['password'] max_pw_size = utils.MAX_PASSWORD_LENGTH if password and len(password) > max_pw_size: raise exception.ValidationSizeError(attribute='password', size=max_pw_size) if ("userId" not in auth['passwordCredentials'] and "username" not in auth['passwordCredentials']): raise exception.ValidationError( attribute='username or userId', target='passwordCredentials') user_id = auth['passwordCredentials'].get('userId', None) if user_id and len(user_id) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='userId', size=CONF.max_param_size) username = auth['passwordCredentials'].get('username', '') if len(username) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='username', size=CONF.max_param_size) if username: try: user_ref = self.identity_api.get_user_by_name( username, DEFAULT_DOMAIN_ID) user_id = user_ref['id'] except exception.UserNotFound as e: raise exception.Unauthorized(e) try: user_ref = self.identity_api.authenticate( user_id=user_id, password=password) except AssertionError as e: raise exception.Unauthorized(e) metadata_ref = {} tenant_id = self._get_project_id_from_auth(auth) tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref( user_id, tenant_id) expiry = core.default_expire_time() return (user_ref, tenant_ref, metadata_ref, expiry, None)
def authenticate(self, request, auth): """Try to authenticate against the identity backend. :param request: A request object. :param auth: Dictionary representing the authentication request. :returns: A tuple containing the user reference, project identifier, token expiration, bind information, and original audit information. """ if 'password' not in auth['passwordCredentials']: raise exception.ValidationError( attribute='password', target='passwordCredentials') password = auth['passwordCredentials']['password'] if password and len(password) > CONF.identity.max_password_length: raise exception.ValidationSizeError( attribute='password', size=CONF.identity.max_password_length) if (not auth['passwordCredentials'].get('userId') and not auth['passwordCredentials'].get('username')): raise exception.ValidationError( attribute='username or userId', target='passwordCredentials') user_id = auth['passwordCredentials'].get('userId') if user_id and len(user_id) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='userId', size=CONF.max_param_size) username = auth['passwordCredentials'].get('username', '') if username: if len(username) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='username', size=CONF.max_param_size) try: user_ref = self.identity_api.get_user_by_name( username, CONF.identity.default_domain_id) user_id = user_ref['id'] except exception.UserNotFound as e: raise exception.Unauthorized(e) try: user_ref = self.identity_api.authenticate( request, user_id=user_id, password=password) except AssertionError as e: raise exception.Unauthorized(e.args[0]) project_id = self._get_project_id_from_auth(auth) expiry = common.default_expire_time() bind = None audit_id = None return (user_ref, project_id, expiry, bind, audit_id)
def _authenticate_ak(self, context, auth): if 'accessKeyCredentials' not in auth: raise exception.ValidationError(attribute='accessKeyCredentials', target='auth') if "accessKey" not in auth['accessKeyCredentials']: raise exception.ValidationError(attribute='password', target='passwordCredentials') access_key = auth['accessKeyCredentials']['accessKey'] #TODO: ATHEENDRA #if access_key and len(access_key) > CONF.identity.max_password_length: # raise exception.ValidationSizeError( # attribute='accessKey', size=CONF.identity.max_password_length) if ("userId" not in auth['accessKeyCredentials'] and "username" not in auth['accessKeyCredentials']): raise exception.ValidationError(attribute='username or userId', target='accessKeyCredentials') user_id = auth['accessKeyCredentials'].get('userId') if user_id and len(user_id) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='userId', size=CONF.max_param_size) username = auth['accessKeyCredentials'].get('username', '') if len(username) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='username', size=CONF.max_param_size) if username: try: user_ref = self.identity_api.get_user_by_name( username, CONF.identity.default_domain_id) user_id = user_ref['id'] except exception.UserNotFound as e: raise exception.Unauthorized(e) try: user_ref = self.identity_api.authenticate_ak(context, user_id=user_id, access_key=access_key) except AssertionError as e: raise exception.Unauthorized(e.args[0]) metadata_ref = {} tenant_id = self._get_project_id_from_auth(auth) tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref( user_id, tenant_id) expiry = core.default_expire_time() return (user_ref, tenant_ref, metadata_ref, expiry, None)
def _authenticate_token(self, context, auth): """Try to authenticate using an already existing token. Returns auth_token_data, (user_ref, tenant_ref, metadata_ref) """ if 'token' not in auth: raise exception.ValidationError(attribute='token', target='auth') if "id" not in auth['token']: raise exception.ValidationError(attribute="id", target="token") old_token = auth['token']['id'] if len(old_token) > CONF.max_token_size: raise exception.ValidationSizeError(attribute='token', size=CONF.max_token_size) try: old_token_ref = self.token_api.get_token(old_token) except exception.NotFound as e: raise exception.Unauthorized(e) wsgi.validate_token_bind(context, old_token_ref) # A trust token cannot be used to get another token if 'trust' in old_token_ref: raise exception.Forbidden() if 'trust_id' in old_token_ref['metadata']: raise exception.Forbidden() user_ref = old_token_ref['user'] user_id = user_ref['id'] tenant_id = self._get_project_id_from_auth(auth) if not CONF.trust.enabled and 'trust_id' in auth: raise exception.Forbidden('Trusts are disabled.') elif CONF.trust.enabled and 'trust_id' in auth: trust_ref = self.trust_api.get_trust(auth['trust_id']) if trust_ref is None: raise exception.Forbidden() if user_id != trust_ref['trustee_user_id']: raise exception.Forbidden() if (trust_ref['project_id'] and tenant_id != trust_ref['project_id']): raise exception.Forbidden() if ('expires' in trust_ref) and (trust_ref['expires']): expiry = trust_ref['expires'] if expiry < timeutils.parse_isotime(timeutils.isotime()): raise exception.Forbidden()() user_id = trust_ref['trustor_user_id'] trustor_user_ref = self.identity_api.get_user( trust_ref['trustor_user_id']) if not trustor_user_ref['enabled']: raise exception.Forbidden()() trustee_user_ref = self.identity_api.get_user( trust_ref['trustee_user_id']) if not trustee_user_ref['enabled']: raise exception.Forbidden()() if trust_ref['impersonation'] is True: current_user_ref = trustor_user_ref else: current_user_ref = trustee_user_ref else: current_user_ref = self.identity_api.get_user(user_id) metadata_ref = {} tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref( user_id, tenant_id) expiry = old_token_ref['expires'] if CONF.trust.enabled and 'trust_id' in auth: trust_id = auth['trust_id'] trust_roles = [] for role in trust_ref['roles']: if 'roles' not in metadata_ref: raise exception.Forbidden()() if role['id'] in metadata_ref['roles']: trust_roles.append(role['id']) else: raise exception.Forbidden() if 'expiry' in trust_ref and trust_ref['expiry']: trust_expiry = timeutils.parse_isotime(trust_ref['expiry']) if trust_expiry < expiry: expiry = trust_expiry metadata_ref['roles'] = trust_roles metadata_ref['trustee_user_id'] = trust_ref['trustee_user_id'] metadata_ref['trust_id'] = trust_id bind = old_token_ref.get('bind') return (current_user_ref, tenant_ref, metadata_ref, expiry, bind)
def _authenticate_local(self, context, auth): """Try to authenticate against the identity backend. Returns auth_token_data, (user_ref, tenant_ref, metadata_ref) """ if 'passwordCredentials' not in auth: raise exception.ValidationError(attribute='passwordCredentials', target='auth') if "password" not in auth['passwordCredentials']: raise exception.ValidationError(attribute='password', target='passwordCredentials') password = auth['passwordCredentials']['password'] max_pw_size = utils.MAX_PASSWORD_LENGTH if password and len(password) > max_pw_size: raise exception.ValidationSizeError(attribute='password', size=max_pw_size) if ("userId" not in auth['passwordCredentials'] and "username" not in auth['passwordCredentials']): raise exception.ValidationError(attribute='username or userId', target='passwordCredentials') user_id = auth['passwordCredentials'].get('userId', None) if user_id and len(user_id) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='userId', size=CONF.max_param_size) username = auth['passwordCredentials'].get('username', '') if len(username) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='username', size=CONF.max_param_size) if username: try: user_ref = self.identity_api.get_user_by_name( context=context, user_name=username, domain_id=DEFAULT_DOMAIN_ID) user_id = user_ref['id'] except exception.UserNotFound as e: raise exception.Unauthorized(e) tenant_id = self._get_project_id_from_auth(context, auth) try: auth_info = self.identity_api.authenticate(context=context, user_id=user_id, password=password, tenant_id=tenant_id) except AssertionError as e: raise exception.Unauthorized(e) (user_ref, tenant_ref, metadata_ref) = auth_info # By now we will have authorized and if a tenant/project was # specified, we will have obtained its metadata. In this case # we just need to add in any group roles. # # TODO (henry-nash) If no tenant was specified, instead check # for a domain and find any related user/group roles self._append_roles( metadata_ref, self._get_group_metadata_ref(context, user_id, tenant_id)) expiry = core.default_expire_time() return (user_ref, tenant_ref, metadata_ref, expiry)
def _authenticate_token(self, context, auth): """Try to authenticate using an already existing token. Returns auth_token_data, (user_ref, tenant_ref, metadata_ref) """ if 'token' not in auth: raise exception.ValidationError(attribute='token', target='auth') if "id" not in auth['token']: raise exception.ValidationError(attribute="id", target="token") old_token = auth['token']['id'] if len(old_token) > CONF.max_token_size: raise exception.ValidationSizeError(attribute='token', size=CONF.max_token_size) try: old_token_ref = self.token_api.get_token(context=context, token_id=old_token) except exception.NotFound as e: raise exception.Unauthorized(e) #A trust token cannot be used to get another token if 'trust' in old_token_ref: raise exception.Forbidden() if 'trust_id' in old_token_ref['metadata']: raise exception.Forbidden() user_ref = old_token_ref['user'] user_id = user_ref['id'] if not CONF.trust.enabled and 'trust_id' in auth: raise exception.Forbidden('Trusts are disabled.') elif CONF.trust.enabled and 'trust_id' in auth: trust_ref = self.trust_api.get_trust(context, auth['trust_id']) if trust_ref is None: raise exception.Forbidden() if user_id != trust_ref['trustee_user_id']: raise exception.Forbidden() if ('expires' in trust_ref) and (trust_ref['expires']): expiry = trust_ref['expires'] if expiry < timeutils.parse_isotime(timeutils.isotime()): raise exception.Forbidden()() user_id = trust_ref['trustor_user_id'] trustor_user_ref = (self.identity_api.get_user( context=context, user_id=trust_ref['trustor_user_id'])) if not trustor_user_ref['enabled']: raise exception.Forbidden()() trustee_user_ref = self.identity_api.get_user( context, trust_ref['trustee_user_id']) if not trustee_user_ref['enabled']: raise exception.Forbidden()() if trust_ref['impersonation'] == 'True': current_user_ref = trustor_user_ref else: current_user_ref = trustee_user_ref else: current_user_ref = self.identity_api.get_user(context=context, user_id=user_id) tenant_id = self._get_project_id_from_auth(context, auth) tenant_ref = self._get_project_ref(context, user_id, tenant_id) metadata_ref = self._get_metadata_ref(context, user_id, tenant_id) # TODO (henry-nash) If no tenant was specified, instead check # for a domain and find any related user/group roles self._append_roles( metadata_ref, self._get_group_metadata_ref(context, user_id, tenant_id)) expiry = old_token_ref['expires'] if CONF.trust.enabled and 'trust_id' in auth: trust_id = auth['trust_id'] trust_roles = [] for role in trust_ref['roles']: if not 'roles' in metadata_ref: raise exception.Forbidden()() if role['id'] in metadata_ref['roles']: trust_roles.append(role['id']) else: raise exception.Forbidden() if 'expiry' in trust_ref and trust_ref['expiry']: trust_expiry = timeutils.parse_isotime(trust_ref['expiry']) if trust_expiry < expiry: expiry = trust_expiry metadata_ref['roles'] = trust_roles metadata_ref['trustee_user_id'] = trust_ref['trustee_user_id'] metadata_ref['trust_id'] = trust_id return (current_user_ref, tenant_ref, metadata_ref, expiry)
def _authenticate_token(self, context, auth): """Try to authenticate using an already existing token. Returns auth_token_data, (user_ref, tenant_ref, metadata_ref) """ if 'token' not in auth: raise exception.ValidationError(attribute='token', target='auth') if "id" not in auth['token']: raise exception.ValidationError(attribute="id", target="token") old_token = auth['token']['id'] if len(old_token) > CONF.max_token_size: raise exception.ValidationSizeError(attribute='token', size=CONF.max_token_size) try: token_model_ref = token_model.KeystoneToken( token_id=old_token, token_data=self.token_provider_api.validate_v2_token( old_token)) except exception.NotFound as e: raise exception.Unauthorized(e) wsgi.validate_token_bind(context, token_model_ref) self._restrict_scope(token_model_ref) user_id = token_model_ref.user_id tenant_id = self._get_project_id_from_auth(auth) if not CONF.trust.enabled and 'trust_id' in auth: raise exception.Forbidden('Trusts are disabled.') elif CONF.trust.enabled and 'trust_id' in auth: try: trust_ref = self.trust_api.get_trust(auth['trust_id']) except exception.TrustNotFound: raise exception.Forbidden() if user_id != trust_ref['trustee_user_id']: raise exception.Forbidden() if (trust_ref['project_id'] and tenant_id != trust_ref['project_id']): raise exception.Forbidden() if ('expires' in trust_ref) and (trust_ref['expires']): expiry = trust_ref['expires'] if expiry < timeutils.parse_isotime(utils.isotime()): raise exception.Forbidden() user_id = trust_ref['trustor_user_id'] trustor_user_ref = self.identity_api.get_user( trust_ref['trustor_user_id']) if not trustor_user_ref['enabled']: raise exception.Forbidden() trustee_user_ref = self.identity_api.get_user( trust_ref['trustee_user_id']) if not trustee_user_ref['enabled']: raise exception.Forbidden() if trust_ref['impersonation'] is True: current_user_ref = trustor_user_ref else: current_user_ref = trustee_user_ref else: current_user_ref = self.identity_api.get_user(user_id) metadata_ref = {} tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref( user_id, tenant_id) expiry = token_model_ref.expires if CONF.trust.enabled and 'trust_id' in auth: trust_id = auth['trust_id'] trust_roles = [] for role in trust_ref['roles']: if 'roles' not in metadata_ref: raise exception.Forbidden() if role['id'] in metadata_ref['roles']: trust_roles.append(role['id']) else: raise exception.Forbidden() if 'expiry' in trust_ref and trust_ref['expiry']: trust_expiry = timeutils.parse_isotime(trust_ref['expiry']) if trust_expiry < expiry: expiry = trust_expiry metadata_ref['roles'] = trust_roles metadata_ref['trustee_user_id'] = trust_ref['trustee_user_id'] metadata_ref['trust_id'] = trust_id bind = token_model_ref.bind audit_id = token_model_ref.audit_chain_id return (current_user_ref, tenant_ref, metadata_ref, expiry, bind, audit_id)
def authenticate(self, context, auth=None): """Authenticate credentials and return a token. Accept auth as a dict that looks like:: { "auth":{ "passwordCredentials":{ "username":"******", "password":"******" }, "tenantName":"customer-x" } } In this case, tenant is optional, if not provided the token will be considered "unscoped" and can later be used to get a scoped token. Alternatively, this call accepts auth with only a token and tenant that will return a token that is scoped to that tenant. """ token_id = uuid.uuid4().hex if 'passwordCredentials' in auth: username = auth['passwordCredentials'].get('username', '') if len(username) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='username', size=CONF.max_param_size) password = auth['passwordCredentials'].get('password', '') max_pw_size = utils.MAX_PASSWORD_LENGTH if len(password) > max_pw_size: raise exception.ValidationSizeError(attribute='password', size=max_pw_size) tenant_name = auth.get('tenantName', None) if tenant_name and len(tenant_name) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='tenantName', size=CONF.max_param_size) user_id = auth['passwordCredentials'].get('userId', None) if user_id and len(user_id) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='userId', size=CONF.max_param_size) if username: user_ref = self.identity_api.get_user_by_name( context=context, user_name=username) if user_ref: user_id = user_ref['id'] # more compat tenant_id = auth.get('tenantId', None) if tenant_id and len(tenant_id) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='tenantId', size=CONF.max_param_size) if tenant_name: tenant_ref = self.identity_api.get_tenant_by_name( context=context, tenant_name=tenant_name) if tenant_ref: tenant_id = tenant_ref['id'] try: auth_info = self.identity_api.authenticate(context=context, user_id=user_id, password=password, tenant_id=tenant_id) (user_ref, tenant_ref, metadata_ref) = auth_info # If the user is disabled don't allow them to authenticate if not user_ref.get('enabled', True): LOG.warning('User %s is disabled' % user_id) raise exception.Unauthorized() # If the tenant is disabled don't allow them to authenticate if tenant_ref and not tenant_ref.get('enabled', True): LOG.warning('Tenant %s is disabled' % tenant_id) raise exception.Unauthorized() except AssertionError as e: raise exception.Unauthorized(e.message) token_ref = self.token_api.create_token( context, token_id, dict(id=token_id, user=user_ref, tenant=tenant_ref, metadata=metadata_ref)) if tenant_ref: catalog_ref = self.catalog_api.get_catalog( context=context, user_id=user_ref['id'], tenant_id=tenant_ref['id'], metadata=metadata_ref) else: catalog_ref = {} elif 'token' in auth: token = auth['token'].get('id', None) if len(token) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='token', size=CONF.max_param_size) tenant_name = auth.get('tenantName') if tenant_name and len(tenant_name) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='tenantName', size=CONF.max_param_size) # more compat if tenant_name: tenant_ref = self.identity_api.get_tenant_by_name( context=context, tenant_name=tenant_name) tenant_id = tenant_ref['id'] else: tenant_id = auth.get('tenantId', None) try: old_token_ref = self.token_api.get_token(context=context, token_id=token) except exception.NotFound: raise exception.Unauthorized() user_ref = old_token_ref['user'] # If the user is disabled don't allow them to authenticate current_user_ref = self.identity_api.get_user( context=context, user_id=user_ref['id']) if not current_user_ref.get('enabled', True): LOG.warning('User %s is disabled' % user_ref['id']) raise exception.Unauthorized() tenants = self.identity_api.get_tenants_for_user( context, user_ref['id']) if tenant_id: assert tenant_id in tenants tenant_ref = self.identity_api.get_tenant(context=context, tenant_id=tenant_id) # If the tenant is disabled don't allow them to authenticate if tenant_ref and not tenant_ref.get('enabled', True): LOG.warning('Tenant %s is disabled' % tenant_id) raise exception.Unauthorized() if tenant_ref: metadata_ref = self.identity_api.get_metadata( context=context, user_id=user_ref['id'], tenant_id=tenant_ref['id']) catalog_ref = self.catalog_api.get_catalog( context=context, user_id=user_ref['id'], tenant_id=tenant_ref['id'], metadata=metadata_ref) else: metadata_ref = {} catalog_ref = {} token_ref = self.token_api.create_token( context, token_id, dict(id=token_id, user=user_ref, tenant=tenant_ref, metadata=metadata_ref, expires=old_token_ref['expires'])) # TODO(termie): optimize this call at some point and put it into the # the return for metadata # fill out the roles in the metadata roles_ref = [] for role_id in metadata_ref.get('roles', []): roles_ref.append(self.identity_api.get_role(context, role_id)) logging.debug('TOKEN_REF %s', token_ref) return self._format_authenticate(token_ref, roles_ref, catalog_ref)
def _authenticate_local(self, context, auth): """Try to authenticate against the identity backend. { "auth":{ "accessKeyCredentials":{ "username":"******", "accesskey":"myaccesskey", "tenantName":"customer-x" } } } Returns auth_token_data, (user_ref, tenant_ref, metadata_ref) """ if 'passwordCredentials' not in auth: raise exception.ValidationError(attribute='passwordCredentials', target='auth') if "password" not in auth['passwordCredentials']: raise exception.ValidationError(attribute='password', target='passwordCredentials') password = auth['passwordCredentials']['password'] if password and len(password) > CONF.identity.max_password_length: raise exception.ValidationSizeError( attribute='password', size=CONF.identity.max_password_length) if ("userId" not in auth['passwordCredentials'] and "username" not in auth['passwordCredentials']): raise exception.ValidationError(attribute='username or userId', target='passwordCredentials') user_id = auth['passwordCredentials'].get('userId') if user_id and len(user_id) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='userId', size=CONF.max_param_size) username = auth['passwordCredentials'].get('username', '') if len(username) > CONF.max_param_size: raise exception.ValidationSizeError(attribute='username', size=CONF.max_param_size) if username: try: user_ref = self.identity_api.get_user_by_name( username, CONF.identity.default_domain_id) user_id = user_ref['id'] except exception.UserNotFound as e: raise exception.Unauthorized(e) try: user_ref = self.identity_api.authenticate(context, user_id=user_id, password=password) except AssertionError as e: raise exception.Unauthorized(e.args[0]) metadata_ref = {} tenant_id = self._get_project_id_from_auth(auth) tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref( user_id, tenant_id) expiry = core.default_expire_time() return (user_ref, tenant_ref, metadata_ref, expiry, None)
def _authenticate_token(self, request, auth): """Try to authenticate using an already existing token. Returns auth_token_data, (user_ref, tenant_ref, metadata_ref) """ if 'token' not in auth: raise exception.ValidationError(attribute='token', target='auth') if 'id' not in auth['token']: raise exception.ValidationError(attribute='id', target='token') old_token = auth['token']['id'] if len(old_token) > CONF.max_token_size: raise exception.ValidationSizeError(attribute='token', size=CONF.max_token_size) try: v3_token_data = self.token_provider_api.validate_token(old_token) # NOTE(lbragstad): Even though we are not using the v2.0 token # reference after we translate it in v3_to_v2_token(), we still # need to perform that check. We have to do this because # v3_to_v2_token will ensure we don't use specific tokens only # attainable via v3 to get new tokens on v2.0. For example, an # exception would be raised if we passed a federated token to # v3_to_v2_token, because federated tokens aren't supported by # v2.0 (the same applies to OAuth tokens, domain-scoped tokens, # etc..). v2_helper = common.V2TokenDataHelper() v2_helper.v3_to_v2_token(v3_token_data, old_token) token_model_ref = token_model.KeystoneToken( token_id=old_token, token_data=v3_token_data) except exception.NotFound as e: raise exception.Unauthorized(e) wsgi.validate_token_bind(request.context_dict, token_model_ref) self._restrict_scope(token_model_ref) user_id = token_model_ref.user_id tenant_id = self._get_project_id_from_auth(auth) if not CONF.trust.enabled and 'trust_id' in auth: raise exception.Forbidden('Trusts are disabled.') elif CONF.trust.enabled and 'trust_id' in auth: try: trust_ref = self.trust_api.get_trust(auth['trust_id']) except exception.TrustNotFound: raise exception.Forbidden() if user_id != trust_ref['trustee_user_id']: raise exception.Forbidden() if (trust_ref['project_id'] and tenant_id != trust_ref['project_id']): raise exception.Forbidden() if ('expires' in trust_ref) and (trust_ref['expires']): expiry = trust_ref['expires'] if expiry < timeutils.parse_isotime(utils.isotime()): raise exception.Forbidden() user_id = trust_ref['trustor_user_id'] trustor_user_ref = self.identity_api.get_user( trust_ref['trustor_user_id']) if not trustor_user_ref['enabled']: raise exception.Forbidden() trustee_user_ref = self.identity_api.get_user( trust_ref['trustee_user_id']) if not trustee_user_ref['enabled']: raise exception.Forbidden() if trust_ref['impersonation'] is True: current_user_ref = trustor_user_ref else: current_user_ref = trustee_user_ref else: current_user_ref = self.identity_api.get_user(user_id) metadata_ref = {} tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref( user_id, tenant_id) expiry = token_model_ref.expires if CONF.trust.enabled and 'trust_id' in auth: trust_id = auth['trust_id'] trust_roles = [] for role in trust_ref['roles']: if 'roles' not in metadata_ref: raise exception.Forbidden() if role['id'] in metadata_ref['roles']: trust_roles.append(role['id']) else: raise exception.Forbidden() if 'expiry' in trust_ref and trust_ref['expiry']: trust_expiry = timeutils.parse_isotime(trust_ref['expiry']) if trust_expiry < expiry: expiry = trust_expiry metadata_ref['roles'] = trust_roles metadata_ref['trustee_user_id'] = trust_ref['trustee_user_id'] metadata_ref['trust_id'] = trust_id bind = token_model_ref.bind audit_id = token_model_ref.audit_chain_id return (current_user_ref, tenant_ref, metadata_ref, expiry, bind, audit_id)
def authenticate(self, request, auth): """Try to authenticate using an already existing token. :param request: A request object. :param auth: Dictionary representing the authentication request. :returns: A tuple containing the user reference, project identifier, token expiration, bind information, and original audit information. """ if 'token' not in auth: raise exception.ValidationError( attribute='token', target='auth') if 'id' not in auth['token']: raise exception.ValidationError( attribute='id', target='token') old_token = auth['token']['id'] if len(old_token) > CONF.max_token_size: raise exception.ValidationSizeError(attribute='token', size=CONF.max_token_size) try: v3_token_data = self.token_provider_api.validate_token( old_token ) # NOTE(lbragstad): Even though we are not using the v2.0 token # reference after we translate it in v3_to_v2_token(), we still # need to perform that check. We have to do this because # v3_to_v2_token will ensure we don't use specific tokens only # attainable via v3 to get new tokens on v2.0. For example, an # exception would be raised if we passed a federated token to # v3_to_v2_token, because federated tokens aren't supported by # v2.0 (the same applies to OAuth tokens, domain-scoped tokens, # etc..). v2_helper = common.V2TokenDataHelper() v2_helper.v3_to_v2_token(v3_token_data, old_token) token_model_ref = token_model.KeystoneToken( token_id=old_token, token_data=v3_token_data ) except exception.NotFound as e: raise exception.Unauthorized(e) wsgi.validate_token_bind(request.context_dict, token_model_ref) self._restrict_scope(token_model_ref) user_id = token_model_ref.user_id project_id = self._get_project_id_from_auth(auth) if not CONF.trust.enabled and 'trust_id' in auth: raise exception.Forbidden('Trusts are disabled.') elif CONF.trust.enabled and 'trust_id' in auth: try: trust_ref = self.trust_api.get_trust(auth['trust_id']) except exception.TrustNotFound: raise exception.Forbidden() # If a trust is being used to obtain access to another project and # the other project doesn't match the project in the trust, we need # to bail because trusts are only good up to a single project. if (trust_ref['project_id'] and project_id != trust_ref['project_id']): raise exception.Forbidden() expiry = token_model_ref.expires user_ref = self.identity_api.get_user(user_id) bind = token_model_ref.bind original_audit_id = token_model_ref.audit_chain_id return (user_ref, project_id, expiry, bind, original_audit_id)