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

Upload 10 files

Browse files
Files changed (1) hide show
  1. app/api/routes/auth_router.py +191 -42
app/api/routes/auth_router.py CHANGED
@@ -87,7 +87,7 @@ async def get_current_user(request: Request, token: str = Depends(oauth2_scheme)
87
  token_data = TokenData(user_id=user_id)
88
  except JWTError:
89
  raise credentials_exception
90
-
91
  query = "SELECT * FROM users WHERE id = ?"
92
  user = request.app.db_conn.execute(query, (token_data.user_id,)).fetchone()
93
  if user is None:
@@ -97,70 +97,121 @@ async def get_current_user(request: Request, token: str = Depends(oauth2_scheme)
97
  # Routes
98
  @router.post("/register", response_model=UserResponse)
99
  async def register(request: Request, user: UserCreate):
100
- # Check if user already exists
101
- query = "SELECT * FROM users WHERE email = ?"
102
- existing_user = request.app.db_conn.execute(query, (user.email,)).fetchone()
103
- if existing_user:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  raise HTTPException(
105
- status_code=status.HTTP_400_BAD_REQUEST,
106
- detail="Email already registered"
107
  )
108
-
109
- # Hash the password
110
- hashed_password = get_password_hash(user.password)
111
-
112
- # Insert the new user
113
- insert_query = "INSERT INTO users (email, hashed_password) VALUES (?, ?)"
114
- request.app.db_conn.execute(insert_query, (user.email, hashed_password))
115
- request.app.db_conn.commit()
116
-
117
- # Get the newly created user
118
- new_user = request.app.db_conn.execute(
119
- "SELECT * FROM users WHERE email = ?",
120
- (user.email,)
121
- ).fetchone()
122
-
123
- return {
124
- "id": new_user[0],
125
- "email": new_user[1],
126
- "is_admin": new_user[5],
127
- "created_at": new_user[3]
128
- }
129
 
130
  @router.post("/login", response_model=Token)
131
  async def login(
132
- request: Request,
133
  form_data: OAuth2PasswordRequestForm = Depends()
134
  ):
135
  # Find the user
136
  query = "SELECT * FROM users WHERE email = ?"
137
  user = request.app.db_conn.execute(query, (form_data.username,)).fetchone()
138
-
139
  if not user or not verify_password(form_data.password, user[2]):
140
  raise HTTPException(
141
  status_code=status.HTTP_401_UNAUTHORIZED,
142
  detail="Incorrect email or password",
143
  headers={"WWW-Authenticate": "Bearer"},
144
  )
145
-
146
  # Update last login
147
  update_query = "UPDATE users SET last_login = CURRENT_TIMESTAMP WHERE id = ?"
148
  request.app.db_conn.execute(update_query, (user[0],))
149
  request.app.db_conn.commit()
150
-
151
  # Create tokens
152
  access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
153
  access_token = create_access_token(
154
- data={"sub": user[0]},
155
  expires_delta=access_token_expires
156
  )
157
-
158
  refresh_token_expires = timedelta(days=REFRESH_TOKEN_EXPIRE_DAYS)
159
  refresh_token = create_refresh_token(
160
- data={"sub": user[0]},
161
  expires_delta=refresh_token_expires
162
  )
163
-
164
  return {
165
  "access_token": access_token,
166
  "refresh_token": refresh_token,
@@ -184,7 +235,7 @@ async def refresh_token(request: Request, refresh_token: str):
184
  detail="Invalid refresh token",
185
  headers={"WWW-Authenticate": "Bearer"},
186
  )
187
-
188
  # Check if user exists
189
  query = "SELECT * FROM users WHERE id = ?"
190
  user = request.app.db_conn.execute(query, (user_id,)).fetchone()
@@ -194,20 +245,20 @@ async def refresh_token(request: Request, refresh_token: str):
194
  detail="User not found",
195
  headers={"WWW-Authenticate": "Bearer"},
196
  )
197
-
198
  # Create new tokens
199
  access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
200
  access_token = create_access_token(
201
- data={"sub": user_id},
202
  expires_delta=access_token_expires
203
  )
204
-
205
  refresh_token_expires = timedelta(days=REFRESH_TOKEN_EXPIRE_DAYS)
206
  new_refresh_token = create_refresh_token(
207
- data={"sub": user_id},
208
  expires_delta=refresh_token_expires
209
  )
210
-
211
  return {
212
  "access_token": access_token,
213
  "refresh_token": new_refresh_token,
@@ -222,3 +273,101 @@ async def get_current_user_info(request: Request, current_user = Depends(get_cur
222
  "is_admin": current_user[5],
223
  "created_at": current_user[3]
224
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  token_data = TokenData(user_id=user_id)
88
  except JWTError:
89
  raise credentials_exception
90
+
91
  query = "SELECT * FROM users WHERE id = ?"
92
  user = request.app.db_conn.execute(query, (token_data.user_id,)).fetchone()
93
  if user is None:
 
97
  # Routes
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(
177
+ status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
178
+ detail=f"Registration failed: {str(e)}"
179
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
 
181
  @router.post("/login", response_model=Token)
182
  async def login(
183
+ request: Request,
184
  form_data: OAuth2PasswordRequestForm = Depends()
185
  ):
186
  # Find the user
187
  query = "SELECT * FROM users WHERE email = ?"
188
  user = request.app.db_conn.execute(query, (form_data.username,)).fetchone()
189
+
190
  if not user or not verify_password(form_data.password, user[2]):
191
  raise HTTPException(
192
  status_code=status.HTTP_401_UNAUTHORIZED,
193
  detail="Incorrect email or password",
194
  headers={"WWW-Authenticate": "Bearer"},
195
  )
196
+
197
  # Update last login
198
  update_query = "UPDATE users SET last_login = CURRENT_TIMESTAMP WHERE id = ?"
199
  request.app.db_conn.execute(update_query, (user[0],))
200
  request.app.db_conn.commit()
201
+
202
  # Create tokens
203
  access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
204
  access_token = create_access_token(
205
+ data={"sub": user[0]},
206
  expires_delta=access_token_expires
207
  )
208
+
209
  refresh_token_expires = timedelta(days=REFRESH_TOKEN_EXPIRE_DAYS)
210
  refresh_token = create_refresh_token(
211
+ data={"sub": user[0]},
212
  expires_delta=refresh_token_expires
213
  )
214
+
215
  return {
216
  "access_token": access_token,
217
  "refresh_token": refresh_token,
 
235
  detail="Invalid refresh token",
236
  headers={"WWW-Authenticate": "Bearer"},
237
  )
238
+
239
  # Check if user exists
240
  query = "SELECT * FROM users WHERE id = ?"
241
  user = request.app.db_conn.execute(query, (user_id,)).fetchone()
 
245
  detail="User not found",
246
  headers={"WWW-Authenticate": "Bearer"},
247
  )
248
+
249
  # Create new tokens
250
  access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
251
  access_token = create_access_token(
252
+ data={"sub": user_id},
253
  expires_delta=access_token_expires
254
  )
255
+
256
  refresh_token_expires = timedelta(days=REFRESH_TOKEN_EXPIRE_DAYS)
257
  new_refresh_token = create_refresh_token(
258
+ data={"sub": user_id},
259
  expires_delta=refresh_token_expires
260
  )
261
+
262
  return {
263
  "access_token": access_token,
264
  "refresh_token": new_refresh_token,
 
273
  "is_admin": current_user[5],
274
  "created_at": current_user[3]
275
  }
276
+
277
+ @router.get("/test-db")
278
+ async def test_database(request: Request):
279
+ """
280
+ Test endpoint to verify database operations.
281
+ This is for debugging purposes only.
282
+ """
283
+ import logging
284
+ logger = logging.getLogger("auth-server")
285
+
286
+ results = {
287
+ "connection_type": getattr(request.app, "db_type", "unknown"),
288
+ "operations": []
289
+ }
290
+
291
+ try:
292
+ # Test 1: Simple SELECT
293
+ logger.info("Test 1: Simple SELECT")
294
+ test_query = "SELECT 1 as test"
295
+ result = request.app.db_conn.execute(test_query).fetchone()
296
+ results["operations"].append({
297
+ "name": "Simple SELECT",
298
+ "success": result is not None,
299
+ "result": str(result) if result is not None else None
300
+ })
301
+ logger.info(f"Test 1 result: {result}")
302
+
303
+ # Test 2: Create a temporary table
304
+ logger.info("Test 2: Create a temporary table")
305
+ create_temp_table = """
306
+ CREATE TABLE IF NOT EXISTS test_table (
307
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
308
+ name TEXT NOT NULL,
309
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP
310
+ )
311
+ """
312
+ request.app.db_conn.execute(create_temp_table)
313
+ request.app.db_conn.commit()
314
+ results["operations"].append({
315
+ "name": "Create temporary table",
316
+ "success": True
317
+ })
318
+ logger.info("Test 2 completed successfully")
319
+
320
+ # Test 3: Insert into the temporary table
321
+ logger.info("Test 3: Insert into the temporary table")
322
+ test_name = f"test_user_{datetime.utcnow().strftime('%Y%m%d%H%M%S')}"
323
+ insert_query = "INSERT INTO test_table (name) VALUES (?)"
324
+ cursor = request.app.db_conn.execute(insert_query, (test_name,))
325
+ request.app.db_conn.commit()
326
+
327
+ # Check if lastrowid is available
328
+ last_id = getattr(cursor, "lastrowid", None)
329
+ results["operations"].append({
330
+ "name": "Insert into temporary table",
331
+ "success": True,
332
+ "last_id": last_id
333
+ })
334
+ logger.info(f"Test 3 completed successfully. Last ID: {last_id}")
335
+
336
+ # Test 4: Select from the temporary table
337
+ logger.info("Test 4: Select from the temporary table")
338
+ select_query = "SELECT * FROM test_table WHERE name = ?"
339
+ result = request.app.db_conn.execute(select_query, (test_name,)).fetchone()
340
+ results["operations"].append({
341
+ "name": "Select from temporary table",
342
+ "success": result is not None,
343
+ "result": str(result) if result is not None else None
344
+ })
345
+ logger.info(f"Test 4 result: {result}")
346
+
347
+ # Test 5: Check if users table exists and has the expected structure
348
+ logger.info("Test 5: Check users table structure")
349
+ try:
350
+ table_info = request.app.db_conn.execute("PRAGMA table_info(users)").fetchall()
351
+ results["operations"].append({
352
+ "name": "Check users table structure",
353
+ "success": len(table_info) > 0,
354
+ "columns": [col[1] for col in table_info] if table_info else []
355
+ })
356
+ logger.info(f"Test 5 result: {table_info}")
357
+ except Exception as e:
358
+ logger.error(f"Error checking users table structure: {str(e)}")
359
+ results["operations"].append({
360
+ "name": "Check users table structure",
361
+ "success": False,
362
+ "error": str(e)
363
+ })
364
+
365
+ return results
366
+ except Exception as e:
367
+ logger.error(f"Database test failed: {str(e)}")
368
+ results["operations"].append({
369
+ "name": "Error during tests",
370
+ "success": False,
371
+ "error": str(e)
372
+ })
373
+ return results