def delete_consumer(self, context, consumer_id):
     user_token_ref = utils.get_token_ref(context)
     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)
Example #2
0
File: wsgi.py Project: hbkqh/patch
    def assert_admin(self, context):
        """Ensure the user is an admin.

        :raises keystone.exception.Unauthorized: if a token could not be
            found/authorized, a user is invalid, or a tenant is
            invalid/not scoped.
        :raises keystone.exception.Forbidden: if the user is not an admin and
            does not have the admin role

        """

        if not context['is_admin']:
            user_token_ref = utils.get_token_ref(context)

            validate_token_bind(context, user_token_ref)
            creds = copy.deepcopy(user_token_ref.metadata)

            try:
                creds['user_id'] = user_token_ref.user_id
            except exception.UnexpectedError:
                LOG.debug('Invalid user')
                raise exception.Unauthorized()

            if user_token_ref.project_scoped:
                creds['tenant_id'] = user_token_ref.project_id
            else:
                LOG.debug('Invalid tenant')
                raise exception.Unauthorized()

            creds['roles'] = user_token_ref.role_names
            # Accept either is_admin or the admin role
            self.policy_api.enforce(creds, 'admin_required', {})
Example #3
0
    def _get_domain_id_for_list_request(self, request):
        """Get the domain_id for a v3 list call.

        If we running with multiple domain drivers, then the caller must
        specify a domain_id either as a filter or as part of the token scope.

        """
        if not CONF.identity.domain_specific_drivers_enabled:
            # We don't need to specify a domain ID in this case
            return

        domain_id = request.params.get('domain_id')
        if domain_id:
            return domain_id

        token_ref = utils.get_token_ref(request.context_dict)

        if token_ref.domain_scoped:
            return token_ref.domain_id
        elif token_ref.project_scoped:
            return token_ref.project_domain_id
        else:
            LOG.warning(
                _LW('No domain information specified as part of list request'))
            raise exception.Unauthorized()
Example #4
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.

        """
        token_ref = utils.get_token_ref(context)

        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.
            #
            # Ahead of actually changing the code to raise an exception, we
            # issue a deprecation warning.
            versionutils.report_deprecated_feature(
                LOG,
                _LW('Not specifying a domain during a create user, group or '
                    'project call, and relying on falling back to the '
                    'default domain, is deprecated as of Liberty and will be '
                    'removed in the N release. Specify the domain explicitly '
                    'or use a domain-scoped token'))
            return CONF.identity.default_domain_id
Example #5
0
    def _get_domain_id_for_list_request(self, request):
        """Get the domain_id for a v3 list call.

        If we running with multiple domain drivers, then the caller must
        specify a domain_id either as a filter or as part of the token scope.

        """
        if not CONF.identity.domain_specific_drivers_enabled:
            # We don't need to specify a domain ID in this case
            return

        domain_id = request.params.get('domain_id')
        if domain_id:
            return domain_id

        token_ref = utils.get_token_ref(request.context_dict)

        if token_ref.domain_scoped:
            return token_ref.domain_id
        elif token_ref.project_scoped:
            return token_ref.project_domain_id
        else:
            LOG.warning(
                _LW('No domain information specified as part of list request'))
            raise exception.Unauthorized()
    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.

        """
        token_ref = utils.get_token_ref(context)

        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.
            #
            # Ahead of actually changing the code to raise an exception, we
            # issue a deprecation warning.
            versionutils.report_deprecated_feature(
                LOG,
                _LW('Not specifying a domain during a create user, group or '
                    'project call, and relying on falling back to the '
                    'default domain, is deprecated as of Liberty and will be '
                    'removed in the N release. Specify the domain explicitly '
                    'or use a domain-scoped token'))
            return CONF.identity.default_domain_id
