def setup_totp(request):
if twofa.models.TOTPDevice.objects.active_for_user(request.user).exists():
messages.error(request, _('You may not have multiple Google Authenticators attached to your account.'))
return redirect('twofa:list')
setup_signer = TimestampSigner('twofa.views.setup_totp:{}'.format(request.user.pk))
if request.method == 'POST' and 'secret' in request.POST:
try:
b32_secret = setup_signer.unsign(request.POST['secret'], max_age=600)
except SignatureExpired:
messages.error(request, _('That took too long and your challenge expired. Here\'s a new one.'))
return redirect('twofa:setup-totp')
except BadSignature:
messages.error(request, _('Whoops - something went wrong. Please try again.'))
return redirect('twofa:setup-totp')
else:
b32_secret = base64.b32encode(secrets.token_bytes(10))
signed_secret = setup_signer.sign(b32_secret)
url = 'otpauth://totp/Sponge:{}?{}'.format(
urlquote(request.user.username),
urlencode({
'secret': b32_secret,
'issuer': 'Sponge'}))
img = qrcode.make(url, image_factory=qrcode.image.svg.SvgPathFillImage)
img_buf = io.BytesIO()
img.save(img_buf)
device = twofa.models.TOTPDevice(base32_secret=b32_secret, owner=request.user)
device.activated_at = timezone.now() # this won't be saved unless the form is valid
form = device.verify_form(secret=signed_secret)
if request.method == 'POST':
form = device.verify_form(request.POST, secret=signed_secret)
if form.is_valid():
# relying on verify_form to save the new device
request.user.twofa_enabled = True
request.user.save()
messages.success(request, _('Your authenticator has been added to your account.'))
return _generate_paper_codes_if_needed(request.user, reverse('twofa:list'))
return render(request, 'twofa/setup/totp.html', {
'form': form, 'qr_code_svg': img_buf.getvalue(), 'b32_secret': b32_secret})
评论列表
文章目录