diff options
Diffstat (limited to 'pydis_site')
| -rw-r--r-- | pydis_site/tests/test_utils_account.py | 94 | ||||
| -rw-r--r-- | pydis_site/utils/account.py | 29 | 
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. | 
