kamau1 commited on
Commit
3fa83ca
·
verified ·
1 Parent(s): ea06f12

Upload 10 files

Browse files
Files changed (1) hide show
  1. app/api/routes/auth_router.py +145 -62
app/api/routes/auth_router.py CHANGED
@@ -98,79 +98,162 @@ async def get_current_user(request: Request, token: str = Depends(oauth2_scheme)
98
  @router.post("/register", response_model=UserResponse)
99
  async def register(request: Request, user: UserCreate):
100
  import logging
 
101
  logger = logging.getLogger("auth-server")
102
 
 
 
 
 
 
 
 
 
103
  try:
104
- # Check if user already exists
105
- query = "SELECT * FROM users WHERE email = ?"
106
- logger.info(f"Checking if user with email {user.email} already exists")
107
- existing_user = request.app.db_conn.execute(query, (user.email,)).fetchone()
108
- if existing_user:
109
- logger.warning(f"User with email {user.email} already exists")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  raise HTTPException(
111
- status_code=status.HTTP_400_BAD_REQUEST,
112
- detail="Email already registered"
113
  )
114
 
115
- # Hash the password
116
- logger.info("Hashing password")
117
- hashed_password = get_password_hash(user.password)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
 
119
- # Insert the new user
120
- logger.info(f"Inserting new user with email {user.email}")
121
- insert_query = "INSERT INTO users (email, hashed_password) VALUES (?, ?)"
122
- cursor = request.app.db_conn.execute(insert_query, (user.email, hashed_password))
123
- request.app.db_conn.commit()
124
 
125
- # Get the last inserted row ID
126
- last_row_id = cursor.lastrowid
127
- logger.info(f"User inserted with ID: {last_row_id}")
128
-
129
- # Get the newly created user by ID (more reliable than by email)
130
- logger.info(f"Retrieving user with ID {last_row_id}")
131
- new_user = request.app.db_conn.execute(
132
- "SELECT * FROM users WHERE id = ?",
133
- (last_row_id,)
134
- ).fetchone()
135
-
136
- if new_user is None:
137
- logger.error(f"Failed to retrieve newly created user with ID {last_row_id}")
138
- # Try to get by email as fallback
139
- logger.info(f"Trying to retrieve user by email {user.email}")
140
- new_user = request.app.db_conn.execute(
141
- "SELECT * FROM users WHERE email = ?",
142
- (user.email,)
143
- ).fetchone()
144
-
145
- if new_user is None:
146
- logger.error(f"Failed to retrieve newly created user with email {user.email}")
147
- raise HTTPException(
148
- status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
149
- detail="User was created but could not be retrieved"
150
- )
151
-
152
- # Log the user data for debugging (excluding password)
153
- logger.info(f"User retrieved: ID={new_user[0]}, Email={new_user[1]}")
154
-
155
- # Check if the user has the expected fields
156
- if len(new_user) < 6:
157
- logger.error(f"User record has unexpected format: {new_user}")
158
- # Return what we can
159
  return {
160
- "id": new_user[0],
161
- "email": new_user[1],
162
- "is_admin": False, # Default value
163
- "created_at": str(new_user[3] if len(new_user) > 3 else "")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  }
165
-
166
- return {
167
- "id": new_user[0],
168
- "email": new_user[1],
169
- "is_admin": bool(new_user[5]) if new_user[5] is not None else False,
170
- "created_at": str(new_user[3]) if new_user[3] is not None else ""
171
- }
172
  except Exception as e:
173
- logger.error(f"Error during user registration: {str(e)}")
174
  if isinstance(e, HTTPException):
175
  raise
176
  raise HTTPException(
 
98
  @router.post("/register", response_model=UserResponse)
99
  async def register(request: Request, user: UserCreate):
100
  import logging
101
+ import time
102
  logger = logging.getLogger("auth-server")
103
 
104
+ # Log the database connection type
105
+ db_type = getattr(request.app, "db_type", "unknown")
106
+ logger.info(f"Database connection type: {db_type}")
107
+
108
+ # Generate a unique identifier for this registration attempt
109
+ registration_id = f"reg_{int(time.time())}"
110
+ logger.info(f"[{registration_id}] Starting registration for email: {user.email}")
111
+
112
  try:
113
+ # Step 1: Check if user already exists - with retry
114
+ for attempt in range(3):
115
+ try:
116
+ logger.info(f"[{registration_id}] Checking if user already exists (attempt {attempt+1})")
117
+ query = "SELECT id FROM users WHERE email = ?"
118
+ existing_user = request.app.db_conn.execute(query, (user.email,)).fetchone()
119
+ if existing_user:
120
+ logger.warning(f"[{registration_id}] User with email {user.email} already exists")
121
+ raise HTTPException(
122
+ status_code=status.HTTP_400_BAD_REQUEST,
123
+ detail="Email already registered"
124
+ )
125
+ logger.info(f"[{registration_id}] User does not exist, proceeding with registration")
126
+ break
127
+ except Exception as e:
128
+ if "HTTPException" in str(type(e)):
129
+ raise
130
+ logger.error(f"[{registration_id}] Error checking if user exists (attempt {attempt+1}): {str(e)}")
131
+ if attempt == 2: # Last attempt
132
+ raise
133
+ time.sleep(1) # Wait before retrying
134
+
135
+ # Step 2: Hash the password
136
+ logger.info(f"[{registration_id}] Hashing password")
137
+ try:
138
+ hashed_password = get_password_hash(user.password)
139
+ logger.info(f"[{registration_id}] Password hashed successfully")
140
+ except Exception as e:
141
+ logger.error(f"[{registration_id}] Error hashing password: {str(e)}")
142
  raise HTTPException(
143
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
144
+ detail=f"Error hashing password: {str(e)}"
145
  )
146
 
147
+ # Step 3: Insert the new user - with retry
148
+ user_id = None
149
+ for attempt in range(3):
150
+ try:
151
+ logger.info(f"[{registration_id}] Inserting new user (attempt {attempt+1})")
152
+
153
+ # Use a direct approach for HTTP API
154
+ if db_type == "http-api":
155
+ # First, get the highest ID to simulate auto-increment
156
+ max_id_result = request.app.db_conn.execute("SELECT MAX(id) FROM users").fetchone()
157
+ next_id = 1
158
+ if max_id_result and max_id_result[0] is not None:
159
+ next_id = int(max_id_result[0]) + 1
160
+
161
+ # Insert with explicit ID
162
+ insert_query = "INSERT INTO users (id, email, hashed_password) VALUES (?, ?, ?)"
163
+ request.app.db_conn.execute(insert_query, (next_id, user.email, hashed_password))
164
+ user_id = next_id
165
+ else:
166
+ # Standard approach for other connection types
167
+ insert_query = "INSERT INTO users (email, hashed_password) VALUES (?, ?)"
168
+ cursor = request.app.db_conn.execute(insert_query, (user.email, hashed_password))
169
+ user_id = getattr(cursor, "lastrowid", None)
170
+
171
+ # Commit the transaction
172
+ request.app.db_conn.commit()
173
+
174
+ if user_id:
175
+ logger.info(f"[{registration_id}] User inserted successfully with ID: {user_id}")
176
+ break
177
+ else:
178
+ logger.warning(f"[{registration_id}] User inserted but couldn't get ID")
179
+ # Continue to try to retrieve by email
180
+ break
181
+ except Exception as e:
182
+ logger.error(f"[{registration_id}] Error inserting user (attempt {attempt+1}): {str(e)}")
183
+ if attempt == 2: # Last attempt
184
+ raise
185
+ time.sleep(1) # Wait before retrying
186
+
187
+ # Step 4: Retrieve the newly created user - with retry
188
+ new_user = None
189
+ for attempt in range(3):
190
+ try:
191
+ # Try by ID if we have it
192
+ if user_id:
193
+ logger.info(f"[{registration_id}] Retrieving user by ID: {user_id} (attempt {attempt+1})")
194
+ new_user = request.app.db_conn.execute("SELECT * FROM users WHERE id = ?", (user_id,)).fetchone()
195
+
196
+ # If not found by ID, try by email
197
+ if not new_user:
198
+ logger.info(f"[{registration_id}] Retrieving user by email: {user.email} (attempt {attempt+1})")
199
+ new_user = request.app.db_conn.execute("SELECT * FROM users WHERE email = ?", (user.email,)).fetchone()
200
+
201
+ if new_user:
202
+ logger.info(f"[{registration_id}] User retrieved successfully")
203
+ break
204
+ else:
205
+ logger.warning(f"[{registration_id}] User not found (attempt {attempt+1})")
206
+ if attempt == 2: # Last attempt
207
+ raise Exception("User was created but could not be retrieved")
208
+ time.sleep(1) # Wait before retrying
209
+ except Exception as e:
210
+ logger.error(f"[{registration_id}] Error retrieving user (attempt {attempt+1}): {str(e)}")
211
+ if attempt == 2: # Last attempt
212
+ raise
213
+ time.sleep(1) # Wait before retrying
214
+
215
+ # Step 5: Construct the response
216
+ if not new_user:
217
+ logger.error(f"[{registration_id}] Failed to retrieve user after multiple attempts")
218
+ # Create a minimal response with what we know
219
+ return {
220
+ "id": user_id or 0,
221
+ "email": user.email,
222
+ "is_admin": False,
223
+ "created_at": ""
224
+ }
225
 
226
+ # Log the user data for debugging
227
+ logger.info(f"[{registration_id}] User data: {new_user}")
 
 
 
228
 
229
+ # Handle different database return formats
230
+ if isinstance(new_user, dict):
231
+ # HTTP API might return a dict
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232
  return {
233
+ "id": new_user.get("id", 0),
234
+ "email": new_user.get("email", user.email),
235
+ "is_admin": bool(new_user.get("is_admin", 0)),
236
+ "created_at": str(new_user.get("created_at", ""))
237
+ }
238
+ elif isinstance(new_user, (list, tuple)):
239
+ # Standard cursor returns a tuple
240
+ return {
241
+ "id": new_user[0] if len(new_user) > 0 else 0,
242
+ "email": new_user[1] if len(new_user) > 1 else user.email,
243
+ "is_admin": bool(new_user[5] if len(new_user) > 5 and new_user[5] is not None else 0),
244
+ "created_at": str(new_user[3] if len(new_user) > 3 and new_user[3] is not None else "")
245
+ }
246
+ else:
247
+ # Fallback for unexpected return type
248
+ logger.error(f"[{registration_id}] Unexpected user data type: {type(new_user)}")
249
+ return {
250
+ "id": user_id or 0,
251
+ "email": user.email,
252
+ "is_admin": False,
253
+ "created_at": ""
254
  }
 
 
 
 
 
 
 
255
  except Exception as e:
256
+ logger.error(f"[{registration_id}] Registration failed: {str(e)}")
257
  if isinstance(e, HTTPException):
258
  raise
259
  raise HTTPException(