Example #7
0
    def assert_admin(self, context):
        """Ensure the user is an admin.

        :raises keystone.exception.Unauthorized: if a token could not be
            found/authorized, a user is invalid, or a tenant is
            invalid/not scoped.
        :raises keystone.exception.Forbidden: if the user is not an admin and
            does not have the admin role

        """
        if not context['is_admin']:
            user_token_ref = utils.get_token_ref(context)

            validate_token_bind(context, user_token_ref)
            creds = copy.deepcopy(user_token_ref.metadata)

            try:
                creds['user_id'] = user_token_ref.user_id
            except exception.UnexpectedError:
                LOG.debug('Invalid user')
                raise exception.Unauthorized()

            if user_token_ref.project_scoped:
                creds['tenant_id'] = user_token_ref.project_id
            else:
                LOG.debug('Invalid tenant')
                raise exception.Unauthorized()

            creds['roles'] = user_token_ref.role_names
            # Accept either is_admin or the admin role
            self.policy_api.enforce(creds, 'admin_required', {})
Example #8
0
 def delete_consumer(self, context, consumer_id):
     user_token_ref = utils.get_token_ref(context)
     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)
Example #9
0
    def authorize_request_token(self, request, request_token_id, roles):
        """An authenticated user is going to authorize a request token.

        As a security precaution, the requested roles must match those in
        the request token. Because this is in a CLI-only world at the moment,
        there is not another easy way to make sure the user knows which roles
        are being requested before authorizing.
        """
        if request.auth_context.get('is_delegated_auth'):
            raise exception.Forbidden(
                _('Cannot authorize a request token'
                  ' with a token issued via delegation.'))

        req_token = self.oauth_api.get_request_token(request_token_id)

        expires_at = req_token['expires_at']
        if expires_at:
            now = timeutils.utcnow()
            expires = timeutils.normalize_time(
                timeutils.parse_isotime(expires_at))
            if now > expires:
                raise exception.Unauthorized(_('Request token is expired'))

        # put the roles in a set for easy comparison
        authed_roles = set()
        for role in roles:
            authed_roles.add(role['id'])

        # verify the authorizing user has the roles
        user_token = utils.get_token_ref(request.context_dict)
        user_id = user_token.user_id
        project_id = req_token['requested_project_id']
        user_roles = self.assignment_api.get_roles_for_user_and_project(
            user_id, project_id)
        cred_set = set(user_roles)

        if not cred_set.issuperset(authed_roles):
            msg = _('authorizing user does not have role required')
            raise exception.Unauthorized(message=msg)

        # create list of just the id's for the backend
        role_ids = list(authed_roles)

        # verify the user has the project too
        req_project_id = req_token['requested_project_id']
        user_projects = self.assignment_api.list_projects_for_user(user_id)
        for user_project in user_projects:
            if user_project['id'] == req_project_id:
                break
        else:
            msg = _("User is not a member of the requested project")
            raise exception.Unauthorized(message=msg)

        # finally authorize the token
        authed_token = self.oauth_api.authorize_request_token(
            request_token_id, user_id, role_ids)

        to_return = {'token': {'oauth_verifier': authed_token['verifier']}}
        return to_return
Example #10
0
 def delete_consumer(self, request, consumer_id):
     user_token_ref = utils.get_token_ref(request.context_dict)
     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, initiator=request.audit_initiator
     )
Example #11
0
 def delete_consumer(self, request, consumer_id):
     user_token_ref = utils.get_token_ref(request.context_dict)
     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,
                                    initiator=request.audit_initiator)
Example #12
0
    def authorize_request_token(self, context, request_token_id, roles):
        """An authenticated user is going to authorize a request token.

        As a security precaution, the requested roles must match those in
        the request token. Because this is in a CLI-only world at the moment,
        there is not another easy way to make sure the user knows which roles
        are being requested before authorizing.
        """
        auth_context = context.get("environment", {}).get("KEYSTONE_AUTH_CONTEXT", {})
        if auth_context.get("is_delegated_auth"):
            raise exception.Forbidden(_("Cannot authorize a request token" " with a token issued via delegation."))

        req_token = self.oauth_api.get_request_token(request_token_id)

        expires_at = req_token["expires_at"]
        if expires_at:
            now = timeutils.utcnow()
            expires = timeutils.normalize_time(timeutils.parse_isotime(expires_at))
            if now > expires:
                raise exception.Unauthorized(_("Request token is expired"))

        # put the roles in a set for easy comparison
        authed_roles = set()
        for role in roles:
            authed_roles.add(role["id"])

        # verify the authorizing user has the roles
        user_token = utils.get_token_ref(context)
        user_id = user_token.user_id
        project_id = req_token["requested_project_id"]
        user_roles = self.assignment_api.get_roles_for_user_and_project(user_id, project_id)
        cred_set = set(user_roles)

        if not cred_set.issuperset(authed_roles):
            msg = _("authorizing user does not have role required")
            raise exception.Unauthorized(message=msg)

        # create list of just the id's for the backend
        role_ids = list(authed_roles)

        # verify the user has the project too
        req_project_id = req_token["requested_project_id"]
        user_projects = self.assignment_api.list_projects_for_user(user_id)
        for user_project in user_projects:
            if user_project["id"] == req_project_id:
                break
        else:
            msg = _("User is not a member of the requested project")
            raise exception.Unauthorized(message=msg)

        # finally authorize the token
        authed_token = self.oauth_api.authorize_request_token(request_token_id, user_id, role_ids)

        to_return = {"token": {"oauth_verifier": authed_token["verifier"]}}
        return to_return
