Skip to content

Commit

Permalink
Adds support for Django 5 and Switches to Github Actions
Browse files Browse the repository at this point in the history
  • Loading branch information
iMerica committed Apr 15, 2024
1 parent 05afb16 commit bbf3403
Show file tree
Hide file tree
Showing 20 changed files with 91 additions and 131 deletions.
46 changes: 0 additions & 46 deletions .circleci/config.yml

This file was deleted.

5 changes: 5 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[flake8]
per-file-ignores =
dj_rest_auth/tests/test_serializers.py:E501,F401
dj_rest_auth/serializers.py:E501
dj_rest_auth/jwt_auth.py:E501
70 changes: 50 additions & 20 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,38 @@
name: Build and Test
name: Lint, Build and Test
on:
push:
branches:
- master
- gha
pull_request:
branches:
- master

jobs:
lint:
runs-on: ubuntu-latest
name: Lint
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python 3.8
uses: actions/setup-python@v5
with:
python-version: 3.8
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install flake8
- name: Lint
run: flake8 dj_rest_auth/ --append-config ./.flake8
build:
runs-on: ubuntu-latest
name: Build
needs: [lint]
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Set up Python 3.8
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: 3.8
- name: Install dependencies
Expand All @@ -25,35 +41,49 @@ jobs:
- name: Build
run: python3 setup.py sdist
- name: Store artifacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
test:
runs-on: ubuntu-latest
name: Test
runs-on: ubuntu-20.04
name: Test Python ${{ matrix.python-version }} + Django ~= ${{ matrix.django-version }}
needs: [build]
strategy:
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11']
django-version: ['3.2', '4.2', '5.0']
exclude:
- python-version: '3.8'
django-version: '5.0'
- python-version: '3.9'
django-version: '5.0'
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up Python 3.8
uses: actions/setup-python@v2
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install tox coveralls
- name: Run Tox on All Supported Django and Python Versions
run: tox
pip install -r dj_rest_auth/tests/requirements.pip
pip install "Django~=${{ matrix.django-version }}.0"
- name: Run Tests
run: |
echo "$(python --version) / Django $(django-admin --version)"
coverage run ./runtests.py
- name: Generate Coverage Report
run: |
mkdir -p test-results/
tox -e coverage
- name: Send results to Coveralls
run: COVERALLS_REPO_TOKEN=Q58WdUuZOi89XHyDeDsGE2lxUGQ2IfqP3 coveralls
coverage report
coverage xml
- name: Code Coverage Summary Report
uses: irongut/[email protected]
with:
filename: coverage.xml
- name: Store test results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: test-results
name: results-${{ matrix.python-version }}-${{ matrix.django-version }}
path: test-results/
28 changes: 0 additions & 28 deletions .github/workflows/stale.yml

