Exemple #1
0
def _build_policy_check_credentials(self, action, context, kwargs):
    kwargs_str = ', '.join(['%s=%s' % (k, kwargs[k]) for k in kwargs])
    kwargs_str = strutils.mask_password(kwargs_str)

    LOG.debug('RBAC: Authorizing %(action)s(%(kwargs)s)', {
        'action': action,
        'kwargs': kwargs_str
    })

    # see if auth context has already been created. If so use it.
    if ('environment' in context
            and authorization.AUTH_CONTEXT_ENV in context['environment']):
        LOG.debug('RBAC: using auth context from the request environment')
        return context['environment'].get(authorization.AUTH_CONTEXT_ENV)

    # There is no current auth context, build it from the incoming token.
    # TODO(morganfainberg): Collapse this logic with AuthContextMiddleware
    # in a sane manner as this just mirrors the logic in AuthContextMiddleware
    try:
        LOG.debug('RBAC: building auth context from the incoming auth token')
        token_ref = token_model.KeystoneToken(
            token_id=context['token_id'],
            token_data=self.token_provider_api.validate_token(
                context['token_id']))
        # NOTE(jamielennox): whilst this maybe shouldn't be within this
        # function it would otherwise need to reload the token_ref from
        # backing store.
        wsgi.validate_token_bind(context, token_ref)
    except exception.TokenNotFound:
        LOG.warning(_LW('RBAC: Invalid token'))
        raise exception.Unauthorized()

    auth_context = authorization.token_to_auth_context(token_ref)

    return auth_context
Exemple #2
0
    def _build_auth_context(self, request):
        token_id = request.headers.get(AUTH_TOKEN_HEADER).strip()

        if token_id == CONF.admin_token:
            # NOTE(gyee): no need to proceed any further as the special admin
            # token is being handled by AdminTokenAuthMiddleware. This code
            # will not be impacted even if AdminTokenAuthMiddleware is removed
            # from the pipeline as "is_admin" is default to "False". This code
            # is independent of AdminTokenAuthMiddleware.
            return {}

        context = {'token_id': token_id}
        context['environment'] = request.environ

        try:
            token_ref = token_model.KeystoneToken(
                token_id=token_id,
                token_data=self.token_provider_api.validate_token(token_id))
            # TODO(gyee): validate_token_bind should really be its own
            # middleware
            wsgi.validate_token_bind(context, token_ref)
            return authorization.token_to_auth_context(token_ref)
        except exception.TokenNotFound:
            LOG.warning(_('RBAC: Invalid token'))
            raise exception.Unauthorized()
Exemple #3
0
    def _create_base_saml_assertion(self, context, auth):
        issuer = CONF.saml.idp_entity_id
        sp_id = auth['scope']['service_provider']['id']
        service_provider = self.federation_api.get_sp(sp_id)
        utils.assert_enabled_service_provider_object(service_provider)
        sp_url = service_provider['sp_url']

        token_id = auth['identity']['token']['id']
        token_data = self.token_provider_api.validate_token(token_id)
        token_ref = token_model.KeystoneToken(token_id, token_data)

        if not token_ref.project_scoped:
            action = _('Use a project scoped token when attempting to create '
                       'a SAML assertion')
            raise exception.ForbiddenAction(action=action)

        subject = token_ref.user_name
        roles = token_ref.role_names
        project = token_ref.project_name
        # NOTE(rodrigods): the domain name is necessary in order to distinguish
        # between projects and users with the same name in different domains.
        project_domain_name = token_ref.project_domain_name
        subject_domain_name = token_ref.user_domain_name

        generator = keystone_idp.SAMLGenerator()
        response = generator.samlize_token(issuer, sp_url, subject,
                                           subject_domain_name, roles, project,
                                           project_domain_name)
        return (response, service_provider)
