Пример #1
0
    def _validate_and_normalize_auth_data(self, auth_payload):
        if 'user' not in auth_payload:
            raise exception.ValidationError(attribute='user',
                                            target=self.METHOD_NAME)
        user_info = auth_payload['user']
        user_id = user_info.get('id')
        user_name = user_info.get('name')
        domain_ref = {}
        if not user_id and not user_name:
            raise exception.ValidationError(attribute='id or name',
                                            target='user')
        try:
            if user_name:
                if 'domain' not in user_info:
                    raise exception.ValidationError(attribute='domain',
                                                    target='user')
                domain_ref = self._lookup_domain(user_info['domain'])
                user_ref = PROVIDERS.identity_api.get_user_by_name(
                    user_name, domain_ref['id'])
            else:
                user_ref = PROVIDERS.identity_api.get_user(user_id)
                domain_ref = PROVIDERS.resource_api.get_domain(
                    user_ref['domain_id'])
                self._assert_domain_is_enabled(domain_ref)
        except exception.UserNotFound as e:
            LOG.warning(six.text_type(e))

            # We need to special case USER NOT FOUND here for CADF
            # notifications as the normal path for notification(s) come from
            # `identity_api.authenticate` and we are a bit before dropping into
            # that method.
            audit_reason = reason.Reason(str(e), str(e.code))
            audit_initiator = notifications.build_audit_initiator()
            # build an appropriate audit initiator with relevant information
            # for the failed request. This will catch invalid user_name and
            # invalid user_id.
            if user_name:
                audit_initiator.user_name = user_name
            else:
                audit_initiator.user_id = user_id
            audit_initiator.domain_id = domain_ref.get('id')
            audit_initiator.domain_name = domain_ref.get('name')
            notifications._send_audit_notification(
                action=_NOTIFY_OP,
                initiator=audit_initiator,
                outcome=taxonomy.OUTCOME_FAILURE,
                target=resource.Resource(typeURI=taxonomy.ACCOUNT_USER),
                event_type=_NOTIFY_EVENT,
                reason=audit_reason)
            raise exception.Unauthorized(e)
        self._assert_user_is_enabled(user_ref)
        self.user_ref = user_ref
        self.user_id = user_ref['id']
        self.domain_id = domain_ref['id']
Пример #2
0
    def _validate_and_normalize_auth_data(self, auth_payload):
        if 'user' not in auth_payload:
            raise exception.ValidationError(attribute='user',
                                            target=self.METHOD_NAME)
        user_info = auth_payload['user']
        user_id = user_info.get('id')
        user_name = user_info.get('name')
        domain_ref = {}
        if not user_id and not user_name:
            raise exception.ValidationError(attribute='id or name',
                                            target='user')
        try:
            if user_name:
                if 'domain' not in user_info:
                    raise exception.ValidationError(attribute='domain',
                                                    target='user')
                domain_ref = self._lookup_domain(user_info['domain'])
                user_ref = PROVIDERS.identity_api.get_user_by_name(
                    user_name, domain_ref['id'])
            else:
                user_ref = PROVIDERS.identity_api.get_user(user_id)
                domain_ref = PROVIDERS.resource_api.get_domain(
                    user_ref['domain_id'])
                self._assert_domain_is_enabled(domain_ref)
        except exception.UserNotFound as e:
            LOG.warning(six.text_type(e))

            # We need to special case USER NOT FOUND here for CADF
            # notifications as the normal path for notification(s) come from
            # `identity_api.authenticate` and we are a bit before dropping into
            # that method.
            audit_reason = reason.Reason(str(e), str(e.code))
            audit_initiator = notifications.build_audit_initiator()
            # build an appropriate audit initiator with relevant information
            # for the failed request. This will catch invalid user_name and
            # invalid user_id.
            if user_name:
                audit_initiator.user_name = user_name
            else:
                audit_initiator.user_id = user_id
            audit_initiator.domain_id = domain_ref.get('id')
            audit_initiator.domain_name = domain_ref.get('name')
            notifications._send_audit_notification(
                action=_NOTIFY_OP,
                initiator=audit_initiator,
                outcome=taxonomy.OUTCOME_FAILURE,
                target=resource.Resource(typeURI=taxonomy.ACCOUNT_USER),
                event_type=_NOTIFY_EVENT,
                reason=audit_reason)
            raise exception.Unauthorized(e)
        self._assert_user_is_enabled(user_ref)
        self.user_ref = user_ref
        self.user_id = user_ref['id']
        self.domain_id = domain_ref['id']
