示例#1
0
    def dispatch(self, request, organization_slug):
        provider = get_provider(organization_slug)
        if provider is None:
            messages.add_message(request, messages.ERROR, ERR_NO_SAML_SSO)
            return self.redirect('/')

        saml_config = build_saml_config(provider.config, organization_slug)
        auth = build_auth(request, saml_config)

        # No need to logout an anonymous user.
        should_logout = request.user.is_authenticated()

        def force_logout():
            request.user.refresh_session_nonce()
            request.user.save()
            logout(request)

        redirect_to = auth.process_slo(
            delete_session_cb=force_logout,
            keep_local_session=not should_logout,
        )

        if not redirect_to:
            redirect_to = get_login_url()

        return self.redirect(redirect_to)
 def handle(self, request):
     next = request.GET.get(REDIRECT_FIELD_NAME, '')
     if not is_safe_url(next, host=request.get_host()):
         next = auth.get_login_url()
     logout(request)
     request.user = AnonymousUser()
     return self.redirect(next)
示例#3
0
 def wrapped(request, *args, **kwargs):
     if not is_active_superuser(request):
         if request.user.is_superuser:
             auth.initiate_login(request, next_url=request.get_full_path())
             return HttpResponseRedirect(auth.get_login_url())
         return render_to_response('sentry/missing_permissions.html', {}, request, status=400)
     return func(request, *args, **kwargs)
示例#4
0
 def handle_auth_required(self, request, *args, **kwargs):
     auth.initiate_login(request, next_url=request.get_full_path())
     if "organization_slug" in kwargs:
         redirect_to = reverse("sentry-auth-organization", args=[kwargs["organization_slug"]])
     else:
         redirect_to = auth.get_login_url()
     return self.redirect(redirect_to, headers={"X-Robots-Tag": "noindex, nofollow"})
示例#5
0
def edit_user(request, user_id):
    if not request.is_superuser():
        return HttpResponseRedirect(auth.get_login_url())

    try:
        user = User.objects.get(pk=user_id)
    except User.DoesNotExist:
        return HttpResponseRedirect(absolute_uri('/manage/users/'))

    form = ChangeUserForm(request.POST or None, instance=user)
    if form.is_valid():
        user = form.save()
        return HttpResponseRedirect(absolute_uri('/manage/users/'))

    project_list = Project.objects.filter(
        status=0,
        organization__member_set__user=user,
    ).order_by('-date_added')

    context = {
        'form': form,
        'the_user': user,
        'project_list': project_list,
    }
    context.update(csrf(request))

    return render_to_response('sentry/admin/users/edit.html', context, request)
示例#6
0
 def handle_auth_required(self, request, *args, **kwargs):
     auth.initiate_login(request, next_url=request.get_full_path())
     if 'organization_slug' in kwargs:
         redirect_to = reverse('sentry-auth-organization', args=[kwargs['organization_slug']])
     else:
         redirect_to = auth.get_login_url()
     return self.redirect(redirect_to, headers={'X-Robots-Tag': 'noindex, nofollow'})
示例#7
0
 def handle(self, request):
     next = request.GET.get(REDIRECT_FIELD_NAME, '')
     if not next.startswith('/'):
         next = auth.get_login_url()
     logout(request)
     request.user = AnonymousUser()
     return self.redirect(next)
示例#8
0
文件: base.py 项目: ForkRepo/sentry
 def handle_auth_required(self, request, *args, **kwargs):
     auth.initiate_login(request, next_url=request.get_full_path())
     if "organization_slug" in kwargs:
         redirect_to = reverse("sentry-auth-organization", args=[kwargs["organization_slug"]])
     else:
         redirect_to = auth.get_login_url()
     return self.redirect(redirect_to)
示例#9
0
文件: saml2.py 项目: getsentry/sentry
    def dispatch(self, request, organization_slug):
        provider = get_provider(organization_slug)
        if provider is None:
            messages.add_message(request, messages.ERROR, ERR_NO_SAML_SSO)
            return self.redirect('/')

        saml_config = build_saml_config(provider.config, organization_slug)
        auth = build_auth(request, saml_config)

        # No need to logout an anonymous user.
        should_logout = request.user.is_authenticated()

        def force_logout():
            request.user.refresh_session_nonce()
            request.user.save()
            logout(request)

        redirect_to = auth.process_slo(
            delete_session_cb=force_logout,
            keep_local_session=not should_logout,
        )

        if not redirect_to:
            redirect_to = get_login_url()

        return self.redirect(redirect_to)
