Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for official Python & Django versions #116

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,25 @@ dist: xenial
language: python
cache: pip
python:
- 2.7.13
- 3.5
- 3.6
- 3.7
- 3.8
- 3.9
- 3.10
- 3.11
install:
- pip install tox-travis
script:
- tox
jobs:
include:
- stage: test
python: '3.6'
python: '3.8'
env: TOXENV=docs
- stage: test
python: '3.7'
python: '3.8'
env: TOXENV=manifest
- stage: deploy
python: '2.7.13'
env: TOXENV=py27-dj111-drf37
python: '3.8'
env: TOXENV=py38-dj42-drf314
deploy:
provider: pypi
user: styria
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ If you want to know more about JWT, check out the following resources:

## Requirements

- Python 2.7, 3.4+
- Django 1.11+
- Django REST Framework 3.7+
- Python 3.8+
- Django 3.2+
- Django REST Framework 3.13+

## Installation

Expand Down
6 changes: 3 additions & 3 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ If you want to know more about JWT, check out the following resources:

## Requirements

- Python 2.7, 3.4+
- Django 1.11+
- Django REST Framework 3.7+
- Python 3.8+
- Django 3.2+
- Django REST Framework 3.13+

## Security

Expand Down
17 changes: 8 additions & 9 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@ classifiers =
License :: OSI Approved :: MIT License
Operating System :: OS Independent
Programming Language :: Python
Programming Language :: Python :: 2
Programming Language :: Python :: 2.7
Programming Language :: Python :: 3
Programming Language :: Python :: 3.5
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Topic :: Internet :: WWW/HTTP

[paths]
Expand All @@ -33,13 +32,13 @@ source =
.tox/*/lib/python*/site-packages/rest_framework_jwt

[options]
python_requires = >= 2.7, != 3.0.*, != 3.1.*, != 3.2.*, != 3.3.*, != 3.4.*
python_requires = >= 3.8
zip_safe = False
include_package_data = True
install_requires =
PyJWT[crypto]>=1.5.2,<3.0.0
Django>=1.11
djangorestframework>=3.7
Django>=3.2
djangorestframework>=3.13

[options.extras_require]
dev =
Expand All @@ -56,7 +55,7 @@ test =
pytest-runner
six
docs =
mkdocs==0.13.2
mkdocs==1.5.2

[bdist_wheel]
universal = 1
Expand Down
20 changes: 8 additions & 12 deletions src/rest_framework_jwt/blacklist/migrations/0002_add_token_id.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Generated by Django 3.1.4 on 2020-12-12 12:15

from django.db import migrations, models
from django import VERSION

import jwt

Expand Down Expand Up @@ -35,15 +34,12 @@ class Migration(migrations.Migration):
name='token',
field=models.TextField(db_index=True, null=True),
),
migrations.RunPython(add_token_id_values, reverse_code=migrations.RunPython.noop)
migrations.RunPython(add_token_id_values, reverse_code=migrations.RunPython.noop),
migrations.AddConstraint(
model_name='blacklistedtoken',
constraint=models.CheckConstraint(
check=models.Q(token_id__isnull=False) | models.Q(token__isnull=False),
name='token_or_id_not_null',
),
),
]
if VERSION >= (2, 2):
operations.append(
migrations.AddConstraint(
model_name='blacklistedtoken',
constraint=models.CheckConstraint(
check=models.Q(token_id__isnull=False) | models.Q(token__isnull=False),
name='token_or_id_not_null',
),
)
)
14 changes: 6 additions & 8 deletions src/rest_framework_jwt/blacklist/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-

from django import VERSION
from django.conf import settings
from django.db import models
from django.db.models import Q
Expand All @@ -17,13 +16,12 @@ def delete_stale_tokens(self):

class BlacklistedToken(models.Model):
class Meta:
if VERSION >= (2, 2):
constraints = [
models.CheckConstraint(
check=Q(token_id__isnull=False) | Q(token__isnull=False),
name='token_or_id_not_null',
)
]
constraints = [
models.CheckConstraint(
check=Q(token_id__isnull=False) | Q(token__isnull=False),
name='token_or_id_not_null',
)
]

# This holds the original token id for refreshed tokens with ids
token_id = models.UUIDField(db_index=True, null=True)
Expand Down
11 changes: 2 additions & 9 deletions src/rest_framework_jwt/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from datetime import datetime
import sys

from django import VERSION
import jwt

from .settings import api_settings
Expand Down Expand Up @@ -36,22 +35,16 @@
from django.utils.encoding import smart_text as smart_str


def has_set_cookie_samesite():
return (VERSION >= (2,1,0))


def set_cookie_with_token(response, name, token):
params = {
'expires': datetime.utcnow() + api_settings.JWT_EXPIRATION_DELTA,
'domain': api_settings.JWT_AUTH_COOKIE_DOMAIN,
'path': api_settings.JWT_AUTH_COOKIE_PATH,
'secure': api_settings.JWT_AUTH_COOKIE_SECURE,
'httponly': True
'httponly': True,
'samesite': api_settings.JWT_AUTH_COOKIE_SAMESITE,
}

if has_set_cookie_samesite():
params.update({'samesite': api_settings.JWT_AUTH_COOKIE_SAMESITE})

response.set_cookie(name, token, **params)


