diff options
| -rw-r--r-- | pydis_site/__init__.py | 5 | ||||
| -rw-r--r-- | pydis_site/apps/home/signals.py | 11 | ||||
| -rw-r--r-- | pydis_site/settings.py | 7 | ||||
| -rw-r--r-- | pydis_site/utils/account.py | 20 | 
4 files changed, 40 insertions, 3 deletions
diff --git a/pydis_site/__init__.py b/pydis_site/__init__.py index c6146450..df67cf71 100644 --- a/pydis_site/__init__.py +++ b/pydis_site/__init__.py @@ -2,3 +2,8 @@ from wiki.plugins.macros.mdx import toc  # Remove the toc header prefix. There's no option for this, so we gotta monkey patch it.  toc.HEADER_ID_PREFIX = '' + +# Empty list of validators for Allauth to ponder over. This is referred to in settings.py +# by a string because Allauth won't let us just give it a list _there_, we have to point +# at a list _somewhere else_ instead. +VALIDATORS = [] diff --git a/pydis_site/apps/home/signals.py b/pydis_site/apps/home/signals.py index 43e861d2..4cb4564b 100644 --- a/pydis_site/apps/home/signals.py +++ b/pydis_site/apps/home/signals.py @@ -262,6 +262,13 @@ class AllauthSignalListener:          except SocialAccount.user.RelatedObjectDoesNotExist:              return  # There's no user account yet, this will be handled by another receiver +        # Ensure that the username on this account is correct +        new_username = f"{user.name}#{user.discriminator}" + +        if account.user.username != new_username: +            account.user.username = new_username +            account.user.first_name = new_username +          if not user.in_guild:              deletion = True @@ -278,7 +285,6 @@ class AllauthSignalListener:              if account.user.is_staff:                  # They're marked as a staff user and they shouldn't be, so let's fix that                  account.user.is_staff = False -                account.user.save(update_fields=("is_staff", ))          else:              new_groups = []              is_staff = False @@ -304,4 +310,5 @@ class AllauthSignalListener:              if account.user.is_staff != is_staff:                  account.user.is_staff = is_staff -                account.user.save(update_fields=("is_staff", )) + +        account.user.save() diff --git a/pydis_site/settings.py b/pydis_site/settings.py index d6ca4860..0d893b2c 100644 --- a/pydis_site/settings.py +++ b/pydis_site/settings.py @@ -409,7 +409,12 @@ AUTHENTICATION_BACKENDS = (  )  ACCOUNT_ADAPTER = "pydis_site.utils.account.AccountAdapter" -ACCOUNT_EMAIL_REQUIRED = False  # Undocumented allauth setting; don't require emails +ACCOUNT_EMAIL_REQUIRED = False       # Undocumented allauth setting; don't require emails  ACCOUNT_EMAIL_VERIFICATION = "none"  # No verification required; we don't use emails for anything + +# We use this validator because Allauth won't let us actually supply a list with no validators +# in it, and we can't just give it a lambda - that'd be too easy, I suppose. +ACCOUNT_USERNAME_VALIDATORS = "pydis_site.VALIDATORS" +  LOGIN_REDIRECT_URL = "home"  SOCIALACCOUNT_ADAPTER = "pydis_site.utils.account.SocialAccountAdapter" diff --git a/pydis_site/utils/account.py b/pydis_site/utils/account.py index adafcea9..9faad986 100644 --- a/pydis_site/utils/account.py +++ b/pydis_site/utils/account.py @@ -1,7 +1,10 @@ +from typing import Any, Dict +  from allauth.account.adapter import DefaultAccountAdapter  from allauth.exceptions import ImmediateHttpResponse  from allauth.socialaccount.adapter import DefaultSocialAccountAdapter  from allauth.socialaccount.models import SocialLogin +from django.contrib.auth.models import User  from django.contrib.messages import ERROR, add_message  from django.http import HttpRequest  from django.shortcuts import redirect @@ -42,3 +45,20 @@ class SocialAccountAdapter(DefaultSocialAccountAdapter):              raise ImmediateHttpResponse(redirect(reverse("home")))          return True + +    def populate_user(self, request: HttpRequest, +                      social_login: SocialLogin, +                      data: Dict[str, Any]) -> User: +        """ +        Method used to populate a Django User with data. + +        We override this so that the Django user is created with the username#discriminator, +        instead of just the username, as Django users must have unique usernames. For display +        purposes, we also set the `name` key, which is used for `first_name` in the database. +        """ +        if social_login.account.provider == "discord": +            discriminator = social_login.account.extra_data["discriminator"] +            data["username"] = f"{data['username']}#{discriminator}" +            data["name"] = data["username"] + +        return super().populate_user(request, social_login, data)  |