Пример #3
0
    def delete(self, group_id, user_id):
        """Remove user from group.

        DELETE /groups/{group_id}/users/{user_id}
        """
        ENFORCER.enforce_call(action='identity:remove_user_from_group',
                              build_target=functools.partial(
                                  self._build_enforcement_target_attr, user_id,
                                  group_id))
        PROVIDERS.identity_api.remove_user_from_group(
            user_id, group_id, initiator=notifications.build_audit_initiator())
        return None, http.client.NO_CONTENT
Пример #4
0
    def put(self, group_id, user_id):
        """Add user to group.

        PUT /groups/{group_id}/users/{user_id}
        """
        ENFORCER.enforce_call(action='identity:add_user_to_group',
                              build_target=functools.partial(
                                  self._build_enforcement_target_attr, user_id,
                                  group_id))
        PROVIDERS.identity_api.add_user_to_group(
            user_id, group_id, initiator=notifications.build_audit_initiator())
        return None, http.client.NO_CONTENT
Пример #5
0
    def post(self):
        oauth_headers = oauth1.get_oauth_headers(flask.request.headers)
        consumer_id = oauth_headers.get('oauth_consumer_key')
        requested_project_id = flask.request.headers.get(
            'Requested-Project-Id')

        if not consumer_id:
            raise exception.ValidationError(attribute='oauth_consumer_key',
                                            target='request')
        if not requested_project_id:
            raise exception.ValidationError(attribute='Requested-Project-Id',
                                            target='request')

        # NOTE(stevemar): Ensure consumer and requested project exist
        PROVIDERS.resource_api.get_project(requested_project_id)
        PROVIDERS.oauth_api.get_consumer(consumer_id)

        url = _update_url_scheme()
        req_headers = {'Requested-Project-Id': requested_project_id}
        req_headers.update(flask.request.headers)
        request_verifier = oauth1.RequestTokenEndpoint(
            request_validator=validator.OAuthValidator(),
            token_generator=oauth1.token_generator)
        h, b, s = request_verifier.create_request_token_response(
            url,
            http_method='POST',
            body=flask.request.args,
            headers=req_headers)
        if not b:
            msg = _('Invalid signature')
            raise exception.Unauthorized(message=msg)
        # show the details of the failure.
        oauth1.validate_oauth_params(b)
        request_token_duration = CONF.oauth1.request_token_duration
        token_ref = PROVIDERS.oauth_api.create_request_token(
            consumer_id,
            requested_project_id,
            request_token_duration,
            initiator=notifications.build_audit_initiator())

        result = ('oauth_token=%(key)s&oauth_token_secret=%(secret)s' % {
            'key': token_ref['id'],
            'secret': token_ref['request_secret']
        })

        if CONF.oauth1.request_token_duration > 0:
            expiry_bit = '&oauth_expires_at=%s' % token_ref['expires_at']
            result += expiry_bit

        resp = flask.make_response(result, http.client.CREATED)
        resp.headers['Content-Type'] = 'application/x-www-form-urlencoded'
        return resp
Пример #6
0
    def post(self):
        oauth_headers = oauth1.get_oauth_headers(flask.request.headers)
        consumer_id = oauth_headers.get('oauth_consumer_key')
        requested_project_id = flask.request.headers.get(
            'Requested-Project-Id')

        if not consumer_id:
            raise exception.ValidationError(
                attribute='oauth_consumer_key', target='request')
        if not requested_project_id:
            raise exception.ValidationError(
                attribute='Requested-Project-Id', target='request')

        # NOTE(stevemar): Ensure consumer and requested project exist
        PROVIDERS.resource_api.get_project(requested_project_id)
        PROVIDERS.oauth_api.get_consumer(consumer_id)

        url = _update_url_scheme()
        req_headers = {'Requested-Project-Id': requested_project_id}
        req_headers.update(flask.request.headers)
        request_verifier = oauth1.RequestTokenEndpoint(
            request_validator=validator.OAuthValidator(),
            token_generator=oauth1.token_generator)
        h, b, s = request_verifier.create_request_token_response(
            url, http_method='POST', body=flask.request.args,
            headers=req_headers)
        if not b:
            msg = _('Invalid signature')
            raise exception.Unauthorized(message=msg)
        # show the details of the failure.
        oauth1.validate_oauth_params(b)
        request_token_duration = CONF.oauth1.request_token_duration
        token_ref = PROVIDERS.oauth_api.create_request_token(
            consumer_id,
            requested_project_id,
            request_token_duration,
            initiator=notifications.build_audit_initiator())

        result = ('oauth_token=%(key)s&oauth_token_secret=%(secret)s'
                  % {'key': token_ref['id'],
                     'secret': token_ref['request_secret']})

        if CONF.oauth1.request_token_duration > 0:
            expiry_bit = '&oauth_expires_at=%s' % token_ref['expires_at']
            result += expiry_bit

        resp = flask.make_response(result, http_client.CREATED)
        resp.headers['Content-Type'] = 'application/x-www-form-urlencoded'
        return resp
