From 624a447e70e72d4e5bea4918124713de691455c0 Mon Sep 17 00:00:00 2001 From: kooshan Date: Tue, 4 Jun 2019 05:12:52 +0430 Subject: [PATCH 1/4] Upgraded to django 2 and some other packages with minor changes. --- py-requirements/base.txt | 17 +++++++---------- py-requirements/dev.txt | 20 ++++++++++---------- src/accounts/urls.py | 26 +++++++++++++------------- src/accounts/views.py | 11 ++++++----- src/base/urls.py | 8 ++++---- src/base/views.py | 2 +- src/djangoreactredux/settings/base.py | 17 ++++++----------- src/djangoreactredux/urls.py | 10 ++++++---- src/lib/utils.py | 8 ++++---- 9 files changed, 57 insertions(+), 62 deletions(-) diff --git a/py-requirements/base.txt b/py-requirements/base.txt index a516ac31..dbf2a829 100644 --- a/py-requirements/base.txt +++ b/py-requirements/base.txt @@ -1,24 +1,21 @@ -Django==1.11.4 -django-extensions==1.8.1 - -django-disposable-email-checker==1.2.1 +Django==2.2.1 +django-extensions==2.1.7 # PostgresSQL -psycopg2==2.7.3 +psycopg2==2.8.2 # serve files -whitenoise==3.3.0 +whitenoise==4.1.2 # Rest Framework -djangorestframework==3.6.4 +djangorestframework==3.9.4 # Sentry -raven==6.1.0 +raven==6.10.0 # for date processing -python-dateutil==2.6.1 +python-dateutil==2.8.0 # Logging git+https://github.com/Seedstars/django-rest-logger.git -django-rest-knox==3.0.3 diff --git a/py-requirements/dev.txt b/py-requirements/dev.txt index 3071ab78..ca0ce3ca 100644 --- a/py-requirements/dev.txt +++ b/py-requirements/dev.txt @@ -1,15 +1,15 @@ -r base.txt -mock==2.0.0 -factory-boy==2.9.2 +mock==3.0.5 +factory-boy==2.12.0 -prospector==0.12.7 -bandit==1.4.0 +prospector==1.1.6.2 +bandit==1.6.0 -pytest==3.2.1 -pytest-cov==2.5.1 -pytest-django==3.1.2 -pytest-pythonpath==0.7.1 -pytest-xdist==1.20.0 +pytest==4.6.1 +pytest-cov==2.7.1 +pytest-django==3.4.8 +pytest-pythonpath==0.7.3 +pytest-xdist==1.28.0 -ptpython==0.41 +ptpython==2.0.4 diff --git a/src/accounts/urls.py b/src/accounts/urls.py index 4ee704bc..48dc03de 100644 --- a/src/accounts/urls.py +++ b/src/accounts/urls.py @@ -1,20 +1,20 @@ -from django.conf.urls import url +from django.urls import path from django.utils.translation import ugettext_lazy as _ import accounts.views urlpatterns = [ - url(_(r'^register/$'), - accounts.views.UserRegisterView.as_view(), - name='register'), - url(_(r'^login/$'), - accounts.views.UserLoginView.as_view(), - name='login'), - url(_(r'^confirm/email/(?P.*)/$'), - accounts.views.UserConfirmEmailView.as_view(), - name='confirm_email'), - url(_(r'^status/email/$'), - accounts.views.UserEmailConfirmationStatusView.as_view(), - name='status'), + path(_('register/'), + accounts.views.UserRegisterView.as_view(), + name='register'), + path(_('login/'), + accounts.views.UserLoginView.as_view(), + name='login'), + path(_('confirm/email//'), + accounts.views.UserConfirmEmailView.as_view(), + name='confirm_email'), + path(_('status/email/'), + accounts.views.UserEmailConfirmationStatusView.as_view(), + name='status'), ] diff --git a/src/accounts/views.py b/src/accounts/views.py index d1ec8097..0126a783 100644 --- a/src/accounts/views.py +++ b/src/accounts/views.py @@ -1,7 +1,7 @@ from django.shortcuts import get_object_or_404 from django_rest_logger import log -from knox.auth import TokenAuthentication -from knox.models import AuthToken +from rest_framework.authentication import TokenAuthentication +from rest_framework.authtoken.models import Token as TokenModel from rest_framework import status from rest_framework.authentication import BasicAuthentication from rest_framework.generics import GenericAPIView @@ -30,10 +30,11 @@ class UserLoginView(GenericAPIView): def post(self, request): """User login with username and password.""" - token = AuthToken.objects.create(request.user) + token = TokenModel.objects.get_or_create(user=request.user) + return Response({ 'user': self.get_serializer(request.user).data, - 'token': token + 'token': token[0].key }) @@ -47,7 +48,7 @@ def get(self, request, activation_key): Receive an activation key as parameter and confirm email. """ - user = get_object_or_404(User, activation_key=str(activation_key)) + user = get_object_or_404(User, activation_key=activation_key) if user.confirm_email(): return Response(status=status.HTTP_200_OK) diff --git a/src/base/urls.py b/src/base/urls.py index 1a00ce27..ffae3c24 100644 --- a/src/base/urls.py +++ b/src/base/urls.py @@ -1,9 +1,9 @@ -from django.conf.urls import url +from django.urls import path from base import views as base_views urlpatterns = [ - url(r'', - base_views.ProtectedDataView.as_view(), - name='protected_data'), + path('', + base_views.ProtectedDataView.as_view(), + name='protected_data'), ] diff --git a/src/base/views.py b/src/base/views.py index 3efb28c0..727d5770 100644 --- a/src/base/views.py +++ b/src/base/views.py @@ -3,7 +3,7 @@ from django.conf import settings from django.http import HttpResponse from django.views.generic import View -from knox.auth import TokenAuthentication +from rest_framework.authentication import TokenAuthentication from rest_framework import status from rest_framework.generics import GenericAPIView from rest_framework.permissions import IsAuthenticated diff --git a/src/djangoreactredux/settings/base.py b/src/djangoreactredux/settings/base.py index a52e28da..7452628e 100644 --- a/src/djangoreactredux/settings/base.py +++ b/src/djangoreactredux/settings/base.py @@ -9,7 +9,7 @@ DEBUG = True -ALLOWED_HOSTS = ['localhost'] +ALLOWED_HOSTS = ['localhost', '127.0.0.1'] # Application definition @@ -22,14 +22,15 @@ 'django.contrib.admin', 'rest_framework', - 'knox', + 'rest_framework.authtoken', + 'rest_auth', 'django_extensions', 'accounts', 'base' ] -MIDDLEWARE_CLASSES = [ +MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'whitenoise.middleware.WhiteNoiseMiddleware', 'django.middleware.common.CommonMiddleware', @@ -38,7 +39,6 @@ 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.common.CommonMiddleware' ] TEMPLATES = [ @@ -90,7 +90,9 @@ 'DEFAULT_PERMISSION_CLASSES': [], 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.SessionAuthentication', + 'rest_framework.authentication.TokenAuthentication', 'rest_framework.authentication.BasicAuthentication', + ], 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE': 20, @@ -100,10 +102,3 @@ 'rest_framework.parsers.MultiPartParser', ], } - -# ############ REST KNOX ######################## -REST_KNOX = { - 'SECURE_HASH_ALGORITHM': 'cryptography.hazmat.primitives.hashes.SHA512', - 'AUTH_TOKEN_CHARACTER_LENGTH': 64, - 'USER_SERIALIZER': 'knox.serializers.UserSerializer' -} diff --git a/src/djangoreactredux/urls.py b/src/djangoreactredux/urls.py index 3b2b3c8d..37a58ae1 100644 --- a/src/djangoreactredux/urls.py +++ b/src/djangoreactredux/urls.py @@ -1,13 +1,15 @@ from django.conf import settings -from django.conf.urls import include, url +from django.conf.urls import include +from django.urls import path from django.views.decorators.cache import cache_page from base import views as base_views + urlpatterns = [ - url(r'^api/v1/accounts/', include('accounts.urls', namespace='accounts')), - url(r'^api/v1/getdata/', include('base.urls', namespace='base')), + path('api/v1/accounts/', include(('accounts.urls', 'accounts'), namespace='accounts')), + path('api/v1/getdata/', include(('base.urls', 'base'), namespace='base')), # catch all others because of how history is handled by react router - cache this page because it will never change - url(r'', cache_page(settings.PAGE_CACHE_SECONDS)(base_views.IndexView.as_view()), name='index'), + path('', cache_page(settings.PAGE_CACHE_SECONDS)(base_views.IndexView.as_view()), name='index'), ] diff --git a/src/lib/utils.py b/src/lib/utils.py index 61ca69fd..6011e332 100644 --- a/src/lib/utils.py +++ b/src/lib/utils.py @@ -1,7 +1,7 @@ -from disposable_email_checker.validators import validate_disposable_email from django.core.exceptions import ValidationError from django.core.validators import validate_email as django_validate_email from django.db import transaction +from email_validator import validate_email as existence_check, EmailNotValidError def validate_email(value): @@ -14,10 +14,10 @@ def validate_email(value): except ValidationError: return False else: - # Check with the disposable list. + # Check if the domain name exists. try: - validate_disposable_email(value) - except ValidationError: + existence_check(value) + except EmailNotValidError: return False else: return True From abe537f5b1012df132f79044c93e4589aa3cf6d7 Mon Sep 17 00:00:00 2001 From: kooshan Date: Tue, 4 Jun 2019 06:27:33 +0430 Subject: [PATCH 2/4] Added two new packages to base.txt --- py-requirements/base.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/py-requirements/base.txt b/py-requirements/base.txt index dbf2a829..7fbd2eb9 100644 --- a/py-requirements/base.txt +++ b/py-requirements/base.txt @@ -19,3 +19,15 @@ python-dateutil==2.8.0 # Logging git+https://github.com/Seedstars/django-rest-logger.git +# email validator +email-validator==1.0.4 +dnspython==1.16.0 +idna==2.8 + +# django rest auth +django-rest-auth==0.9.5 +six==1.10.0 +pycodestyle==2.5.0 +pytz==2019.1 +sqlparse==0.3.0 + From 2c6d06913777d406d298d0f42c1a8ec54b5550e9 Mon Sep 17 00:00:00 2001 From: kooshan Date: Tue, 4 Jun 2019 07:16:58 +0430 Subject: [PATCH 3/4] Updated README.md file --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1e05cfb8..a62badd8 100644 --- a/README.md +++ b/README.md @@ -35,14 +35,14 @@ We build on the shoulders of giants with the following technologies: * [Django](https://www.djangoproject.com/) * [Django REST framework](http://www.django-rest-framework.org/) Django REST framework is a powerful and flexible toolkit for building Web APIs -* [Django REST Knox](https://github.com/James1345/django-rest-knox) Token based authentication for API endpoints +* [Django Rest Auth](https://github.com/Tivix/django-rest-auth) Authentication Methods for API endpoints * [WhiteNoise](http://whitenoise.evans.io/en/latest/django.html) to serve files efficiently from Django * [Prospector](http://prospector.landscape.io/en/master/) a complete Python static analysis tool * [Bandit](https://github.com/openstack/bandit) a security linter from OpenStack Security * [pytest](http://pytest.org/latest/) a mature full-featured Python testing tool * [Mock](http://www.voidspace.org.uk/python/mock/) mocking and testing Library * [Responses](https://github.com/getsentry/responses) a utility for mocking out the Python Requests library - +* [Python Email Validator](https://github.com/JoshData/python-email-validator) Validation and Domain Check for Emails ## Readme Notes From e0c4e31b02eecb34510f43d00eb917632118e240 Mon Sep 17 00:00:00 2001 From: kooshan Date: Tue, 4 Jun 2019 16:14:17 +0430 Subject: [PATCH 4/4] Modified tests for the new package email_validator & Django 2.2.1 --- tests/python/accounts/test_serializers.py | 2 +- tests/python/accounts/test_views.py | 2 +- tests/python/base/test_views.py | 2 +- tests/python/utils/test_utils.py | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/python/accounts/test_serializers.py b/tests/python/accounts/test_serializers.py index b4bc55a8..a0b1812a 100644 --- a/tests/python/accounts/test_serializers.py +++ b/tests/python/accounts/test_serializers.py @@ -8,7 +8,7 @@ class UserRegistrationSerializerTest(CustomTestCase, APITestCase): INVALID_DATA_DICT = [ - {'data': {'email': 'test1@mailinator.com', + {'data': {'email': 'test1@FAKEmailinator.com', 'first_name': 'test', 'last_name': 'user', 'password': 'test'}, diff --git a/tests/python/accounts/test_views.py b/tests/python/accounts/test_views.py index a1c52932..e798cf0c 100644 --- a/tests/python/accounts/test_views.py +++ b/tests/python/accounts/test_views.py @@ -1,7 +1,7 @@ import uuid import base64 -from django.core.urlresolvers import reverse +from django.urls import reverse from rest_framework import status from rest_framework.test import APITestCase diff --git a/tests/python/base/test_views.py b/tests/python/base/test_views.py index 8222d2cb..1b614882 100644 --- a/tests/python/base/test_views.py +++ b/tests/python/base/test_views.py @@ -1,4 +1,4 @@ -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import override_settings from rest_framework import status from rest_framework.test import APITestCase diff --git a/tests/python/utils/test_utils.py b/tests/python/utils/test_utils.py index dcea3964..ba69749f 100644 --- a/tests/python/utils/test_utils.py +++ b/tests/python/utils/test_utils.py @@ -7,5 +7,5 @@ class BaseTests(TestCase): def test_validate_email(self): self.assertEqual(validate_email('fail'), False) self.assertEqual(validate_email(''), False) - self.assertEqual(validate_email('test@mailinator.com'), False) - self.assertEqual(validate_email('good.email@example.com'), False) + self.assertEqual(validate_email('test@mFAKEmailinator.com'), False) + self.assertEqual(validate_email('good(email@example.com'), False)