|
22 | 22 | # .. toggle_target_removal_date: 2025-08-18 |
23 | 23 | SKIP_UPDATE_EMAIL_ON_USERNAME_MISMATCH = SettingToggle("SKIP_UPDATE_EMAIL_ON_USERNAME_MISMATCH", default=False) |
24 | 24 |
|
25 | | -# .. toggle_name: DEBUG_GET_USER_IF_EXISTS |
| 25 | +# .. toggle_name: IGNORE_LOGGED_IN_USER_ON_MISMATCH |
26 | 26 | # .. toggle_implementation: SettingToggle |
27 | | -# .. toggle_default: False |
28 | | -# .. toggle_description: Enables detailed debugging and monitoring for the get_user_if_exists pipeline function. |
29 | | -# When enabled (True), additional logging and custom attributes will be set to help debug |
30 | | -# user account conflicts and authentication issues. |
| 27 | +# .. toggle_default: True |
| 28 | +# .. toggle_description: Controls behavior when there's a username mismatch between the logged-in user |
| 29 | +# and social auth details. When enabled (True), ignores the logged-in user and proceeds with |
| 30 | +# user lookup from social auth details. When disabled (False), proceeds with the logged-in user |
| 31 | +# despite the mismatch. This toggle is for temporary rollout only to ensure we don't create bugs. |
31 | 32 | # .. toggle_use_cases: temporary |
32 | | -# .. toggle_creation_date: 2025-07-23 |
33 | | -# .. toggle_target_removal_date: 2025-09-23 |
34 | | -DEBUG_GET_USER_IF_EXISTS = SettingToggle("DEBUG_GET_USER_IF_EXISTS", default=False) |
| 33 | +# .. toggle_creation_date: 2025-07-25 |
| 34 | +# .. toggle_target_removal_date: 2025-09-25 |
| 35 | +IGNORE_LOGGED_IN_USER_ON_MISMATCH = SettingToggle("IGNORE_LOGGED_IN_USER_ON_MISMATCH", default=True) |
35 | 36 |
|
36 | 37 |
|
37 | 38 | # pylint: disable=unused-argument |
38 | 39 | # The function parameters must be named exactly as they are below. |
39 | 40 | # Do not change them to appease Pylint. |
40 | 41 | def get_user_if_exists(strategy, details, user=None, *args, **kwargs): # pylint: disable=keyword-arg-before-vararg |
41 | | - """Return a User with the given username iff the User exists. |
42 | | -
|
43 | | - Enhanced with debugging capabilities to track user account conflicts and authentication issues. |
44 | 42 | """ |
45 | | - details_username = details.get('username') |
46 | | - |
47 | | - # Set custom attributes for debugging |
48 | | - # .. custom_attribute_name: get_user_if_exists.details_username |
49 | | - # .. custom_attribute_description: Records the username provided in the social details |
50 | | - # to help debug authentication and user lookup issues. |
51 | | - set_custom_attribute('get_user_if_exists.details_username', details_username) |
52 | | - |
53 | | - # .. custom_attribute_name: get_user_if_exists.user_provided |
54 | | - # .. custom_attribute_description: Indicates whether a user object was already provided |
55 | | - # to the pipeline function, which affects the lookup logic. |
56 | | - set_custom_attribute('get_user_if_exists.user_provided', user is not None) |
57 | | - |
58 | | - # .. custom_attribute_name: get_user_if_exists.debug_enabled |
59 | | - # .. custom_attribute_description: Tracks whether the DEBUG_GET_USER_IF_EXISTS |
60 | | - # toggle is enabled during this pipeline execution. |
61 | | - set_custom_attribute('get_user_if_exists.debug_enabled', DEBUG_GET_USER_IF_EXISTS.is_enabled()) |
62 | | - |
| 43 | + Return a User with the given username iff the User exists. |
| 44 | + """ |
63 | 45 | if user: |
64 | | - # User is already provided - this typically happens when user exists from previous pipeline steps |
65 | | - existing_username = getattr(user, 'username', None) |
66 | | - |
67 | | - # .. custom_attribute_name: get_user_if_exists.existing_user_username |
68 | | - # .. custom_attribute_description: Records the username of the existing user object |
69 | | - # when a user is already provided to the pipeline. |
70 | | - set_custom_attribute('get_user_if_exists.existing_user_username', existing_username) |
71 | | - |
72 | | - # Check for username mismatch between provided user and details |
73 | | - username_mismatch = details_username != existing_username |
| 46 | + # Check for username mismatch and toggle behavior |
| 47 | + details_username = details.get('username') |
| 48 | + user_username = getattr(user, 'username', None) |
| 49 | + username_mismatch = details_username != user_username |
74 | 50 |
|
75 | 51 | # .. custom_attribute_name: get_user_if_exists.username_mismatch |
76 | 52 | # .. custom_attribute_description: Tracks whether there's a mismatch between |
77 | | - # the username in details and the existing user's username. |
| 53 | + # the username in the social details and the user's actual username. |
| 54 | + # True if usernames don't match, False if they match. |
78 | 55 | set_custom_attribute('get_user_if_exists.username_mismatch', username_mismatch) |
79 | 56 |
|
80 | | - if DEBUG_GET_USER_IF_EXISTS.is_enabled() or username_mismatch: |
81 | | - logger.info( |
82 | | - "get_user_if_exists: User already provided. Username mismatch: %s. " |
83 | | - "Details username: %s, Existing user username: %s", |
84 | | - username_mismatch, |
85 | | - details_username, |
86 | | - existing_username |
87 | | - ) |
| 57 | + # .. custom_attribute_name: get_user_if_exists.ignore_toggle_enabled |
| 58 | + # .. custom_attribute_description: Tracks whether the IGNORE_LOGGED_IN_USER_ON_MISMATCH |
| 59 | + # toggle is enabled during this pipeline execution. |
| 60 | + set_custom_attribute('get_user_if_exists.ignore_toggle_enabled', IGNORE_LOGGED_IN_USER_ON_MISMATCH.is_enabled()) |
88 | 61 |
|
89 | | - if username_mismatch: |
90 | | - logger.warning( |
91 | | - "Username mismatch in get_user_if_exists. Details username: %s, " |
92 | | - "Existing user username: %s. This may indicate an authentication issue.", |
93 | | - details_username, |
94 | | - existing_username |
| 62 | + if username_mismatch and IGNORE_LOGGED_IN_USER_ON_MISMATCH.is_enabled(): |
| 63 | + logger.info( |
| 64 | + "Username mismatch detected. Details: %s, User: %s. Ignoring logged-in user.", |
| 65 | + details_username, user_username |
95 | 66 | ) |
96 | | - |
97 | | - return {'is_new': False} |
98 | | - |
99 | | - # No user provided, attempt to find user by username from details |
100 | | - if not details_username: |
101 | | - logger.warning("get_user_if_exists: No username provided in details") |
102 | | - # .. custom_attribute_name: get_user_if_exists.no_username_in_details |
103 | | - # .. custom_attribute_description: Indicates that no username was provided in the details, |
104 | | - # which may indicate an issue with the authentication provider. |
105 | | - set_custom_attribute('get_user_if_exists.no_username_in_details', True) |
106 | | - return {} |
| 67 | + else: |
| 68 | + return {'is_new': False} |
107 | 69 |
|
108 | 70 | try: |
109 | | - found_user = User.objects.get(username=details_username) |
110 | | - |
111 | | - # .. custom_attribute_name: get_user_if_exists.user_found |
112 | | - # .. custom_attribute_description: Indicates that a user was successfully found |
113 | | - # by username lookup in the database. |
114 | | - set_custom_attribute('get_user_if_exists.user_found', True) |
115 | | - |
116 | | - # .. custom_attribute_name: get_user_if_exists.found_user_id |
117 | | - # .. custom_attribute_description: Records the ID of the user found by username lookup |
118 | | - # to help track user account conflicts. |
119 | | - set_custom_attribute('get_user_if_exists.found_user_id', found_user.id) |
120 | | - |
121 | | - if DEBUG_GET_USER_IF_EXISTS.is_enabled(): |
122 | | - logger.info( |
123 | | - "get_user_if_exists: Found existing user with username '%s' (ID: %s)", |
124 | | - details_username, |
125 | | - found_user.id |
126 | | - ) |
| 71 | + username = details.get('username') |
127 | 72 |
|
128 | | - # Return the user if it exists |
129 | 73 | return { |
130 | 74 | 'is_new': False, |
131 | | - 'user': found_user |
| 75 | + 'user': User.objects.get(username=username) |
132 | 76 | } |
133 | 77 | except User.DoesNotExist: |
134 | | - # .. custom_attribute_name: get_user_if_exists.user_found |
135 | | - # .. custom_attribute_description: Indicates that no user was found |
136 | | - # by username lookup in the database. |
137 | | - set_custom_attribute('get_user_if_exists.user_found', False) |
138 | | - |
139 | | - if DEBUG_GET_USER_IF_EXISTS.is_enabled(): |
140 | | - logger.info( |
141 | | - "get_user_if_exists: No user found with username '%s'", |
142 | | - details_username |
143 | | - ) |
| 78 | + pass |
144 | 79 |
|
145 | | - except Exception as e: |
146 | | - # Handle any unexpected errors during user lookup |
147 | | - logger.error( |
148 | | - "get_user_if_exists: Unexpected error during user lookup for username '%s': %s", |
149 | | - details_username, |
150 | | - str(e) |
151 | | - ) |
152 | | - |
153 | | - # .. custom_attribute_name: get_user_if_exists.lookup_error |
154 | | - # .. custom_attribute_description: Indicates that an unexpected error occurred |
155 | | - # during user lookup, which may indicate database or system issues. |
156 | | - set_custom_attribute('get_user_if_exists.lookup_error', True) |
157 | | - |
158 | | - # .. custom_attribute_name: get_user_if_exists.error_message |
159 | | - # .. custom_attribute_description: Records the error message when an unexpected |
160 | | - # error occurs during user lookup. |
161 | | - set_custom_attribute('get_user_if_exists.error_message', str(e)) |
162 | | - |
163 | | - # Nothing to return since we don't have a user |
164 | 80 | return {} |
165 | 81 |
|
166 | 82 |
|
167 | 83 | def update_email(strategy, details, user=None, *args, **kwargs): # pylint: disable=keyword-arg-before-vararg |
168 | | - """Update the user's email address using data from provider.""" |
| 84 | + """ |
| 85 | + Update the user's email address using data from provider. |
| 86 | + """ |
169 | 87 |
|
170 | 88 | if user: |
171 | 89 | # Get usernames for comparison, using defensive coding |
|
0 commit comments