示例#10
0
def create_new_user(request):
    if not request.is_superuser():
        return HttpResponseRedirect(auth.get_login_url())

    form = NewUserForm(
        request.POST or None, initial={
            'send_welcome_mail': True,
            'create_project': True,
        }
    )
    if form.is_valid():
        user = form.save(commit=False)

        # create a random password
        password = uuid.uuid4().hex
        user.set_password(password)

        user.save()

        if form.cleaned_data['send_welcome_mail']:
            context = {
                'username': user.username,
                'password': password,
                'url': absolute_uri(auth.get_login_url()),
            }
            body = render_to_string('sentry/emails/welcome_mail.txt', context, request)

            try:
                send_mail(
                    '%s Welcome to Sentry' % (options.get('mail.subject-prefix'), ),
                    body,
                    options.get('mail.from'), [user.email],
                    fail_silently=False
                )
            except Exception as e:
                logger = logging.getLogger('sentry.mail.errors')
                logger.exception(e)

        return HttpResponseRedirect(absolute_uri('/manage/users/'))

    context = {
        'form': form,
    }
    context.update(csrf(request))

    return render_to_response('sentry/admin/users/new.html', context, request)
示例#11
0
def create_new_user(request):
    if not request.is_superuser():
        return HttpResponseRedirect(auth.get_login_url())

    form = NewUserForm(request.POST or None,
                       initial={
                           'send_welcome_mail': True,
                           'create_project': True,
                       })
    if form.is_valid():
        user = form.save(commit=False)

        # create a random password
        password = uuid.uuid4().hex
        user.set_password(password)

        user.save()

        if form.cleaned_data['send_welcome_mail']:
            context = {
                'username': user.username,
                'password': password,
                'url': absolute_uri(auth.get_login_url()),
            }
            body = render_to_string('sentry/emails/welcome_mail.txt', context,
                                    request)

            try:
                send_mail('%s Welcome to Sentry' %
                          (options.get('mail.subject-prefix'), ),
                          body,
                          options.get('mail.from'), [user.email],
                          fail_silently=False)
            except Exception as e:
                logger = logging.getLogger('sentry.mail.errors')
                logger.exception(e)

        return HttpResponseRedirect(absolute_uri('/manage/users/'))

    context = {
        'form': form,
    }
    context.update(csrf(request))

    return render_to_response('sentry/admin/users/new.html', context, request)
示例#12
0
 def handle_auth_required(self, request, *args, **kwargs):
     from sentry.utils import auth  # Django 1.9 setup issue
     auth.initiate_login(request, next_url=request.get_full_path())
     if 'organization_slug' in kwargs:
         redirect_to = reverse('sentry-auth-organization',
                               args=[kwargs['organization_slug']])
     else:
         redirect_to = auth.get_login_url()
     return self.redirect(redirect_to)
示例#13
0
    def handle(self, request):
        user = auth.get_pending_2fa_user(request)
        if user is None or request.user.is_authenticated():
            return HttpResponseRedirect(auth.get_login_url())

        interfaces = Authenticator.objects.all_interfaces_for_user(user)

        # If for whatever reason we ended up here but the user has no 2FA
        # enabled, we just continue successfully.
        if not interfaces:
            return self.perform_signin(request, user)

        challenge = activation = None
        interface = self.negotiate_interface(request, interfaces)
        if request.method == 'GET':
            activation = interface.activate(request)
            if activation is not None and activation.type == 'challenge':
                challenge = activation.challenge
        elif 'challenge' in request.POST:
            challenge = json.loads(request.POST['challenge'])

        form = TwoFactorForm()

        # If an OTP response was supplied, we try to make it pass.
        otp = request.POST.get('otp')
        if otp:
            used_interface = self.validate_otp(otp, interface, interfaces)
            if used_interface is not None:
                return self.perform_signin(request, user, used_interface)
            self.fail_signin(request, user, form)

        # If a challenge and response exists, validate
        if challenge:
            response = request.POST.get('response')
            if response:
                response = json.loads(response)
                if interface.validate_response(request, challenge, response):
                    return self.perform_signin(request, user, interface)
                self.fail_signin(request, user, form)

        return render_to_response(
            [
                'sentry/twofactor_%s.html' % interface.interface_id,
                'sentry/twofactor.html'
            ], {
                'form':
                form,
                'interface':
                interface,
                'other_interfaces':
                self.get_other_interfaces(interface, interfaces),
                'activation':
                activation,
            },
            request,
            status=200)
