diff --git a/example/example/auth.py b/example/example/auth.py index afd587b..6d6fda6 100644 --- a/example/example/auth.py +++ b/example/example/auth.py @@ -1,30 +1,36 @@ 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 import authenticate, login, logout from django.contrib.auth.models import User + + def loginView(request): - context={} - if request.method=="POST": - username=request.POST["username"] - password=request.POST["password"] - user=authenticate(username=username,password=password) + context = {} + if request.method == "POST": + username = request.POST["username"] + password = request.POST["password"] + user = authenticate(username=username, password=password) if user: from mfa.helpers import has_mfa - res = has_mfa(username = username, request = request) # has_mfa returns false or HttpResponseRedirect + + 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 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' + +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')) + return HttpResponseRedirect(reverse("home")) def logoutView(request): logout(request) - return render(request,"logout.html",{}) \ No newline at end of file + return render(request, "logout.html", {}) diff --git a/example/example/settings.py b/example/example/settings.py index 37735a2..a3fe9f2 100644 --- a/example/example/settings.py +++ b/example/example/settings.py @@ -20,7 +20,7 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = '#9)q!_i3@pr-^3oda(e^3$x!kq3b4f33#5l@+=+&vuz+p6gb3g' +SECRET_KEY = "#9)q!_i3@pr-^3oda(e^3$x!kq3b4f33#5l@+=+&vuz+p6gb3g" # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True @@ -31,54 +31,54 @@ ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [ - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'mfa', - 'sslserver' + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", + "mfa", + "sslserver", ] MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", ] -ROOT_URLCONF = 'example.urls' +ROOT_URLCONF = "example.urls" TEMPLATES = [ { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [os.path.join(BASE_DIR ,'example','templates' )], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [os.path.join(BASE_DIR, "example", "templates")], + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", ], }, }, ] -WSGI_APPLICATION = 'example.wsgi.application' +WSGI_APPLICATION = "example.wsgi.application" # Database # https://docs.djangoproject.com/en/2.0/ref/settings/#databases DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': 'test_db', + "default": { + "ENGINE": "django.db.backends.sqlite3", + "NAME": "test_db", } } @@ -88,16 +88,16 @@ DATABASES = { AUTH_PASSWORD_VALIDATORS = [ { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", }, ] @@ -105,9 +105,9 @@ AUTH_PASSWORD_VALIDATORS = [ # Internationalization # https://docs.djangoproject.com/en/2.0/topics/i18n/ -LANGUAGE_CODE = 'en-us' +LANGUAGE_CODE = "en-us" -TIME_ZONE = 'UTC' +TIME_ZONE = "UTC" USE_I18N = True @@ -119,32 +119,33 @@ USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/2.0/howto/static-files/ -STATIC_URL = '/static/' -#STATIC_ROOT=(os.path.join(BASE_DIR,'static')) -STATICFILES_DIRS=[os.path.join(BASE_DIR,'static')] -LOGIN_URL="/auth/login" +STATIC_URL = "/static/" +# STATIC_ROOT=(os.path.join(BASE_DIR,'static')) +STATICFILES_DIRS = [os.path.join(BASE_DIR, "static")] +LOGIN_URL = "/auth/login" -EMAIL_FROM='Test App' -EMAIL_HOST="smtp.gmail.com" -EMAIL_PORT=587 -EMAIL_HOST_USER="" -EMAIL_HOST_PASSWORD='' -EMAIL_USE_TLS=True +EMAIL_FROM = "Test App" +EMAIL_HOST = "smtp.gmail.com" +EMAIL_PORT = 587 +EMAIL_HOST_USER = "" +EMAIL_HOST_PASSWORD = "" +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 = ("",) # Can the user disable his key (Added in 1.2.0). +MFA_REDIRECT_AFTER_REGISTRATION = "registered" +MFA_SUCCESS_REGISTRATION_MSG = "Go to Home" -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=('',) # Can the user disable his key (Added in 1.2.0). -MFA_REDIRECT_AFTER_REGISTRATION="registered" -MFA_SUCCESS_REGISTRATION_MSG="Go to Home" +TOKEN_ISSUER_NAME = "PROJECT_NAME" # TOTP Issuer name -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" +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" diff --git a/example/example/urls.py b/example/example/urls.py index bd0dc4d..d8ce223 100644 --- a/example/example/urls.py +++ b/example/example/urls.py @@ -14,14 +14,14 @@ 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,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"), +from django.urls import path, re_path, include +from . import views, auth - re_path('^$',views.home,name='home'), - path('registered/',views.registered,name='registered') +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"), + re_path("^$", views.home, name="home"), + path("registered/", views.registered, name="registered"), ] diff --git a/example/example/views.py b/example/example/views.py index 98e80e9..74b03ee 100644 --- a/example/example/views.py +++ b/example/example/views.py @@ -1,11 +1,12 @@ -from django.shortcuts import render from django.contrib.auth.decorators import login_required +from django.shortcuts import render @login_required() def home(request): - return render(request,"home.html",{}) + return render(request, "home.html", {}) + @login_required() def registered(request): - return render(request,"home.html",{"registered":True}) + return render(request, "home.html", {"registered": True}) diff --git a/setup.py b/setup.py index ae6cc81..dbb4b6a 100644 --- a/setup.py +++ b/setup.py @@ -3,33 +3,32 @@ from setuptools import find_packages, setup setup( - name='django-mfa2', - version='2.2.0', - description='Allows user to add 2FA to their accounts', + name="django-mfa2", + version="2.2.0", + description="Allows user to add 2FA to their accounts", long_description=open("README.md").read(), long_description_content_type="text/markdown", - - author='Mohamed El-Kalioby', - author_email = 'mkalioby@mkalioby.com', - url = 'https://github.com/mkalioby/django-mfa2/', - download_url='https://github.com/mkalioby/django-mfa2/', - license='MIT', + author="Mohamed El-Kalioby", + author_email="mkalioby@mkalioby.com", + url="https://github.com/mkalioby/django-mfa2/", + download_url="https://github.com/mkalioby/django-mfa2/", + license="MIT", packages=find_packages(), install_requires=[ - 'django >= 2.0', - 'jsonfield', - 'simplejson', - 'pyotp', - 'python-u2flib-server', - 'ua-parser', - 'user-agents', - 'python-jose', - 'fido2 == 0.9.1', - 'jsonLookup' - ], + "django >= 2.0", + "jsonfield", + "simplejson", + "pyotp", + "python-u2flib-server", + "ua-parser", + "user-agents", + "python-jose", + "fido2 == 0.9.1", + "jsonLookup", + ], python_requires=">=3.5", include_package_data=True, - zip_safe=False, # because we're including static files + zip_safe=False, # because we're including static files classifiers=[ "Development Status :: 5 - Production/Stable", "Environment :: Web Environment", @@ -48,5 +47,5 @@ setup( "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Topic :: Software Development :: Libraries :: Python Modules", -] + ], )