Exemple #4
0
    def assert_kerberos_bind(self,
                             tokens,
                             bind_level,
                             use_kerberos=True,
                             success=True):
        if not isinstance(tokens, dict):
            for token in tokens:
                self.assert_kerberos_bind(token,
                                          bind_level,
                                          use_kerberos=use_kerberos,
                                          success=success)
        elif use_kerberos == ANY:
            for val in (True, False):
                self.assert_kerberos_bind(tokens,
                                          bind_level,
                                          use_kerberos=val,
                                          success=success)
        else:
            context = {'environment': {}}
            self.config_fixture.config(group='token',
                                       enforce_token_bind=bind_level)

            if use_kerberos:
                context['environment']['REMOTE_USER'] = KERBEROS_BIND
                context['environment']['AUTH_TYPE'] = 'Negotiate'

            # NOTE(morganfainberg): This assumes a V3 token.
            token_ref = token_model.KeystoneToken(token_id=uuid.uuid4().hex,
                                                  token_data=tokens)

            if not success:
                self.assertRaises(exception.Unauthorized,
                                  wsgi.validate_token_bind, context, token_ref)
            else:
                wsgi.validate_token_bind(context, token_ref)
    def test_token_model_v2_federated_user(self):
        token_data = token_model.KeystoneToken(token_id=uuid.uuid4().hex,
                                               token_data=self.v2_sample_token)
        federation_data = {
            'identity_provider': {
                'id': uuid.uuid4().hex
            },
            'protocol': {
                'id': 'saml2'
            },
            'groups': [{
                'id': uuid.uuid4().hex
            } for x in range(1, 5)]
        }
        self.assertFalse(token_data.is_federated_user)
        self.assertEqual([], token_data.federation_group_ids)
        self.assertIsNone(token_data.federation_protocol_id)
        self.assertIsNone(token_data.federation_idp_id)

        token_data['user'][federation_constants.FEDERATION] = federation_data

        # Federated users should not exist in V2, the data should remain empty
        self.assertFalse(token_data.is_federated_user)
        self.assertEqual([], token_data.federation_group_ids)
        self.assertIsNone(token_data.federation_protocol_id)
        self.assertIsNone(token_data.federation_idp_id)
    def test_token_model_v3_federated_user(self):
        token_data = token_model.KeystoneToken(token_id=uuid.uuid4().hex,
                                               token_data=self.v3_sample_token)
        federation_data = {
            'identity_provider': {
                'id': uuid.uuid4().hex
            },
            'protocol': {
                'id': 'saml2'
            },
            'groups': [{
                'id': uuid.uuid4().hex
            } for x in range(1, 5)]
        }

        self.assertFalse(token_data.is_federated_user)
        self.assertEqual([], token_data.federation_group_ids)
        self.assertIsNone(token_data.federation_protocol_id)
        self.assertIsNone(token_data.federation_idp_id)

        token_data['user'][federation_constants.FEDERATION] = federation_data

        self.assertTrue(token_data.is_federated_user)
        self.assertEqual([x['id'] for x in federation_data['groups']],
                         token_data.federation_group_ids)
        self.assertEqual(federation_data['protocol']['id'],
                         token_data.federation_protocol_id)
        self.assertEqual(federation_data['identity_provider']['id'],
                         token_data.federation_idp_id)