示例#14
0
 def wrapped(request, *args, **kwargs):
     if not request.user.is_authenticated():
         auth.initiate_login(request, next_url=request.get_full_path())
         if 'organization_slug' in kwargs:
             redirect_uri = reverse('sentry-auth-organization',
                                    args=[kwargs['organization_slug']])
         else:
             redirect_uri = auth.get_login_url()
         return HttpResponseRedirect(redirect_uri)
     return func(request, *args, **kwargs)
示例#15
0
 def wrapped(request, *args, **kwargs):
     if not request.user.is_authenticated():
         auth.initiate_login(request, next_url=request.get_full_path())
         if "organization_slug" in kwargs:
             redirect_uri = reverse("sentry-auth-organization",
                                    args=[kwargs["organization_slug"]])
         else:
             redirect_uri = auth.get_login_url()
         return HttpResponseRedirect(redirect_uri)
     return func(request, *args, **kwargs)
示例#16
0
def idp_confirm_email(request: Request, key: str) -> Response:
    verification_key = get_redis_key(key)
    if verify_account(key):
        request.session["confirm_account_verification_key"] = verification_key
        # TODO Change so it redirects to a confirmation page that needs to be made: Simple page with a confirmation msg and redirect to login
        login = get_login_url()
        redirect = HttpResponseRedirect(login)
        return redirect
    # TODO add view that shows key not found
    return HttpResponseNotFound()
