Spaces:
Running
Running
Upload 11 files
Browse files
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 |
-
|
223 |
-
|
224 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
|
|
|
235 |
try:
|
236 |
-
|
237 |
-
|
238 |
-
|
|
|
239 |
user_id = id_result[0]
|
240 |
-
logger.info(f"[{operation_id}] Got ID from
|
241 |
except Exception as e2:
|
242 |
-
logger.error(f"[{operation_id}] Error getting ID from
|
|
|
|
|
|
|
243 |
|
244 |
-
# Verify the super user was created
|
245 |
-
|
246 |
-
|
247 |
|
248 |
-
|
249 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
250 |
else:
|
251 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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():
|