Exemple #7
0
        def inner(self, request, *args, **kwargs):
            request.assert_authenticated()

            if request.context.is_admin:
                LOG.warning(_LW('RBAC: Bypassing authorization'))
            elif callback is not None:
                prep_info = {'f_name': f.__name__, 'input_attr': kwargs}
                callback(self, request, prep_info, *args, **kwargs)
            else:
                action = 'identity:%s' % f.__name__
                creds = _build_policy_check_credentials(
                    self, action, request.context_dict, kwargs)

                policy_dict = {}

                # Check to see if we need to include the target entity in our
                # policy checks.  We deduce this by seeing if the class has
                # specified a get_member() method and that kwargs contains the
                # appropriate entity id.
                if (hasattr(self, 'get_member_from_driver')
                        and self.get_member_from_driver is not None):
                    key = '%s_id' % self.member_name
                    if key in kwargs:
                        ref = self.get_member_from_driver(kwargs[key])
                        policy_dict['target'] = {self.member_name: ref}

                # TODO(henry-nash): Move this entire code to a member
                # method inside v3 Auth
                if request.context_dict.get('subject_token_id') is not None:
                    window_seconds = self._token_validation_window(request)
                    token_ref = token_model.KeystoneToken(
                        token_id=request.context_dict['subject_token_id'],
                        token_data=self.token_provider_api.validate_token(
                            request.context_dict['subject_token_id'],
                            window_seconds=window_seconds))
                    policy_dict.setdefault('target', {})
                    policy_dict['target'].setdefault(self.member_name, {})
                    policy_dict['target'][self.member_name]['user_id'] = (
                        token_ref.user_id)
                    try:
                        user_domain_id = token_ref.user_domain_id
                    except exception.UnexpectedError:
                        user_domain_id = None
                    if user_domain_id:
                        policy_dict['target'][self.member_name].setdefault(
                            'user', {})
                        policy_dict['target'][
                            self.member_name]['user'].setdefault('domain', {})
                        policy_dict['target'][
                            self.member_name]['user']['domain']['id'] = (
                                user_domain_id)

                # Add in the kwargs, which means that any entity provided as a
                # parameter for calls like create and update will be included.
                policy_dict.update(kwargs)
                self.policy_api.enforce(creds, action,
                                        utils.flatten_dict(policy_dict))
                LOG.debug('RBAC: Authorization granted')
            return f(self, request, *args, **kwargs)
Exemple #8
0
 def _get_user_id(self, context):
     if 'token_id' in context:
         token_id = context['token_id']
         token_data = self.token_provider_api.validate_token(token_id)
         token_ref = token_model.KeystoneToken(token_id=token_id,
                                               token_data=token_data)
         return token_ref.user_id
     return None
Exemple #9
0
    def fill_context(self, request):
        # The request context stores itself in thread-local memory for logging.

        if authorization.AUTH_CONTEXT_ENV in request.environ:
            msg = ('Auth context already exists in the request '
                   'environment; it will be used for authorization '
                   'instead of creating a new one.')
            LOG.warning(msg)
            return

        kwargs = {'authenticated': False, 'overwrite': True}
        request_context = context.RequestContext.from_environ(
            request.environ, **kwargs)
        request.environ[context.REQUEST_CONTEXT_ENV] = request_context

        # NOTE(gyee): token takes precedence over SSL client certificates.
        # This will preserve backward compatibility with the existing
        # behavior. Tokenless authorization with X.509 SSL client
        # certificate is effectively disabled if no trusted issuers are
        # provided.

        if request.environ.get(wsgi.CONTEXT_ENV, {}).get('is_admin', False):
            request_context.is_admin = True
            auth_context = {}

        elif request.token_auth.has_user_token:
            # Keystone enforces policy on some values that other services
            # do not, and should not, use.  This adds them in to the context.
            token = token_model.KeystoneToken(token_id=request.user_token,
                                              token_data=request.token_info)
            self._keystone_specific_values(token, request_context)
            request_context.auth_token = request.user_token
            auth_context = request_context.to_policy_values()
            additional = {
                'trust_id': request_context.trust_id,
                'trustor_id': request_context.trustor_id,
                'trustee_id': request_context.trustee_id,
                'domain_id': request_context._domain_id,
                'domain_name': request_context.domain_name,
                'group_ids': request_context.group_ids,
                'token': token
            }
            auth_context.update(additional)

        elif self._validate_trusted_issuer(request):
            auth_context = self._build_tokenless_auth_context(request)

        else:
            # There is either no auth token in the request or the certificate
            # issuer is not trusted. No auth context will be set. This
            # typically happens on an initial token request.
            return

        # set authenticated to flag to keystone that a token has been validated
        request_context.authenticated = True

        LOG.debug('RBAC: auth_context: %s', auth_context)
        request.environ[authorization.AUTH_CONTEXT_ENV] = auth_context
    def test_oauth_variables_not_set(self):
        token_data = copy.deepcopy(test_token_provider.SAMPLE_V3_TOKEN)
        token = token_model.KeystoneToken(token_id=uuid.uuid4().hex,
                                          token_data=token_data)

        auth_context = authorization.token_to_auth_context(token)

        self.assertIsNone(auth_context['access_token_id'])
        self.assertIsNone(auth_context['consumer_id'])
