From 8a86bdf3f4c90a69c6601fc94c684a82b05202ae Mon Sep 17 00:00:00 2001 From: Enrico Zini Date: Fri, 1 May 2020 19:19:47 +0200 Subject: [PATCH] Sync to changes in contributors.d.o. refs: #25 --- signon/middleware.py | 8 ++- signon/tests/test_authentication.py | 77 +++++++++++++++++++++++++++++ signon/views.py | 6 ++- 3 files changed, 89 insertions(+), 2 deletions(-) diff --git a/signon/middleware.py b/signon/middleware.py index cb4bcdcc..cad88033 100644 --- a/signon/middleware.py +++ b/signon/middleware.py @@ -96,7 +96,13 @@ class SignonMiddleware: for identity in request.signon_identities.values(): if user is None: user = User.objects.create_from_identity(identity) - identity.user = user + log.info("%s: auto created from identity %s", user, identity) + identity.person = user + log.info("%s: auto bound to identity %s", user, identity) + identity.save( + audit_author=User.objects.get_housekeeper(), + audit_notes=f"Auto associated during automatic creation of user {user}", + ) def _signon_auto_bind(self, request): """ diff --git a/signon/tests/test_authentication.py b/signon/tests/test_authentication.py index 8df36978..b20f2565 100644 --- a/signon/tests/test_authentication.py +++ b/signon/tests/test_authentication.py @@ -2,6 +2,7 @@ from __future__ import annotations from unittest import mock from django.test import TestCase, override_settings from django.urls import reverse +from django.contrib.auth import get_user_model from signon.unittest import SignonFixtureMixin from signon import providers @@ -275,3 +276,79 @@ class TestAuthentication(SignonFixtureMixin, TestCase): self.identities.salsa2.refresh_from_db() self.assertIsNone(self.identities.salsa2.person) + + @override_settings(SIGNON_AUTO_CREATE_USER=True) + def test_auto_create_user_debsso(self): + User = get_user_model() + if not hasattr(User.objects, "create_from_identity"): + self.skipTest("user model manager does not implement create_from_identity") + + # One bound debsso account + self.identities.create( + "debsso", issuer="debsso", subject="new@debian.org", audit_skip=True) + + def _instantiate_identities(_self, request): + request.signon_identities = { + "debsso": self.identities.debsso, + } + + with mock.patch("signon.middleware.SignonMiddleware._instantiate_identities", _instantiate_identities): + client = self.make_test_client(None) + with self.assertLogs() as log: + response = client.get(reverse('signon:whoami')) + + self.identities.debsso.refresh_from_db() + person = self.identities.debsso.person + + self.assertEqual(log.output, [ + f"INFO:signon.middleware:{person}: auto created from identity -:debsso:new@debian.org", + f"INFO:signon.middleware:{person}: auto bound to identity {person}:debsso:new@debian.org", + ]) + + self.assertEqual(response.status_code, 200) + + request = response.wsgi_request + self.assertEqual(request.signon_identities, { + "debsso": self.identities.debsso, + }) + + self.assertIsNotNone(person) + self.assertEqual(list(person.identities.all()), [self.identities.debsso]) + + @override_settings(SIGNON_AUTO_CREATE_USER=True) + def test_auto_create_user_salsa(self): + User = get_user_model() + if not hasattr(User.objects, "create_from_identity"): + self.skipTest("user model manager does not implement create_from_identity") + + # One bound debsso account + self.identities.create( + "salsa", issuer="salsa", subject="2", username="new", audit_skip=True) + + def _instantiate_identities(_self, request): + request.signon_identities = { + "salsa": self.identities.salsa, + } + + with mock.patch("signon.middleware.SignonMiddleware._instantiate_identities", _instantiate_identities): + client = self.make_test_client(None) + with self.assertLogs() as log: + response = client.get(reverse('signon:whoami')) + + self.identities.salsa.refresh_from_db() + person = self.identities.salsa.person + + self.assertEqual(log.output, [ + f"INFO:signon.middleware:{person}: auto created from identity -:salsa:2", + f"INFO:signon.middleware:{person}: auto bound to identity {person}:salsa:2", + ]) + + self.assertEqual(response.status_code, 200) + + request = response.wsgi_request + self.assertEqual(request.signon_identities, { + "salsa": self.identities.salsa, + }) + + self.assertIsNotNone(person) + self.assertEqual(list(person.identities.all()), [self.identities.salsa]) diff --git a/signon/views.py b/signon/views.py index 69342dd8..1d75e725 100644 --- a/signon/views.py +++ b/signon/views.py @@ -42,7 +42,11 @@ class Logout(View): # Log out the Django user if they were logged in. auth.logout(request) - return redirect("home") + next_url = request.POST.get("next") + if next_url is None: + return redirect("home") + else: + return redirect(next_url) class Whoami(View): -- GitLab