Пример #7
0
    def _validate_endpoint_region(endpoint):
        """Ensure the region for the endpoint exists.

        If 'region_id' is used to specify the region, then we will let the
        manager/driver take care of this.  If, however, 'region' is used,
        then for backward compatibility, we will auto-create the region.

        """
        if (endpoint.get('region_id') is None
                and endpoint.get('region') is not None):
            # To maintain backward compatibility with clients that are
            # using the v3 API in the same way as they used the v2 API,
            # create the endpoint region, if that region does not exist
            # in keystone.
            endpoint['region_id'] = endpoint.pop('region')
            try:
                PROVIDERS.catalog_api.get_region(endpoint['region_id'])
            except exception.RegionNotFound:
                region = dict(id=endpoint['region_id'])
                PROVIDERS.catalog_api.create_region(
                    region, initiator=notifications.build_audit_initiator())
        return endpoint
Пример #8
0
    def _validate_endpoint_region(endpoint):
        """Ensure the region for the endpoint exists.

        If 'region_id' is used to specify the region, then we will let the
        manager/driver take care of this.  If, however, 'region' is used,
        then for backward compatibility, we will auto-create the region.

        """
        if (endpoint.get('region_id') is None and
                endpoint.get('region') is not None):
            # To maintain backward compatibility with clients that are
            # using the v3 API in the same way as they used the v2 API,
            # create the endpoint region, if that region does not exist
            # in keystone.
            endpoint['region_id'] = endpoint.pop('region')
            try:
                PROVIDERS.catalog_api.get_region(endpoint['region_id'])
            except exception.RegionNotFound:
                region = dict(id=endpoint['region_id'])
                PROVIDERS.catalog_api.create_region(
                    region, initiator=notifications.build_audit_initiator())
        return endpoint
Пример #9
0
    def post(self):
        oauth_headers = oauth1.get_oauth_headers(flask.request.headers)
        consumer_id = oauth_headers.get('oauth_consumer_key')
        request_token_id = oauth_headers.get('oauth_token')
        oauth_verifier = oauth_headers.get('oauth_verifier')

        if not consumer_id:
            raise exception.ValidationError(attribute='oauth_consumer_key',
                                            target='request')
        if not request_token_id:
            raise exception.ValidationError(attribute='oauth_token',
                                            target='request')
        if not oauth_verifier:
            raise exception.ValidationError(attribute='oauth_verifier',
                                            target='request')

        req_token = PROVIDERS.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'))

        url = _update_url_scheme()
        access_verifier = oauth1.AccessTokenEndpoint(
            request_validator=validator.OAuthValidator(),
            token_generator=oauth1.token_generator)
        try:
            h, b, s = access_verifier.create_access_token_response(
                url,
                http_method='POST',
                body=flask.request.args,
                headers=dict(flask.request.headers))
        except NotImplementedError:
            # Client key or request token validation failed, since keystone
            # does not yet support dummy client or dummy request token,
            # so we will raise unauthorized exception instead.
            try:
                PROVIDERS.oauth_api.get_consumer(consumer_id)
            except exception.NotFound:
                msg = _('Provided consumer does not exist.')
                LOG.warning('Provided consumer does not exist.')
                raise exception.Unauthorized(message=msg)
            if req_token['consumer_id'] != consumer_id:
                msg = ('Provided consumer key does not match stored consumer '
                       'key.')
                tr_msg = _('Provided consumer key does not match stored '
                           'consumer key.')
                LOG.warning(msg)
                raise exception.Unauthorized(message=tr_msg)
        # The response body is empty since either one of the following reasons
        if not b:
            if req_token['verifier'] != oauth_verifier:
                msg = 'Provided verifier does not match stored verifier'
                tr_msg = _('Provided verifier does not match stored verifier')
            else:
                msg = 'Invalid signature'
                tr_msg = _('Invalid signature')
            LOG.warning(msg)
            raise exception.Unauthorized(message=tr_msg)
        # show the details of the failure
        oauth1.validate_oauth_params(b)
        if not req_token.get('authorizing_user_id'):
            msg = _('Request Token does not have an authorizing user id.')
            LOG.warning('Request Token does not have an authorizing user id.')
            raise exception.Unauthorized(message=msg)

        access_token_duration = CONF.oauth1.access_token_duration
        token_ref = PROVIDERS.oauth_api.create_access_token(
            request_token_id,
            access_token_duration,
            initiator=notifications.build_audit_initiator())

        result = ('oauth_token=%(key)s&oauth_token_secret=%(secret)s' % {
            'key': token_ref['id'],
            'secret': token_ref['access_secret']
        })

        if CONF.oauth1.access_token_duration > 0:
            expiry_bit = '&oauth_expires_at=%s' % (token_ref['expires_at'])
            result += expiry_bit

        resp = flask.make_response(result, http.client.CREATED)
        resp.headers['Content-Type'] = 'application/x-www-form-urlencoded'
        return resp
