Initial Import
This commit is contained in:
10
mfa/templates/ApproveLogin/Add.html
Normal file
10
mfa/templates/ApproveLogin/Add.html
Normal file
@@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
62
mfa/templates/FIDO2/Add.html
Normal file
62
mfa/templates/FIDO2/Add.html
Normal file
@@ -0,0 +1,62 @@
|
||||
{% extends "base.html" %}
|
||||
{% block head %}
|
||||
<script type="application/javascript" src="{{ STATIC_URL }}js/cbor.js"></script>
|
||||
<script type="application/javascript">
|
||||
function begin_reg(){
|
||||
fetch('{% url 'fido2_begin_reg' %}',{}).then(function(response) {
|
||||
if(response.ok)
|
||||
{
|
||||
return response.arrayBuffer();
|
||||
}
|
||||
throw new Error('Error getting registration data!');
|
||||
}).then(CBOR.decode).then(function(options) {
|
||||
options.publicKey.attestation="direct"
|
||||
console.log(options)
|
||||
|
||||
return navigator.credentials.create(options);
|
||||
}).then(function(attestation) {
|
||||
return fetch('{% url 'fido2_complete_reg' %}', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/cbor'},
|
||||
body: CBOR.encode({
|
||||
"attestationObject": new Uint8Array(attestation.response.attestationObject),
|
||||
"clientDataJSON": new Uint8Array(attestation.response.clientDataJSON),
|
||||
})
|
||||
});
|
||||
}).then(function(response) {
|
||||
|
||||
var stat = response.ok ? 'successful' : 'unsuccessful';
|
||||
return response.json()
|
||||
}).then(function (res)
|
||||
{
|
||||
if (res["status"] =='OK')
|
||||
$("#res").html("<div class='alert alert-success'>Registered Successfully, <a href='{% url 'mfa_home' %}'> Go to Security Home</a></div>")
|
||||
else
|
||||
$("#res").html("<div class='alert alert-danger'>Registeration Failed as " + res["message"] + ", <a href='javascript:void(0)' onclick='begin_reg()'> try again or <a href='{% url 'mfa_home' %}'> Go to Security Home</a></div>")
|
||||
|
||||
|
||||
}, function(reason) {
|
||||
$("#res").html("<div class='alert alert-danger'>Registeration Failed as " +reason +", <a href='javascript:void(0)' onclick='begin_reg()'> try again </a> or <a href='{% url 'mfa_home' %}'> Go to Security Home</a></div>")
|
||||
})
|
||||
}
|
||||
$(document).ready(setTimeout(begin_reg,500))
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong> FIDO2 Security Key</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
||||
|
||||
<div class="row alert alert-pr" id="res">
|
||||
<p style="color: green">Your broswer should ask you to confirm you indentity.</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% include "modal.html" %}
|
||||
{% endblock %}
|
||||
4
mfa/templates/FIDO2/Auth.html
Normal file
4
mfa/templates/FIDO2/Auth.html
Normal file
@@ -0,0 +1,4 @@
|
||||
{% extends "login_base.html" %}
|
||||
{% block form %}
|
||||
{% include 'FIDO2/recheck.html' with mode='auth' %}
|
||||
{% endblock %}
|
||||
103
mfa/templates/FIDO2/recheck.html
Normal file
103
mfa/templates/FIDO2/recheck.html
Normal file
@@ -0,0 +1,103 @@
|
||||
<script type="application/javascript" src="{{ STATIC_URL }}js/cbor.js"></script>
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-10 col-sm-offset-1 col-xs-12 col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong> Security Key</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
||||
<div class="row">
|
||||
<div style="padding-left: 15px" class="col-md-10 col-md-offset-1" id="main_paragraph" align="center">
|
||||
{% if mode == "auth" %}
|
||||
Welcome back <img src="{% url 'getUserImage' request.session.base_username %}" title="{{ request.session.base_username }}" style="padding: 3px;height: 50px" class="img-circle"/> {{ request.session.base_username }}<br/>
|
||||
<a href="{% url 'mfa_reset_cookie' %}">Not me</a>
|
||||
<br/>
|
||||
|
||||
{% endif %}
|
||||
<p style="color: green">please press the button on your security key to prove it is you.</p>
|
||||
{% if mode == "auth" %}
|
||||
<form id="u2f_login" action="{% url 'fido2_complete_auth' %}" method="post" enctype="multipart/form-data">
|
||||
{% elif mode == "recheck" %}
|
||||
<form id="u2f_login" action="{% url 'u2f_recheck' %}" method="post">
|
||||
{% endif %}
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="response" id="response" value=""/>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div style="padding-left: 15px">
|
||||
|
||||
{% if request.session.mfa_methods|length > 1 %}
|
||||
<a href="{% url 'mfa_methods_list' %}">Select Another Method</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
function authen()
|
||||
{
|
||||
fetch('{% url 'fido2_begin_auth' %}', {
|
||||
method: 'GET',
|
||||
}).then(function(response) {
|
||||
if(response.ok) return response.arrayBuffer();
|
||||
throw new Error('No credential available to authenticate!');
|
||||
}).then(CBOR.decode).then(function(options) {
|
||||
console.log(options)
|
||||
return navigator.credentials.get(options);
|
||||
}).then(function(assertion) {
|
||||
res=CBOR.encode({
|
||||
"credentialId": new Uint8Array(assertion.rawId),
|
||||
"authenticatorData": new Uint8Array(assertion.response.authenticatorData),
|
||||
"clientDataJSON": new Uint8Array(assertion.response.clientDataJSON),
|
||||
"signature": new Uint8Array(assertion.response.signature)
|
||||
});
|
||||
|
||||
return fetch('{% url 'fido2_complete_auth' %}', {
|
||||
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/cbor'},
|
||||
body:res,
|
||||
|
||||
}).then(function (response) {if (response.ok) return res = response.json()}).then(function (res) {
|
||||
if (res.status=="OK")
|
||||
{
|
||||
{% if mode == "auth" %}
|
||||
window.location.href=res.redirect;
|
||||
{% elif mode == "recheck" %}
|
||||
mfa_success_function();
|
||||
{% endif %}
|
||||
}
|
||||
else {
|
||||
{% if mode == "auth" %}
|
||||
alert("Error occured, please try again")
|
||||
login()
|
||||
{% elif mode == "recheck" %}
|
||||
mfa_failed_function();
|
||||
{% endif %}
|
||||
}
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
$(document).ready(function () {
|
||||
if (location.protocol != 'https:') {
|
||||
$("#main_paragraph").addClass("alert alert-danger")
|
||||
$("#main_paragraph").html("FIDO2 must work under secure context")
|
||||
} else {
|
||||
authen()
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
95
mfa/templates/MFA.html
Normal file
95
mfa/templates/MFA.html
Normal file
@@ -0,0 +1,95 @@
|
||||
{% extends "base.html" %}
|
||||
{% block head %}
|
||||
<script src="{{ STATIC_URL }}js/qrious.min.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
function confirmDel(id) {
|
||||
$.ajax({
|
||||
url:"{% url 'mfa_delKey' %}",
|
||||
data:{"id":id},
|
||||
success:function (data) {
|
||||
alert(data)
|
||||
window.location.reload();
|
||||
}
|
||||
})
|
||||
}
|
||||
function deleteKey(id,name)
|
||||
{
|
||||
$("#modal-title").html("Confirm Delete")
|
||||
$("#modal-body").html("Are you sure you want to delete '"+name+"'? you may lose access to your system if this your only 2FA.");
|
||||
$("#actionBtn").remove()
|
||||
$("#modal-footer").prepend("<button id='actionBtn' class='btn btn-danger' onclick='confirmDel("+id+")'>Confirm Deletion</button>")
|
||||
$("#popUpModal").modal()
|
||||
}
|
||||
function toggleKey(id) {
|
||||
$.ajax({
|
||||
url:"{% url 'toggle_key' %}?id="+id,
|
||||
success:function (data) {
|
||||
if (data == "Error")
|
||||
$("#toggle_"+id).toggle()
|
||||
|
||||
},
|
||||
error:function (data) {
|
||||
$("#toggle_"+id).toggle()
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<link href="{{ STATIC_URL }}css/bootstrap-toggle.min.css" rel="stylesheet">
|
||||
<script src="{{ STATIC_URL }}js/bootstrap-toggle.min.js"></script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div align="center">
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-success dropdown-toggle" data-toggle="dropdown">
|
||||
Add Method <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
{% if not 'TOTP' in UNALLOWED_AUTHEN_METHODS %}
|
||||
<li><a href="{% url 'start_new_otop' %}">Authenticator app</a></li>
|
||||
{% endif %}
|
||||
{% if not 'U2F' in UNALLOWED_AUTHEN_METHODS %}
|
||||
<li><a href="{% url 'start_u2f' %}">Security Key</a></li>
|
||||
{% endif %}
|
||||
{% if not 'FIDO2' in UNALLOWED_AUTHEN_METHODS %}
|
||||
<li><a href="{% url 'start_fido2' %}">FIDO2 Security Key</a></li>
|
||||
{% endif %}
|
||||
{% if not 'Trusted_Devices' in UNALLOWED_AUTHEN_METHODS %}
|
||||
<li><a href="{% url 'start_td' %}">Trusted Device</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
<table class="table table-striped">
|
||||
<tr>
|
||||
|
||||
<th>Type</th>
|
||||
<th>Date Added</th>
|
||||
<th>Expires On</th>
|
||||
<th>Device</th>
|
||||
<th>Last Used</th>
|
||||
<th>Status</th>
|
||||
<th>Delete</th>
|
||||
</tr>
|
||||
{% for key in keys %}
|
||||
<tr>
|
||||
|
||||
<td>{{ key.key_type }}</td>
|
||||
<td>{{ key.added_on }}</td>
|
||||
<td>{{ key.expires }}</td>
|
||||
<td>{% if key.device %}{{ key.device }}{% endif %}</td>
|
||||
<td>{{ key.last_used }}</td>
|
||||
<td><input type="checkbox" id="toggle_{{ key.id }}" {% if key.enabled %}checked{% endif %} data-onstyle="success" data-offstyle="danger" onchange="toggleKey({{ key.id }})" data-toggle="toggle"></td>
|
||||
<td><a href="javascript:void(0)" onclick="deleteKey({{ key.id }},'{{ key.key_type }}')"> <span class="fa fa-trash"></span></a></td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr><td colspan="7" align="center">You didn't have any keys yet.</td> </tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% include "modal.html" %}
|
||||
{% endblock %}
|
||||
105
mfa/templates/TOTP/Add.html
Normal file
105
mfa/templates/TOTP/Add.html
Normal file
@@ -0,0 +1,105 @@
|
||||
{% extends "base.html" %}
|
||||
{% block head %}
|
||||
<style>
|
||||
#two-factor-steps {
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 3px;
|
||||
padding: 15px;
|
||||
}
|
||||
.row{
|
||||
margin: 0px;
|
||||
}
|
||||
</style>
|
||||
<script src="{{ STATIC_URL }}js/qrious.min.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
var key="";
|
||||
$(document).ready(function addToken() {
|
||||
$.ajax({
|
||||
"url":"{% url 'get_new_otop' %}",dataType:"JSON",
|
||||
success:function (data) {
|
||||
window.key=data.secret_key;
|
||||
var qr = new QRious({
|
||||
element: document.getElementById('qr'),
|
||||
value: data.qr
|
||||
});
|
||||
$("#second_step").show()
|
||||
}
|
||||
})
|
||||
});
|
||||
function showKey() {
|
||||
$("#modal-title").html("Your Secret Key")
|
||||
$("#modal-body").html("<pre>"+window.key+"</pre")
|
||||
$("#popUpModal").modal('show')
|
||||
}
|
||||
function verify() {
|
||||
answer=$("#answer").val()
|
||||
$.ajax({
|
||||
"url":"{% url 'verify_otop' %}?key="+key+ "&answer="+answer,
|
||||
success:function (data) {
|
||||
if (data == "Error")
|
||||
alert("You entered wrong numbers, please try again")
|
||||
else
|
||||
{
|
||||
alert("Your authenticator is added successfully.")
|
||||
window.location.href="{% url 'mfa_home' %}"
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
function showTOTP() {
|
||||
$("#modal-title").html("One Time Password Apps")
|
||||
html="<div class='row'><ul>"+
|
||||
"<li>Android: <a href='https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2' target='_blank'>Google Authenticator</a> | <a href='https://play.google.com/store/apps/details?id=com.authy.authy' target='_blank'>Authy</a></li>"
|
||||
html+="<li>iPhone/iPad: <a href='https://itunes.apple.com/us/app/authy/id494168017' target='_blank'>Authy</a></li> "
|
||||
html+="<li>Chrome: <a href='https://chrome.google.com/webstore/detail/authenticator/bhghoamapcdpbohphigoooaddinpkbai?hl=en'>Google Authenticator</a> | <a href='https://chrome.google.com/webstore/detail/authy/gaedmjdfmmahhbjefcbgaolhhanlaolb?hl=en' target='_blank'>Authy</a></li>"
|
||||
html+="</ul></div>"
|
||||
$("#modal-body").html(html)
|
||||
$('#popUpModal').modal('show')
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<div class="col-md-6 col-md-offset-3" id="two-factor-steps">
|
||||
<div class="row" align="center">
|
||||
<h4>Adding Authenticator</h4>
|
||||
</div>
|
||||
<div class="row">
|
||||
|
||||
<p>Scan the image below with the two-factor authentication app on your <a href="javascript:void(0)" onclick="showTOTP()">phone/PC</a> phone/PC. If you can’t use a barcode,
|
||||
<a href="javascript:void(0)" onclick="showKey()">enter this text</a> instead. </p>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div align="center" style="display: none" id="second_step">
|
||||
|
||||
<img id="qr"/>
|
||||
|
||||
</div>
|
||||
<div class="row">
|
||||
|
||||
<p><b>Enter the six-digit code from the application</b></p>
|
||||
<p style="color: #333333;font-size: 10px">After scanning the barcode image, the app will display a six-digit code that you can enter below. </p>
|
||||
|
||||
</div>
|
||||
<div class="row">
|
||||
|
||||
|
||||
<input style="display: inline;width: 95%" maxlength="6" size="6" class="form-control" id="answer" placeholder="e.g 785481"/>
|
||||
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6" style="padding-left: 0px">
|
||||
<button class="btn btn-success" onclick="verify()">Enable</button>
|
||||
</div>
|
||||
<div class="col-md-6" align="right" style="padding-right: 30px">
|
||||
<a href="{% url 'mfa_home' %}"><button class="btn btn-default">Cancel</button></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% include "modal.html" %}
|
||||
{% endblock %}
|
||||
76
mfa/templates/TOTP/recheck.html
Normal file
76
mfa/templates/TOTP/recheck.html
Normal file
@@ -0,0 +1,76 @@
|
||||
<script type="application/javascript">
|
||||
function send_totp() {
|
||||
$.ajax({"url":"{% url 'totp_recheck' %}", method:"POST",dataType:"JSON",
|
||||
data:{"csrfmiddlewaretoken":"{{ csrf_token }}","otp":$("#otp").val()},
|
||||
success:function (data) {
|
||||
if (data["recheck"])
|
||||
mfa_success_function();
|
||||
else {
|
||||
mfa_failed_function();
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
</script>
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-10 col-sm-offset-1 col-xs-12 col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong> One Time Password</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
||||
<FORM METHOD="POST" ACTION="{% url 'totp_auth' %}" Id="formLogin" onSubmit="" name="FrontPage_Form1">
|
||||
|
||||
|
||||
{% csrf_token %}
|
||||
{% if invalid %}
|
||||
<div class="alert alert-danger">
|
||||
Sorry, The provided token is not valid.
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if quota %}
|
||||
<div class="alert alert-warning">
|
||||
{{ quota }}
|
||||
</div>
|
||||
{% endif %}
|
||||
<fieldset>
|
||||
<div class="row">
|
||||
<div class="col-sm-12 col-md-12">
|
||||
<p>Enter the 6-digits on your authenticator.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-12 col-md-12">
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">
|
||||
<i class="glyphicon glyphicon-lock"></i>
|
||||
</span>
|
||||
<input class="form-control" size="6" MaxLength="6" value="" placeholder="e.g 55552" name="otp" type="text" id="otp" autofocus>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<input type="{% if mode == "auth" %}submit{% elif mode == 'recheck' %}button{% endif %}" {% if mode == "recheck" %}onclick="send_totp()" {% endif %} class="btn btn-lg btn-success btn-block" value="Sign in">
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</FORM>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6" style="padding-left: 25px">
|
||||
{% if request.session.mfa_methods|length > 1 %}
|
||||
<a href="{% url 'mfa_methods_list' %}">Select Another Method</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
13
mfa/templates/TOTP/verify.html
Normal file
13
mfa/templates/TOTP/verify.html
Normal file
@@ -0,0 +1,13 @@
|
||||
{% extends "login_base.html" %}
|
||||
{% block head %}
|
||||
<style>
|
||||
.row{
|
||||
margin-left: 15px;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
{% block form %}
|
||||
|
||||
{% include "TOTP/recheck.html" with mode='auth' %}
|
||||
|
||||
{% endblock %}
|
||||
123
mfa/templates/TrustedDevices/Add.html
Normal file
123
mfa/templates/TrustedDevices/Add.html
Normal file
@@ -0,0 +1,123 @@
|
||||
{% extends "login_base.html" %}
|
||||
{% block head %}
|
||||
<script type="application/javascript">
|
||||
function checkFlag() {
|
||||
if ($("#agree").is(":checked"))
|
||||
return true;
|
||||
else
|
||||
alert("Please agree to the statement first");
|
||||
return false;
|
||||
}
|
||||
function checkTrusted() {
|
||||
$.ajax({
|
||||
url:"{% url 'td_checkTrusted' %}",
|
||||
success:function (data) {
|
||||
if (data == "OK")
|
||||
window.location.href="{% url 'td_securedevice' %}";
|
||||
else
|
||||
setTimeout('checkTrusted()',2000)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
$(document).ready(checkTrusted())
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block form %}
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-10 col-sm-offset-1 col-xs-12 col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong> Add Trusted Device</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{% if success %}
|
||||
<div class="alert alert-warning">
|
||||
Please check your PC window, to continue the process.
|
||||
</div>
|
||||
{% elif added %}
|
||||
<div class="alert alert-success">
|
||||
Your device is now trusted, please try to <a href="{% url 'login' %}"> login</a>
|
||||
</div>
|
||||
|
||||
{% else %}
|
||||
<div class="alert alert-warning">Please make sure you are not in private (incognito) mode <i class="fal fa-user-secret"></i></div>
|
||||
<FORM METHOD="POST" ACTION="{% url 'add_td' %}" Id="formLogin" onSubmit="return checkFlag()" name="FrontPage_Form1">
|
||||
{% csrf_token %}
|
||||
{% if invalid %}
|
||||
<div class="alert alert-danger">
|
||||
{{ invalid }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if quota %}
|
||||
<div class="alert alert-warning">
|
||||
{{ quota }}
|
||||
</div>
|
||||
{% endif %}
|
||||
<fieldset>
|
||||
<div class="row">
|
||||
<div class="col-sm-12 col-md-12">
|
||||
{# <img class="profile-img" src="{{ STATIC_URL }}img/users.png" alt="">#}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-12 col-md-12">
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">
|
||||
<i class="glyphicon glyphicon-user"></i>
|
||||
</span>
|
||||
<input class="form-control" id="username" size="30" MaxLength="30" placeholder="Username" name="username" value="{{ username }}" type="text" autofocus autocomplete="on">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">
|
||||
<i class="fa fa-key"></i>
|
||||
</span>
|
||||
<input class="form-control" placeholder="e.g GAK-Y2M" id='key' style="text-transform: uppercase" name="key" type="text" size="9" MaxLength="9" value="{{ key }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<span class="input-group">
|
||||
<input id='agree' name="agree" type="checkbox"><span style="color: red"> I confirm that this device is mine and it is only used by me.</span>
|
||||
|
||||
</div>
|
||||
{% comment %}
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">
|
||||
|
||||
|
||||
<select size="1" name="Institution_Code" style="font-size: 10pt; font-family: Calibri; height: 34px;width: 230px">
|
||||
{% for ins in institutes %}
|
||||
<option value="{{ ins.institution_code }}">{{ ins.alias }}</option>
|
||||
{% endfor %}
|
||||
|
||||
</select>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{% endcomment %}
|
||||
<div class="form-group">
|
||||
<input type="submit" class="btn btn-lg btn-success btn-block" value="Trust Device">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="panel-footer ">
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
27
mfa/templates/TrustedDevices/Done.html
Normal file
27
mfa/templates/TrustedDevices/Done.html
Normal file
@@ -0,0 +1,27 @@
|
||||
{% extends "login_base.html" %}
|
||||
{% block head %}
|
||||
{% endblock %}
|
||||
{% block form %}
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-10 col-sm-offset-1 col-xs-12 col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong> Add Trusted Device</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="alert alert-success">
|
||||
Your device is now trusted, please try to <a href="{{ HOST }}{{ BASE_URL }}accounts/login/"> login</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="panel-footer ">
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
4
mfa/templates/TrustedDevices/email.html
Normal file
4
mfa/templates/TrustedDevices/email.html
Normal file
@@ -0,0 +1,4 @@
|
||||
<p>Dear {{ request.user.last_name }}, {{ request.user.first_name }}</p>
|
||||
<p>You requested the link to add a new trusted device, please follow the link below<br/>
|
||||
<a href="{{ HOST }}{% url 'mfa_add_new_trusted_device' %}">{{ HOST }}{% url 'mfa_add_new_trusted_device' %}</a>
|
||||
</p>
|
||||
100
mfa/templates/TrustedDevices/start.html
Normal file
100
mfa/templates/TrustedDevices/start.html
Normal file
@@ -0,0 +1,100 @@
|
||||
{% extends "base.html" %}
|
||||
{% block head %}
|
||||
<style>
|
||||
#two-factor-steps {
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 3px;
|
||||
padding: 15px;
|
||||
}
|
||||
.row{
|
||||
margin: 0px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
function sendEmail() {
|
||||
$("#modal-title").html("Send Link")
|
||||
$("#modal-body").html("Sending Email, Please wait....");
|
||||
$("#popUpModal").modal();
|
||||
$.ajax({
|
||||
"url":"{% url 'td_sendemail' %}",
|
||||
success:function (data) {
|
||||
alert(data);
|
||||
$("#popUpModal").modal('toggle')
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
function failedMFA() {
|
||||
$("#modal-body").html("<div class='alert alert-danger'>Failed to validate you, please <a href='javascript:void(0)' onclick='getUserAgent()'>try again</a></div>")
|
||||
}
|
||||
function checkMFA() {
|
||||
recheck_mfa(trustDevice,failedMFA,true)
|
||||
}
|
||||
function trustDevice() {
|
||||
|
||||
$.ajax(
|
||||
{
|
||||
|
||||
"url":"{% url 'td_trust_device' %}",
|
||||
success: function (data) {
|
||||
if (data == "OK")
|
||||
{
|
||||
alert("Your are done, your device should show final confirmation")
|
||||
window.location.href="{% url 'mfa_home' %}"
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
function getUserAgent() {
|
||||
$.ajax({
|
||||
"url":"{% url 'td_get_useragent' %}",success: function(data)
|
||||
{
|
||||
if (data == "")
|
||||
setTimeout('getUserAgent()',5000)
|
||||
else
|
||||
{
|
||||
$("#modal-title").html("Confirm Trusted Device")
|
||||
$("#actionBtn").remove();
|
||||
$("#modal-footer").prepend("<button id='actionBtn' class='btn btn-success' onclick='checkMFA()'>Trust Device</button>")
|
||||
$("#modal-body").html(data)
|
||||
$("#popUpModal").modal()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
$(document).ready(getUserAgent())
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<div class="col-md-6 col-md-offset-3" id="two-factor-steps">
|
||||
<div class="row" align="center">
|
||||
<h4>Add Trusted Device</h4>
|
||||
</div>
|
||||
|
||||
<div class="row" >
|
||||
{% 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>
|
||||
<li>Using your mobile/table, open Chrome/Firefox.</li>
|
||||
<li>Go to <b>{{ HOST }}{{ BASE_URL }}devices/add</b> <a href="javascript:void(0)" onclick="sendEmail()" title="Send to my email"><i class="fas fa-paper-plane"></i></a></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>
|
||||
|
||||
</ol>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% include "modal.html" %}
|
||||
{% include 'mfa_check.html' %}
|
||||
{% endblock %}
|
||||
14
mfa/templates/TrustedDevices/user-agent.html
Normal file
14
mfa/templates/TrustedDevices/user-agent.html
Normal file
@@ -0,0 +1,14 @@
|
||||
<table>
|
||||
<tr>
|
||||
<th>Browser: </th>
|
||||
<td>{{ ua.browser.family }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Version: </th>
|
||||
<td>{{ ua.browser.version_string }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Device: </th>
|
||||
<td>{{ ua.device.brand }} / {{ ua.device.model }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
48
mfa/templates/U2F/Add.html
Normal file
48
mfa/templates/U2F/Add.html
Normal file
@@ -0,0 +1,48 @@
|
||||
{% extends "base.html" %}
|
||||
{% block head %}
|
||||
<style>
|
||||
#two-factor-steps {
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 3px;
|
||||
padding: 15px;
|
||||
}
|
||||
.row{
|
||||
margin: 0px;
|
||||
}
|
||||
</style>
|
||||
<script src="{{ STATIC_URL }}js/u2f-api.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function addToken() {
|
||||
data=JSON.parse('{{ token|safe }}')
|
||||
console.log(data)
|
||||
u2f.register(data.appId,data.registerRequests,data.registeredKeys,function (response) {
|
||||
$.ajax({
|
||||
"url":"{% url 'bind_u2f' %}",method:"POST",
|
||||
data:{"csrfmiddlewaretoken":"{{ csrf_token }}","response":JSON.stringify(response)},
|
||||
success:function (data) {
|
||||
if (data == "OK")
|
||||
{
|
||||
alert("Your device is added successfully.")
|
||||
window.location.href="{% url 'mfa_home' %}"
|
||||
}
|
||||
}
|
||||
})
|
||||
},5000)
|
||||
})
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<div class="col-md-6 col-md-offset-3" id="two-factor-steps">
|
||||
<div class="row" align="center">
|
||||
<h4>Adding Security Key</h4>
|
||||
</div>
|
||||
<div class="row">
|
||||
<p style="color: green">Your secure Key should be flashing now, please press on button.</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% include "modal.html" %}
|
||||
{% endblock %}
|
||||
4
mfa/templates/U2F/Auth.html
Normal file
4
mfa/templates/U2F/Auth.html
Normal file
@@ -0,0 +1,4 @@
|
||||
{% extends "login_base.html" %}
|
||||
{% block form %}
|
||||
{% include 'U2F/recheck.html' with mode='auth' %}
|
||||
{% endblock %}
|
||||
97
mfa/templates/U2F/recheck.html
Normal file
97
mfa/templates/U2F/recheck.html
Normal file
@@ -0,0 +1,97 @@
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-10 col-sm-offset-1 col-xs-12 col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong> Security Key</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
||||
<div class="row">
|
||||
<div style="padding-left: 15px" class="col-md-10 col-md-offset-1" id="main_paragraph" align="center">
|
||||
<p style="color: green">Your key should be flashing now, please press the button.</p>
|
||||
{% if mode == "auth" %}
|
||||
<form id="u2f_login" action="{% url 'u2f_verify' %}" method="post">
|
||||
{% elif mode == "recheck" %}
|
||||
<form id="u2f_login" action="{% url 'u2f_recheck' %}" method="post">
|
||||
{% endif %}
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="response" id="response" value=""/>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div style="padding-left: 15px">
|
||||
|
||||
{% if request.session.mfa_methods|length > 1 %}
|
||||
<a href="{% url 'mfa_methods_list' %}">Select Another Method</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="{{ STATIC_URL }}js/u2f-api.js" type="text/javascript"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
if (location.protocol != 'https:')
|
||||
{
|
||||
$("#main_paragraph").addClass("alert alert-danger")
|
||||
$("#main_paragraph").html("U2F must work under secure context")
|
||||
}
|
||||
else {
|
||||
|
||||
|
||||
data = JSON.parse('{{ token|safe }}')
|
||||
console.log(data)
|
||||
u2f.sign(data.appId, data.challenge, data.registeredKeys, function (response) {
|
||||
console.log(response)
|
||||
if (response.hasOwnProperty("errorCode") && response.errorCode != 0 )
|
||||
{
|
||||
if (response.errorCode == 4)
|
||||
{
|
||||
alert("Invalid Security Key, this security isn't linked to your account")
|
||||
}
|
||||
else if (response.errorCode == 5)
|
||||
{
|
||||
alert("Verification Timeout, please refresh the page to try again")
|
||||
}
|
||||
else
|
||||
{
|
||||
alert("Unspecified error, please try again later or try another browser.")
|
||||
}
|
||||
}
|
||||
{% if mode == "auth" %}
|
||||
else {
|
||||
$("#response").val(JSON.stringify(response))
|
||||
$("#u2f_login").submit();
|
||||
}
|
||||
{% elif mode == "recheck" %}
|
||||
else {
|
||||
$.ajax({
|
||||
"url":"{% url 'u2f_recheck' %}",
|
||||
method: "POST",
|
||||
data: {"csrfmiddlewaretoken":"{{ csrf_token }}","response":JSON.stringify(response)},
|
||||
success:function (data) {
|
||||
if (data["recheck"]) {
|
||||
mfa_success_function();
|
||||
}
|
||||
else {
|
||||
mfa_failed_function();
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
{% endif %}
|
||||
}, 5000)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
</script>
|
||||
36
mfa/templates/mfa_check.html
Normal file
36
mfa/templates/mfa_check.html
Normal file
@@ -0,0 +1,36 @@
|
||||
<script type="application/javascript">
|
||||
mfa_success_function=null;
|
||||
mfa_failed_function=null;
|
||||
function is_mfa() {
|
||||
{% if request.session.mfa.verified %}
|
||||
return true;
|
||||
{% else %}
|
||||
return false;
|
||||
{% endif %}
|
||||
}
|
||||
function recheck_mfa(success_func,fail_func,must_mfa) {
|
||||
if (!must_mfa) success_func()
|
||||
window.mfa_success_function=success_func;
|
||||
window.mfa_failed_function=fail_func;
|
||||
$.ajax({
|
||||
"url":"{% url 'mfa_recheck' %}",
|
||||
success:function (data) {
|
||||
if (data.hasOwnProperty("res")) {
|
||||
if (data["res"])
|
||||
success_func();
|
||||
else fail_func();
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#modal-title").html("Recheck Indentity")
|
||||
$("#modal-body").html(data["html"])
|
||||
$("#popUpModal").modal()
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
{% include "modal.html" %}
|
||||
26
mfa/templates/select_mfa_method.html
Normal file
26
mfa/templates/select_mfa_method.html
Normal file
@@ -0,0 +1,26 @@
|
||||
{% extends "login_base.html" %}
|
||||
{% block form %}
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-10 col-sm-offset-1 col-xs-12 col-md-10 col-md-offset-1 col-lg-8 col-lg-offset-2">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong> Select Second Verification Method</strong>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<ul>
|
||||
{% for method in request.session.mfa_methods %}
|
||||
|
||||
<li><a href="{% url "mfa_goto" method %}">
|
||||
{% if method == "TOTP" %}Authenticator App
|
||||
{% elif method == "U2F" %}Secure Key
|
||||
{% elif method == "FIDO2" %}FIDO2 Secure Key
|
||||
{% endif %}
|
||||
</a> </li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user