示例#17
0
    def handle(self, request):
        user = auth.get_pending_2fa_user(request)
        if user is None or request.user.is_authenticated():
            return HttpResponseRedirect(auth.get_login_url())

        interfaces = Authenticator.objects.all_interfaces_for_user(user)

        # If for whatever reason we ended up here but the user has no 2FA
        # enabled, we just continue successfully.
        if not interfaces:
            return self.perform_signin(request, user)

        challenge = activation = None
        interface = self.negotiate_interface(request, interfaces)
        if request.method == "GET":
            activation = interface.activate(request)
            if activation is not None and activation.type == "challenge":
                challenge = activation.challenge
        elif "challenge" in request.POST:
            challenge = json.loads(request.POST["challenge"])

        form = TwoFactorForm()

        # If an OTP response was supplied, we try to make it pass.
        otp = request.POST.get("otp")
        if otp:
            used_interface = self.validate_otp(otp, interface, interfaces)
            if used_interface is not None:
                return self.perform_signin(request, user, used_interface)
            self.fail_signin(request, user, form)

        # If a challenge and response exists, validate
        if challenge:
            response = request.POST.get("response")
            if response:
                response = json.loads(response)
                if interface.validate_response(request, challenge, response):
                    return self.perform_signin(request, user, interface)
                self.fail_signin(request, user, form)

        return render_to_response(
            ["sentry/twofactor_%s.html" % interface.interface_id, "sentry/twofactor.html"],
            {
                "form": form,
                "interface": interface,
                "other_interfaces": self.get_other_interfaces(interface, interfaces),
                "activation": activation,
            },
            request,
            status=200,
        )
    def handle(self, request, organization, member_id):
        try:
            member = OrganizationMember.objects.get(
                Q(user__is_active=True) | Q(user__isnull=True),
                organization=organization,
                id=member_id,
            )
        except OrganizationMember.DoesNotExist:
            return self.redirect(auth.get_login_url())

        if request.POST.get('op') == 'reinvite' and member.is_pending:
            return self.resend_invite(request, organization, member)
        elif request.POST.get('op') == 'regenerate' and member.is_pending:
            return self.resend_invite(request,
                                      organization,
                                      member,
                                      regen=True)

        can_admin, allowed_roles = self.get_allowed_roles(
            request, organization, member)

        all_teams = Team.objects.filter(organization=organization,
                                        status=TeamStatus.VISIBLE)

        if member.user == request.user or not can_admin:
            return self.view_member(request, organization, member, all_teams)

        form = self.get_form(request, member, all_teams, allowed_roles)
        if form.is_valid():
            member = form.save(request.user, organization,
                               request.META['REMOTE_ADDR'])

            messages.add_message(request, messages.SUCCESS,
                                 _('Your changes were saved.'))

            redirect = reverse('sentry-organization-member-settings',
                               args=[organization.slug, member.id])

            return self.redirect(redirect)

        context = {
            'member': member,
            'form': form,
            'invite_link': member.get_invite_link(),
            'role_list': [(r, r in allowed_roles) for r in roles.get_all()],
            'all_teams': all_teams
        }

        return self.respond('sentry/organization-member-settings.html',
                            context)
    def handle(self, request, organization, member_id):
        try:
            member = OrganizationMember.objects.get(
                Q(user__is_active=True) | Q(user__isnull=True),
                organization=organization,
                id=member_id,
            )
        except OrganizationMember.DoesNotExist:
            return self.redirect(auth.get_login_url())

        if request.POST.get('op') == 'reinvite' and member.is_pending:
            return self.resend_invite(request, organization, member)
        elif request.POST.get('op') == 'regenerate' and member.is_pending:
            return self.resend_invite(request, organization, member, regen=True)

        can_admin, allowed_roles = self.get_allowed_roles(request, organization, member)

        all_teams = Team.objects.filter(
            organization=organization,
            status=TeamStatus.VISIBLE
        )

        if member.user == request.user or not can_admin:
            return self.view_member(request, organization, member, all_teams)

        form = self.get_form(request, member, all_teams, allowed_roles)
        if form.is_valid():
            member = form.save(request.user, organization, request.META['REMOTE_ADDR'])

            messages.add_message(request, messages.SUCCESS,
                _('Your changes were saved.'))

            redirect = reverse('sentry-organization-member-settings',
                               args=[organization.slug, member.id])

            return self.redirect(redirect)

        context = {
            'member': member,
            'form': form,
            'invite_link': member.get_invite_link(),
            'role_list': [
                (r, r in allowed_roles)
                for r in roles.get_all()
            ],
            'all_teams': all_teams
        }

        return self.respond('sentry/organization-member-settings.html', context)
示例#20
0
def configure_plugin(request, slug):
    plugin = plugins.get(slug)
    if not plugin.has_site_conf():
        return HttpResponseRedirect(auth.get_login_url())

    view = plugin.configure(request=request)
    if isinstance(view, HttpResponse):
        return view

    return render_to_response('sentry/admin/plugins/configure.html', {
        'plugin': plugin,
        'title': plugin.get_conf_title(),
        'slug': plugin.slug,
        'view': view,
    }, request)
示例#21
0
def email_unsubscribe_project(request, project_id):
    # For now we only support getting here from the signed link.
    if not request.user_from_signed_request:
        raise Http404()
    try:
        project = Project.objects.get(pk=project_id)
    except Project.DoesNotExist:
        raise Http404()

    if request.method == 'POST':
        if 'cancel' not in request.POST:
            UserOption.objects.set_value(
                request.user, project, 'mail:alert', 0)
        return HttpResponseRedirect(auth.get_login_url())

    context = csrf(request)
    context['project'] = project
    return render_to_response('sentry/account/email_unsubscribe_project.html',
                              context, request)
示例#22
0
def email_unsubscribe_project(request, project_id):
    # For now we only support getting here from the signed link.
    if not request.user_from_signed_request:
        raise Http404()
    try:
        project = Project.objects.get(pk=project_id)
    except Project.DoesNotExist:
        raise Http404()

    if request.method == 'POST':
        if 'cancel' not in request.POST:
            UserOption.objects.set_value(request.user, project, 'mail:alert',
                                         0)
        return HttpResponseRedirect(auth.get_login_url())

    context = csrf(request)
    context['project'] = project
    return render_to_response('sentry/account/email_unsubscribe_project.html',
                              context, request)