This file was deleted.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Dj-Rest-Auth
[![<iMerica>](https://circleci.com/gh/iMerica/dj-rest-auth.svg?style=svg)](https://app.circleci.com/pipelines/github/iMerica/dj-rest-auth)
[![<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/)


Drop-in API endpoints for handling authentication securely in Django Rest Framework. Works especially well
Expand Down
2 changes: 1 addition & 1 deletion dj_rest_auth/__version__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
__title__ = 'dj-rest-auth'
__description__ = 'Authentication and Registration in Django Rest Framework.'
__url__ = 'http://github.com/iMerica/dj-rest-auth'
__version__ = '5.1.0'
__version__ = '6.0.0'
__author__ = '@iMerica https://github.com/iMerica'
__author_email__ = '[email protected]'
__license__ = 'MIT'
Expand Down
4 changes: 2 additions & 2 deletions dj_rest_auth/app_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
'JWT_AUTH_SECURE': False,
'JWT_AUTH_HTTPONLY': True,
'JWT_AUTH_SAMESITE': 'Lax',
'JWT_AUTH_COOKIE_DOMAIN' : None,
'JWT_AUTH_COOKIE_DOMAIN': None,
'JWT_AUTH_RETURN_EXPIRATION': False,
'JWT_AUTH_COOKIE_USE_CSRF': False,
'JWT_AUTH_COOKIE_ENFORCE_CSRF_ON_UNAUTHENTICATED': False,
Expand All @@ -59,7 +59,7 @@
)

# List of settings that have been removed
REMOVED_SETTINGS = ( )
REMOVED_SETTINGS = []


class APISettings(_APISettings): # pragma: no cover
Expand Down
3 changes: 1 addition & 2 deletions dj_rest_auth/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,7 @@ def save(self, request, **kwargs):
'uid': uid,
}
if (
allauth_account_settings.AUTHENTICATION_METHOD
!= allauth_account_settings.AuthenticationMethod.EMAIL
allauth_account_settings.AUTHENTICATION_METHOD != allauth_account_settings.AuthenticationMethod.EMAIL
):
context['username'] = user_username(user)
get_adapter(request).send_mail(
Expand Down
3 changes: 1 addition & 2 deletions dj_rest_auth/jwt_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ def set_jwt_access_cookie(response, access_token):
cookie_samesite = api_settings.JWT_AUTH_SAMESITE
cookie_domain = api_settings.JWT_AUTH_COOKIE_DOMAIN


if cookie_name:
response.set_cookie(
cookie_name,
Expand Down Expand Up @@ -139,7 +138,7 @@ def authenticate(self, request):
if header is None:
if cookie_name:
raw_token = request.COOKIES.get(cookie_name)
if api_settings.JWT_AUTH_COOKIE_ENFORCE_CSRF_ON_UNAUTHENTICATED: #True at your own risk
if api_settings.JWT_AUTH_COOKIE_ENFORCE_CSRF_ON_UNAUTHENTICATED: # True at your own risk
self.enforce_csrf(request)
elif raw_token is not None and api_settings.JWT_AUTH_COOKIE_USE_CSRF:
self.enforce_csrf(request)
Expand Down
5 changes: 3 additions & 2 deletions dj_rest_auth/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from .app_settings import api_settings


def get_token_model():
token_model = api_settings.TOKEN_MODEL
session_login = api_settings.SESSION_LOGIN
Expand All @@ -15,13 +16,13 @@ def get_token_model():
'more of `TOKEN_MODEL`, `USE_JWT` or `SESSION_LOGIN`'
)
if (
token_model == DefaultTokenModel
and 'rest_framework.authtoken' not in settings.INSTALLED_APPS
token_model == DefaultTokenModel and 'rest_framework.authtoken' not in settings.INSTALLED_APPS
):
raise ImproperlyConfigured(
'You must include `rest_framework.authtoken` in INSTALLED_APPS '
'or set TOKEN_MODEL to None'
)
return token_model


TokenModel = get_token_model()
3 changes: 1 addition & 2 deletions dj_rest_auth/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,7 @@ def validate_auth_user_status(user):
def validate_email_verification_status(user, email=None):
from allauth.account import app_settings as allauth_account_settings
if (
allauth_account_settings.EMAIL_VERIFICATION == allauth_account_settings.EmailVerificationMethod.MANDATORY
and not user.emailaddress_set.filter(email=user.email, verified=True).exists()
allauth_account_settings.EMAIL_VERIFICATION == allauth_account_settings.EmailVerificationMethod.MANDATORY and not user.emailaddress_set.filter(email=user.email, verified=True).exists()
):
raise serializers.ValidationError(_('E-mail is not verified.'))

Expand Down
1 change: 0 additions & 1 deletion dj_rest_auth/tests/requirements.pip
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
coveralls==1.11.1
django-allauth==0.61.1
django>=2.2
djangorestframework-simplejwt>=5.3.1
flake8==3.8.4
responses==0.12.1
Expand Down
19 changes: 9 additions & 10 deletions dj_rest_auth/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ def test_registration_allowed_with_custom_no_password_serializer(self):
self.assertEqual(new_user.username, payload['username'])
self.assertFalse(new_user.has_usable_password())

## Also check that regular registration also works
# Also check that regular registration also works
user_count = get_user_model().objects.all().count()

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


@override_api_settings(USE_JWT=True)
def test_registration_with_jwt(self):
user_count = get_user_model().objects.all().count()
Expand Down Expand Up @@ -837,15 +836,15 @@ def test_wo_csrf_enforcement(self):
self.assertTrue('jwt-auth' in list(client.cookies.keys()))
self.assertEquals(resp.status_code, 200)

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

## TEST WITH COOKIES
# TEST WITH COOKIES
resp = client.get('/protected-view/')
self.assertEquals(resp.status_code, 200)

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

## TEST WITH JWT AUTH HEADER
# TEST WITH JWT AUTH HEADER
jwtclient = APIClient(enforce_csrf_checks=True)
token = resp.data['access']
resp = jwtclient.get('/protected-view/')
Expand All @@ -909,7 +908,7 @@ def test_csrf_wo_login_csrf_enforcement(self):
@override_api_settings(USE_JWT=True)
@override_api_settings(JWT_AUTH_COOKIE='jwt-auth')
@override_api_settings(JWT_AUTH_COOKIE_USE_CSRF=True)
@override_api_settings(JWT_AUTH_COOKIE_ENFORCE_CSRF_ON_UNAUTHENTICATED=True) # True at your own risk
@override_api_settings(JWT_AUTH_COOKIE_ENFORCE_CSRF_ON_UNAUTHENTICATED=True) # True at your own risk
@override_settings(
REST_FRAMEWORK=dict(
DEFAULT_AUTHENTICATION_CLASSES=[
Expand Down Expand Up @@ -942,9 +941,9 @@ def test_csrf_w_login_csrf_enforcement(self):
self.assertTrue('csrftoken' in list(client.cookies.keys()))
self.assertEquals(resp.status_code, 200)

## TEST WITH JWT AUTH HEADER does not make sense
# TEST WITH JWT AUTH HEADER does not make sense

## TEST WITH COOKIES
# TEST WITH COOKIES
resp = client.get('/protected-view/')
self.assertEquals(resp.status_code, 200)
# fail w/o csrftoken in payload
Expand All @@ -958,7 +957,7 @@ def test_csrf_w_login_csrf_enforcement(self):
@override_api_settings(USE_JWT=True)
@override_api_settings(JWT_AUTH_COOKIE='jwt-auth')
@override_api_settings(JWT_AUTH_COOKIE_USE_CSRF=False)
@override_api_settings(JWT_AUTH_COOKIE_ENFORCE_CSRF_ON_UNAUTHENTICATED=True) # True at your own risk
@override_api_settings(JWT_AUTH_COOKIE_ENFORCE_CSRF_ON_UNAUTHENTICATED=True) # True at your own risk
@override_settings(
REST_FRAMEWORK=dict(
DEFAULT_AUTHENTICATION_CLASSES=[
Expand Down Expand Up @@ -1064,7 +1063,7 @@ def test_custom_token_refresh_view(self):
# Ensure access keys are provided in response
self.assertIn('access', refresh_resp.data)
self.assertIn('access_expiration', refresh_resp.data)

@override_api_settings(JWT_AUTH_RETURN_EXPIRATION=True)
@override_api_settings(USE_JWT=True)
@override_api_settings(JWT_AUTH_COOKIE='xxx')
Expand Down
1 change: 0 additions & 1 deletion dj_rest_auth/tests/test_social.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import responses
from allauth.socialaccount.models import SocialApp
from allauth.socialaccount.providers.facebook.provider import GRAPH_API_URL
from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.sites.models import Site
from django.test import TestCase
Expand Down
1 change: 1 addition & 0 deletions dj_rest_auth/tests/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ def validate_password1(self, password):
return super().validate_password1(password)
return None


class NoPasswordRegisterView(RegisterView):
serializer_class = NoPassowrdRegisterSerializer

Expand Down
2 changes: 1 addition & 1 deletion dj_rest_auth/tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ def override_api_settings(**settings):
try:
delattr(api_settings, k)
except AttributeError:
pass
pass
Loading

0 comments on commit bbf3403

Please sign in to comment.