Expand Down
7 changes: 2 additions & 5 deletions tests/views/test_authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework_jwt.compat import gettext_lazy as _
from rest_framework_jwt.compat import has_set_cookie_samesite
from rest_framework_jwt.settings import api_settings

import re
Expand Down Expand Up @@ -208,8 +207,7 @@ def test_valid_credentials_with_auth_cookie_enabled_returns_jwt_and_cookie(
assert setcookie['path'] == '/'
assert setcookie['secure'] is True
assert setcookie['httponly'] is True # hardcoded
if has_set_cookie_samesite():
assert setcookie['samesite'] == 'Lax'
assert setcookie['samesite'] == 'Lax'

assert response.status_code == status.HTTP_201_CREATED
assert "token" in force_str(response.content)
Expand Down Expand Up @@ -237,8 +235,7 @@ def test_auth_cookie_settings(
assert setcookie['path'] == '/pa/th'
assert 'secure' not in setcookie.items()
assert setcookie['httponly'] is True # hardcoded
if has_set_cookie_samesite():
assert setcookie['samesite'] == 'Strict'
assert setcookie['samesite'] == 'Strict'


def test_multi_keys_hash_hash(
Expand Down
55 changes: 19 additions & 36 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
[tox]
envlist =
docs,manifest,
py{27,35}-dj111-drf{37,38,39}-pyjwt1-codecov
py{36,37}-dj111-drf{37,38,39}-pyjwt{1,2}-codecov
py35-dj20-drf{37,38,39}-pyjwt1-codecov
py{36,37}-dj20-drf{37,38,39}-pyjwt{1,2}-codecov
py35-dj21-drf{37,38,39,310}-pyjwt1-codecov
py{36,37}-dj21-drf{37,38,39,310}-pyjwt{1,2}-codecov
py35-dj22-drf{37,38,39,310}-pyjwt1-codecov
py{36,37}-dj22-drf{37,38,39,310}-pyjwt{1,2}-codecov
py{36,37,38}-dj30-drf{311}-pyjwt{1,2}-codecov
py{36,37,38}-dj{30,31,32}-drf{311,312}-pyjwt{1,2}-codecov
py{39,310}-dj{30,31,32}-drf{311,312,313}-pyjwt{1,2}-codecov
py{39,310}-dj40-drf313-pyjwt{1,2}-codecov
py{38,39,310}-dj{32}-drf{313,314}-pyjwt{1,2}-codecov
py{38,39,310,311}-dj{41}-drf{313,314}-pyjwt{1,2}-codecov
py{38,39,310,311}-dj{42}-drf{314}-pyjwt{1,2}-codecov

[travis:env]
TRAVIS =
Expand All @@ -22,35 +13,27 @@ TRAVIS =
description = run the test suite
usedevelop = true
passenv =
CI TRAVIS TRAVIS_*
CI
TRAVIS
TRAVIS_*
setenv =
PYTHONDONTWRITEBYTECODE=1
PYTHONWARNINGS=once
PYTHONPATH={toxinidir}/demo
deps =
dj111: Django>=1.11,<1.12
dj20: Django>=2.0,<2.1
dj21: Django>=2.1,<2.2
dj22: Django>=2.2,<2.3
dj30: Django>=3.0,<3.1
dj31: Django>=3.1,<3.2
dj32: Django>=3.2,<3.3
dj40: Django>=4.0,<4.1
drf37: djangorestframework>=3.7,<3.8
drf38: djangorestframework>=3.8,<3.9
drf39: djangorestframework>=3.9,<3.10
drf310: djangorestframework>=3.10,<3.11
drf311: djangorestframework>=3.11,<3.12
drf312: djangorestframework>=3.12,<3.13
dj32: Django>=3.2,<4.0
dj41: Django>=4.1,<4.2
dj42: Django>=4.2,<4.3
drf313: djangorestframework>=3.13,<3.14
drf314: djangorestframework>=3.14,<3.15
pyjwt1: PyJWT[crypto]>=1.5.2,<2.0.0
pyjwt2: PyJWT[crypto]>=2.0.0,<3.0.0
cryptography<3.4 # Avoiding the "needs Rust" versions
coverage: coverage
codecov: codecov
# bash is used to create the codecov flags from the envname,
# only when codecov is used in the envname
whitelist_externals =
allowlist_externals =
/bin/bash
/usr/bin/bash
commands =
Expand All @@ -61,39 +44,39 @@ extras =

[testenv:docs]
description = build the documentation
basepython = python3.6
basepython = python3.8
commands = mkdocs {posargs:build}
extras =
test
docs

[testenv:changelog]
description = build the changelog
basepython = python3
basepython = python3.8
deps =
towncrier==18.6.0
towncrier==23.6.0
skip_install = true
commands =
python -V
towncrier {posargs}

[testenv:manifest]
basepython = python3
basepython = python3.8
deps = check-manifest
skip_install = true
commands = check-manifest

[testenv:release]
description = build the changelog, bump the package version, commit and tag
basepython=python2.7
basepython=python3.8
skip_install = true
whitelist_externals =
allowlist_externals =
git
tox
passenv =
HOME
deps =
bumpversion==0.5.3
bumpversion==0.6.0
commands_pre =
tox -e changelog -- --yes
git commit -m "Build changelog"
Expand All @@ -116,7 +99,7 @@ commands =

[testenv:deploy]
description = build the package and deploy it to PyPI.org
basepython = python3
basepython = python3.8
isolated_build = True
skip_install = true
setenv =
Expand Down