Adding Example app
This commit is contained in:
@@ -2,6 +2,7 @@ from django.shortcuts import render
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.urls import reverse
|
||||
from django.contrib.auth import authenticate,login,logout
|
||||
from django.contrib.auth.models import User
|
||||
def loginView(request):
|
||||
context={}
|
||||
if request.method=="POST":
|
||||
@@ -9,11 +10,20 @@ def loginView(request):
|
||||
password=request.POST["password"]
|
||||
user=authenticate(username=username,password=password)
|
||||
if user:
|
||||
login(request,user)
|
||||
return HttpResponseRedirect(reverse('home'))
|
||||
from mfa.helpers import has_mfa
|
||||
res = has_mfa(username = username, request = request) # has_mfa returns false or HttpResponseRedirect
|
||||
if res:
|
||||
return res
|
||||
return create_session(request,user.username)
|
||||
context["invalid"]=True
|
||||
return render(request, "login.html", context)
|
||||
|
||||
def create_session(request,username):
|
||||
user=User.objects.get(username=username)
|
||||
user.backend='django.contrib.auth.backends.ModelBackend'
|
||||
login(request, user)
|
||||
return HttpResponseRedirect(reverse('home'))
|
||||
|
||||
|
||||
def logoutView(request):
|
||||
logout(request)
|
||||
|
||||
@@ -37,6 +37,8 @@ INSTALLED_APPS = [
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'mfa',
|
||||
'sslserver'
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
@@ -120,4 +122,27 @@ USE_TZ = True
|
||||
STATIC_URL = '/static/'
|
||||
#STATIC_ROOT=(os.path.join(BASE_DIR,'static'))
|
||||
STATICFILES_DIRS=[os.path.join(BASE_DIR,'static')]
|
||||
LOGIN_URL="/auth/login"
|
||||
LOGIN_URL="/auth/login"
|
||||
|
||||
EMAIL_FROM='Test App'
|
||||
EMAIL_HOST="smtp.gmail.com"
|
||||
EMAIL_PORT=587
|
||||
EMAIL_HOST_USER="mkalioby@gmail.com"
|
||||
EMAIL_HOST_PASSWORD='wanted85'
|
||||
EMAIL_USE_TLS=True
|
||||
|
||||
|
||||
|
||||
MFA_UNALLOWED_METHODS=() # Methods that shouldn't be allowed for the user
|
||||
MFA_LOGIN_CALLBACK="example.auth.create_session" # A function that should be called by username to login the user in session
|
||||
MFA_RECHECK=True # Allow random rechecking of the user
|
||||
MFA_RECHECK_MIN=10 # Minimum interval in seconds
|
||||
MFA_RECHECK_MAX=30 # Maximum in seconds
|
||||
MFA_QUICKLOGIN=True # Allow quick login for returning users by provide only their 2FA
|
||||
MFA_HIDE_DISABLE=('FIDO2',) # Can the user disable his key (Added in 1.2.0).
|
||||
|
||||
TOKEN_ISSUER_NAME="PROJECT_NAME" #TOTP Issuer name
|
||||
|
||||
U2F_APPID="https://localhost" #URL For U2F
|
||||
FIDO_SERVER_ID=u"localhost" # Server rp id for FIDO2, it the full domain of your project
|
||||
FIDO_SERVER_NAME=u"PROJECT_NAME"
|
||||
|
||||
156
example/example/templates/base.html
Normal file
156
example/example/templates/base.html
Normal file
@@ -0,0 +1,156 @@
|
||||
{% load static %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<title>SB Admin - Blank Page</title>
|
||||
|
||||
<!-- Custom fonts for this template-->
|
||||
<link href="{% static 'vendor/fontawesome-free/css/all.min.css'%}" rel="stylesheet" type="text/css">
|
||||
|
||||
<!-- Page level plugin CSS-->
|
||||
<link href="{% static 'vendor/datatables/dataTables.bootstrap4.css'%}" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="{% static 'css/sb-admin.css'%}" rel="stylesheet">
|
||||
<script src="{% static 'vendor/jquery/jquery.min.js'%}"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body id="page-top">
|
||||
|
||||
<nav class="navbar navbar-expand navbar-dark bg-dark static-top">
|
||||
<button class="btn btn-link btn-sm text-white order-1 order-sm-0" id="sidebarToggle" href="#">
|
||||
<i class="fas fa-bars"></i>
|
||||
</button>
|
||||
<a class="navbar-brand mr-1" href="index.html">Django-mfa2</a>
|
||||
|
||||
|
||||
|
||||
<!-- Navbar Search -->
|
||||
<form class="d-none d-md-inline-block form-inline ml-auto mr-0 mr-md-3 my-2 my-md-0">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" placeholder="Search for..." aria-label="Search" aria-describedby="basic-addon2">
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-primary" type="button">
|
||||
<i class="fas fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- Navbar -->
|
||||
<ul class="navbar-nav ml-auto ml-md-0">
|
||||
<li class="nav-item dropdown no-arrow mx-1">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="alertsDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<i class="fas fa-bell fa-fw"></i>
|
||||
<span class="badge badge-danger"></span>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="alertsDropdown">
|
||||
<a class="dropdown-item" href="#">Action</a>
|
||||
<a class="dropdown-item" href="#">Another action</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#">Something else here</a>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<i class="fas fa-user-circle fa-fw"></i> {{ request.user.username }}
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item" href="#">Settings</a>
|
||||
<a class="dropdown-item" href="{% url 'mfa_home' %}">Security</a>
|
||||
<a class="dropdown-item" href="#">Activity Log</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#logoutModal">Logout</a>
|
||||
</div>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</nav>
|
||||
|
||||
<div id="wrapper">
|
||||
|
||||
<!-- Sidebar -->
|
||||
<ul class="sidebar navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="index.html">
|
||||
<i class="fas fa-fw fa-tachometer-alt"></i>
|
||||
<span>Dashboard</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<div id="content-wrapper">
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- Breadcrumbs-->
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
|
||||
<!-- Sticky Footer -->
|
||||
<footer class="sticky-footer">
|
||||
<div class="container my-auto">
|
||||
<div class="copyright text-center my-auto">
|
||||
<span>Copyright © Your Website 2019</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
<!-- /.content-wrapper -->
|
||||
|
||||
</div>
|
||||
<!-- /#wrapper -->
|
||||
|
||||
<!-- Scroll to Top Button-->
|
||||
<a class="scroll-to-top rounded" href="#page-top">
|
||||
<i class="fas fa-angle-up"></i>
|
||||
</a>
|
||||
|
||||
<!-- Logout Modal-->
|
||||
<div class="modal fade" id="logoutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">Ready to Leave?</h5>
|
||||
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">Select "Logout" below if you are ready to end your current session.</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||
<a class="btn btn-primary" href="{% url 'logout' %}">Logout</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bootstrap core JavaScript-->
|
||||
<script src="{% static 'vendor/bootstrap/js/bootstrap.bundle.min.js'%}"></script>
|
||||
|
||||
<!-- Core plugin JavaScript-->
|
||||
<script src="{%static 'vendor/jquery-easing/jquery.easing.min.js'%}"></script>
|
||||
|
||||
<!-- Custom scripts for all pages-->
|
||||
<script src="{% static 'js/sb-admin.min.js'%}"></script>
|
||||
{% block head %}
|
||||
{% endblock %}
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,96 +1,6 @@
|
||||
{% extends 'base.html' %}
|
||||
{% load static %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<title>SB Admin - Blank Page</title>
|
||||
|
||||
<!-- Custom fonts for this template-->
|
||||
<link href="{% static 'vendor/fontawesome-free/css/all.min.css'%}" rel="stylesheet" type="text/css">
|
||||
|
||||
<!-- Page level plugin CSS-->
|
||||
<link href="{% static 'vendor/datatables/dataTables.bootstrap4.css'%}" rel="stylesheet">
|
||||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="{% static 'css/sb-admin.css'%}" rel="stylesheet">
|
||||
|
||||
</head>
|
||||
|
||||
<body id="page-top">
|
||||
|
||||
<nav class="navbar navbar-expand navbar-dark bg-dark static-top">
|
||||
<button class="btn btn-link btn-sm text-white order-1 order-sm-0" id="sidebarToggle" href="#">
|
||||
<i class="fas fa-bars"></i>
|
||||
</button>
|
||||
<a class="navbar-brand mr-1" href="index.html">Django-mfa2</a>
|
||||
|
||||
|
||||
|
||||
<!-- Navbar Search -->
|
||||
<form class="d-none d-md-inline-block form-inline ml-auto mr-0 mr-md-3 my-2 my-md-0">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" placeholder="Search for..." aria-label="Search" aria-describedby="basic-addon2">
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-primary" type="button">
|
||||
<i class="fas fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- Navbar -->
|
||||
<ul class="navbar-nav ml-auto ml-md-0">
|
||||
<li class="nav-item dropdown no-arrow mx-1">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="alertsDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<i class="fas fa-bell fa-fw"></i>
|
||||
<span class="badge badge-danger"></span>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="alertsDropdown">
|
||||
<a class="dropdown-item" href="#">Action</a>
|
||||
<a class="dropdown-item" href="#">Another action</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#">Something else here</a>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="nav-item dropdown no-arrow">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<i class="fas fa-user-circle fa-fw"></i> {{ request.user.username }}
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="userDropdown">
|
||||
<a class="dropdown-item" href="#">Settings</a>
|
||||
<a class="dropdown-item" href="#">Activity Log</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="#" data-toggle="modal" data-target="#logoutModal">Logout</a>
|
||||
</div>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</nav>
|
||||
|
||||
<div id="wrapper">
|
||||
|
||||
<!-- Sidebar -->
|
||||
<ul class="sidebar navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="index.html">
|
||||
<i class="fas fa-fw fa-tachometer-alt"></i>
|
||||
<span>Dashboard</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<div id="content-wrapper">
|
||||
|
||||
{% block content %}
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- Breadcrumbs-->
|
||||
@@ -106,57 +16,4 @@
|
||||
<hr>
|
||||
|
||||
</div>
|
||||
<!-- /.container-fluid -->
|
||||
|
||||
<!-- Sticky Footer -->
|
||||
<footer class="sticky-footer">
|
||||
<div class="container my-auto">
|
||||
<div class="copyright text-center my-auto">
|
||||
<span>Copyright © Your Website 2019</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
<!-- /.content-wrapper -->
|
||||
|
||||
</div>
|
||||
<!-- /#wrapper -->
|
||||
|
||||
<!-- Scroll to Top Button-->
|
||||
<a class="scroll-to-top rounded" href="#page-top">
|
||||
<i class="fas fa-angle-up"></i>
|
||||
</a>
|
||||
|
||||
<!-- Logout Modal-->
|
||||
<div class="modal fade" id="logoutModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">Ready to Leave?</h5>
|
||||
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">Select "Logout" below if you are ready to end your current session.</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
|
||||
<a class="btn btn-primary" href="{% url 'logout' %}">Logout</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bootstrap core JavaScript-->
|
||||
<script src="{% static 'vendor/jquery/jquery.min.js'%}"></script>
|
||||
<script src="{% static 'vendor/bootstrap/js/bootstrap.bundle.min.js'%}"></script>
|
||||
|
||||
<!-- Core plugin JavaScript-->
|
||||
<script src="{%static 'vendor/jquery-easing/jquery.easing.min.js'%}"></script>
|
||||
|
||||
<!-- Custom scripts for all pages-->
|
||||
<script src="{% static 'js/sb-admin.min.js'%}"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
{% endblock %}
|
||||
45
example/example/templates/mfa_auth_base.html
Normal file
45
example/example/templates/mfa_auth_base.html
Normal file
@@ -0,0 +1,45 @@
|
||||
{% load static %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
|
||||
<title>Login</title>
|
||||
|
||||
<!-- Custom fonts for this template-->
|
||||
<link href="{% static 'vendor/fontawesome-free/css/all.min.css'%}" rel="stylesheet" type="text/css">
|
||||
|
||||
<!-- Custom styles for this template-->
|
||||
<link href="{% static 'css/sb-admin.css'%}" rel="stylesheet">
|
||||
<script src="{% static 'vendor/jquery/jquery.min.js'%}"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="bg-dark">
|
||||
|
||||
<div class="container">
|
||||
<div class="card card-login mx-auto mt-5">
|
||||
<div class="card-header">Login</div>
|
||||
<div class="card-body">
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Bootstrap core JavaScript-->
|
||||
<script src="{%static 'vendor/bootstrap/js/bootstrap.bundle.min.js'%}"></script>
|
||||
|
||||
<!-- Core plugin JavaScript-->
|
||||
<script src="{% static 'vendor/jquery-easing/jquery.easing.min.js'%}"></script>
|
||||
{% block head %}
|
||||
{% endblock %}
|
||||
</body>
|
||||
|
||||
</html>
|
||||
2
example/example/templates/mfa_email_token_template.html
Normal file
2
example/example/templates/mfa_email_token_template.html
Normal file
@@ -0,0 +1,2 @@
|
||||
<p>Dear {{ user.username }}</p>
|
||||
Your OTP is: <b>{{ otp }}</b>
|
||||
@@ -14,10 +14,11 @@ Including another URLconf
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
from django.contrib import admin
|
||||
from django.urls import path,re_path
|
||||
from django.urls import path,re_path,include
|
||||
from . import views,auth
|
||||
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"),
|
||||
|
||||
|
||||
Reference in New Issue
Block a user