Skip to content

Commit

Permalink
#70 closed
Browse files Browse the repository at this point in the history
  • Loading branch information
mkalioby committed Dec 19, 2022
1 parent 25be381 commit 17ef0f4
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 14 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# Change Log
## 2.7.0 (Dev)
* Fixed #70
* Add QR Code for trusted device link
* Better formatting for trusted device start page.
## 2.6.1
* Fix: CVE-2022-42731: related to the possibility of registration replay attack.
Thanks to 'SSE (Secure Systems Engineering)'
Expand Down
3 changes: 2 additions & 1 deletion example/example/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@
from django.contrib import admin
from django.urls import path,re_path,include
from . import views,auth
from mfa import TrustedDevice
urlpatterns = [
path('admin/', admin.site.urls),
path('mfa/', include('mfa.urls')),
path('auth/login',auth.loginView,name="login"),
path('auth/logout',auth.logoutView,name="logout"),

path('devices/add/', TrustedDevice.add,name="add_trusted_device"),
re_path('^$',views.home,name='home'),
path('registered/',views.registered,name='registered')
]
12 changes: 8 additions & 4 deletions mfa/TrustedDevice.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@
from .models import *
import user_agents
from django.utils import timezone
from django.urls import reverse

def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
x=''.join(random.choice(chars) for _ in range(size))
if not User_Keys.objects.filter(properties__shas="$.key="+x).exists(): return x
if not User_Keys.objects.filter(properties__icontains='"key": "%s"'%x).exists(): return x
else: return id_generator(size,chars)

def getUserAgent(request):
Expand Down Expand Up @@ -57,12 +58,13 @@ def getCookie(request):
def add(request):
context=csrf(request)
if request.method=="GET":
context.update({"username":request.GET.get('u',''),"key":request.GET.get('k','')})
return render(request,"TrustedDevices/Add.html",context)
else:
key=request.POST["key"].replace("-","").replace(" ","").upper()
context["username"] = request.POST["username"]
context["key"] = request.POST["key"]
trusted_keys=User_Keys.objects.filter(username=request.POST["username"],properties__has="$.key="+key)
trusted_keys=User_Keys.objects.filter(username=request.POST["username"],properties__icontains='"key": "%s"'%key)
cookie=False
if trusted_keys.exists():
tk=trusted_keys[0]
Expand Down Expand Up @@ -97,7 +99,7 @@ def start(request):
request.session["td_id"]=td.id
try:
if td==None: td=User_Keys.objects.get(id=request.session["td_id"])
context={"key":td.properties["key"]}
context={"key":td.properties["key"],"url":request.scheme+"://"+request.get_host() + reverse('add_trusted_device')}
except:
del request.session["td_id"]
return start(request)
Expand All @@ -124,12 +126,14 @@ def verify(request):
json= jwt.decode(request.COOKIES.get('deviceid'),settings.SECRET_KEY)
if json["username"].lower()== request.session['base_username'].lower():
try:
uk = User_Keys.objects.get(username=request.POST["username"].lower(), properties__has="$.key=" + json["key"])
uk = User_Keys.objects.get(username=request.POST["username"].lower(), properties__icontains='"key": "%s"'%json["key"])
if uk.enabled and uk.properties["status"] == "trusted":
uk.last_used=timezone.now()
uk.save()
request.session["mfa"] = {"verified": True, "method": "Trusted Device","id":uk.id}
return True
except:
import traceback
print(traceback.format_exc())
return False
return False
53 changes: 46 additions & 7 deletions mfa/templates/TrustedDevices/start.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{% extends "base.html" %}
{% load static %}
{% block head %}
<script src="{% static 'mfa/js/qrious.min.js' %}" type="text/javascript"></script>
<style>
#two-factor-steps {
border: 1px solid #ccc;
Expand All @@ -12,6 +14,12 @@
</style>

<script type="text/javascript">
$(document).ready(function (){
var qr = new QRious({
element: document.getElementById('qr'),
value: "{{ url }}?u={{ request.user.username }}&k={{ key }}"
});
})
function sendEmail() {
$("#modal-title").html("Send Link")
$("#modal-body").html("Sending Email, Please wait....");
Expand Down Expand Up @@ -82,21 +90,52 @@ <h4>Add Trusted Device</h4>
{% if not_allowed %}
<div class="alert alert-danger">You can't add any more devices, you need to remove previously trusted devices first.</div>
{% else %}
<p style="color: green">Allow access from mobile phone and tables.</p>
<h5>Steps:</h5>
<ol>
<p style="color: green">Allow access from mobile phone and tables.</p><br/>
<br/>
</div>
<div class="row">
<h5>Steps:</h5>
</div>

<div class="row">
<div class="col-md-6">
<h5>Using Camera</h5>
<ol>
<li>Using your mobile/table, open Chrome/Firefox.</li>
<li>Scan the following barcode <br/>
<img id="qr"/> <br/>
</li>
<li>Confirm the consent and submit form.</li>
</ol>
</div>


<div class="col-md-6">
<h5>Manual</h5>
<ol>
<li>Using your mobile/table, open Chrome/Firefox.</li>
<li>Go to <b>{{ HOST }}{{ BASE_URL }}devices/add</b>&nbsp;&nbsp;<a href="javascript:void(0)" onclick="sendEmail()" title="Send to my email"><i class="fas fa-paper-plane"></i></a></li>
<li>Go to <b>{{ url }}</b>&nbsp;&nbsp;</li>
<li>Enter your username & following 6 digits<br/>
<span style="font-size: 16px;font-weight: bold; margin-left: 50px">{{ key|slice:":3" }} - {{ key|slice:"3:" }}</span>
</li>
<li>This window will ask to confirm the device.</li>
<li>Confirm the consent and submit form.</li>
</div>
</div>
<div class="row">
<div class="col-md-8 offset-2">
This window will ask to confirm the device.
</div>
</div>


</ol>
{% endif %}
</div>
</div>
</div>

<br/>
<br/>
<br/>
<br/>
{% include "modal.html" %}
{% include 'mfa_check.html' %}
{% endblock %}
5 changes: 3 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

setup(
name='django-mfa2',
version='2.6.1',
version='2.7.0RC1',
description='Allows user to add 2FA to their accounts',
long_description=open("README.md").read(),
long_description_content_type="text/markdown",
Expand All @@ -31,7 +31,8 @@
include_package_data=True,
zip_safe=False, # because we're including static files
classifiers=[
"Development Status :: 5 - Production/Stable",
# "Development Status :: 5 - Production/Stable",
"Development Status :: 4 - Beta",
"Environment :: Web Environment",
"Framework :: Django",
"Framework :: Django :: 2.0",
Expand Down

0 comments on commit 17ef0f4

Please sign in to comment.