kamau1 commited on
Commit
a2b7f60
·
verified ·
1 Parent(s): d4210dc

Upload 11 files

Browse files
Files changed (1) hide show
  1. main.py +292 -15
main.py CHANGED
@@ -219,9 +219,39 @@ async def startup_db_client():
219
  logger.info(f"[{operation_id}] Password hashed successfully")
220
 
221
  # Insert the super user with admin privileges
222
- insert_query = "INSERT INTO users (email, hashed_password, is_admin) VALUES (?, ?, 1)"
223
- cursor = app.db_conn.execute(insert_query, (super_user_email, hashed_password))
224
- app.db_conn.commit()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
225
 
226
  # Try to get the user ID
227
  user_id = None
@@ -231,24 +261,95 @@ async def startup_db_client():
231
  except Exception as e:
232
  logger.warning(f"[{operation_id}] Could not get lastrowid: {str(e)}")
233
 
234
- # If lastrowid is not available, try to get the ID using a query
 
235
  try:
236
- id_query = "SELECT id FROM users WHERE email = ?"
237
- id_result = app.db_conn.execute(id_query, (super_user_email,)).fetchone()
238
- if id_result:
 
239
  user_id = id_result[0]
240
- logger.info(f"[{operation_id}] Got ID from query: {user_id}")
241
  except Exception as e2:
242
- logger.error(f"[{operation_id}] Error getting ID from query: {str(e2)}")
 
 
 
243
 
244
- # Verify the super user was created
245
- verify_query = "SELECT id, email, is_admin FROM users WHERE email = ?"
246
- verify_result = app.db_conn.execute(verify_query, (super_user_email,)).fetchone()
247
 
248
- if verify_result:
249
- logger.info(f"[{operation_id}] Super user created successfully with ID: {verify_result[0]}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250
  else:
251
- logger.error(f"[{operation_id}] Failed to verify super user after creation")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252
 
253
  except Exception as e:
254
  logger.error(f"[{operation_id}] Error creating super user: {str(e)}")
@@ -771,6 +872,182 @@ async def health_check():
771
  "database_type": getattr(app, "db_type", "unknown")
772
  }
773
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
774
  # Database test endpoint
775
  @app.get("/test-db", tags=["General"])
776
  async def test_database():
 
219
  logger.info(f"[{operation_id}] Password hashed successfully")
220
 
221
  # Insert the super user with admin privileges
222
+ # Use a transaction-like approach with multiple commits to ensure it works
223
+ try:
224
+ # First try with a transaction
225
+ logger.info(f"[{operation_id}] Inserting super user with transaction-like approach")
226
+ insert_query = "INSERT INTO users (email, hashed_password, is_admin) VALUES (?, ?, 1)"
227
+ cursor = app.db_conn.execute(insert_query, (super_user_email, hashed_password))
228
+ app.db_conn.commit()
229
+ logger.info(f"[{operation_id}] Committed super user insert")
230
+ except Exception as e:
231
+ logger.error(f"[{operation_id}] Error during super user insert: {str(e)}")
232
+ # If there was an error, check if it's because the user already exists
233
+ if "UNIQUE constraint failed" in str(e):
234
+ logger.info(f"[{operation_id}] User already exists (UNIQUE constraint)")
235
+ else:
236
+ # If it's another error, try a different approach
237
+ try:
238
+ logger.info(f"[{operation_id}] Trying alternative insert approach")
239
+ # Try to get the highest ID to simulate auto-increment
240
+ max_id_result = app.db_conn.execute("SELECT MAX(id) FROM users").fetchone()
241
+ logger.info(f"[{operation_id}] Max ID result: {max_id_result}")
242
+
243
+ next_id = 1
244
+ if max_id_result and max_id_result[0] is not None:
245
+ next_id = int(max_id_result[0]) + 1
246
+
247
+ # Insert with explicit ID
248
+ insert_query = "INSERT INTO users (id, email, hashed_password, is_admin) VALUES (?, ?, ?, 1)"
249
+ cursor = app.db_conn.execute(insert_query, (next_id, super_user_email, hashed_password))
250
+ app.db_conn.commit()
251
+ logger.info(f"[{operation_id}] Committed super user insert with explicit ID: {next_id}")
252
+ except Exception as e2:
253
+ logger.error(f"[{operation_id}] Alternative insert approach also failed: {str(e2)}")
254
+ raise
255
 
