Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SocialLoginView returns 200 regardless of SocialLoginSerializer error #658

Open
benshaji-sequoiaat opened this issue Sep 26, 2024 · 0 comments

Comments

@benshaji-sequoiaat
Copy link

benshaji-sequoiaat commented Sep 26, 2024

Some context of the issue

I use Auth0 as my provider. Everything works well except when someone tries to login with same email address created in Auth0. In Auth0, you can use social login (say with Microsoft account) with an email [email protected]. At the same time, we can manually create a user with this very same email by click "create user" option in Auth0. No issues in Auth0, all it sees is two users.

How above issue with Auth0 affects me

I already have an account which was created when i had used "Login with Microsoft" option. Now, when i use the email-password account that i've created with "create user" in Auth0, my API should say, "A user with this email already exist", which it does, but not returning the error.

More about my API

django-allauth==0.61.1
dj-rest-auth==6.0.0
Django==5.0.1

I use a custom user model

class LocalUserAccounts(AbstractUser):
    """Django custom user model"""

    email = models.EmailField(max_length=254, unique=True)
    show_intro = models.BooleanField(null=True, blank=True, default=True)

    def __str__(self):
        return f"{self.email}"

Below is my view for the endpoint /oauth/auth0/

class Auth0Login(SocialLoginView):
    """OAuth login endpoint"""

    adapter_class = Auth0OAuth2Adapter
    callback_url = CONSTANTS.OAUTH_CALLBACK_URL
    client_class = OAuth2Client

Error that i get when tries to login with an account with same email

IP:127.0.0.1 for /oauth/auth0/
>>> self.serializer: SocialLoginSerializer(context={'request': <rest_framework.request.Request: POST '/oauth/auth0/'>, 'format': None, 'view': <eboost.oauth_providersettings.Auth0Login object>}, data=<QueryDict: {'code': ['8KMR7PcOGZFJAxfcs4u9asEH5Cp5FxrPlUmfHTOrMQcor']}>):
    access_token = CharField(allow_blank=True, required=False)
    code = CharField(allow_blank=True, required=False)
    id_token = CharField(allow_blank=True, required=False)
Traceback (most recent call last):
  File ".venv/lib/python3.12/site-packages/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv/lib/python3.12/site-packages/dj_rest_auth/views.py", line 129, in post
    self.serializer.is_valid(raise_exception=True)
  File ".venv/lib/python3.12/site-packages/rest_framework/serializers.py", line 235, in is_valid
    raise ValidationError(self.errors)
rest_framework.exceptions.ValidationError: {'non_field_errors': [ErrorDetail(string='User is already registered with this e-mail address.', code='invalid')], 'status_code': 400}
[26/Sep/2024 07:48:23] "POST /oauth/auth0/ HTTP/1.1" 200 773

Okay, it found that there's a user already existing with this email address which i just tried to login with, so account is not created which is totally expected.

Let's also look into SocialLoginSerializer, we'll see where above exception is raised:

if not login.is_existing:
    # We have an account already signed up in a different flow
    # with the same email address: raise an exception.
    # This needs to be handled in the frontend. We can not just
    # link up the accounts due to security constraints
    if allauth_account_settings.UNIQUE_EMAIL:
        # Do we have an account already with this email address?
        account_exists = get_user_model().objects.filter(
            email=login.user.email,
        ).exists()
        if account_exists:
            raise serializers.ValidationError(
                _('User is already registered with this e-mail address.'),
            )

    login.lookup()
    try:
        login.save(request, connect=True)
    except IntegrityError as ex:
        raise serializers.ValidationError(
            _('User is already registered with this e-mail address.'),
        ) from ex

Here, it says the unique email must be handled in the front-end. But, how does the frontend know if it's not returning this "'User is already registered with this e-mail address" error with some bad response code? That's my whole question is.

What's the actual issue / What do i expect

The question that I have is simply, why does SocialLoginView returns 200 when there's an exception in the SocialLoginSerializer class raising validation error. If it returns the error with a bad response code, all is good.

Quick question, does this ans say about anything i can do here: https://stackoverflow.com/a/63211074

Please feel free to tell me if i need to expand this issue in more verbose or if i need to add more info

Thanks for reading!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant