Better Error Handling
This commit is contained in:
104
mfa/FIDO2.py
104
mfa/FIDO2.py
@@ -12,7 +12,7 @@ from django.conf import settings
|
|||||||
from .models import *
|
from .models import *
|
||||||
from fido2.utils import websafe_decode,websafe_encode
|
from fido2.utils import websafe_decode,websafe_encode
|
||||||
from fido2.ctap2 import AttestedCredentialData
|
from fido2.ctap2 import AttestedCredentialData
|
||||||
from .views import login
|
from .views import login,reset_cookie
|
||||||
import datetime
|
import datetime
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
@@ -87,54 +87,60 @@ def authenticate_begin(request):
|
|||||||
|
|
||||||
@csrf_exempt
|
@csrf_exempt
|
||||||
def authenticate_complete(request):
|
def authenticate_complete(request):
|
||||||
credentials = []
|
|
||||||
username=request.session.get("base_username",request.user.username)
|
|
||||||
server=getServer()
|
|
||||||
credentials=getUserCredentials(username)
|
|
||||||
data = cbor.decode(request.body)
|
|
||||||
credential_id = data['credentialId']
|
|
||||||
client_data = ClientData(data['clientDataJSON'])
|
|
||||||
auth_data = AuthenticatorData(data['authenticatorData'])
|
|
||||||
signature = data['signature']
|
|
||||||
try:
|
try:
|
||||||
cred = server.authenticate_complete(
|
credentials = []
|
||||||
request.session.pop('fido_state'),
|
username=request.session.get("base_username",request.user.username)
|
||||||
credentials,
|
server=getServer()
|
||||||
credential_id,
|
credentials=getUserCredentials(username)
|
||||||
client_data,
|
data = cbor.decode(request.body)
|
||||||
auth_data,
|
credential_id = data['credentialId']
|
||||||
signature
|
client_data = ClientData(data['clientDataJSON'])
|
||||||
)
|
auth_data = AuthenticatorData(data['authenticatorData'])
|
||||||
except ValueError:
|
signature = data['signature']
|
||||||
return HttpResponse(simplejson.dumps({'status': "ERR", "message": "Wrong challenge received, make sure that this is your security and try again."}),
|
|
||||||
content_type = "application/json")
|
|
||||||
except Exception as excep:
|
|
||||||
try:
|
try:
|
||||||
from raven.contrib.django.raven_compat.models import client
|
cred = server.authenticate_complete(
|
||||||
client.captureException()
|
request.session.pop('fido_state'),
|
||||||
except:
|
credentials,
|
||||||
pass
|
credential_id,
|
||||||
return HttpResponse(simplejson.dumps({'status': "ERR",
|
client_data,
|
||||||
"message": "Err: " + excep.message}),
|
auth_data,
|
||||||
content_type = "application/json")
|
signature
|
||||||
|
)
|
||||||
|
except ValueError:
|
||||||
|
return HttpResponse(simplejson.dumps({'status': "ERR", "message": "Wrong challenge received, make sure that this is your security and try again."}),
|
||||||
|
content_type = "application/json")
|
||||||
|
except Exception as excep:
|
||||||
|
try:
|
||||||
|
from raven.contrib.django.raven_compat.models import client
|
||||||
|
client.captureException()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return HttpResponse(simplejson.dumps({'status': "ERR",
|
||||||
|
"message": excep.message}),
|
||||||
|
content_type = "application/json")
|
||||||
|
|
||||||
if request.session.get("mfa_recheck",False):
|
if request.session.get("mfa_recheck",False):
|
||||||
import time
|
import time
|
||||||
request.session["mfa"]["rechecked_at"]=time.time()
|
request.session["mfa"]["rechecked_at"]=time.time()
|
||||||
return HttpResponse(simplejson.dumps({'status': "OK"}),
|
return HttpResponse(simplejson.dumps({'status': "OK"}),
|
||||||
content_type="application/json")
|
content_type="application/json")
|
||||||
else:
|
else:
|
||||||
import random
|
import random
|
||||||
keys = User_Keys.objects.filter(username=username, key_type="FIDO2", enabled=1)
|
keys = User_Keys.objects.filter(username=username, key_type="FIDO2", enabled=1)
|
||||||
for k in keys:
|
for k in keys:
|
||||||
if AttestedCredentialData(websafe_decode(k.properties["device"])).credential_id == cred.credential_id:
|
if AttestedCredentialData(websafe_decode(k.properties["device"])).credential_id == cred.credential_id:
|
||||||
k.last_used = timezone.now()
|
k.last_used = timezone.now()
|
||||||
k.save()
|
k.save()
|
||||||
mfa = {"verified": True, "method": "FIDO2",'id':k.id}
|
mfa = {"verified": True, "method": "FIDO2",'id':k.id}
|
||||||
if getattr(settings, "MFA_RECHECK", False):
|
if getattr(settings, "MFA_RECHECK", False):
|
||||||
mfa["next_check"] = int((datetime.datetime.now()+ datetime.timedelta(
|
mfa["next_check"] = int((datetime.datetime.now()+ datetime.timedelta(
|
||||||
seconds=random.randint(settings.MFA_RECHECK_MIN, settings.MFA_RECHECK_MAX))).strftime("%s"))
|
seconds=random.randint(settings.MFA_RECHECK_MIN, settings.MFA_RECHECK_MAX))).strftime("%s"))
|
||||||
request.session["mfa"] = mfa
|
request.session["mfa"] = mfa
|
||||||
res=login(request)
|
if not request.user.is_authenticated():
|
||||||
return HttpResponse(simplejson.dumps({'status':"OK","redirect":res["location"]}),content_type="application/json")
|
res=login(request)
|
||||||
return HttpResponse(simplejson.dumps({'status': "ERR","message":"Unknown error happened"}),content_type="application/json")
|
if not "location" in res: return reset_cookie(request)
|
||||||
|
return HttpResponse(simplejson.dumps({'status':"OK","redirect":res["location"]}),content_type="application/json")
|
||||||
|
return HttpResponse(simplejson.dumps({'status': "OK"}),
|
||||||
|
content_type = "application/json")
|
||||||
|
except Exception as exp:
|
||||||
|
return HttpResponse(simplejson.dumps({'status': "ERR","message":exp.message}),content_type="application/json")
|
||||||
|
|||||||
@@ -82,7 +82,7 @@
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$("#msgdiv").addClass("alert alert-danger").removeClass("alert-success")
|
$("#msgdiv").addClass("alert alert-danger").removeClass("alert-success")
|
||||||
$("#res").html("<div class='alert alert-danger'>Verification Failed as " + res["message"] + ", <a href='javascript:void(0)' onclick='authen())'> try again or <a href='javascript:void(0)' onclick='history.back()'> Go Back</a></div>")
|
$("#msgdiv").html("Verification Failed as " + res.message + ", <a href='javascript:void(0)' onclick='authen())'> try again</a> or <a href='javascript:void(0)' onclick='history.back()'> Go Back</a>")
|
||||||
|
|
||||||
{% if mode == "auth" %}
|
{% if mode == "auth" %}
|
||||||
|
|
||||||
|
|||||||
@@ -27,10 +27,7 @@ urlpatterns = [
|
|||||||
url(r'fido2/complete_auth', FIDO2.authenticate_complete, name="fido2_complete_auth"),
|
url(r'fido2/complete_auth', FIDO2.authenticate_complete, name="fido2_complete_auth"),
|
||||||
url(r'fido2/begin_reg', FIDO2.begin_registeration, name="fido2_begin_reg"),
|
url(r'fido2/begin_reg', FIDO2.begin_registeration, name="fido2_begin_reg"),
|
||||||
url(r'fido2/complete_reg', FIDO2.complete_reg, name="fido2_complete_reg"),
|
url(r'fido2/complete_reg', FIDO2.complete_reg, name="fido2_complete_reg"),
|
||||||
url(r'u2f/bind', U2F.bind, name="bind_u2f"),
|
url(r'fido2/recheck', FIDO2.recheck, name="fido2_recheck"),
|
||||||
url(r'u2f/auth', U2F.auth, name="u2f_auth"),
|
|
||||||
url(r'u2f/process_recheck', U2F.process_recheck, name="u2f_recheck"),
|
|
||||||
url(r'u2f/verify', U2F.verify, name="u2f_verify"),
|
|
||||||
|
|
||||||
|
|
||||||
url(r'td/$', TrustedDevice.start, name="start_td"),
|
url(r'td/$', TrustedDevice.start, name="start_td"),
|
||||||
|
|||||||
2
setup.py
2
setup.py
@@ -4,7 +4,7 @@ from setuptools import find_packages, setup
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='django-mfa2',
|
name='django-mfa2',
|
||||||
version='1.7.5',
|
version='1.7.11',
|
||||||
description='Allows user to add 2FA to their accounts',
|
description='Allows user to add 2FA to their accounts',
|
||||||
long_description=open("README.md").read(),
|
long_description=open("README.md").read(),
|
||||||
long_description_content_type="text/markdown",
|
long_description_content_type="text/markdown",
|
||||||
|
|||||||
Reference in New Issue
Block a user