From 27b6c7195f5cf6d41a43e6dc6b73576ede131664 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Bedna=C5=99=C3=ADk?= <jan.bednarik@gmail.com> Date: Wed, 9 Dec 2020 01:06:17 +0100 Subject: [PATCH] Signal for post_login event --- README.md | 12 ++++++++++++ pirates/auth.py | 16 +++++++++++++++- pirates/signals.py | 3 +++ setup.py | 9 +++++++-- tests/requirements.txt | 1 + tests/test_auth.py | 42 ++++++++++++++++++++++++++++++++++++++++-- tox.ini | 3 ++- 7 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 pirates/signals.py diff --git a/README.md b/README.md index 469a4e1..5116df2 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ Django app na uživatele, týmy a skupiny, s napojením na LDAP a SSO. [](https://github.com/psf/black) [](LICENSE) + + ## Použití @@ -73,3 +75,13 @@ OIDC_OP_USER_ENDPOINT = join(OIDC_RP_REALM_URL, "protocol/openid-connect/userinf ``` URL patterns pro OpenID Connect už jsou součástí `pirates.urls` (viz výše). + +#### Signál po přihlášení + +Po přihlášení uživatele je poslán signál `pirates.signals.post_login` s +parametry: + +* `sender` - `PiratesOIDCAuthenticationBackend` +* `user` - přihlášený uživatel (instance `AUTH_USER_MODEL`) +* `created` - `True`/`False` zda-li byl vytvořen nový uživatel +* `request` - instance `HttpRequest` diff --git a/pirates/auth.py b/pirates/auth.py index e45133e..eade397 100644 --- a/pirates/auth.py +++ b/pirates/auth.py @@ -1,5 +1,7 @@ from mozilla_django_oidc.auth import OIDCAuthenticationBackend +from .signals import post_login + class PiratesOIDCAuthenticationBackend(OIDCAuthenticationBackend): """ @@ -23,13 +25,25 @@ class PiratesOIDCAuthenticationBackend(OIDCAuthenticationBackend): first_name = claims.get("given_name", "") last_name = claims.get("family_name", "") email = claims.get("email", "") - return self.UserModel.objects.create( + user = self.UserModel.objects.create( sso_id=sso_id, first_name=first_name, last_name=last_name, email=email ) + self.send_post_login_signal(user, True, claims) + return user def update_user(self, user, claims): user.first_name = claims.get("given_name", "") user.last_name = claims.get("family_name", "") user.email = claims.get("email", "") user.save() + self.send_post_login_signal(user, False, claims) return user + + def send_post_login_signal(self, user, created, claims): + post_login.send( + sender=self.__class__, + user=user, + created=created, + claims=claims, + request=self.request, + ) diff --git a/pirates/signals.py b/pirates/signals.py new file mode 100644 index 0000000..d14a130 --- /dev/null +++ b/pirates/signals.py @@ -0,0 +1,3 @@ +from django.dispatch import Signal + +post_login = Signal() diff --git a/setup.py b/setup.py index 345874a..3e71bf9 100755 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ def read(fname): setup( name="pirates", - version="0.3.1", + version="0.4.0", license="MIT", description="Django app for users, teamds and groups.", long_description=read("README.md"), @@ -34,7 +34,12 @@ setup( "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", "Programming Language :: Python :: Implementation :: CPython", + "Framework :: Django", + "Framework :: Django :: 2.2", + "Framework :: Django :: 3.0", + "Framework :: Django :: 3.1", "Topic :: Utilities", ], project_urls={ @@ -44,5 +49,5 @@ setup( }, keywords=["django", "openid", "sso"], python_requires=">=3.6", - install_requires=["mozilla-django-oidc>=1.2.3,<2", "python-ldap>=3.2.0,<4"], + install_requires=["mozilla-django-oidc>=1.2.4,<2", "python-ldap>=3.2.0,<4"], ) diff --git a/tests/requirements.txt b/tests/requirements.txt index e2f939e..8bb1a4e 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -2,3 +2,4 @@ pytest pytest-cov pytest-factoryboy pytest-django +pytest-mock diff --git a/tests/test_auth.py b/tests/test_auth.py index b9f6952..98cf4c5 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -10,8 +10,10 @@ fake = Faker() @pytest.fixture -def backend(): - return PiratesOIDCAuthenticationBackend() +def backend(mocker): + instance = PiratesOIDCAuthenticationBackend() + instance.request = mocker.Mock() + return instance def test_auth_backend__get_sso_id(backend): @@ -69,3 +71,39 @@ def test_auth_backend__update_user(backend, user): assert updated_user.last_name == claims["family_name"] assert updated_user.email == claims["email"] assert get_user_model().objects.get() == updated_user + + +def test_auth_backend__create_user__send_post_login(backend, mocker): + m_post_login = mocker.patch("pirates.auth.post_login") + claims = { + "sub": fake.random_letters(), + "given_name": fake.first_name(), + "family_name": fake.last_name(), + "email": fake.email(), + } + user = backend.create_user(claims) + m_post_login.send.assert_called_once_with( + sender=backend.__class__, + user=user, + created=True, + claims=claims, + request=backend.request, + ) + + +def test_auth_backend__update_user__send_post_login(backend, user, mocker): + m_post_login = mocker.patch("pirates.auth.post_login") + claims = { + "sub": fake.random_letters(), + "given_name": fake.first_name(), + "family_name": fake.last_name(), + "email": fake.email(), + } + updated_user = backend.update_user(user, claims) + m_post_login.send.assert_called_once_with( + sender=backend.__class__, + user=updated_user, + created=False, + claims=claims, + request=backend.request, + ) diff --git a/tox.ini b/tox.ini index bc14a56..a7bafd6 100644 --- a/tox.ini +++ b/tox.ini @@ -1,10 +1,11 @@ [tox] envlist = - py{36,37,38}-django{30,22} + py{36,37,38,39}-django{31,30,22} [testenv] deps = -r{toxinidir}/tests/requirements.txt + django31: Django>=3.1,<3.2 django30: Django>=3.0,<3.1 django22: Django>=2.2,<3 setenv = -- GitLab