Example #13
0
    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 keystone.exception.Forbidden: when token is invalid

        """
        token_ref = utils.get_token_ref(context)

        if token_ref.user_id != user_id:
            raise exception.Forbidden(_("Token belongs to another user"))
    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

        """
        token_ref = utils.get_token_ref(context)

        if token_ref.user_id != user_id:
            raise exception.Forbidden(_('Token belongs to another user'))
Example #15
0
File: wsgi.py Project: hbkqh/patch
    def _get_trust_id_for_request(self, context):
        """Get the trust_id for a call.

        Retrieve the trust_id from the token
        Returns None if token is not trust scoped
        """
        if ('token_id' not in context
                or context.get('token_id') == CONF.admin_token):
            LOG.debug(('will not lookup trust as the request auth token is '
                       'either absent or it is the system admin token'))
            return None
        token_ref = utils.get_token_ref(context)
        return token_ref.trust_id
Example #16
0
    def _get_trust_id_for_request(self, context):
        """Get the trust_id for a call.

        Retrieve the trust_id from the token
        Returns None if token is not trust scoped
        """
        if ('token_id' not in context or
                context.get('token_id') == CONF.admin_token):
            LOG.debug(('will not lookup trust as the request auth token is '
                       'either absent or it is the system admin token'))
            return None
        token_ref = utils.get_token_ref(context)
        return token_ref.trust_id
Example #17
0
    def authorize_request_token(self, request, request_token_id, roles):
        """An authenticated user is going to authorize a request token.

        As a security precaution, the requested roles must match those in
        the request token. Because this is in a CLI-only world at the moment,
        there is not another easy way to make sure the user knows which roles
        are being requested before authorizing.
        """
        if request.context.is_delegated_auth:
            raise exception.Forbidden(
                _('Cannot authorize a request token'
                  ' with a token issued via delegation.'))

        req_token = self.oauth_api.get_request_token(request_token_id)

        expires_at = req_token['expires_at']
        if expires_at:
            now = timeutils.utcnow()
            expires = timeutils.normalize_time(
                timeutils.parse_isotime(expires_at))
            if now > expires:
                raise exception.Unauthorized(_('Request token is expired'))

        # put the roles in a set for easy comparison
        authed_roles = set()
        for role in roles:
            authed_roles.add(role['id'])

        # verify the authorizing user has the roles
        user_token = utils.get_token_ref(request.context_dict)
        user_id = user_token.user_id
        project_id = req_token['requested_project_id']
        user_roles = self.assignment_api.get_roles_for_user_and_project(
            user_id, project_id)
        cred_set = set(user_roles)

        if not cred_set.issuperset(authed_roles):
            msg = _('authorizing user does not have role required')
            raise exception.Unauthorized(message=msg)

        # create list of just the id's for the backend
        role_ids = list(authed_roles)

        # finally authorize the token
        authed_token = self.oauth_api.authorize_request_token(
            request_token_id, user_id, role_ids)

        to_return = {'token': {'oauth_verifier': authed_token['verifier']}}
        return to_return
