Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 7684d0b

Browse files
Add _legacy_get_session_auth_hash to fix Django 3.1 support
1 parent becd3b7 commit 7684d0b

File tree

13 files changed

+148
-22
lines changed

13 files changed

+148
-22
lines changed

‎.github/workflows/ci.yml‎

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ jobs:
44
docs:
55
runs-on: ubuntu-latest
66
steps:
7-
- uses: actions/setup-python@v1.1.1
8-
- uses: actions/checkout@v2.0.0
7+
- uses: actions/setup-python@v2
8+
- uses: actions/checkout@v2
99
- run: python -m pip install -r requirements.txt
1010
- run: python setup.py develop
1111
- run: python setup.py build_sphinx -W
@@ -18,16 +18,37 @@ jobs:
1818
python-version: [3.6, 3.7, 3.8]
1919
steps:
2020
- name: Set up Python ${{ matrix.python-version }}
21-
uses: actions/setup-python@v1.1.1
21+
uses: actions/setup-python@v2
2222
with:
2323
python-version: ${{ matrix.python-version }}
24-
- uses: actions/checkout@v2.0.0
24+
- uses: actions/checkout@v2
2525
- run: python setup.py test
2626
- name: Codecov
2727
run: |
2828
python -m pip install codecov
2929
codecov -t ${{secrets.CODECOV_TOKEN}}
3030
31+
extras:
32+
needs: [docs]
33+
runs-on: ubuntu-latest
34+
strategy:
35+
matrix:
36+
extras:
37+
- wagtail
38+
python-version: [3.8]
39+
steps:
40+
- name: Set up Python ${{ matrix.python-version }}
41+
uses: actions/setup-python@v2
42+
with:
43+
python-version: ${{ matrix.python-version }}
44+
- uses: actions/checkout@v2
45+
- run: python -m pip install -e ".[${{ matrix.extras }}]"
46+
- run: python setup.py test
47+
- name: Codecov
48+
run: |
49+
python -m pip install codecov
50+
codecov -t ${{ secrets.CODECOV_TOKEN }}
51+
3152
3253
PostgreSQL:
3354
needs: [docs]
@@ -50,10 +71,10 @@ jobs:
5071
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
5172
steps:
5273
- name: Set up Python ${{ matrix.python-version }}
53-
uses: actions/setup-python@v1.1.1
74+
uses: actions/setup-python@v2
5475
with:
5576
python-version: ${{ matrix.python-version }}
56-
- uses: actions/checkout@v2.0.0
77+
- uses: actions/checkout@v2
5778
- run: python -m pip install psycopg2-binary Django==${{ matrix.django-version }}
5879
- run: python setup.py test
5980
env:

‎mailauth/contrib/admin/views.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from django.contrib.auth import REDIRECT_FIELD_NAME
22
from django.urls import reverse
3-
from django.utils.translation import ugettext_lazy as _
3+
from django.utils.translation import gettext_lazy as _
44

55
from mailauth.views import LoginView
66

‎mailauth/contrib/user/migrations/0002_emailuser_session_salt.py‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
# Generated by Django 2.2.1 on 2019年05月27日 10:39
22

3-
import django.utils.crypto
43
from django.db import migrations, models
54

5+
import mailauth
6+
67

78
class Migration(migrations.Migration):
89

@@ -14,6 +15,6 @@ class Migration(migrations.Migration):
1415
migrations.AddField(
1516
model_name='emailuser',
1617
name='session_salt',
17-
field=models.CharField(default=django.utils.crypto.get_random_string, editable=False, max_length=12),
18+
field=models.CharField(default=mailauth.contrib.user.models._get_session_salt, editable=False, max_length=12),
1819
),
1920
]
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Generated by Django 3.1 on 2020年08月12日 07:22
2+
3+
import django
4+
from django.db import migrations, models
5+
6+
import mailauth.contrib.user.models
7+
8+
9+
class Migration(migrations.Migration):
10+
11+
dependencies = [
12+
('mailauth_user', '0003_ci_unique_index'),
13+
]
14+
15+
operations = [
16+
migrations.AlterField(
17+
model_name='emailuser',
18+
name='first_name',
19+
field=models.CharField(blank=True, max_length=150, verbose_name='first name'),
20+
),
21+
]

‎mailauth/contrib/user/models.py‎

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from django.conf import settings
12
from django.contrib.auth.base_user import BaseUserManager
23
from django.contrib.auth.models import AbstractUser
34
from django.db import models
@@ -37,6 +38,10 @@ def create_superuser(self, email, **extra_fields):
3738
return self._create_user(email, **extra_fields)
3839

3940

41+
def _get_session_salt():
42+
return get_random_string(12)
43+
44+
4045
class AbstractEmailUser(AbstractUser):
4146
EMAIL_FIELD = 'email'
4247
USERNAME_FIELD = 'email'
@@ -51,7 +56,7 @@ class AbstractEmailUser(AbstractUser):
5156
# Salt for the session hash replacing the password in this function.
5257
session_salt = models.CharField(
5358
max_length=12, editable=False,
54-
default=get_random_string,
59+
default=_get_session_salt,
5560
)
5661

5762
def has_usable_password(self):
@@ -62,12 +67,29 @@ def has_usable_password(self):
6267
class Meta(AbstractUser.Meta):
6368
abstract = True
6469

