@@ -98,6 +98,40 @@ async def delete_user(self, user_id: UUID) -> bool:
9898 """Delete a user"""
9999 return await self .repository .delete (user_id )
100100
101+ async def update_user_if_needed (self , user_id : UUID , token_data : Dict [str , Any ], user_data : Dict [str , Any ]) -> Dict [str , Any ]:
102+ """
103+ Update user only if data has changed
104+
105+ Args:
106+ user_id: The user's UUID
107+ token_data: Dictionary containing user data from the authentication token
108+ user_data: Current user data from the database
109+
110+ Returns:
111+ The updated user data dictionary or the original if no update was needed
112+ """
113+ # Check if user data needs to be updated
114+ update_data = {}
115+ fields_to_check = [
116+ "username" , "email" , "email_verified" ,
117+ "name" , "given_name" , "family_name"
118+ ]
119+
120+ for field in fields_to_check :
121+ token_value = token_data .get (field )
122+ if token_value is not None and user_data .get (field ) != token_value :
123+ update_data [field ] = token_value
124+
125+ # Handle roles separately as they might have a different structure
126+ if "roles" in token_data and user_data .get ("roles" ) != token_data ["roles" ]:
127+ update_data ["roles" ] = token_data ["roles" ]
128+
129+ # Update user if any field has changed
130+ if update_data :
131+ return await self .update_user (user_id , update_data )
132+
133+ return user_data
134+
101135 async def sync_user_with_token_data (self , user_id : UUID , token_data : Dict [str , Any ]) -> Optional [Dict [str , Any ]]:
102136 """
103137 Synchronize user data in the database with data from the authentication token.
@@ -117,6 +151,7 @@ async def sync_user_with_token_data(self, user_id: UUID, token_data: Dict[str, A
117151 # If user doesn't exist, create a new one
118152 if not user_data :
119153 try :
154+ print (f"User with ID '{ user_id } ' does not exist. Creating user from token data." )
120155 return await self .create_user (
121156 user_id = user_id ,
122157 username = token_data .get ("username" , "" ),
@@ -131,28 +166,16 @@ async def sync_user_with_token_data(self, user_id: UUID, token_data: Dict[str, A
131166 print (f"Error creating user: { e } " )
132167 # Handle case where user might have been created in a race condition
133168 if "already exists" in str (e ):
169+ print (f"Race condition detected: User with ID '{ user_id } ' was created by another process." )
134170 user_data = await self .get_user (user_id )
171+ if user_data :
172+ # User exists now, proceed with update if needed
173+ return await self .update_user_if_needed (user_id , token_data , user_data )
174+ else :
175+ # This shouldn't happen - user creation failed but user doesn't exist
176+ raise ValueError (f"Failed to create or find user with ID '{ user_id } '" )
135177 else :
136178 raise e
137179
138- # Check if user data needs to be updated
139- update_data = {}
140- fields_to_check = [
141- "username" , "email" , "email_verified" ,
142- "name" , "given_name" , "family_name"
143- ]
144-
145- for field in fields_to_check :
146- token_value = token_data .get (field )
147- if token_value is not None and user_data .get (field ) != token_value :
148- update_data [field ] = token_value
149-
150- # Handle roles separately as they might have a different structure
151- if "roles" in token_data and user_data .get ("roles" ) != token_data ["roles" ]:
152- update_data ["roles" ] = token_data ["roles" ]
153-
154- # Update user if any field has changed
155- if update_data :
156- return await self .update_user (user_id , update_data )
157-
158- return user_data
180+ # User exists, update if needed
181+ return await self .update_user_if_needed (user_id , token_data , user_data )
0 commit comments