예제 #1
0
    def has_object_permission(self, request, view, organization):
        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:
            if request.auth.organization_id == organization.id:
                request.access = access.from_auth(request.auth)
            else:
                request.access = access.DEFAULT

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

            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={
                        'organization_id': organization.id,
                        'user_id': request.user.id,
                    }
                )
            elif request.user.is_authenticated():
                # session auth needs to confirm various permissions
                if self.needs_sso(request, organization):

                    logger.info(
                        'access.must-sso',
                        extra={
                            'organization_id': organization.id,
                            'user_id': request.user.id,
                        }
                    )

                    raise SsoRequired(organization)

                if self.is_not_2fa_compliant(
                        request.user, organization):
                    logger.info(
                        'access.not-2fa-compliant',
                        extra={
                            'organization_id': organization.id,
                            'user_id': request.user.id,
                        }
                    )
                    raise TwoFactorRequired()

        allowed_scopes = set(self.scope_map.get(request.method, []))
        return any(request.access.has_scope(s) for s in allowed_scopes)
예제 #2
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)
예제 #3
0
    def determine_access(self, request, organization):
        from sentry.api.base import logger
        from sentry.auth import access  # Django 1.9 setup issue
        from sentry.utils import auth

        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:
            if request.auth.organization_id == organization.id:
                request.access = access.from_auth(request.auth)
            else:
                request.access = access.DEFAULT

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

            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={
                                'organization_id': organization.id,
                                'user_id': request.user.id,
                            })
            elif request.user.is_authenticated():
                # session auth needs to confirm various permissions
                if self.needs_sso(request, organization):

                    logger.info('access.must-sso',
                                extra={
                                    'organization_id': organization.id,
                                    'user_id': request.user.id,
                                })

                    raise SsoRequired(organization)

                if self.is_not_2fa_compliant(request.user, organization):
                    logger.info('access.not-2fa-compliant',
                                extra={
                                    'organization_id': organization.id,
                                    'user_id': request.user.id,
                                })
                    raise TwoFactorRequired()
예제 #4
0
    def put(self, request: Request):
        """
        Verify a User
        `````````````

        This endpoint verifies the currently authenticated user (for example, to gain superuser).

        :auth: required
        """
        if not request.user.is_authenticated:
            return Response(status=status.HTTP_401_UNAUTHORIZED)

        validator = AuthVerifyValidator(data=request.data)
        if not validator.is_valid():
            return self.respond(validator.errors,
                                status=status.HTTP_400_BAD_REQUEST)

        authenticated = False
        # See if we have a u2f challenge/response
        if "challenge" in validator.validated_data and "response" in validator.validated_data:
            try:
                interface = Authenticator.objects.get_interface(
                    request.user, "u2f")
                if not interface.is_enrolled():
                    raise LookupError()
                challenge = json.loads(validator.validated_data["challenge"])
                response = json.loads(validator.validated_data["response"])
                can_webauthn_signin = self.check_can_webauthn_signin(
                    request.user, request.user)
                authenticated = interface.validate_response(
                    request, challenge, response, can_webauthn_signin)
            except ValueError:
                pass
            except LookupError:
                pass

        # attempt password authentication
        else:
            authenticated = request.user.check_password(
                validator.validated_data["password"])

        # UI treats 401s by redirecting, this 401 should be ignored
        if not authenticated:
            return Response({"detail": {
                "code": "ignore"
            }},
                            status=status.HTTP_403_FORBIDDEN)

        try:
            # Must use the real request object that Django knows about
            auth.login(request._request, request.user)
        except auth.AuthUserPasswordExpired:
            return Response(
                {
                    "code":
                    "password-expired",
                    "message":
                    "Cannot sign-in with basic auth because password has expired.",
                },
                status=status.HTTP_403_FORBIDDEN,
            )

        if request.user.is_superuser and not is_active_superuser(
                request) and Superuser.org_id:
            # if a superuser hitting this endpoint is not active, they are most likely
            # trying to become active, and likely need to re-identify with SSO to do so.
            redirect = request.META.get("HTTP_REFERER", "")
            if not is_safe_url(redirect, allowed_hosts=(request.get_host(), )):
                redirect = None

            initiate_login(request, redirect)
            raise SsoRequired(
                Organization.objects.get_from_cache(id=Superuser.org_id))

        request.user = request._request.user

        return self.get(request)