From 3e8a7e308cdef31d22af8fb30f3b7fbd413ae2ca Mon Sep 17 00:00:00 2001 From: Gabriel Le Breton Date: Wed, 3 Jul 2019 11:09:15 -0400 Subject: [PATCH] Add django-axes package with custom serializer --- demo/demo/settings.py | 34 +++++++++++++++++++++++++++---- demo/myapp/__init__.py | 0 demo/myapp/admin.py | 3 +++ demo/myapp/apps.py | 5 +++++ demo/myapp/migrations/__init__.py | 0 demo/myapp/models.py | 3 +++ demo/myapp/serializers.py | 16 +++++++++++++++ demo/myapp/tests.py | 3 +++ demo/myapp/views.py | 3 +++ demo/requirements.txt | 1 + 10 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 demo/myapp/__init__.py create mode 100644 demo/myapp/admin.py create mode 100644 demo/myapp/apps.py create mode 100644 demo/myapp/migrations/__init__.py create mode 100644 demo/myapp/models.py create mode 100644 demo/myapp/serializers.py create mode 100644 demo/myapp/tests.py create mode 100644 demo/myapp/views.py diff --git a/demo/demo/settings.py b/demo/demo/settings.py index 514a8fb..194b670 100644 --- a/demo/demo/settings.py +++ b/demo/demo/settings.py @@ -31,7 +31,7 @@ INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', - # 'django.contrib.messages', + 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.sites', @@ -39,12 +39,15 @@ INSTALLED_APPS = ( 'rest_framework.authtoken', 'rest_auth', + 'allauth', 'allauth.account', 'rest_auth.registration', 'allauth.socialaccount', 'allauth.socialaccount.providers.facebook', 'rest_framework_swagger', + + 'axes', ) MIDDLEWARE = ( @@ -54,10 +57,9 @@ MIDDLEWARE = ( 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', -) -# For backwards compatibility for Django 1.8 -MIDDLEWARE_CLASSES = MIDDLEWARE + 'axes.middleware.AxesMiddleware', +) ROOT_URLCONF = 'demo.urls' @@ -127,3 +129,27 @@ SWAGGER_SETTINGS = { 'LOGIN_URL': 'login', 'LOGOUT_URL': 'logout', } + +AUTHENTICATION_BACKENDS = [ + + # AxesBackend should be the first backend in the AUTHENTICATION_BACKENDS list. + 'axes.backends.AxesBackend', + + # Required for rest-auth when using Axes to prevent 'Unable to log in with provided credentials.' + 'allauth.account.auth_backends.AuthenticationBackend', + + # Django ModelBackend is the default authentication backend. + 'django.contrib.auth.backends.ModelBackend', +] + +CACHES = { + 'default': { + 'BACKEND': 'django.core.cache.backends.db.DatabaseCache', + 'LOCATION': 'django_database_cache', + } +} + +REST_AUTH_SERIALIZERS = { + 'LOGIN_SERIALIZER': 'myapp.serializers.RestAuthLoginSerializer', + # 'TOKEN_SERIALIZER': 'path.to.custom.TokenSerializer', +} diff --git a/demo/myapp/__init__.py b/demo/myapp/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/demo/myapp/admin.py b/demo/myapp/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/demo/myapp/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/demo/myapp/apps.py b/demo/myapp/apps.py new file mode 100644 index 0000000..74d6d13 --- /dev/null +++ b/demo/myapp/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class MyappConfig(AppConfig): + name = 'myapp' diff --git a/demo/myapp/migrations/__init__.py b/demo/myapp/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/demo/myapp/models.py b/demo/myapp/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/demo/myapp/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/demo/myapp/serializers.py b/demo/myapp/serializers.py new file mode 100644 index 0000000..1b9f590 --- /dev/null +++ b/demo/myapp/serializers.py @@ -0,0 +1,16 @@ +from axes.helpers import get_lockout_message +from rest_auth import serializers +from rest_auth.serializers import LoginSerializer +from rest_framework import exceptions + + +# noinspection PyAbstractClass +class RestAuthLoginSerializer(LoginSerializer): + + def validate(self, attrs): + try: + attrs = super().validate(attrs) + except exceptions.ValidationError: + if getattr(self.context['request'], 'axes_locked_out', None): + raise serializers.ValidationError(get_lockout_message()) + return attrs diff --git a/demo/myapp/tests.py b/demo/myapp/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/demo/myapp/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/demo/myapp/views.py b/demo/myapp/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/demo/myapp/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/demo/requirements.txt b/demo/requirements.txt index 93c8000..3eec24d 100644 --- a/demo/requirements.txt +++ b/demo/requirements.txt @@ -4,3 +4,4 @@ djangorestframework>=3.9.4 django-allauth>=0.39.1 six==1.12.0 django-rest-swagger==2.2.0 +django-axes==5.0.7