Skip to content

Commit b608360

Browse files
iMericaq0w
andauthored
Adds support for Django 5 and Moves to Github Actions for core CI/CD (#615)
* Support Django5+ * Test GHA * Adds tests * Updates tox to test Django 5 * Corrects Python version * Adds support for Django 5 and Switches to Github Actions --------- Co-authored-by: q0w <43147888+q0w@users.noreply.github.com>
1 parent 069cd11 commit b608360

21 files changed

+131
-124
lines changed

.circleci/config.yml

-46
This file was deleted.

.flake8

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[flake8]
2+
per-file-ignores =
3+
dj_rest_auth/tests/test_serializers.py:E501,F401
4+
dj_rest_auth/serializers.py:E501
5+
dj_rest_auth/jwt_auth.py:E501

.github/workflows/main.yml

+83-8
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,89 @@
1-
name: Release to PyPi
2-
on: [push]
1+
name: Lint, Build and Test
2+
on:
3+
push:
4+
branches:
5+
- master
6+
pull_request:
7+
branches:
8+
- master
39

410
jobs:
11+
lint:
12+
runs-on: ubuntu-latest
13+
name: Lint
14+
steps:
15+
- name: Checkout
16+
uses: actions/checkout@v4
17+
- name: Set up Python 3.8
18+
uses: actions/setup-python@v5
19+
with:
20+
python-version: 3.8
21+
- name: Install dependencies
22+
run: |
23+
python -m pip install --upgrade pip
24+
pip install flake8
25+
- name: Lint
26+
run: flake8 dj_rest_auth/ --append-config ./.flake8
527
build:
6-
name: Publish
728
runs-on: ubuntu-latest
29+
name: Build
30+
needs: [lint]
31+
steps:
32+
- name: Checkout
33+
uses: actions/checkout@v4
34+
- name: Set up Python 3.8
35+
uses: actions/setup-python@v5
36+
with:
37+
python-version: 3.8
38+
- name: Install dependencies
39+
run: |
40+
python -m pip install --upgrade pip
41+
- name: Build
42+
run: python3 setup.py sdist
43+
- name: Store artifacts
44+
uses: actions/upload-artifact@v4
45+
with:
46+
name: dist
47+
path: dist/
48+
test:
49+
runs-on: ubuntu-20.04
50+
name: Test Python ${{ matrix.python-version }} + Django ~= ${{ matrix.django-version }}
51+
needs: [build]
52+
strategy:
53+
matrix:
54+
python-version: ['3.8', '3.9', '3.10', '3.11']
55+
django-version: ['3.2', '4.2', '5.0']
56+
exclude:
57+
- python-version: '3.8'
58+
django-version: '5.0'
59+
- python-version: '3.9'
60+
django-version: '5.0'
861
steps:
9-
- name: Publish package
10-
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
11-
uses: pypa/gh-action-pypi-publish@master
62+
- name: Checkout
63+
uses: actions/checkout@v4
64+
- name: Set up Python ${{ matrix.python-version }}
65+
uses: actions/setup-python@v5
66+
with:
67+
python-version: ${{ matrix.python-version }}
68+
- name: Install dependencies
69+
run: |
70+
pip install -r dj_rest_auth/tests/requirements.pip
71+
pip install "Django~=${{ matrix.django-version }}.0"
72+
- name: Run Tests
73+
run: |
74+
echo "$(python --version) / Django $(django-admin --version)"
75+
coverage run ./runtests.py
76+
- name: Generate Coverage Report
77+
run: |
78+
mkdir -p test-results/
79+
coverage report
80+
coverage xml
81+
- name: Code Coverage Summary Report
82+
uses: irongut/CodeCoverageSummary@v1.3.0
83+
with:
84+
filename: coverage.xml
85+
- name: Store test results
86+
uses: actions/upload-artifact@v4
1287
with:
13-
user: __token__
14-
password: ${{ secrets.pypi_password }}
88+
name: results-${{ matrix.python-version }}-${{ matrix.django-version }}
89+
path: test-results/

.github/workflows/stale.yml

-28
This file was deleted.

README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
# Dj-Rest-Auth
2-
[![<iMerica>](https://circleci.com/gh/iMerica/dj-rest-auth.svg?style=svg)](https://app.circleci.com/pipelines/github/iMerica/dj-rest-auth)
2+
[![<iMerica>](https://github.com/iMerica/dj-rest-auth/actions/workflows/main.yml/badge.svg)](https://github.com/iMerica/dj-rest-auth/actions/workflows/main.yml/)
33

44

55
Drop-in API endpoints for handling authentication securely in Django Rest Framework. Works especially well
66
with SPAs (e.g., React, Vue, Angular), and Mobile applications.
77

88
## Requirements
9-
- Django 2, 3, or 4 (See Unit Test Coverage in CI)
10-
- Python 3
9+
- Django 3, 4 and 5 (See Unit Test Coverage in CI)
10+
- Python >= 3.8
1111

1212
## Quick Setup
1313

dj_rest_auth/__version__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
__title__ = 'dj-rest-auth'
22
__description__ = 'Authentication and Registration in Django Rest Framework.'
33
__url__ = 'http://github.com/iMerica/dj-rest-auth'
4-
__version__ = '5.1.0'
4+
__version__ = '6.0.0'
55
__author__ = '@iMerica https://github.com/iMerica'
66
__author_email__ = 'imichael@pm.me'
77
__license__ = 'MIT'

dj_rest_auth/app_settings.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
'JWT_AUTH_SECURE': False,
3636
'JWT_AUTH_HTTPONLY': True,
3737
'JWT_AUTH_SAMESITE': 'Lax',
38-
'JWT_AUTH_COOKIE_DOMAIN' : None,
38+
'JWT_AUTH_COOKIE_DOMAIN': None,
3939
'JWT_AUTH_RETURN_EXPIRATION': False,
4040
'JWT_AUTH_COOKIE_USE_CSRF': False,
4141
'JWT_AUTH_COOKIE_ENFORCE_CSRF_ON_UNAUTHENTICATED': False,
@@ -59,7 +59,7 @@
5959
)
6060

6161
# List of settings that have been removed
62-
REMOVED_SETTINGS = ( )
62+
REMOVED_SETTINGS = []
6363

6464

6565
class APISettings(_APISettings): # pragma: no cover

dj_rest_auth/forms.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,7 @@ def save(self, request, **kwargs):
7373
'uid': uid,
7474
}
7575
if (
76-
allauth_account_settings.AUTHENTICATION_METHOD
77-
!= allauth_account_settings.AuthenticationMethod.EMAIL
76+
allauth_account_settings.AUTHENTICATION_METHOD != allauth_account_settings.AuthenticationMethod.EMAIL
7877
):
7978
context['username'] = user_username(user)
8079
get_adapter(request).send_mail(

dj_rest_auth/jwt_auth.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ def set_jwt_access_cookie(response, access_token):
1818
cookie_samesite = api_settings.JWT_AUTH_SAMESITE
1919
cookie_domain = api_settings.JWT_AUTH_COOKIE_DOMAIN
2020

21-
2221
if cookie_name:
2322
response.set_cookie(
2423
cookie_name,
@@ -139,7 +138,7 @@ def authenticate(self, request):
139138
if header is None:
140139
if cookie_name:
141140
raw_token = request.COOKIES.get(cookie_name)
142-
if api_settings.JWT_AUTH_COOKIE_ENFORCE_CSRF_ON_UNAUTHENTICATED: #True at your own risk
141+
if api_settings.JWT_AUTH_COOKIE_ENFORCE_CSRF_ON_UNAUTHENTICATED: # True at your own risk
143142
self.enforce_csrf(request)
144143
elif raw_token is not None and api_settings.JWT_AUTH_COOKIE_USE_CSRF:
145144
self.enforce_csrf(request)

dj_rest_auth/models.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from .app_settings import api_settings
66

7+
78
def get_token_model():
89
token_model = api_settings.TOKEN_MODEL
910
session_login = api_settings.SESSION_LOGIN
@@ -15,13 +16,13 @@ def get_token_model():
1516
'more of `TOKEN_MODEL`, `USE_JWT` or `SESSION_LOGIN`'
1617
)
1718
if (
18-
token_model == DefaultTokenModel
19-
and 'rest_framework.authtoken' not in settings.INSTALLED_APPS
19+
token_model == DefaultTokenModel and 'rest_framework.authtoken' not in settings.INSTALLED_APPS
2020
):
2121
raise ImproperlyConfigured(
2222
'You must include `rest_framework.authtoken` in INSTALLED_APPS '
2323
'or set TOKEN_MODEL to None'
2424
)
2525
return token_model
2626

27+
2728
TokenModel = get_token_model()

dj_rest_auth/serializers.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,7 @@ def validate_auth_user_status(user):
110110
def validate_email_verification_status(user, email=None):
111111
from allauth.account import app_settings as allauth_account_settings
112112
if (
113-
allauth_account_settings.EMAIL_VERIFICATION == allauth_account_settings.EmailVerificationMethod.MANDATORY
114-
and not user.emailaddress_set.filter(email=user.email, verified=True).exists()
113+
allauth_account_settings.EMAIL_VERIFICATION == allauth_account_settings.EmailVerificationMethod.MANDATORY and not user.emailaddress_set.filter(email=user.email, verified=True).exists()
115114
):
116115
raise serializers.ValidationError(_('E-mail is not verified.'))
117116

dj_rest_auth/tests/requirements.pip

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
coveralls==1.11.1
22
django-allauth==0.61.1
3-
django>=2.2,<5.0
4-
djangorestframework-simplejwt==4.6.0
3+
djangorestframework-simplejwt>=5.3.1
54
flake8==3.8.4
65
responses==0.12.1
76
unittest-xml-reporting==3.0.4

dj_rest_auth/tests/test_api.py

+9-10
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,7 @@ def test_registration_allowed_with_custom_no_password_serializer(self):
501501
self.assertEqual(new_user.username, payload['username'])
502502
self.assertFalse(new_user.has_usable_password())
503503

504-
## Also check that regular registration also works
504+
# Also check that regular registration also works
505505
user_count = get_user_model().objects.all().count()
506506

507507
# test empty payload
@@ -514,7 +514,6 @@ def test_registration_allowed_with_custom_no_password_serializer(self):
514514
new_user = get_user_model().objects.latest('id')
515515
self.assertEqual(new_user.username, self.REGISTRATION_DATA['username'])
516516

517-
518517
@override_api_settings(USE_JWT=True)
519518
def test_registration_with_jwt(self):
520519
user_count = get_user_model().objects.all().count()
@@ -837,15 +836,15 @@ def test_wo_csrf_enforcement(self):
837836
self.assertTrue('jwt-auth' in list(client.cookies.keys()))
838837
self.assertEquals(resp.status_code, 200)
839838

840-
## TEST WITH JWT AUTH HEADER
839+
# TEST WITH JWT AUTH HEADER
841840
jwtclient = APIClient(enforce_csrf_checks=True)
842841
token = resp.data['access']
843842
resp = jwtclient.get('/protected-view/', HTTP_AUTHORIZATION='Bearer ' + token)
844843
self.assertEquals(resp.status_code, 200)
845844
resp = jwtclient.post('/protected-view/', {}, HTTP_AUTHORIZATION='Bearer ' + token)
846845
self.assertEquals(resp.status_code, 200)
847846

848-
## TEST WITH COOKIES
847+
# TEST WITH COOKIES
849848
resp = client.get('/protected-view/')
850849
self.assertEquals(resp.status_code, 200)
851850

@@ -883,7 +882,7 @@ def test_csrf_wo_login_csrf_enforcement(self):
883882
self.assertTrue('csrftoken' in list(client.cookies.keys()))
884883
self.assertEquals(resp.status_code, 200)
885884

886-
## TEST WITH JWT AUTH HEADER
885+
# TEST WITH JWT AUTH HEADER
887886
jwtclient = APIClient(enforce_csrf_checks=True)
888887
token = resp.data['access']
889888
resp = jwtclient.get('/protected-view/')
@@ -909,7 +908,7 @@ def test_csrf_wo_login_csrf_enforcement(self):
909908
@override_api_settings(USE_JWT=True)
910909
@override_api_settings(JWT_AUTH_COOKIE='jwt-auth')
911910
@override_api_settings(JWT_AUTH_COOKIE_USE_CSRF=True)
912-
@override_api_settings(JWT_AUTH_COOKIE_ENFORCE_CSRF_ON_UNAUTHENTICATED=True) # True at your own risk
911+
@override_api_settings(JWT_AUTH_COOKIE_ENFORCE_CSRF_ON_UNAUTHENTICATED=True) # True at your own risk
913912
@override_settings(
914913
REST_FRAMEWORK=dict(
915914
DEFAULT_AUTHENTICATION_CLASSES=[
@@ -942,9 +941,9 @@ def test_csrf_w_login_csrf_enforcement(self):
942941
self.assertTrue('csrftoken' in list(client.cookies.keys()))
943942
self.assertEquals(resp.status_code, 200)
944943

945-
## TEST WITH JWT AUTH HEADER does not make sense
944+
# TEST WITH JWT AUTH HEADER does not make sense
946945

947-
## TEST WITH COOKIES
946+
# TEST WITH COOKIES
948947
resp = client.get('/protected-view/')
949948
self.assertEquals(resp.status_code, 200)
950949
# fail w/o csrftoken in payload
@@ -958,7 +957,7 @@ def test_csrf_w_login_csrf_enforcement(self):
958957
@override_api_settings(USE_JWT=True)
959958
@override_api_settings(JWT_AUTH_COOKIE='jwt-auth')
960959
@override_api_settings(JWT_AUTH_COOKIE_USE_CSRF=False)
961-
@override_api_settings(JWT_AUTH_COOKIE_ENFORCE_CSRF_ON_UNAUTHENTICATED=True) # True at your own risk
960+
@override_api_settings(JWT_AUTH_COOKIE_ENFORCE_CSRF_ON_UNAUTHENTICATED=True) # True at your own risk
962961
@override_settings(
963962
REST_FRAMEWORK=dict(
964963
DEFAULT_AUTHENTICATION_CLASSES=[
@@ -1064,7 +1063,7 @@ def test_custom_token_refresh_view(self):
10641063
# Ensure access keys are provided in response
10651064
self.assertIn('access', refresh_resp.data)
10661065
self.assertIn('access_expiration', refresh_resp.data)
1067-
1066+
10681067
@override_api_settings(JWT_AUTH_RETURN_EXPIRATION=True)
10691068
@override_api_settings(USE_JWT=True)
10701069
@override_api_settings(JWT_AUTH_COOKIE='xxx')

dj_rest_auth/tests/test_serializers.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from allauth.socialaccount.providers.facebook.views import FacebookOAuth2Adapter
33
from allauth.socialaccount.providers.facebook.views import FacebookProvider
44
from allauth.socialaccount.models import SocialApp
5-
from allauth.exceptions import ImmediateHttpResponse
5+
from allauth.core.exceptions import ImmediateHttpResponse
66
from django.contrib.auth import get_user_model
77
from django.urls import reverse
88
from django.core.exceptions import ValidationError

dj_rest_auth/tests/test_social.py

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import responses
44
from allauth.socialaccount.models import SocialApp
55
from allauth.socialaccount.providers.facebook.provider import GRAPH_API_URL
6-
from django.conf import settings
76
from django.contrib.auth import get_user_model
87
from django.contrib.sites.models import Site
98
from django.test import TestCase

0 commit comments

Comments
 (0)