Refs #775 -- Pluggable authentication backends (#1447)

* Drag-and-drop: Force csrf_token to be present

* Rough design

* Missing file

* b.visble

* Forms

* Docs

* Tests

* Fix variable
This commit is contained in:
Raphael Michel
2019-10-17 09:11:03 +02:00
committed by GitHub
parent e34511b984
commit 8a6a515b6a
25 changed files with 476 additions and 72 deletions
+77
View File
@@ -103,6 +103,51 @@ class LoginFormTest(TestCase):
response = self.client.get('/control/login')
self.assertEqual(response.status_code, 200)
def test_wrong_backend(self):
self.user = User.objects.create_user('hallo@example.com', 'dummy', auth_backend='test_request')
response = self.client.post('/control/login', {
'email': 'hallo@example.com',
'password': 'dummy',
})
self.assertEqual(response.status_code, 200)
def test_backends_shown(self):
response = self.client.get('/control/login')
self.assertEqual(response.status_code, 200)
assert b'Form' in response.content
assert b'pretix User' in response.content
assert b'Request' not in response.content
def test_form_backend(self):
response = self.client.get('/control/login?backend=test_form')
self.assertEqual(response.status_code, 200)
assert b'name="username"' in response.content
response = self.client.post('/control/login?backend=test_form', {
'username': 'dummy',
'password': 'dummy',
})
self.assertEqual(response.status_code, 200)
assert b'alert-danger' in response.content
response = self.client.post('/control/login?backend=test_form', {
'username': 'foo',
'password': 'bar',
})
self.assertEqual(response.status_code, 302)
response = self.client.get('/control/')
assert b'foo' in response.content
def test_request_backend(self):
response = self.client.get('/control/login?backend=test_request')
self.assertEqual(response.status_code, 200)
assert b'name="email"' in response.content
response = self.client.get('/control/login', HTTP_X_LOGIN_EMAIL='hallo@example.org')
self.assertEqual(response.status_code, 302)
response = self.client.get('/control/')
assert b'hallo@example.org' in response.content
class RegistrationFormTest(TestCase):
@@ -201,6 +246,24 @@ class RegistrationFormTest(TestCase):
assert time.time() - self.client.session['pretix_auth_login_time'] < 60
assert not self.client.session['pretix_auth_long_session']
@override_settings(PRETIX_REGISTRATION=False)
def test_disabled(self):
response = self.client.post('/control/register', {
'email': 'dummy@dummy.dummy',
'password': 'foobarbar',
'password_repeat': 'foobarbar'
})
self.assertEqual(response.status_code, 403)
@override_settings(PRETIX_AUTH_BACKENDS=['tests.testdummy.auth.TestFormAuthBackend'])
def test_no_native_auth(self):
response = self.client.post('/control/register', {
'email': 'dummy@dummy.dummy',
'password': 'foobarbar',
'password_repeat': 'foobarbar'
})
self.assertEqual(response.status_code, 403)
@pytest.fixture
def class_monkeypatch(request, monkeypatch):
@@ -560,6 +623,20 @@ class PasswordRecoveryFormTest(TestCase):
self.user = User.objects.get(id=self.user.id)
self.assertTrue(self.user.check_password('demo'))
@override_settings(PRETIX_PASSWORD_RESET=False)
def test_disabled(self):
response = self.client.post('/control/forgot', {
'email': 'dummy@dummy.dummy',
})
self.assertEqual(response.status_code, 403)
@override_settings(PRETIX_AUTH_BACKENDS=['tests.testdummy.auth.TestFormAuthBackend'])
def test_no_native_auth(self):
response = self.client.post('/control/forgot', {
'email': 'dummy@dummy.dummy',
})
self.assertEqual(response.status_code, 403)
class SessionTimeOutTest(TestCase):
def setUp(self):
+12
View File
@@ -72,6 +72,18 @@ class UserSettingsTest(SoupTest):
self.user = User.objects.get(pk=self.user.pk)
assert self.user.password == pw
def test_change_password_wrong_backend(self):
self.user.auth_backend = 'test_request'
self.user.save()
self.save({
'new_pw': 'foobarbar',
'new_pw_repeat': 'foobarbar',
'old_pw': 'dummy',
})
pw = self.user.password
self.user = User.objects.get(pk=self.user.pk)
assert self.user.password == pw
def test_change_password_success(self):
doc = self.save({
'new_pw': 'foobarbar',
+7 -1
View File
@@ -8,5 +8,11 @@ TEMPLATES[0]['DIRS'].append(os.path.join(TEST_DIR, 'templates')) # NOQA
INSTALLED_APPS.append('tests.testdummy') # NOQA
PRETIX_AUTH_BACKENDS = [
'pretix.base.auth.NativeAuthBackend',
'tests.testdummy.auth.TestFormAuthBackend',
'tests.testdummy.auth.TestRequestAuthBackend',
]
for a in PLUGINS:
INSTALLED_APPS.remove(a)
INSTALLED_APPS.remove(a)
+38
View File
@@ -0,0 +1,38 @@
from collections import OrderedDict
from django import forms
from pretix.base.auth import BaseAuthBackend
from pretix.base.models import User
class TestFormAuthBackend(BaseAuthBackend):
identifier = 'test_form'
verbose_name = 'Form'
@property
def login_form_fields(self) -> dict:
return OrderedDict([
('username', forms.CharField(max_length=100)),
('password', forms.CharField(max_length=100)),
])
def form_authenticate(self, request, form_data):
if form_data['username'] == 'foo' and form_data['password'] == 'bar':
return User.objects.get_or_create(
email='foo@example.com',
auth_backend='test_form'
)[0]
class TestRequestAuthBackend(BaseAuthBackend):
identifier = 'test_request'
verbose_name = 'Request'
visible = False
def request_authenticate(self, request):
if 'X-Login-Email' in request.headers:
return User.objects.get_or_create(
email=request.headers['X-Login-Email'],
auth_backend='test_request'
)[0]