示例#23
0
def email_unsubscribe_project(request, project_id):
    # For now we only support getting here from the signed link.
    if not request.user_from_signed_request:
        raise Http404()
    try:
        project = Project.objects.get(pk=project_id)
    except Project.DoesNotExist:
        raise Http404()

    if request.method == "POST":
        if "cancel" not in request.POST:
            UserOption.objects.set_value(
                user=request.user, key="mail:alert", value=0, project=project
            )
        return HttpResponseRedirect(auth.get_login_url())

    context = csrf(request)
    context["project"] = project
    return render_to_response("sentry/account/email_unsubscribe_project.html", context, request)
示例#24
0
文件: saml2.py 项目: saldanac/sentry
    def dispatch(self, request, organization_slug):
        provider = get_provider(organization_slug)
        if provider is None:
            messages.add_message(request, messages.ERROR, ERR_NO_SAML_SSO)
            return HttpResponseRedirect('/')

        saml_config = provider.build_saml_config(organization_slug)
        auth = provider.build_auth(request, saml_config)

        def force_logout():
            request.user.refresh_session_nonce()
            request.user.save()
            logout(request)

        redirect_to = auth.process_slo(delete_session_cb=force_logout)
        if not redirect_to:
            redirect_to = get_login_url()

        return self.redirect(redirect_to)
示例#25
0
def email_unsubscribe_project(request, project_id):
    # For now we only support getting here from the signed link.
    if not request.user_from_signed_request:
        raise Http404()
    try:
        project = Project.objects.get(pk=project_id)
    except Project.DoesNotExist:
        raise Http404()

    if request.method == "POST":
        if "cancel" not in request.POST:
            NotificationSetting.objects.update_settings(
                ExternalProviders.EMAIL,
                NotificationSettingTypes.ISSUE_ALERTS,
                NotificationSettingOptionValues.NEVER,
                user=request.user,
                project=project,
            )
        return HttpResponseRedirect(auth.get_login_url())

    context = csrf(request)
    context["project"] = project
    return render_to_response("sentry/account/email_unsubscribe_project.html",
                              context, request)
示例#26
0
 def redirect(self, request: Request) -> Response:
     next_url = request.GET.get(REDIRECT_FIELD_NAME, "")
     if not is_safe_url(next_url, allowed_hosts=(request.get_host(), )):
         next_url = auth.get_login_url()
     return super().redirect(next_url)
