示例#1
0
    def determine_access(self, request: Request, organization):
        from sentry.api.base import logger

        if request.user and request.user.is_authenticated and request.auth:
            request.access = access.from_request(
                request, organization, scopes=request.auth.get_scopes())

        elif request.auth:
            request.access = access.from_auth(request.auth, organization)

        else:
            request.access = access.from_request(request, organization)

            extra = {
                "organization_id": organization.id,
                "user_id": request.user.id
            }

            if auth.is_user_signed_request(request):
                # if the user comes from a signed request
                # we let them pass if sso is enabled
                logger.info(
                    "access.signed-sso-passthrough",
                    extra=extra,
                )
            elif request.user.is_authenticated:
                # session auth needs to confirm various permissions
                if self.needs_sso(request, organization):

                    logger.info(
                        "access.must-sso",
                        extra=extra,
                    )

                    raise SsoRequired(organization)

                if self.is_not_2fa_compliant(request, organization):
                    logger.info(
                        "access.not-2fa-compliant",
                        extra=extra,
                    )
                    if request.user.is_superuser and organization.id != Superuser.org_id:
                        raise SuperuserRequired()

                    raise TwoFactorRequired()

                if self.is_member_disabled_from_limit(request, organization):
                    logger.info(
                        "access.member-disabled-from-limit",
                        extra=extra,
                    )
                    raise MemberDisabledOverLimit(organization)
示例#2
0
    def dispatch(self, request: Request, *args, **kwargs) -> Response:
        """
        Identical to rest framework's dispatch except we add the ability
        to convert arguments (for common URL params).
        """
        with sentry_sdk.start_span(op="base.dispatch.setup", description=type(self).__name__):
            self.args = args
            self.kwargs = kwargs
            request = self.initialize_request(request, *args, **kwargs)
            self.load_json_body(request)
            self.request = request
            self.headers = self.default_response_headers  # deprecate?

        # Tags that will ultimately flow into the metrics backend at the end of
        # the request (happens via middleware/stats.py).
        request._metric_tags = {}

        start_time = time.time()

        origin = request.META.get("HTTP_ORIGIN", "null")
        # A "null" value should be treated as no Origin for us.
        # See RFC6454 for more information on this behavior.
        if origin == "null":
            origin = None

        try:
            with sentry_sdk.start_span(op="base.dispatch.request", description=type(self).__name__):
                if origin:
                    if request.auth:
                        allowed_origins = request.auth.get_allowed_origins()
                    else:
                        allowed_origins = None
                    if not is_valid_origin(origin, allowed=allowed_origins):
                        response = Response(f"Invalid origin: {origin}", status=400)
                        self.response = self.finalize_response(request, response, *args, **kwargs)
                        return self.response

                self.initial(request, *args, **kwargs)

                # Get the appropriate handler method
                if request.method.lower() in self.http_method_names:
                    handler = getattr(self, request.method.lower(), self.http_method_not_allowed)

                    (args, kwargs) = self.convert_args(request, *args, **kwargs)
                    self.args = args
                    self.kwargs = kwargs
                else:
                    handler = self.http_method_not_allowed

                if getattr(request, "access", None) is None:
                    # setup default access
                    request.access = access.from_request(request)

            with sentry_sdk.start_span(
                op="base.dispatch.execute",
                description=f"{type(self).__name__}.{handler.__name__}",
            ):
                response = handler(request, *args, **kwargs)

        except Exception as exc:
            response = self.handle_exception(request, exc)

        if origin:
            self.add_cors_headers(request, response)

        self.response = self.finalize_response(request, response, *args, **kwargs)

        if settings.SENTRY_API_RESPONSE_DELAY:
            duration = time.time() - start_time

            if duration < (settings.SENTRY_API_RESPONSE_DELAY / 1000.0):
                with sentry_sdk.start_span(
                    op="base.dispatch.sleep",
                    description=type(self).__name__,
                ) as span:
                    span.set_data("SENTRY_API_RESPONSE_DELAY", settings.SENTRY_API_RESPONSE_DELAY)
                    time.sleep(settings.SENTRY_API_RESPONSE_DELAY / 1000.0 - duration)

        return self.response