Exemple #11
0
def callback(self, context, prep_info, *args, **kwargs):
    token_ref = ""
    if context.get('token_id') is not None:
        token_ref = token_model.KeystoneToken(
            token_id=context['token_id'],
            token_data=self.token_provider_api.validate_token(
                context['token_id']))
    if not token_ref:
        raise exception.Unauthorized
 def delete_consumer(self, context, consumer_id):
     user_token_ref = token_model.KeystoneToken(
         token_id=context['token_id'],
         token_data=self.token_provider_api.validate_token(
             context['token_id']))
     payload = {'user_id': user_token_ref.user_id,
                'consumer_id': consumer_id}
     _emit_user_oauth_consumer_token_invalidate(payload)
     self.oauth_api.delete_consumer(consumer_id)
 def delete_consumer(self, context, consumer_id):
     user_token_ref = token_model.KeystoneToken(
         token_id=context['token_id'],
         token_data=self.token_provider_api.validate_token(
             context['token_id']))
     payload = {'user_id': user_token_ref.user_id,
                'consumer_id': consumer_id}
     _emit_user_oauth_consumer_token_invalidate(payload)
     initiator = notifications._get_request_audit_info(context)
     self.oauth_api.delete_consumer(consumer_id, initiator)
Exemple #14
0
    def _get_token_ref():
        """
        For getting the token
        """
        LOG.info("inside get token ref")

        token_id = id
        response = self.token_provider_api.validate_token(token_id)
        return token_model.KeystoneToken(token_id=token_id,
                                         token_data=response)
    def set_user_password(self, request, user_id, user):
        token_id = request.context_dict.get('token_id')
        original_password = user.get('original_password')

        token_data = self.token_provider_api.validate_token(token_id)
        token_ref = token_model.KeystoneToken(token_id=token_id,
                                              token_data=token_data)

        if token_ref.user_id != user_id:
            raise exception.Forbidden('Token belongs to another user')
        if original_password is None:
            raise exception.ValidationError(target='user',
                                            attribute='original password')

        try:
            user_ref = self.identity_api.authenticate(
                request, user_id=token_ref.user_id, password=original_password)
            if not user_ref.get('enabled', True):
                # NOTE(dolph): why can't you set a disabled user's password?
                raise exception.Unauthorized('User is disabled')
        except AssertionError:
            raise exception.Unauthorized(
                _('v2.0 password change call failed '
                  'due to rejected authentication'))

        update_dict = {'password': user['password'], 'id': user_id}

        old_admin = request.context.is_admin
        request.context.is_admin = True

        super(UserController, self).set_user_password(request, user_id,
                                                      update_dict)

        request.context.is_admin = old_admin

        # Issue a new token based upon the original token data. This will
        # always be a V2.0 token.

        # NOTE(lbragstad): Since we just updated the password and presisted a
        # revocation event for the user changing the password, it is necessary
        # to wait one second before authenticating. This ensures we are in the
        # threshold of a new second before getting a new token.
        import time
        time.sleep(1)

        new_token_id, new_token_data = self.token_provider_api.issue_token(
            token_ref.user_id,
            token_ref.methods,
            project_id=token_ref.project_id,
            parent_audit_id=token_ref.audit_chain_id)
        v2_helper = token_controllers.V2TokenDataHelper()
        v2_token_data = v2_helper.v3_to_v2_token(new_token_data, new_token_id)
        LOG.debug('TOKEN_REF %s', new_token_data)
        return v2_token_data
    def test_user_id_missing_in_token_raises_exception(self):
        # If there's no user ID in the token then an Unauthorized
        # exception is raised.
        token_data = copy.deepcopy(test_token_provider.SAMPLE_V3_TOKEN)
        del token_data['token']['user']['id']

        token = token_model.KeystoneToken(token_id=uuid.uuid4().hex,
                                          token_data=token_data)

        self.assertRaises(exception.Unauthorized,
                          authorization.token_to_auth_context, token)