示例#27
0
    def handle(self, request: Request) -> Response:
        user = auth.get_pending_2fa_user(request)
        if user is None:
            return HttpResponseRedirect(auth.get_login_url())

        interfaces = Authenticator.objects.all_interfaces_for_user(user)

        # If for whatever reason we ended up here but the user has no 2FA
        # enabled, we just continue successfully.
        if not interfaces:
            return self.perform_signin(request, user)

        challenge = activation = None
        interface = self.negotiate_interface(request, interfaces)

        if request.method == "POST" and ratelimiter.is_limited(
                f"auth-2fa:user:{user.id}", limit=5, window=60):
            # TODO: Maybe email the account owner or do something to notify someone
            # This would probably be good for them to know.
            return HttpResponse(
                "You have made too many 2FA attempts. Please try again later.",
                content_type="text/plain",
                status=429,
            )
        # check if webauthn-login feature flag is enabled for frontend
        webauthn_signin_ff = self._check_can_webauthn_signin(
            user, request.user)

        if request.method == "GET":
            if interface.type == U2fInterface.type:
                activation = interface.activate(request, webauthn_signin_ff)
            else:
                activation = interface.activate(request)

            if activation is not None and activation.type == "challenge":
                challenge = activation.challenge

                if webauthn_signin_ff and interface.type == U2fInterface.type:
                    activation.challenge = {}
                    activation.challenge[
                        "webAuthnAuthenticationData"] = b64encode(challenge)

        elif "challenge" in request.POST:
            challenge = json.loads(request.POST["challenge"])
        form = TwoFactorForm()

        # If an OTP response was supplied, we try to make it pass.
        otp = request.POST.get("otp")
        if otp:
            used_interface = self.validate_otp(otp, interface, interfaces)
            if used_interface is not None:
                return self.perform_signin(request, user, used_interface)
            self.fail_signin(request, user, form)

        #  If a challenge and response exists, validate
        if challenge:
            response = request.POST.get("response")
            if response:
                response = json.loads(response)
                if interface.validate_response(request, challenge, response,
                                               webauthn_signin_ff):
                    return self.perform_signin(request, user, interface)
                self.fail_signin(request, user, form)

        return render_to_response(
            [
                "sentry/twofactor_%s.html" % interface.interface_id,
                "sentry/twofactor.html"
            ],
            {
                "form":
                form,
                "interface":
                interface,
                "other_interfaces":
                self.get_other_interfaces(interface, interfaces),
                "activation":
                activation,
                "isWebauthnSigninFFEnabled":
                webauthn_signin_ff,
            },
            request,
            status=200,
        )
    def handle(self, request):
        user = auth.get_pending_2fa_user(request)
        if user is None:
            return HttpResponseRedirect(auth.get_login_url())

        interfaces = Authenticator.objects.all_interfaces_for_user(user)

        # If for whatever reason we ended up here but the user has no 2FA
        # enabled, we just continue successfully.
        if not interfaces:
            return self.perform_signin(request, user)

        challenge = activation = None
        interface = self.negotiate_interface(request, interfaces)

        if request.method == 'POST' and ratelimiter.is_limited(
            u'auth-2fa:user:{}'.format(user.id),
            limit=5,
            window=60,
        ):
            # TODO: Maybe email the account owner or do something to notify someone
            # This would probably be good for them to know.
            return HttpResponse(
                'You have made too many 2FA attempts. Please try again later.',
                content_type='text/plain',
                status=429,
            )

        if request.method == 'GET':
            activation = interface.activate(request)
            if activation is not None and activation.type == 'challenge':
                challenge = activation.challenge
        elif 'challenge' in request.POST:
            challenge = json.loads(request.POST['challenge'])

        form = TwoFactorForm()

        # If an OTP response was supplied, we try to make it pass.
        otp = request.POST.get('otp')
        if otp:
            used_interface = self.validate_otp(otp, interface, interfaces)
            if used_interface is not None:
                return self.perform_signin(request, user, used_interface)
            self.fail_signin(request, user, form)

        # If a challenge and response exists, validate
        if challenge:
            response = request.POST.get('response')
            if response:
                response = json.loads(response)
                if interface.validate_response(request, challenge, response):
                    return self.perform_signin(request, user, interface)
                self.fail_signin(request, user, form)

        return render_to_response(
            ['sentry/twofactor_%s.html' % interface.interface_id, 'sentry/twofactor.html'], {
                'form': form,
                'interface': interface,
                'other_interfaces': self.get_other_interfaces(interface, interfaces),
                'activation': activation,
            },
            request,
            status=200
        )