256
  # Try to get the user ID
257
  user_id = None
 
261
  except Exception as e:
262
  logger.warning(f"[{operation_id}] Could not get lastrowid: {str(e)}")
263
 
264
+ # If we couldn't get the lastrowid, try to get it with a direct query
265
+ if not user_id or user_id == 0:
266
  try:
267
+ # Try to get the last inserted ID using a direct query
268
+ id_query = "SELECT last_insert_rowid()"
269
+ id_result = app.db_conn.execute(id_query).fetchone()
270
+ if id_result and id_result[0]:
271
  user_id = id_result[0]
272
+ logger.info(f"[{operation_id}] Got ID from last_insert_rowid(): {user_id}")
273
  except Exception as e2:
274
+ logger.error(f"[{operation_id}] Error getting ID from last_insert_rowid(): {str(e2)}")
275
+
276
+ # Add a small delay to ensure the database has processed the insert
277
+ time.sleep(1)
278
 
279
+ # Verify the super user was created with retry
280
+ max_retries = 3
281
+ verify_success = False
282
 
283
+ for attempt in range(max_retries):
284
+ try:
285
+ logger.info(f"[{operation_id}] Verifying super user creation (attempt {attempt+1})")
286
+
287
+ # If we don't have a user ID yet, try to get it first
288
+ if not user_id:
289
+ try:
290
+ id_query = "SELECT id FROM users WHERE email = ?"
291
+ id_result = app.db_conn.execute(id_query, (super_user_email,)).fetchone()
292
+ if id_result:
293
+ user_id = id_result[0]
294
+ logger.info(f"[{operation_id}] Got ID from query: {user_id}")
295
+ except Exception as e2:
296
+ logger.error(f"[{operation_id}] Error getting ID from query: {str(e2)}")
297
+
298
+ # Verify the super user was created
299
+ verify_query = "SELECT id, email, is_admin FROM users WHERE email = ?"
300
+ verify_result = app.db_conn.execute(verify_query, (super_user_email,)).fetchone()
301
+
302
+ if verify_result:
303
+ logger.info(f"[{operation_id}] Super user verified successfully with ID: {verify_result[0]}")
304
+ verify_success = True
305
+ break
306
+ else:
307
+ logger.warning(f"[{operation_id}] Verification attempt {attempt+1} failed, user not found")
308
+
309
+ # Try a different query approach
310
+ try:
311
+ all_users = app.db_conn.execute("SELECT id, email FROM users").fetchall()
312
+ logger.info(f"[{operation_id}] All users in database: {all_users}")
313
+
314
+ # Check if our user is in the list
315
+ for user in all_users:
316
+ if len(user) > 1 and user[1] == super_user_email:
317
+ logger.info(f"[{operation_id}] Found super user in all users list with ID: {user[0]}")
318
+ verify_success = True
319
+ break
320
+ except Exception as e:
321
+ logger.error(f"[{operation_id}] Error listing all users: {str(e)}")
322
+
323
+ if verify_success:
324
+ break
325
+
326
+ # If this is not the last attempt, wait before retrying
327
+ if attempt < max_retries - 1:
328
+ time.sleep(2) # Increase delay between retries
329
+ except Exception as e:
330
+ logger.error(f"[{operation_id}] Error during verification attempt {attempt+1}: {str(e)}")
331
+ if attempt < max_retries - 1:
332
+ time.sleep(2)
333
+
334
+ if verify_success:
335
+ logger.info(f"[{operation_id}] Super user creation verified successfully")
336
  else:
337
+ # Even if verification failed, the user might still have been created
338
+ # Try one more approach - insert again and catch the unique constraint violation
339
+ try:
340
+ logger.info(f"[{operation_id}] Trying to insert again to check if user exists")
341
+ app.db_conn.execute(insert_query, (super_user_email, hashed_password))
342
+ app.db_conn.commit()
343
+ logger.info(f"[{operation_id}] Second insert succeeded, which is unexpected")
344
+ except Exception as e:
345
+ if "UNIQUE constraint failed" in str(e):
346
+ logger.info(f"[{operation_id}] UNIQUE constraint violation confirms user exists")
347
+ verify_success = True
348
+ else:
349
+ logger.error(f"[{operation_id}] Second insert failed with unexpected error: {str(e)}")
350
+
351
+ if not verify_success:
352
+ logger.error(f"[{operation_id}] Failed to verify super user after creation")
353
 
