django-pfx 1.4.dev44__tar.gz → 1.4.dev48__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/PKG-INFO +1 -1
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/django_pfx.egg-info/PKG-INFO +1 -1
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/default_settings.py +2 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/models/otp_user_mixin.py +7 -3
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/tests/test_auth_api.py +54 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/.gitignore +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/.gitlab-ci.yml +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/.pre-commit-config.yaml +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/LICENSE +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/MANIFEST.in +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/README.md +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/django_pfx.egg-info/SOURCES.txt +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/django_pfx.egg-info/dependency_links.txt +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/django_pfx.egg-info/requires.txt +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/django_pfx.egg-info/top_level.txt +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/doc/Makefile +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/doc/conf.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/doc/index.rst +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/doc/source/api.views.rst +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/doc/source/authentication.md +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/doc/source/decorator.md +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/doc/source/generate_openapi.md +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/doc/source/getting_started.md +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/doc/source/internationalisation.md +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/doc/source/model.md +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/doc/source/pfx_views.md +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/doc/source/profiling.md +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/doc/source/settings.md +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/doc/source/testing.md +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/img/pfx.png +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/img/pfx.svg +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/make_messages +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/manage.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/__init__.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/__init__.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/apidoc/__init__.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/apidoc/parameters.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/apidoc/schema.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/apidoc/tags.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/apps.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/decorator/__init__.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/decorator/rest.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/exceptions.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/fields.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/http/__init__.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/http/json_response.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/locale/fr/LC_MESSAGES/django.mo +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/locale/fr/LC_MESSAGES/django.po +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/management/__init__.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/management/commands/__init__.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/management/commands/makeapidoc.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/management/commands/profile.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/middleware/__init__.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/middleware/authentication.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/middleware/locale.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/middleware/profiling.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/migrations/0001_initial.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/migrations/__init__.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/models/__init__.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/models/abstract_pfx_base_user.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/models/cache_mixins.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/models/login_ban.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/models/not_null_fields.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/models/pfx_models.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/models/pfx_user.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/models/user_filtered_queryset_mixin.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/serializers/__init__.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/serializers/json.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/settings.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/shortcuts.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/storage/__init__.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/storage/s3_storage.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/templates/registration/otp_code_email.txt +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/templates/registration/otp_code_subject.txt +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/templates/registration/password_reset_email.txt +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/templates/registration/password_reset_subject.txt +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/templates/registration/welcome_email.txt +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/templates/registration/welcome_subject.txt +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/test.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/urls.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/__init__.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/authentication_views.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/fields.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/filters_views.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/locale_views.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/parameters/__init__.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/parameters/date_format.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/parameters/groups.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/parameters/list_count.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/parameters/list_items.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/parameters/list_mode.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/parameters/list_order.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/parameters/list_search.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/parameters/media_redirect.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/parameters/meta_fields.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/parameters/meta_filters.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/parameters/meta_orders.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/parameters/subset.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/parameters/subset_limit.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/parameters/subset_offset.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/parameters/subset_page.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/parameters/subset_page_size.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/parameters/subset_page_subset.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/rest_views.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/settings/__init__.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/settings/dev.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pyproject.toml +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/requirements.txt +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/serve-doc +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/setup.cfg +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/setup.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/__init__.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/locale/fr/LC_MESSAGES/django.po +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/models.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/settings/__init__.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/settings/ci.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/settings/common.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/settings/dev.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/settings/dev_custom_example.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/settings/dev_default.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/tests/__init__.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/tests/basic_api_errors.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/tests/basic_api_test.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/tests/test_api_doc.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/tests/test_body_mixin.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/tests/test_cache.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/tests/test_client.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/tests/test_fields.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/tests/test_filters.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/tests/test_locale_api.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/tests/test_perm_tests.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/tests/test_perms_api.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/tests/test_profiling_middleware.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/tests/test_settings.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/tests/test_shortcuts.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/tests/test_timezone_middleware.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/tests/test_tools.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/tests/test_user_queryset.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/tests/test_view_decorators.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/tests/test_view_fields.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/urls.py +0 -0
- {django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/tests/views.py +0 -0
|
@@ -69,10 +69,13 @@ class OtpUserMixin(models.Model):
|
|
|
69
69
|
"""Return the setup URL for OTP activation.
|
|
70
70
|
"""
|
|
71
71
|
import pyotp
|
|
72
|
+
args = dict(
|
|
73
|
+
name=self.get_username(), issuer_name=settings.PFX_SITE_NAME)
|
|
74
|
+
if settings.PFX_OTP_IMAGE:
|
|
75
|
+
args['image'] = settings.PFX_OTP_IMAGE
|
|
72
76
|
return pyotp.totp.TOTP(
|
|
73
77
|
tmp and self.otp_secret_token_tmp or
|
|
74
|
-
self.otp_secret_token).provisioning_uri(
|
|
75
|
-
name=self.email, issuer_name=settings.PFX_SITE_NAME)
|
|
78
|
+
self.otp_secret_token).provisioning_uri(**args)
|
|
76
79
|
|
|
77
80
|
def is_otp_valid(self, otp_code, tmp=False):
|
|
78
81
|
"""Verify an OTP code.
|
|
@@ -84,7 +87,8 @@ class OtpUserMixin(models.Model):
|
|
|
84
87
|
"""
|
|
85
88
|
import pyotp
|
|
86
89
|
totp = pyotp.parse_uri(self.get_otp_setup_uri(tmp=tmp))
|
|
87
|
-
valid = totp.verify(
|
|
90
|
+
valid = totp.verify(
|
|
91
|
+
otp_code, valid_window=settings.PFX_OTP_VALID_WINDOW)
|
|
88
92
|
if not valid and timezone.now() <= self.hotp_expiry:
|
|
89
93
|
hotp = pyotp.hotp.HOTP(
|
|
90
94
|
tmp and self.otp_secret_token_tmp or
|
|
@@ -8,6 +8,7 @@ from django.conf import settings
|
|
|
8
8
|
from django.contrib.auth.tokens import default_token_generator
|
|
9
9
|
from django.core import mail
|
|
10
10
|
from django.test import TransactionTestCase, modify_settings, override_settings
|
|
11
|
+
from django.utils import timezone
|
|
11
12
|
from django.utils.encoding import force_bytes
|
|
12
13
|
from django.utils.http import urlsafe_base64_encode
|
|
13
14
|
|
|
@@ -894,6 +895,7 @@ class AuthAPITest(TestAssertMixin, TransactionTestCase):
|
|
|
894
895
|
self.assertRC(response, 200)
|
|
895
896
|
self.client.token = self.get_val(response, 'token')
|
|
896
897
|
|
|
898
|
+
@override_settings(PFX_OTP_IMAGE="https://example.org/fake.png")
|
|
897
899
|
def test_otp_enable(self):
|
|
898
900
|
self.client.login(username='jrr.tolkien', password='RIGHT PASSWORD')
|
|
899
901
|
|
|
@@ -901,7 +903,14 @@ class AuthAPITest(TestAssertMixin, TransactionTestCase):
|
|
|
901
903
|
response = self.client.get('/api/auth/otp/setup-uri')
|
|
902
904
|
self.assertRC(response, 200)
|
|
903
905
|
self.assertJIn(response, 'setup_uri', "otpauth://totp/")
|
|
906
|
+
self.assertJIn(response, 'setup_uri', "Books%20Demo:jrr.tolkien")
|
|
907
|
+
self.assertJIn(response, 'setup_uri', "issuer=Books%20Demo")
|
|
908
|
+
self.assertJIn(
|
|
909
|
+
response, 'setup_uri',
|
|
910
|
+
"image=https%3A%2F%2Fexample.org%2Ffake.png")
|
|
904
911
|
self.user1.refresh_from_db()
|
|
912
|
+
self.assertJIn(
|
|
913
|
+
response, 'setup_uri', f"secret={self.user1.otp_secret_token_tmp}")
|
|
905
914
|
self.assertIsNone(self.user1.otp_secret_token)
|
|
906
915
|
self.assertEqual(len(self.user1.otp_secret_token_tmp), 32)
|
|
907
916
|
|
|
@@ -1080,6 +1089,51 @@ class AuthAPITest(TestAssertMixin, TransactionTestCase):
|
|
|
1080
1089
|
datetime.fromtimestamp(decoded['exp']),
|
|
1081
1090
|
datetime(2023, 5, 2, 8, 10))
|
|
1082
1091
|
|
|
1092
|
+
@override_settings(
|
|
1093
|
+
PFX_OTP_VALID_WINDOW=0,
|
|
1094
|
+
PFX_TOKEN_SHORT_VALIDITY={'minutes': 30})
|
|
1095
|
+
def test_otp_login_valid_window_0(self):
|
|
1096
|
+
totp = self.enable_otp(self.user1)
|
|
1097
|
+
|
|
1098
|
+
with freeze_time("2023-05-01 08:00:00"):
|
|
1099
|
+
response = self.client.post('/api/auth/login', dict(
|
|
1100
|
+
username='jrr.tolkien',
|
|
1101
|
+
password='RIGHT PASSWORD'))
|
|
1102
|
+
self.assertRC(response, 200)
|
|
1103
|
+
token = self.get_val(response, 'token')
|
|
1104
|
+
|
|
1105
|
+
response = self.client.post('/api/auth/otp/login', dict(
|
|
1106
|
+
token=token, otp_code=totp.at(
|
|
1107
|
+
timezone.now() - timedelta(seconds=1))))
|
|
1108
|
+
self.assertRC(response, 422)
|
|
1109
|
+
|
|
1110
|
+
response = self.client.post('/api/auth/otp/login', dict(
|
|
1111
|
+
token=token, otp_code=totp.at(timezone.now())))
|
|
1112
|
+
self.assertRC(response, 200)
|
|
1113
|
+
|
|
1114
|
+
@override_settings(
|
|
1115
|
+
PFX_OTP_VALID_WINDOW=1,
|
|
1116
|
+
PFX_TOKEN_SHORT_VALIDITY={'minutes': 30})
|
|
1117
|
+
def test_otp_login_valid_window_1(self):
|
|
1118
|
+
totp = self.enable_otp(self.user1)
|
|
1119
|
+
|
|
1120
|
+
with freeze_time("2023-05-01 08:00:00"):
|
|
1121
|
+
response = self.client.post('/api/auth/login', dict(
|
|
1122
|
+
username='jrr.tolkien',
|
|
1123
|
+
password='RIGHT PASSWORD'))
|
|
1124
|
+
self.assertRC(response, 200)
|
|
1125
|
+
token = self.get_val(response, 'token')
|
|
1126
|
+
|
|
1127
|
+
response = self.client.post('/api/auth/otp/login', dict(
|
|
1128
|
+
token=token, otp_code=totp.at(
|
|
1129
|
+
timezone.now() - timedelta(seconds=31))))
|
|
1130
|
+
self.assertRC(response, 422)
|
|
1131
|
+
|
|
1132
|
+
response = self.client.post('/api/auth/otp/login', dict(
|
|
1133
|
+
token=token, otp_code=totp.at(
|
|
1134
|
+
timezone.now() - timedelta(seconds=30))))
|
|
1135
|
+
self.assertRC(response, 200)
|
|
1136
|
+
|
|
1083
1137
|
@override_settings(
|
|
1084
1138
|
PFX_TOKEN_SHORT_VALIDITY={'minutes': 30},
|
|
1085
1139
|
PFX_LOGIN_BAN_FAILED_NUMBER=2,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/models/user_filtered_queryset_mixin.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/templates/registration/otp_code_email.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/templates/registration/welcome_email.txt
RENAMED
|
File without changes
|
{django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/templates/registration/welcome_subject.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/parameters/media_redirect.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/parameters/subset_page_size.py
RENAMED
|
File without changes
|
{django_pfx-1.4.dev44 → django_pfx-1.4.dev48}/pfx/pfxcore/views/parameters/subset_page_subset.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|