Example #18
0
    def get_projects_for_token(self, context, **kw):
        """Get valid tenants for token based on token used to authenticate.

        Pulls the token from the context, validates it and gets the valid
        tenants for the user in the token.

        Doesn't care about token scopedness.

        """
        token_ref = utils.get_token_ref(context)

        tenant_refs = self.assignment_api.list_projects_for_user(token_ref.user_id)
        tenant_refs = [
            self.v3_to_v2_project(ref) for ref in tenant_refs if ref["domain_id"] == CONF.identity.default_domain_id
        ]
        params = {"limit": context["query_string"].get("limit"), "marker": context["query_string"].get("marker")}
        return self.format_project_list(tenant_refs, **params)
Example #19
0
    def get_projects_for_token(self, request, **kw):
        """Get valid tenants for token based on token used to authenticate.
        Pulls the token from the context, validates it and gets the valid
        tenants for the user in the token.
        Doesn't care about token scopedness.
        """
        token_ref = utils.get_token_ref(request.context_dict)

        tenant_refs = (self.assignment_api.list_projects_for_user(
            token_ref.user_id))
        tenant_refs = [
            self.v3_to_v2_project(ref) for ref in tenant_refs
            if ref['domain_id'] == CONF.identity.default_domain_id
        ]
        params = {
            'limit': request.params.get('limit'),
            'marker': request.params.get('marker'),
        }
        return self.format_project_list(tenant_refs, **params)
Example #20
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.

        """
        token_ref = utils.get_token_ref(context)

        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
Example #21
0
    def get_projects_for_token(self, request, **kw):
        """Get valid tenants for token based on token used to authenticate.

        Pulls the token from the context, validates it and gets the valid
        tenants for the user in the token.

        Doesn't care about token scopedness.

        """
        token_ref = utils.get_token_ref(request.context_dict)

        tenant_refs = (
            self.assignment_api.list_projects_for_user(token_ref.user_id))
        tenant_refs = [self.v3_to_v2_project(ref) for ref in tenant_refs
                       if ref['domain_id'] == CONF.identity.default_domain_id]
        params = {
            'limit': request.params.get('limit'),
            'marker': request.params.get('marker'),
        }
        return self.format_project_list(tenant_refs, **params)
Example #22
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.

        """
        token_ref = utils.get_token_ref(context)

        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
Example #23
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.

        """
        try:
            token_ref = utils.get_token_ref(context)
        except exception.Unauthorized:
            if context.get('is_admin'):
                raise exception.ValidationError(
                    _('You have tried to create a resource using the admin '
                      'token. As this token is not within a domain you must '
                      'explicitly include a domain for this resource to '
                      'belong to.'))
            raise

        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.
            #
            # Ahead of actually changing the code to raise an exception, we
            # issue a deprecation warning.
            versionutils.report_deprecated_feature(
                LOG,
                _LW('Not specifying a domain during a create user, group or '
                    'project call, and relying on falling back to the '
                    'default domain, is deprecated as of Liberty. There is no '
                    'plan to remove this compatibility, however, future API '
                    'versions may remove this, so please specify the domain '
                    'explicitly or use a domain-scoped token.'))
            return CONF.identity.default_domain_id
Example #24
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.

        """
        try:
            token_ref = utils.get_token_ref(context)
        except exception.Unauthorized:
            if context.get('is_admin'):
                raise exception.ValidationError(
                    _('You have tried to create a resource using the admin '
                      'token. As this token is not within a domain you must '
                      'explicitly include a domain for this resource to '
                      'belong to.'))
            raise

        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.
            #
            # Ahead of actually changing the code to raise an exception, we
            # issue a deprecation warning.
            versionutils.report_deprecated_feature(
                LOG,
                _LW('Not specifying a domain during a create user, group or '
                    'project call, and relying on falling back to the '
                    'default domain, is deprecated as of Liberty. There is no '
                    'plan to remove this compatibility, however, future API '
                    'versions may remove this, so please specify the domain '
                    'explicitly or use a domain-scoped token.'))
            return CONF.identity.default_domain_id
Example #25
0
 def _get_user_id(self, context):
     try:
         token_ref = utils.get_token_ref(context)
     except exception.Unauthorized:
         return None
     return token_ref.user_id
Example #26
0
 def _get_user_id(self, context):
     try:
         token_ref = utils.get_token_ref(context)
     except exception.Unauthorized:
         return None
     return token_ref.user_id