Spaces:
Running
Running
Upload 10 files
Browse files- 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 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
raise HTTPException(
|
111 |
-
status_code=status.
|
112 |
-
detail="
|
113 |
)
|
114 |
|
115 |
-
#
|
116 |
-
|
117 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
118 |
|
119 |
-
#
|
120 |
-
logger.info(f"
|
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 |
-
#
|
126 |
-
|
127 |
-
|
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
|
161 |
-
"email": new_user
|
162 |
-
"is_admin":
|
163 |
-
"created_at": str(new_user
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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"
|
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(
|