354
  except Exception as e:
355
  logger.error(f"[{operation_id}] Error creating super user: {str(e)}")
 
872
  "database_type": getattr(app, "db_type", "unknown")
873
  }
874
 
875
+ # Super user check/create endpoint
876
+ @app.get("/ensure-super-user", tags=["General"])
877
+ async def ensure_super_user():
878
+ """
879
+ Check if the super user exists and create it if it doesn't.
880
+ This endpoint can be used to manually trigger super user creation.
881
+
882
+ Returns:
883
+ dict: Information about the super user status.
884
+ """
885
+ logger.info("Ensure super user endpoint accessed")
886
+
887
+ try:
888
+ # Check if super user exists
889
+ super_user_email = "[email protected]"
890
+ query = "SELECT id, is_admin FROM users WHERE email = ?"
891
+ existing_user = app.db_conn.execute(query, (super_user_email,)).fetchone()
892
+
893
+ if existing_user:
894
+ user_id = existing_user[0]
895
+ is_admin = existing_user[1] if len(existing_user) > 1 else 0
896
+
897
+ # If user exists but is not admin, make them admin
898
+ if not is_admin:
899
+ update_query = "UPDATE users SET is_admin = 1 WHERE id = ?"
900
+ app.db_conn.execute(update_query, (user_id,))
901
+ app.db_conn.commit()
902
+ logger.info(f"Updated user {user_id} to have admin privileges")
903
+
904
+ return {
905
+ "status": "updated",
906
+ "message": f"Super user already existed with ID {user_id} and was updated to have admin privileges",
907
+ "user_id": user_id,
908
+ "email": super_user_email
909
+ }
910
+ else:
911
+ return {
912
+ "status": "exists",
913
+ "message": f"Super user already exists with ID {user_id} and has admin privileges",
914
+ "user_id": user_id,
915
+ "email": super_user_email
916
+ }
917
+
918
+ # User doesn't exist, create it
919
+ logger.info("Super user does not exist, creating now")
920
+
921
+ # Create password hashing context
922
+ pwd_context = CryptContext(
923
+ schemes=["argon2"],
924
+ argon2__time_cost=4,
925
+ argon2__memory_cost=102400,
926
+ argon2__parallelism=8,
927
+ argon2__salt_len=16
928
+ )
929
+
930
+ # Hash the password
931
+ super_user_password = "TestPassword123!"
932
+ hashed_password = pwd_context.hash(super_user_password)
933
+
934
+ # Insert the super user with admin privileges
935
+ # Use a transaction-like approach with multiple commits to ensure it works
936
+ try:
937
+ # First try with a transaction
938
+ logger.info("Inserting super user with transaction-like approach")
939
+ insert_query = "INSERT INTO users (email, hashed_password, is_admin) VALUES (?, ?, 1)"
940
+ cursor = app.db_conn.execute(insert_query, (super_user_email, hashed_password))
941
+ app.db_conn.commit()
942
+ logger.info("Committed super user insert")
943
+ except Exception as e:
944
+ logger.error(f"Error during super user insert: {str(e)}")
945
+ # If there was an error, check if it's because the user already exists
946
+ if "UNIQUE constraint failed" in str(e):
947
+ logger.info("User already exists (UNIQUE constraint)")
948
+ # Try to get the user ID
949
+ id_query = "SELECT id FROM users WHERE email = ?"
950
+ id_result = app.db_conn.execute(id_query, (super_user_email,)).fetchone()
951
+ if id_result:
952
+ user_id = id_result[0]
953
+ logger.info(f"Found existing user with ID: {user_id}")
954
+ cursor = None # Set cursor to None to indicate we didn't insert
955
+ else:
956
+ # If it's another error, try a different approach
957
+ try:
958
+ logger.info("Trying alternative insert approach")
959
+ # Try to get the highest ID to simulate auto-increment
960
+ max_id_result = app.db_conn.execute("SELECT MAX(id) FROM users").fetchone()
961
+ logger.info(f"Max ID result: {max_id_result}")
962
+
963
+ next_id = 1
964
+ if max_id_result and max_id_result[0] is not None:
965
+ next_id = int(max_id_result[0]) + 1
966
+
967
+ # Insert with explicit ID
968
+ insert_query = "INSERT INTO users (id, email, hashed_password, is_admin) VALUES (?, ?, ?, 1)"
969
+ cursor = app.db_conn.execute(insert_query, (next_id, super_user_email, hashed_password))
970
+ app.db_conn.commit()
971
+ logger.info(f"Committed super user insert with explicit ID: {next_id}")
972
+ except Exception as e2:
973
+ logger.error(f"Alternative insert approach also failed: {str(e2)}")
974
+ raise
975
+
976
+ # Try to get the user ID
977
+ user_id = None
978
+ try:
979
+ user_id = cursor.lastrowid
980
+ logger.info(f"Got lastrowid: {user_id}")
981
+ except Exception as e:
982
+ logger.warning(f"Could not get lastrowid: {str(e)}")
983
+
984
+ # If we couldn't get the lastrowid or it's 0, try alternative methods
985
+ if not user_id or user_id == 0:
986
+ try:
987
+ # Try to get the last inserted ID using a direct query
988
+ id_query = "SELECT last_insert_rowid()"
989
+ id_result = app.db_conn.execute(id_query).fetchone()
990
+ if id_result and id_result[0]:
991
+ user_id = id_result[0]
992
+ logger.info(f"Got ID from last_insert_rowid(): {user_id}")
993
+ except Exception as e2:
994
+ logger.error(f"Error getting ID from last_insert_rowid(): {str(e2)}")
995
+
996
+ # If still no ID, try to get it by email
997
+ if not user_id or user_id == 0:
998
+ try:
999
+ id_query = "SELECT id FROM users WHERE email = ?"
1000
+ id_result = app.db_conn.execute(id_query, (super_user_email,)).fetchone()
1001
+ if id_result:
1002
+ user_id = id_result[0]
1003
+ logger.info(f"Got ID from query by email: {user_id}")
1004
+ except Exception as e2:
1005
+ logger.error(f"Error getting ID from query by email: {str(e2)}")
1006
+
1007
+ # Add a small delay to ensure the database has processed the insert
1008
+ time.sleep(1)
1009
+
1010
+ # Verify the super user was created
1011
+ verify_query = "SELECT id, email, is_admin FROM users WHERE email = ?"
1012
+ verify_result = app.db_conn.execute(verify_query, (super_user_email,)).fetchone()
1013
+
1014
+ if verify_result:
1015
+ return {
1016
+ "status": "created",
1017
+ "message": f"Super user created successfully with ID {verify_result[0]}",
1018
+ "user_id": verify_result[0],
1019
+ "email": super_user_email
1020
+ }
1021
+ else:
1022
+ # Try to list all users to see if our user is there
1023
+ try:
1024
+ all_users = app.db_conn.execute("SELECT id, email FROM users").fetchall()
1025
+ logger.info(f"All users in database: {all_users}")
1026
+
1027
+ # Check if our user is in the list
1028
+ for user in all_users:
1029
+ if len(user) > 1 and user[1] == super_user_email:
1030
+ return {
1031
+ "status": "created_found_in_list",
1032
+ "message": f"Super user created and found in user list with ID {user[0]}",
1033
+ "user_id": user[0],
1034
+ "email": super_user_email
1035
+ }
1036
+ except Exception as e:
1037
+ logger.error(f"Error listing all users: {str(e)}")
1038
+
1039
+ return {
1040
+ "status": "creation_unverified",
1041
+ "message": "Super user may have been created but could not be verified",
1042
+ "email": super_user_email
1043
+ }
1044
+ except Exception as e:
1045
+ logger.error(f"Error ensuring super user: {str(e)}")
1046
+ return {
1047
+ "status": "error",
1048
+ "message": f"Error ensuring super user: {str(e)}"
1049
+ }
1050
+
1051
  # Database test endpoint
1052
  @app.get("/test-db", tags=["General"])
1053
  async def test_database():