def handle(self, request): user = auth.get_pending_2fa_user(request) if user is None or request.user.is_authenticated(): return HttpResponseRedirect(reverse('sentry')) 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): 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): user = auth.get_pending_2fa_user(request) if user is None or request.user.is_authenticated(): return HttpResponseRedirect(reverse('sentry')) 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: 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 )