From 1a7b3abc787126679db2bcc005ed45aac16381a9 Mon Sep 17 00:00:00 2001 From: Chris Maillefaud Date: Wed, 31 Jul 2024 11:32:19 -0300 Subject: [PATCH] feat: add option to add all created users as staff Also fix bugs when reading upper and lower case emails --- .github/workflows/stale.yml | 2 +- .run/Serve Docs.run.xml | 31 ++++++++++++ django_google_sso/main.py | 15 ++++-- django_google_sso/tests/test_user_helper.py | 56 +++++++++++++++++++++ docs/users.md | 7 +++ pyproject.toml | 1 + 6 files changed, 106 insertions(+), 6 deletions(-) create mode 100644 .run/Serve Docs.run.xml diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 937eeff..0375b39 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -14,7 +14,7 @@ jobs: steps: - uses: actions/stale@v4 with: - days-before-stale: 60 # Mark as stale after 60 days + days-before-stale: 30 # Mark as stale after 60 days days-before-close: 7 # Close 7 days after being marked as stale stale-issue-message: 'This issue has been marked as stale due to lack of activity. It will be closed in 7 days if no further activity occurs.' stale-pr-message: 'This pull request has been marked as stale due to lack of activity. It will be closed in 7 days if no further activity occurs.' diff --git a/.run/Serve Docs.run.xml b/.run/Serve Docs.run.xml new file mode 100644 index 0000000..ef868a2 --- /dev/null +++ b/.run/Serve Docs.run.xml @@ -0,0 +1,31 @@ + + + + + diff --git a/django_google_sso/main.py b/django_google_sso/main.py index 9a54c91..eebc32f 100644 --- a/django_google_sso/main.py +++ b/django_google_sso/main.py @@ -88,7 +88,7 @@ class UserHelper: @property def user_email(self): - return self.user_info["email"] + return self.user_info["email"].lower() @property def user_model(self) -> AbstractUser | Model: @@ -113,8 +113,10 @@ def get_or_create_user(self, extra_users_args: dict | None = None): user_defaults = extra_users_args or {} if self.username_field.name not in user_defaults: user_defaults[self.username_field.name] = self.user_email + if "email" not in user_defaults: + user_defaults["email"] = self.user_email user, created = self.user_model.objects.get_or_create( - email=self.user_email, defaults=user_defaults + email__iexact=self.user_email, defaults=user_defaults ) self.check_first_super_user(user) self.check_for_update(created, user) @@ -145,7 +147,7 @@ def check_for_update(self, created, user): def check_first_super_user(self, user): if conf.GOOGLE_SSO_AUTO_CREATE_FIRST_SUPERUSER: superuser_exists = self.user_model.objects.filter( - is_superuser=True, email__contains=f"@{self.user_email.split('@')[-1]}" + is_superuser=True, email__icontains=f"@{self.user_email.split('@')[-1]}" ).exists() if not superuser_exists: message_text = _( @@ -159,7 +161,10 @@ def check_first_super_user(self, user): self.user_changed = True def check_for_permissions(self, user): - if user.email in conf.GOOGLE_SSO_STAFF_LIST: + if ( + user.email in conf.GOOGLE_SSO_STAFF_LIST + or "*" in conf.GOOGLE_SSO_STAFF_LIST + ): message_text = _( f"User email: {self.user_email} in GOOGLE_SSO_STAFF_LIST. " f"Added Staff Permission." @@ -178,6 +183,6 @@ def check_for_permissions(self, user): user.is_staff = True def find_user(self): - query = self.user_model.objects.filter(email=self.user_email) + query = self.user_model.objects.filter(email__iexact=self.user_email) if query.exists(): return query.get() diff --git a/django_google_sso/tests/test_user_helper.py b/django_google_sso/tests/test_user_helper.py index c680638..8286e2f 100644 --- a/django_google_sso/tests/test_user_helper.py +++ b/django_google_sso/tests/test_user_helper.py @@ -2,6 +2,7 @@ from copy import deepcopy import pytest +from django.contrib.auth.models import User from django_google_sso import conf from django_google_sso.main import UserHelper @@ -88,6 +89,32 @@ def test_update_existing_user_record( assert user.email == google_response_update["email"] +def test_add_all_users_to_staff_list( + faker, google_response, callback_request, settings +): + # Arrange + settings.GOOGLE_SSO_STAFF_LIST = ["*"] + settings.GOOGLE_SSO_AUTO_CREATE_FIRST_SUPERUSER = False + importlib.reload(conf) + + emails = [ + faker.email(), + faker.email(), + faker.email(), + ] + + # Act + for email in emails: + response = deepcopy(google_response) + response["email"] = email + helper = UserHelper(response, callback_request) + helper.get_or_create_user() + helper.find_user() + + # Assert + assert User.objects.filter(is_staff=True).count() == 3 + + def test_create_staff_from_list(google_response, callback_request, settings): # Arrange settings.GOOGLE_SSO_AUTO_CREATE_FIRST_SUPERUSER = False @@ -140,3 +167,32 @@ def test_different_null_values(google_response, callback_request, monkeypatch): # Assert assert user_one.googlessouser.locale == "pt_BR" assert user_two.googlessouser.locale == "pt_BR" + + +def test_duplicated_emails(google_response, callback_request): + # Arrange + User.objects.create( + email=google_response["email"].upper(), + username=google_response["email"].upper(), + first_name=google_response["given_name"], + last_name=google_response["family_name"], + ) + + lowercase_email_response = deepcopy(google_response) + lowercase_email_response["email"] = lowercase_email_response["email"].lower() + uppercase_email_response = deepcopy(google_response) + uppercase_email_response["email"] = uppercase_email_response["email"].upper() + + # Act + user_one_helper = UserHelper(uppercase_email_response, callback_request) + user_one_helper.get_or_create_user() + user_one = user_one_helper.find_user() + + user_two_helper = UserHelper(lowercase_email_response, callback_request) + user_two_helper.get_or_create_user() + user_two = user_two_helper.find_user() + + # Assert + assert user_one.id == user_two.id + assert user_one.email == user_two.email + assert User.objects.count() == 1 diff --git a/docs/users.md b/docs/users.md index c275745..f6c6a22 100644 --- a/docs/users.md +++ b/docs/users.md @@ -40,6 +40,13 @@ GOOGLE_SSO_SUPERUSER_LIST = ["another-email@my-domain.com"] GOOGLE_SSO_AUTO_CREATE_FIRST_SUPERUSER = True ``` +For staff user creation _only_, you can add all users using "*" as the value: + +```python +# Use "*" to add all users as staff +GOOGLE_SSO_STAFF_LIST = ["*"] +``` + ## Fine-tuning users before creation If you need to do some processing _before_ user is created, you can set the diff --git a/pyproject.toml b/pyproject.toml index bf2c7f3..0f60831 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -70,6 +70,7 @@ google-auth-oauthlib = "*" auto-changelog = "*" arrow = "*" black = {version = "*", allow-prereleases = true} +Faker = "*" pre-commit = "*" pytest-coverage = "*" pytest-django = "*"