Exemple #17
0
    def endpoints(self, request, token_id):
        """Return a list of endpoints available to the token."""
        self.assert_admin(request)

        token_data = self.token_provider_api.validate_token(token_id)
        token_ref = token_model.KeystoneToken(token_id, token_data)

        catalog_ref = None
        if token_ref.project_id:
            catalog_ref = self.catalog_api.get_catalog(token_ref.user_id,
                                                       token_ref.project_id)

        return Auth.format_endpoint_list(catalog_ref)
Exemple #18
0
    def test_token_model_dual_scoped_token(self):
        domain = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex}
        self.v2_sample_token['access']['domain'] = domain
        self.v3_sample_token['token']['domain'] = domain

        # V2 Tokens Cannot be domain scoped, this should work
        token_model.KeystoneToken(token_id=uuid.uuid4().hex,
                                  token_data=self.v2_sample_token)

        self.assertRaises(exception.UnexpectedError,
                          token_model.KeystoneToken,
                          token_id=uuid.uuid4().hex,
                          token_data=self.v3_sample_token)
Exemple #19
0
    def test_token_is_unscoped(self):
        # Check contents of auth_context when the token is unscoped.
        token_data = copy.deepcopy(test_token_provider.SAMPLE_V3_TOKEN)
        del token_data['token']['project']

        token = token_model.KeystoneToken(token_id=uuid.uuid4().hex,
                                          token_data=token_data)

        auth_context = authorization.token_to_auth_context(token)

        self.assertNotIn('project_id', auth_context)
        self.assertNotIn('domain_id', auth_context)
        self.assertNotIn('domain_name', auth_context)
    def test_oauth_variables_set_for_oauth_token(self):
        token_data = copy.deepcopy(test_token_provider.SAMPLE_V3_TOKEN)
        access_token_id = uuid.uuid4().hex
        consumer_id = uuid.uuid4().hex
        token_data['token']['OS-OAUTH1'] = {
            'access_token_id': access_token_id,
            'consumer_id': consumer_id
        }
        token = token_model.KeystoneToken(token_id=uuid.uuid4().hex,
                                          token_data=token_data)

        auth_context = authorization.token_to_auth_context(token)

        self.assertEqual(access_token_id, auth_context['access_token_id'])
        self.assertEqual(consumer_id, auth_context['consumer_id'])
Exemple #21
0
    def revoke_token(self, token_id, revoke_chain=False):
        token_ref = token_model.KeystoneToken(
            token_id=token_id, token_data=self.validate_token(token_id))

        project_id = token_ref.project_id if token_ref.project_scoped else None
        domain_id = token_ref.domain_id if token_ref.domain_scoped else None

        if revoke_chain:
            self.revoke_api.revoke_by_audit_chain_id(token_ref.audit_chain_id,
                                                     project_id=project_id,
                                                     domain_id=domain_id)
        else:
            self.revoke_api.revoke_by_audit_id(token_ref.audit_id)

        if CONF.token.revoke_by_id and self._needs_persistence:
            self._persistence.delete_token(token_id=token_id)
Exemple #22
0
    def _get_token_ref(self, token_id, belongs_to=None):
        """Return a token if a valid one exists.

        Optionally, limited to a token owned by a specific tenant.

        """
        token_ref = token_model.KeystoneToken(
            token_id=token_id,
            token_data=self.token_provider_api.validate_token(token_id))
        if belongs_to:
            if not token_ref.project_scoped:
                raise exception.Unauthorized(
                    _('Token does not belong to specified tenant.'))
            if token_ref.project_id != belongs_to:
                raise exception.Unauthorized(
                    _('Token does not belong to specified tenant.'))
        return token_ref
