From ecfc0089bff5072e0525e0d558425f204be4291b Mon Sep 17 00:00:00 2001 From: Julian Baumann Date: Wed, 6 Dec 2023 17:05:59 +0100 Subject: [PATCH] migrate to keycloak as IDP (#422) --- myhpi/core/auth.py | 37 +++++++++++++++++++---------------- myhpi/core/models.py | 25 +++++++++++++++++++---- myhpi/settings.py | 8 ++++---- myhpi/tests/core/test_auth.py | 5 ++--- 4 files changed, 47 insertions(+), 28 deletions(-) diff --git a/myhpi/core/auth.py b/myhpi/core/auth.py index a3cf975a..0f24b0cd 100644 --- a/myhpi/core/auth.py +++ b/myhpi/core/auth.py @@ -7,8 +7,15 @@ def mail_replacement(email): class MyHPIOIDCAB(OIDCAuthenticationBackend): + def _update_groups(self, user, claims): + group_names = claims.get("roles", []) + groups = set() + for group in group_names: + groups.add(Group.objects.get_or_create(name__iexact=group)[0]) + user.groups.set(groups) + def create_user(self, claims): - email = mail_replacement(claims.get("email")) + email = claims.get("email") first_name = claims.get("given_name", "") last_name = claims.get("family_name", "") username = claims.get("sub") @@ -16,24 +23,15 @@ def create_user(self, claims): user = self.UserModel.objects.create_user( username, email=email, first_name=first_name, last_name=last_name ) - - try: - hpi = Group.objects.get(name="HPI") - user.groups.add(hpi) - except Group.DoesNotExist: - pass - - if "student" in email.split("@")[1]: - try: - student = Group.objects.get(name="Student") - user.groups.add(student) - except Group.DoesNotExist: - pass - + self._update_groups(user, claims) return user def update_user(self, user, claims): - user.email = mail_replacement(claims.get("email")) + user.email = claims.get("email") + user.first_name = claims.get("given_name", "") + user.last_name = claims.get("family_name", "") + # group updating currently disabled until all groups are migrated to keycloak + # self._update_groups(user, claims) user.save() return user @@ -43,4 +41,9 @@ def filter_users_by_claims(self, claims): username = claims.get("sub") if not username: return self.UserModel.objects.none() - return self.UserModel.objects.filter(username__iexact=username) + users = self.UserModel.objects.filter(username__iexact=username) + if not users.exists(): + users = self.UserModel.objects.filter( + email__iexact=mail_replacement(claims.get("email")) + ) + return users diff --git a/myhpi/core/models.py b/myhpi/core/models.py index b7e418ce..6a3c5b20 100644 --- a/myhpi/core/models.py +++ b/myhpi/core/models.py @@ -170,12 +170,29 @@ def get_last_minutes(self): return existing_minutes.last().specific -class UserSelectWidget(s2forms.ModelSelect2MultipleWidget): +class UserSelectMultipleWidget(s2forms.ModelSelect2MultipleWidget): search_fields = [ "username__icontains", "email__icontains", + "first_name__icontains", + "last_name__icontains", ] + def label_from_instance(self, obj): + return f"{obj.first_name} {obj.last_name}" + + +class UserSelectWidget(s2forms.ModelSelect2Widget): + search_fields = [ + "username__icontains", + "email__icontains", + "first_name__icontains", + "last_name__icontains", + ] + + def label_from_instance(self, obj): + return f"{obj.first_name} {obj.last_name}" + class Minutes(BasePage): date = DateField() @@ -193,9 +210,9 @@ class Minutes(BasePage): content_panels = Page.content_panels + [ FieldPanel("date"), - FieldPanel("moderator"), - FieldPanel("author"), - FieldPanel("participants", widget=UserSelectWidget({"data-width": "100%"})), + FieldPanel("moderator", widget=UserSelectWidget({"data-width": "100%"})), + FieldPanel("author", widget=UserSelectWidget({"data-width": "100%"})), + FieldPanel("participants", widget=UserSelectMultipleWidget({"data-width": "100%"})), FieldPanel("labels"), FieldPanel("body"), FieldPanel("guests"), diff --git a/myhpi/settings.py b/myhpi/settings.py index 3baacd04..3543846f 100644 --- a/myhpi/settings.py +++ b/myhpi/settings.py @@ -78,10 +78,10 @@ OIDC_RP_CLIENT_ID = env.str("OIDC_RP_CLIENT_ID") OIDC_RP_CLIENT_SECRET = env.str("OIDC_RP_CLIENT_SECRET") -OIDC_OP_AUTHORIZATION_ENDPOINT = "https://oidc.hpi.de/auth" -OIDC_OP_TOKEN_ENDPOINT = "https://oidc.hpi.de/token" -OIDC_OP_USER_ENDPOINT = "https://oidc.hpi.de/me" -OIDC_OP_JWKS_ENDPOINT = "https://oidc.hpi.de/certs" +OIDC_OP_AUTHORIZATION_ENDPOINT = "https://auth.myhpi.de/realms/fsr/protocol/openid-connect/auth" +OIDC_OP_TOKEN_ENDPOINT = "https://auth.myhpi.de/realms/fsr/protocol/openid-connect/token" +OIDC_OP_USER_ENDPOINT = "https://auth.myhpi.de/realms/fsr/protocol/openid-connect/userinfo" +OIDC_OP_JWKS_ENDPOINT = "https://auth.myhpi.de/realms/fsr/protocol/openid-connect/certs" LOGIN_REDIRECT_URL = "/" LOGOUT_REDIRECT_URL = "/" diff --git a/myhpi/tests/core/test_auth.py b/myhpi/tests/core/test_auth.py index 63998d40..198b2f67 100644 --- a/myhpi/tests/core/test_auth.py +++ b/myhpi/tests/core/test_auth.py @@ -30,8 +30,7 @@ def test_create_student(self): } user = self.auth_backend.create_user(claims) self.assertEqual(user.username, "grace.hopper") - self.assertEqual(user.email, "grace.hopper@student.example.com") - self.assertTrue(user.groups.filter(name="Student").exists()) + self.assertEqual(user.email, "grace.hopper@student.uni-potsdam.example.com") def test_update_user(self): claims = { @@ -47,5 +46,5 @@ def test_update_user(self): claims["email"] = "jw.goethe@weimar.eu" user = self.auth_backend.update_user(user, claims) self.assertEqual(user.first_name, "Johann Wolfgang") - self.assertEqual(user.last_name, "Goethe") + self.assertEqual(user.last_name, "von Goethe") self.assertEqual(user.email, "jw.goethe@weimar.eu")