Skip to content

Commit

Permalink
Fix username+email swapping.
Browse files Browse the repository at this point in the history
No-Issue

Signed-off-by: James Tanner <[email protected]>
  • Loading branch information
jctanner committed Oct 16, 2023
1 parent 95fca99 commit 73c70ae
Showing 1 changed file with 24 additions and 64 deletions.
88 changes: 24 additions & 64 deletions galaxy_ng/social/pipeline/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@ def get_username(strategy, details, backend, user=None, *args, **kwargs):

def create_user(strategy, details, backend, user=None, *args, **kwargs):

logger.info(f'create_user(1): user-kwarg:{user}')
if user:
logger.info(f'create_user(1): user-kwarg:{user}:{user.id}')
else:
logger.info(f'create_user(1): user-kwarg:{user}')
logger.info(f'create_user(2): details:{details}')

if user:
if user.username != details.get('username'):
user.username = details.get('username')
user.save()
logger.info(f'create_user(2): returning user-kwarg {user}')
logger.info(f'create_user(2): returning user-kwarg {user}:{user.id}')
return {'is_new': False}

fields = dict(
Expand All @@ -33,7 +37,7 @@ def create_user(strategy, details, backend, user=None, *args, **kwargs):
)

if not fields:
logger.info(f'create_user(3): no fields for {user}')
logger.info(f'create_user(3): no fields for {user}:{user.id}')
return

# bypass the strange logic that can't find the user ... ?
Expand All @@ -47,111 +51,67 @@ def create_user(strategy, details, backend, user=None, *args, **kwargs):
)

# check for all possible emails ...
possible_emails = [generate_unverified_email(github_id), email]
possible_emails = [generate_unverified_email(github_id)]
if email:
possible_emails.append(email)

found_email = None
for possible_email in possible_emails:

# if the email is null maybe that causes the user hijacking?
if not email:
if not possible_email:
continue

found_email = User.objects.filter(email=possible_email).first()
if found_email is not None:
logger.info(f'create_user(5): found user {found_email} via email {possible_email}')
logger.info(f'create_user(5): found user {found_email}:{found_email.id} via email {possible_email}')
break

if found_email is not None:

# fix the username if they've changed their login since last time
if found_email.username != username:
logger.info(f'create_user(6): set found user {found_email} username to {username}')
logger.info(f'create_user(6): set found user {found_email}:{found_email.id} username to {username}')
found_email.username = username
found_email.save()

if found_email.email != email:
logger.info(f'create_user(7): set found user {found_email} email to {email}')
logger.info(f'create_user(7): set found user {found_email}:{found_email.id} email to {email}')
found_email.email = email
found_email.save()

logger.info(
f'create_user(8): returning found user {found_email} via email {possible_email}'
f'create_user(8): returning found user {found_email}:{found_email.id} via email {possible_email}'
)
return {
'is_new': False,
'user': found_email
}

logger.info(f'create_user(9): did not find any users via matching emails {possible_emails}')

found_username = User.objects.filter(username=username).first()
if found_username:
logger.info(f'create_user(10): found user:{found_username}:{found_username.id}:{found_username.email} by username:{username}')

if found_username is not None and found_username.email:
# we have an old user who's got the username but it's not the same person logging in ...
# so change that username? The email should be unique right?
logger.info(f'create_user(9): set {found_username} username to {found_username.email}')
logger.info(f'create_user(11): set {found_username}:{found_username.id}:{found_username.email} username to {found_username.email}')
found_username.username = found_username.email
found_username.save()

found_username = User.objects.filter(username=username).first()
if found_username is not None:
logger.info(f'create_user(10): {found_username}')
logger.info(f'create_user(12): {found_username}')
return {
'is_new': False,
'user': found_username
}

new_user = strategy.create_user(**fields)
logger.info(f'create_user(11): {new_user}')
logger.info(f'create_user(13): {new_user}')
return {
'is_new': True,
'user': new_user
}


def user_details(strategy, details, backend, user=None, *args, **kwargs):
"""Update user details using data from provider."""

if not user:
return

changed = False # flag to track changes

# Default protected user fields (username, id, pk and email) can be ignored
# by setting the SOCIAL_AUTH_NO_DEFAULT_PROTECTED_USER_FIELDS to True
if strategy.setting("NO_DEFAULT_PROTECTED_USER_FIELDS") is True:
protected = ()
else:
protected = (
"username",
"id",
"pk",
"email",
"password",
"is_active",
"is_staff",
"is_superuser",
)

protected = protected + tuple(strategy.setting("PROTECTED_USER_FIELDS", []))

# Update user model attributes with the new data sent by the current
# provider. Update on some attributes is disabled by default, for
# example username and id fields. It's also possible to disable update
# on fields defined in SOCIAL_AUTH_PROTECTED_USER_FIELDS.
field_mapping = strategy.setting("USER_FIELD_MAPPING", {}, backend)
for name, value in details.items():
# Convert to existing user field if mapping exists
name = field_mapping.get(name, name)
if value is None or not hasattr(user, name) or name in protected:
continue

current_value = getattr(user, name, None)
if current_value == value:
continue

immutable_fields = tuple(strategy.setting("IMMUTABLE_USER_FIELDS", []))
if name in immutable_fields and current_value:
continue

changed = True
setattr(user, name, value)

if changed:
strategy.storage.user.changed(user)

0 comments on commit 73c70ae

Please sign in to comment.