Exemple #23
0
    def test_token_is_domain_scoped(self):
        # Check contents of auth_context when token is domain-scoped.
        token_data = copy.deepcopy(test_token_provider.SAMPLE_V3_TOKEN)
        del token_data['token']['project']

        domain_id = uuid.uuid4().hex
        domain_name = uuid.uuid4().hex
        token_data['token']['domain'] = {'id': domain_id, 'name': domain_name}

        token = token_model.KeystoneToken(token_id=uuid.uuid4().hex,
                                          token_data=token_data)

        auth_context = authorization.token_to_auth_context(token)

        self.assertNotIn('project_id', auth_context)

        self.assertEqual(domain_id, auth_context['domain_id'])
        self.assertEqual(domain_name, auth_context['domain_name'])
    def test_token_is_project_scoped_with_trust(self):
        # Check auth_context result when the token is project-scoped and has
        # trust info.

        # SAMPLE_V3_TOKEN has OS-TRUST:trust in it.
        token_data = test_token_provider.SAMPLE_V3_TOKEN
        token = token_model.KeystoneToken(token_id=uuid.uuid4().hex,
                                          token_data=token_data)

        auth_context = authorization.token_to_auth_context(token)

        self.assertEqual(token, auth_context['token'])
        self.assertTrue(auth_context['is_delegated_auth'])
        self.assertEqual(token_data['token']['user']['id'],
                         auth_context['user_id'])
        self.assertEqual(token_data['token']['user']['name'],
                         auth_context['user_name'])
        self.assertEqual(token_data['token']['user']['domain']['id'],
                         auth_context['user_domain_id'])
        self.assertEqual(token_data['token']['user']['domain']['name'],
                         auth_context['user_domain_name'])
        self.assertEqual(token_data['token']['project']['id'],
                         auth_context['project_id'])
        self.assertEqual(token_data['token']['project']['domain']['id'],
                         auth_context['project_domain_id'])
        self.assertEqual(token_data['token']['project']['domain']['name'],
                         auth_context['project_domain_name'])
        self.assertNotIn('domain_id', auth_context)
        self.assertNotIn('domain_name', auth_context)
        self.assertEqual(token_data['token']['OS-TRUST:trust']['id'],
                         auth_context['trust_id'])
        self.assertEqual(
            token_data['token']['OS-TRUST:trust']['trustor_user_id'],
            auth_context['trustor_id'])
        self.assertEqual(
            token_data['token']['OS-TRUST:trust']['trustee_user_id'],
            auth_context['trustee_id'])
        self.assertItemsEqual(
            [r['name'] for r in token_data['token']['roles']],
            auth_context['roles'])
        self.assertIsNone(auth_context['consumer_id'])
        self.assertIsNone(auth_context['access_token_id'])
        self.assertNotIn('group_ids', auth_context)
Exemple #25
0
    def test_token_is_for_federated_user(self):
        # When the token is for a federated user then group_ids is in
        # auth_context.
        token_data = copy.deepcopy(test_token_provider.SAMPLE_V3_TOKEN)

        group_ids = [uuid.uuid4().hex for x in range(1, 5)]

        federation_data = {'identity_provider': {'id': uuid.uuid4().hex},
                           'protocol': {'id': 'saml2'},
                           'groups': [{'id': gid} for gid in group_ids]}
        token_data['token']['user'][federation_constants.FEDERATION] = (
            federation_data)

        token = token_model.KeystoneToken(token_id=uuid.uuid4().hex,
                                          token_data=token_data)

        auth_context = authorization.token_to_auth_context(token)

        self.assertItemsEqual(group_ids, auth_context['group_ids'])
    def _assert_identity(self, context, user_id):
        """Check that the provided token belongs to the user.

        :param context: standard context
        :param user_id: id of user
        :raises exception.Forbidden: when token is invalid

        """
        try:
            token_data = self.token_provider_api.validate_token(
                context['token_id'])
        except exception.TokenNotFound as e:
            raise exception.Unauthorized(e)

        token_ref = token_model.KeystoneToken(token_id=context['token_id'],
                                              token_data=token_data)

        if token_ref.user_id != user_id:
            raise exception.Forbidden(_('Token belongs to another user'))
Exemple #27
0
    def revoke_token(self, token_id, revoke_chain=False):
        token_ref = token_model.KeystoneToken(
            token_id=token_id, token_data=self.validate_token(token_id))

        project_id = token_ref.project_id if token_ref.project_scoped else None
        domain_id = token_ref.domain_id if token_ref.domain_scoped else None

        if revoke_chain:
            PROVIDERS.revoke_api.revoke_by_audit_chain_id(
                token_ref.audit_chain_id,
                project_id=project_id,
                domain_id=domain_id)
        else:
            PROVIDERS.revoke_api.revoke_by_audit_id(token_ref.audit_id)

        # FIXME(morganfainberg): Does this cache actually need to be
        # invalidated? We maintain a cached revocation list, which should be
        # consulted before accepting a token as valid.  For now we will
        # do the explicit individual token invalidation.
        self.invalidate_individual_token_cache(token_id)
Exemple #28
0
    def revoke_token(self, token_id, revoke_chain=False):
        if self.revoke_api:
            revoke_by_expires = False
            project_id = None
            domain_id = None

            token_ref = token_model.KeystoneToken(
                token_id=token_id, token_data=self.validate_token(token_id))

            user_id = token_ref.user_id
            expires_at = token_ref.expires
            audit_id = token_ref.audit_id
            audit_chain_id = token_ref.audit_chain_id
            if token_ref.project_scoped:
                project_id = token_ref.project_id
            if token_ref.domain_scoped:
                domain_id = token_ref.domain_id

            if audit_id is None and not revoke_chain:
                LOG.debug('Received token with no audit_id.')
                revoke_by_expires = True

            if audit_chain_id is None and revoke_chain:
                LOG.debug('Received token with no audit_chain_id.')
                revoke_by_expires = True

            if revoke_by_expires:
                self.revoke_api.revoke_by_expiration(user_id,
                                                     expires_at,
                                                     project_id=project_id,
                                                     domain_id=domain_id)
            elif revoke_chain:
                self.revoke_api.revoke_by_audit_chain_id(audit_chain_id,
                                                         project_id=project_id,
                                                         domain_id=domain_id)
            else:
                self.revoke_api.revoke_by_audit_id(audit_id)

        if CONF.token.revoke_by_id:
            self._persistence.delete_token(token_id=token_id)
Exemple #29
0
def _handle_subject_token_id(self, request, policy_dict):
    if request.subject_token is not None:
        window_seconds = token_validation_window(request)

        token_ref = token_model.KeystoneToken(
            token_id=request.subject_token,
            token_data=self.token_provider_api.validate_token(
                request.subject_token, window_seconds=window_seconds))
        policy_dict.setdefault('target', {})
        policy_dict['target'].setdefault(self.member_name, {})
        policy_dict['target'][self.member_name]['user_id'] = (
            token_ref.user_id)
        try:
            user_domain_id = token_ref.user_domain_id
        except exception.UnexpectedError:
            user_domain_id = None
        if user_domain_id:
            policy_dict['target'][self.member_name].setdefault('user', {})
            policy_dict['target'][self.member_name]['user'].setdefault(
                'domain', {})
            policy_dict['target'][self.member_name]['user']['domain']['id'] = (
                user_domain_id)
Exemple #30
0
    def _get_domain_id_from_token(self, context):
        """Get the domain_id for a v3 create call.

        In the case of a v3 create entity call that does not specify a domain
        ID, the spec says that we should use the domain scoping from the token
        being used.

        """
        # We could make this more efficient by loading the domain_id
        # into the context in the wrapper function above (since
        # this version of normalize_domain will only be called inside
        # a v3 protected call).  However, this optimization is probably not
        # worth the duplication of state
        try:
            token_ref = token_model.KeystoneToken(
                token_id=context['token_id'],
                token_data=self.token_provider_api.validate_token(
                    context['token_id']))
        except KeyError:
            # This might happen if we use the Admin token, for instance
            raise exception.ValidationError(
                _('A domain-scoped token must be used'))
        except (exception.TokenNotFound,
                exception.UnsupportedTokenVersionException):
            LOG.warning(
                _LW('Invalid token found while getting domain ID '
                    'for list request'))
            raise exception.Unauthorized()

        if token_ref.domain_scoped:
            return token_ref.domain_id
        else:
            # TODO(henry-nash): We should issue an exception here since if
            # a v3 call does not explicitly specify the domain_id in the
            # entity, it should be using a domain scoped token.  However,
            # the current tempest heat tests issue a v3 call without this.
            # This is raised as bug #1283539.  Once this is fixed, we
            # should remove the line below and replace it with an error.
            return CONF.identity.default_domain_id