aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Gareth Coles <[email protected]>2019-10-20 18:05:33 +0100
committerGravatar Gareth Coles <[email protected]>2019-10-20 18:05:33 +0100
commit3caa7675f9c5c33b6a8e91c633945d5152383a76 (patch)
tree83861cec2808fbdbf87efd68083c6d80137151d5
parentSignals: Complete coverage in tests (diff)
Update Django users with Discord username+discrim.
This sets both the Django User's `username` and `first_name` params.
-rw-r--r--pydis_site/__init__.py5
-rw-r--r--pydis_site/apps/home/signals.py11
-rw-r--r--pydis_site/settings.py7
-rw-r--r--pydis_site/utils/account.py20
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)