示例#29
0
    def handle_basic_auth(self, request, **kwargs):
        can_register = self.can_register(request)

        op = request.POST.get("op")
        organization = kwargs.pop("organization", None)

        if not op:
            # Detect that we are on the register page by url /register/ and
            # then activate the register tab by default.
            if "/register" in request.path_info and can_register:
                op = "register"
            elif request.GET.get("op") == "sso":
                op = "sso"

        login_form = self.get_login_form(request)
        if can_register:
            register_form = self.get_register_form(
                request,
                initial={"username": request.session.get("invite_email", "")})
        else:
            register_form = None

        if can_register and register_form.is_valid():
            user = register_form.save()
            user.send_confirm_emails(is_new_user=True)
            user_signup.send_robust(sender=self,
                                    user=user,
                                    source="register-form",
                                    referrer="in-app")

            # HACK: grab whatever the first backend is and assume it works
            user.backend = settings.AUTHENTICATION_BACKENDS[0]

            auth.login(
                request,
                user,
                organization_id=organization.id if organization else None)

            # can_register should only allow a single registration
            request.session.pop("can_register", None)
            request.session.pop("invite_email", None)

            # Attempt to directly accept any pending invites
            invite_helper = ApiInviteHelper.from_cookie(request=request,
                                                        instance=self)

            # In single org mode, associate the user to the only organization.
            #
            # XXX: Only do this if there isn't a pending invitation. The user
            # may need to configure 2FA in which case, we don't want to make
            # the association for them.
            if settings.SENTRY_SINGLE_ORGANIZATION and not invite_helper:
                organization = Organization.get_default()
                OrganizationMember.objects.create(
                    organization=organization,
                    role=organization.default_role,
                    user=user)

            if invite_helper and invite_helper.valid_request:
                invite_helper.accept_invite()
                response = self.redirect_to_org(request)
                remove_invite_cookie(request, response)

                return response

            return self.redirect(auth.get_login_redirect(request))

        elif request.method == "POST":
            from sentry.app import ratelimiter
            from sentry.utils.hashlib import md5_text

            login_attempt = (op == "login" and request.POST.get("username")
                             and request.POST.get("password"))

            if login_attempt and ratelimiter.is_limited(
                    "auth:login:username:{}".format(
                        md5_text(
                            login_form.clean_username(
                                request.POST["username"])).hexdigest()),
                    limit=10,
                    window=60,  # 10 per minute should be enough for anyone
            ):
                login_form.errors["__all__"] = [
                    "You have made too many login attempts. Please try again later."
                ]
                metrics.incr("login.attempt",
                             instance="rate_limited",
                             skip_internal=True,
                             sample_rate=1.0)
            elif login_form.is_valid():
                user = login_form.get_user()

                auth.login(
                    request,
                    user,
                    organization_id=organization.id if organization else None)
                metrics.incr("login.attempt",
                             instance="success",
                             skip_internal=True,
                             sample_rate=1.0)

                if not user.is_active:
                    return self.redirect(reverse("sentry-reactivate-account"))
                if organization and settings.SENTRY_SINGLE_ORGANIZATION:
                    try:
                        om = OrganizationMember.objects.get(
                            organization=organization, email=user.email)
                    except OrganizationMember.DoesNotExist:
                        pass
                    else:
                        # XXX(jferge): if user is in 2fa removed state,
                        # dont redirect to org login page instead redirect to general login where
                        # they will be prompted to check their email
                        if om.user is None:
                            return self.redirect(auth.get_login_url())

                return self.redirect(auth.get_login_redirect(request))
            else:
                metrics.incr("login.attempt",
                             instance="failure",
                             skip_internal=True,
                             sample_rate=1.0)

        context = {
            "op": op or "login",
            "server_hostname": get_server_hostname(),
            "login_form": login_form,
            "organization": organization,
            "register_form": register_form,
            "CAN_REGISTER": can_register,
            "join_request_link": self.get_join_request_link(organization),
        }
        context.update(additional_context.run_callbacks(request))
        return self.respond_login(request, context, **kwargs)
示例#30
0
 def wrapped(request, *args, **kwargs):
     if not request.user_from_signed_request:
         messages.add_message(request, messages.ERROR, ERR_BAD_SIGNATURE)
         return HttpResponseRedirect(auth.get_login_url())
     return func(request, *args, **kwargs)
示例#31
0
 def get_redirect_uri(self, request, exception):
     return absolute_uri(auth.get_login_url())
示例#32
0
 def redirect(self, request):
     next = request.GET.get(REDIRECT_FIELD_NAME, "")
     if not is_safe_url(next, host=request.get_host()):
         next = auth.get_login_url()
     return super().redirect(next)
示例#33
0
 def redirect(self, request):
     next = request.GET.get(REDIRECT_FIELD_NAME, '')
     if not is_safe_url(next, host=request.get_host()):
         next = auth.get_login_url()
     return super(AuthLogoutView, self).redirect(next)
示例#34
0
 def wrapped(request, *args, **kwargs):
     if not request.user_from_signed_request:
         messages.add_message(
             request, messages.ERROR, ERR_BAD_SIGNATURE)
         return HttpResponseRedirect(auth.get_login_url())
     return func(request, *args, **kwargs)
示例#35
0
 def get_redirect_uri(self, request, exception):
     return absolute_uri(auth.get_login_url())