aboutsummaryrefslogtreecommitdiffstats
path: root/pydis_site
diff options
context:
space:
mode:
authorGravatar Gareth Coles <[email protected]>2019-10-22 17:05:01 +0100
committerGravatar Gareth Coles <[email protected]>2019-10-22 17:05:01 +0100
commit604e3c09f9d07268bc4424fd06b0a1dcfb1b8976 (patch)
treeebdf7c5ae243cf95ca369332d9073a356507b967 /pydis_site
parentMerge branch 'master' into allauth-user-settings (diff)
Prevent user signup when they've never joined+verified
Diffstat (limited to 'pydis_site')
-rw-r--r--pydis_site/tests/test_utils_account.py94
-rw-r--r--pydis_site/utils/account.py29
2 files changed, 110 insertions, 13 deletions
diff --git a/pydis_site/tests/test_utils_account.py b/pydis_site/tests/test_utils_account.py
index 91c2808c..d2946368 100644
--- a/pydis_site/tests/test_utils_account.py
+++ b/pydis_site/tests/test_utils_account.py
@@ -7,6 +7,7 @@ from django.contrib.messages.storage.base import BaseStorage
from django.http import HttpRequest
from django.test import TestCase
+from pydis_site.apps.api.models import Role, User as DiscordUser
from pydis_site.utils.account import AccountAdapter, SocialAccountAdapter
@@ -18,21 +19,74 @@ class AccountUtilsTests(TestCase):
user=self.django_user, provider="discord", uid=0
)
+ self.discord_account_role = SocialAccount.objects.create(
+ user=self.django_user, provider="discord", uid=1
+ )
+
+ self.discord_account_two_roles = SocialAccount.objects.create(
+ user=self.django_user, provider="discord", uid=2
+ )
+
+ self.discord_account_not_present = SocialAccount.objects.create(
+ user=self.django_user, provider="discord", uid=3
+ )
+
self.github_account = SocialAccount.objects.create(
user=self.django_user, provider="github", uid=0
)
+ self.discord_user = DiscordUser.objects.create(
+ id=0,
+ name="user",
+ discriminator=0
+ )
+
+ self.discord_user_role = DiscordUser.objects.create(
+ id=1,
+ name="user present",
+ discriminator=0
+ )
+
+ self.discord_user_two_roles = DiscordUser.objects.create(
+ id=2,
+ name="user with both roles",
+ discriminator=0
+ )
+
+ everyone_role = Role.objects.create(
+ id=0,
+ name="@everyone",
+ colour=0,
+ permissions=0,
+ position=0
+ )
+
+ self.discord_user_role.roles.add(everyone_role)
+ self.discord_user_two_roles.roles.add(everyone_role)
+
+ self.discord_user_two_roles.roles.add(Role.objects.create(
+ id=1,
+ name="Developers",
+ colour=0,
+ permissions=0,
+ position=1
+ ))
+
def test_account_adapter(self):
"""Test that our Allauth account adapter functions correctly."""
adapter = AccountAdapter()
self.assertFalse(adapter.is_open_for_signup(HttpRequest()))
- def test_social_account_adapter(self):
- """Test that our Allauth social account adapter functions correctly."""
+ def test_social_account_adapter_signup(self):
+ """Test that our Allauth social account adapter correctly handles signups."""
adapter = SocialAccountAdapter()
discord_login = SocialLogin(account=self.discord_account)
+ discord_login_role = SocialLogin(account=self.discord_account_role)
+ discord_login_two_roles = SocialLogin(account=self.discord_account_two_roles)
+ discord_login_not_present = SocialLogin(account=self.discord_account_not_present)
+
github_login = SocialLogin(account=self.github_account)
messages_request = HttpRequest()
@@ -43,8 +97,36 @@ class AccountUtilsTests(TestCase):
with self.assertRaises(ImmediateHttpResponse):
adapter.is_open_for_signup(messages_request, github_login)
- self.assertEqual(len(messages_request._messages._queued_messages), 1)
- self.assertEqual(mock_redirect.call_count, 1)
- self.assertEqual(mock_reverse.call_count, 1)
+ with self.assertRaises(ImmediateHttpResponse):
+ adapter.is_open_for_signup(messages_request, discord_login)
+
+ with self.assertRaises(ImmediateHttpResponse):
+ adapter.is_open_for_signup(messages_request, discord_login_role)
+
+ with self.assertRaises(ImmediateHttpResponse):
+ adapter.is_open_for_signup(messages_request, discord_login_not_present)
+
+ self.assertEqual(len(messages_request._messages._queued_messages), 4)
+ self.assertEqual(mock_redirect.call_count, 4)
+ self.assertEqual(mock_reverse.call_count, 4)
+
+ self.assertTrue(adapter.is_open_for_signup(HttpRequest(), discord_login_two_roles))
+
+ def test_social_account_adapter_populate(self):
+ """Test that our Allauth social account adapter correctly handles data population."""
+ adapter = SocialAccountAdapter()
+
+ discord_login = SocialLogin(
+ account=self.discord_account,
+ user=self.django_user
+ )
+
+ discord_login.account.extra_data["discriminator"] = "0000"
+
+ user = adapter.populate_user(
+ HttpRequest(), discord_login,
+ {"username": "user"}
+ )
- self.assertTrue(adapter.is_open_for_signup(HttpRequest(), discord_login))
+ self.assertEqual(user.username, "user#0000")
+ self.assertEqual(user.first_name, "user#0000")
diff --git a/pydis_site/utils/account.py b/pydis_site/utils/account.py
index 9faad986..e64919de 100644
--- a/pydis_site/utils/account.py
+++ b/pydis_site/utils/account.py
@@ -4,12 +4,19 @@ 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.auth.models import User as DjangoUser
from django.contrib.messages import ERROR, add_message
from django.http import HttpRequest
from django.shortcuts import redirect
from django.urls import reverse
+from pydis_site.apps.api.models import User as DiscordUser
+
+ERROR_CONNECT_DISCORD = ("You must login with Discord before connecting another account. "
+ "Your account details have not been saved.")
+ERROR_JOIN_DISCORD = ("Please join the Discord server and verify that you accept the rules and "
+ "privacy policy.")
+
class AccountAdapter(DefaultAccountAdapter):
"""An Allauth account adapter that prevents signups via form submission."""
@@ -36,11 +43,19 @@ class SocialAccountAdapter(DefaultSocialAccountAdapter):
a non-Discord connection, as we require this connection for our users.
"""
if social_login.account.provider != "discord":
- add_message(
- request, ERROR,
- "You must login with Discord before connecting another account. Your account "
- "details have not been saved."
- )
+ add_message(request, ERROR, ERROR_CONNECT_DISCORD)
+
+ raise ImmediateHttpResponse(redirect(reverse("home")))
+
+ try:
+ user = DiscordUser.objects.get(id=int(social_login.account.uid))
+ except DiscordUser.DoesNotExist:
+ add_message(request, ERROR, ERROR_JOIN_DISCORD)
+
+ raise ImmediateHttpResponse(redirect(reverse("home")))
+
+ if user.roles.count() <= 1:
+ add_message(request, ERROR, ERROR_JOIN_DISCORD)
raise ImmediateHttpResponse(redirect(reverse("home")))
@@ -48,7 +63,7 @@ class SocialAccountAdapter(DefaultSocialAccountAdapter):
def populate_user(self, request: HttpRequest,
social_login: SocialLogin,
- data: Dict[str, Any]) -> User:
+ data: Dict[str, Any]) -> DjangoUser:
"""
Method used to populate a Django User with data.