Пример #10
0
    def audit_initiator(self):
        """A pyCADF initiator describing the current authenticated context.

        As a property.
        """
        return notifications.build_audit_initiator()
Пример #11
0
    def post(self):
        oauth_headers = oauth1.get_oauth_headers(flask.request.headers)
        consumer_id = oauth_headers.get('oauth_consumer_key')
        request_token_id = oauth_headers.get('oauth_token')
        oauth_verifier = oauth_headers.get('oauth_verifier')

        if not consumer_id:
            raise exception.ValidationError(
                attribute='oauth_consumer_key', target='request')
        if not request_token_id:
            raise exception.ValidationError(
                attribute='oauth_token', target='request')
        if not oauth_verifier:
            raise exception.ValidationError(
                attribute='oauth_verifier', target='request')

        req_token = PROVIDERS.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'))

        url = _update_url_scheme()
        access_verifier = oauth1.AccessTokenEndpoint(
            request_validator=validator.OAuthValidator(),
            token_generator=oauth1.token_generator)
        try:
            h, b, s = access_verifier.create_access_token_response(
                url,
                http_method='POST',
                body=flask.request.args,
                headers=flask.request.headers)
        except NotImplementedError:
            # Client key or request token validation failed, since keystone
            # does not yet support dummy client or dummy request token,
            # so we will raise unauthorized exception instead.
            try:
                PROVIDERS.oauth_api.get_consumer(consumer_id)
            except exception.NotFound:
                msg = _('Provided consumer does not exist.')
                LOG.warning('Provided consumer does not exist.')
                raise exception.Unauthorized(message=msg)
            if req_token['consumer_id'] != consumer_id:
                msg = ('Provided consumer key does not match stored consumer '
                       'key.')
                tr_msg = _('Provided consumer key does not match stored '
                           'consumer key.')
                LOG.warning(msg)
                raise exception.Unauthorized(message=tr_msg)
        # The response body is empty since either one of the following reasons
        if not b:
            if req_token['verifier'] != oauth_verifier:
                msg = 'Provided verifier does not match stored verifier'
                tr_msg = _('Provided verifier does not match stored verifier')
            else:
                msg = 'Invalid signature'
                tr_msg = _('Invalid signature')
            LOG.warning(msg)
            raise exception.Unauthorized(message=tr_msg)
        # show the details of the failure
        oauth1.validate_oauth_params(b)
        if not req_token.get('authorizing_user_id'):
            msg = _('Request Token does not have an authorizing user id.')
            LOG.warning('Request Token does not have an authorizing user id.')
            raise exception.Unauthorized(message=msg)

        access_token_duration = CONF.oauth1.access_token_duration
        token_ref = PROVIDERS.oauth_api.create_access_token(
            request_token_id,
            access_token_duration,
            initiator=notifications.build_audit_initiator())

        result = ('oauth_token=%(key)s&oauth_token_secret=%(secret)s'
                  % {'key': token_ref['id'],
                     'secret': token_ref['access_secret']})

        if CONF.oauth1.access_token_duration > 0:
            expiry_bit = '&oauth_expires_at=%s' % (token_ref['expires_at'])
            result += expiry_bit

        resp = flask.make_response(result, http_client.CREATED)
        resp.headers['Content-Type'] = 'application/x-www-form-urlencoded'
        return resp
Пример #12
0
    def audit_initiator(self):
        """A pyCADF initiator describing the current authenticated context.

        As a property.
        """
        return notifications.build_audit_initiator()