70+
def _legacy_get_session_auth_hash(self):
71+
# RemovedInDjango40Warning: pre-Django 3.1 hashes will be invalid.
72+
key_salt = "mailauth.contrib.user.models.EmailUserManager.get_session_auth_hash"
73+
if not self.session_salt:
74+
raise ValueError("'session_salt' must be set")
75+
return salted_hmac(key_salt, self.session_salt, algorithm='sha1').hexdigest()
76+
6577
def get_session_auth_hash(self):
6678
"""Return an HMAC of the :attr:`.session_salt` field."""
6779
key_salt = "mailauth.contrib.user.models.EmailUserManager.get_session_auth_hash"
6880
if not self.session_salt:
6981
raise ValueError("'session_salt' must be set")
70-
return salted_hmac(key_salt, self.session_salt).hexdigest()
82+
algorithm = getattr(settings, 'DEFAULT_HASHING_ALGORITHM', None)
83+
if algorithm is None:
84+
return salted_hmac(key_salt, self.session_salt).hexdigest()
85+
return salted_hmac(
86+
key_salt,
87+
self.session_salt,
88+
# RemovedInDjango40Warning: when the deprecation ends, replace
89+
# with:
90+
# algorithm='sha256',
91+
algorithm=algorithm,
92+
).hexdigest()
7193

7294

7395
delattr(AbstractEmailUser, 'password')

‎setup.cfg‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ tests_require =
3838
pytest
3939
pytest-django
4040
pytest-cov
41-
wagtail
4241

4342
[options.package_data]
4443
* = *.txt, *.rst, *.html, *.po

‎tests/conftest.py‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import django
12
import pytest
23
from django.contrib.auth import get_user_model
34
from django.utils import timezone
@@ -36,7 +37,9 @@ def admin_user(db):
3637
@pytest.fixture()
3738
def signature():
3839
"""Return a signature matching the user fixture."""
39-
return 'LZ.173QUS.1Hjptg.lf2hFgOXQtjQsFypS2ItRG2hkpA'
40+
if django.VERSION < (3, 1):
41+
return 'LZ.173QUS.1Hjptg.lf2hFgOXQtjQsFypS2ItRG2hkpA'
42+
return 'LZ.173QUS.1Hjptg.UtFdkTPoyrSA0IB6AUEhtz_hMyFZY0kcREE1HnWdFq4'
4043

4144

4245
@pytest.fixture()

‎tests/contrib/auth/test_models.py‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import django
12
import pytest
23
from django.core.exceptions import FieldDoesNotExist
34

@@ -28,6 +29,32 @@ def test_get_session_auth_hash__unique(self, db):
2829

2930
assert spiderman.get_session_auth_hash() != ironman.get_session_auth_hash()
3031

32+
@pytest.mark.skipif(django.VERSION < (3, 1), reason="requires Django 3.1 or higher")
33+
def test_legacy_get_session_auth_hash__default(self, db):
34+
user = EmailUser(email='spiderman@avengers.com')
35+
36+
assert user.session_salt
37+
assert user._legacy_get_session_auth_hash()
38+
39+
@pytest.mark.skipif(django.VERSION < (3, 1), reason="requires Django 3.1 or higher")
40+
def test_legacy_get_session_auth_hash__value_error(self, db):
41+
user = EmailUser(email='spiderman@avengers.com', session_salt=None)
42+
43+
with pytest.raises(ValueError) as e:
44+
user._legacy_get_session_auth_hash()
45+
46+
assert "'session_salt' must be set" in str(e.value)
47+
48+
@pytest.mark.skipif(django.VERSION < (3, 1), reason="requires Django 3.1 or higher")
49+
def test_legacy_get_session_auth_hash__unique(self, db):
50+
spiderman = EmailUser(email='spiderman@avengers.com')
51+
ironman = EmailUser(email='ironman@avengers.com')
52+
53+
assert (
54+
spiderman._legacy_get_session_auth_hash() !=
55+
ironman._legacy_get_session_auth_hash()
56+
)
57+
3158
def test_password_field(self):
3259
user = EmailUser(email='spiderman@avengers.com')
3360
with pytest.raises(FieldDoesNotExist):

‎tests/contrib/wagtail/test_views.py‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
1-
from mailauth.contrib.wagtail.views import LoginView
1+
import pytest
2+
23
from mailauth.forms import EmailLoginForm
34

45

56
class TestLoginView:
67
def test_get_from_class(self):
8+
pytest.importorskip('wagtail')
9+
from mailauth.contrib.wagtail.views import LoginView
710
assert issubclass(LoginView().get_form_class(), EmailLoginForm)
811

912
def test_form_valid(self, rf, db):
13+
pytest.importorskip('wagtail')
14+
from mailauth.contrib.wagtail.views import LoginView
1015
view = LoginView()
1116
request = rf.get('/')
1217

‎tests/test_backends.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,5 +62,5 @@ def test_get_login_url(self, signer, signature):
6262
backend = MailAuthBackend()
6363
MailAuthBackend.signer = signer
6464
assert backend.get_login_url(signature) == (
65-
"/accounts/login/LZ.173QUS.1Hjptg.lf2hFgOXQtjQsFypS2ItRG2hkpA"
65+
f"/accounts/login/{signature}"
6666
)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /