Spaces:
Running
Running
Upload 11 files
Browse files- direct_sql.py +238 -0
- main.py +229 -44
direct_sql.py
ADDED
@@ -0,0 +1,238 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env python3
|
2 |
+
"""
|
3 |
+
Direct SQL Script for Turso Database
|
4 |
+
|
5 |
+
This script uses the HTTP API directly to interact with the Turso database.
|
6 |
+
It's designed to work around issues with the libsql-experimental driver.
|
7 |
+
"""
|
8 |
+
|
9 |
+
import os
|
10 |
+
import sys
|
11 |
+
import json
|
12 |
+
import requests
|
13 |
+
import logging
|
14 |
+
import time
|
15 |
+
from dotenv import load_dotenv
|
16 |
+
|
17 |
+
# Configure logging
|
18 |
+
logging.basicConfig(
|
19 |
+
level=logging.INFO,
|
20 |
+
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
21 |
+
)
|
22 |
+
logger = logging.getLogger("direct-sql")
|
23 |
+
|
24 |
+
# Load environment variables
|
25 |
+
load_dotenv()
|
26 |
+
|
27 |
+
# Get Turso database connection details
|
28 |
+
DATABASE_URL = os.getenv("TURSO_DATABASE_URL")
|
29 |
+
AUTH_TOKEN = os.getenv("TURSO_AUTH_TOKEN")
|
30 |
+
|
31 |
+
if not DATABASE_URL or not AUTH_TOKEN:
|
32 |
+
logger.error("Missing Turso credentials. TURSO_DATABASE_URL and TURSO_AUTH_TOKEN must be set.")
|
33 |
+
sys.exit(1)
|
34 |
+
|
35 |
+
# Clean the auth token
|
36 |
+
AUTH_TOKEN = AUTH_TOKEN.strip()
|
37 |
+
|
38 |
+
# Convert URL from libsql:// to https://
|
39 |
+
if DATABASE_URL.startswith("libsql://"):
|
40 |
+
HTTP_URL = DATABASE_URL.replace("libsql://", "https://")
|
41 |
+
else:
|
42 |
+
HTTP_URL = DATABASE_URL
|
43 |
+
|
44 |
+
# Ensure the URL doesn't have a trailing slash
|
45 |
+
HTTP_URL = HTTP_URL.rstrip('/')
|
46 |
+
|
47 |
+
# Verify the URL format
|
48 |
+
if not HTTP_URL.startswith("https://"):
|
49 |
+
logger.warning(f"HTTP URL does not start with https://: {HTTP_URL}")
|
50 |
+
# Try to fix the URL
|
51 |
+
if "://" not in HTTP_URL:
|
52 |
+
HTTP_URL = f"https://{HTTP_URL}"
|
53 |
+
logger.info(f"Added https:// prefix to URL: {HTTP_URL}")
|
54 |
+
|
55 |
+
logger.info(f"Using HTTP URL: {HTTP_URL}")
|
56 |
+
|
57 |
+
def execute_sql(sql, params=None):
|
58 |
+
"""Execute SQL using the HTTP API directly."""
|
59 |
+
# Format the request according to the v2/pipeline specification
|
60 |
+
requests_data = []
|
61 |
+
|
62 |
+
# Prepare the statement
|
63 |
+
stmt = {"sql": sql}
|
64 |
+
|
65 |
+
# Add parameters if provided
|
66 |
+
if params:
|
67 |
+
# Convert parameters to the expected format
|
68 |
+
args = []
|
69 |
+
for param in params:
|
70 |
+
if param is None:
|
71 |
+
args.append({"type": "null", "value": None})
|
72 |
+
elif isinstance(param, int):
|
73 |
+
args.append({"type": "integer", "value": str(param)})
|
74 |
+
elif isinstance(param, float):
|
75 |
+
args.append({"type": "float", "value": str(param)})
|
76 |
+
else:
|
77 |
+
args.append({"type": "text", "value": str(param)})
|
78 |
+
|
79 |
+
stmt["args"] = args
|
80 |
+
|
81 |
+
requests_data.append({"type": "execute", "stmt": stmt})
|
82 |
+
|
83 |
+
# Always close the connection at the end
|
84 |
+
requests_data.append({"type": "close"})
|
85 |
+
|
86 |
+
# Prepare the final request payload
|
87 |
+
data = {"requests": requests_data}
|
88 |
+
|
89 |
+
# Use the v2/pipeline endpoint
|
90 |
+
pipeline_url = f"{HTTP_URL}/v2/pipeline"
|
91 |
+
logger.info(f"Sending request to: {pipeline_url}")
|
92 |
+
|
93 |
+
headers = {
|
94 |
+
"Authorization": f"Bearer {AUTH_TOKEN}",
|
95 |
+
"Content-Type": "application/json"
|
96 |
+
}
|
97 |
+
|
98 |
+
try:
|
99 |
+
response = requests.post(pipeline_url, headers=headers, json=data, timeout=10)
|
100 |
+
|
101 |
+
# Log response status
|
102 |
+
logger.info(f"Response status: {response.status_code}")
|
103 |
+
|
104 |
+
# Check for auth errors specifically
|
105 |
+
if response.status_code == 401:
|
106 |
+
logger.error(f"Authentication error (401): {response.text}")
|
107 |
+
return None
|
108 |
+
|
109 |
+
# Raise for other errors
|
110 |
+
response.raise_for_status()
|
111 |
+
|
112 |
+
# Parse the response
|
113 |
+
result = response.json()
|
114 |
+
|
115 |
+
# Process the response
|
116 |
+
if "results" in result and len(result["results"]) > 0:
|
117 |
+
return result["results"][0]
|
118 |
+
|
119 |
+
return None
|
120 |
+
except requests.exceptions.RequestException as e:
|
121 |
+
logger.error(f"HTTP request failed: {str(e)}")
|
122 |
+
return None
|
123 |
+
|
124 |
+
def create_test_user():
|
125 |
+
"""Create a test user with email [email protected]."""
|
126 |
+
# Generate a unique test ID
|
127 |
+
test_id = f"test_{int(time.time())}"
|
128 |
+
logger.info(f"[{test_id}] Starting test user creation")
|
129 |
+
|
130 |
+
# First check if the test user already exists
|
131 |
+
logger.info(f"[{test_id}] Checking if test user already exists")
|
132 |
+
check_query = "SELECT id FROM users WHERE email = ?"
|
133 |
+
check_result = execute_sql(check_query, ["[email protected]"])
|
134 |
+
|
135 |
+
if check_result and "rows" in check_result and len(check_result["rows"]) > 0:
|
136 |
+
user_id = check_result["rows"][0]["values"][0]
|
137 |
+
logger.info(f"[{test_id}] Test user already exists with ID: {user_id}")
|
138 |
+
return {
|
139 |
+
"success": True,
|
140 |
+
"user_id": user_id,
|
141 |
+
"email": "[email protected]",
|
142 |
+
"status": "already_exists"
|
143 |
+
}
|
144 |
+
|
145 |
+
# Use a pre-hashed password
|
146 |
+
logger.info(f"[{test_id}] Using pre-hashed password for test user")
|
147 |
+
# This is a pre-hashed version of "TestPassword123!" using Argon2
|
148 |
+
hashed_password = "$argon2id$v=19$m=65536,t=3,p=4$NElQRUZCWDRZSHpIWWRGSA$TYU8R7EfXGgEu9FWZGMX9AVwmMwpSKECCZMXgbzr6JE"
|
149 |
+
|
150 |
+
# Insert the test user
|
151 |
+
logger.info(f"[{test_id}] Inserting test user with email: [email protected]")
|
152 |
+
insert_query = "INSERT INTO users (email, hashed_password) VALUES (?, ?)"
|
153 |
+
insert_result = execute_sql(insert_query, ["[email protected]", hashed_password])
|
154 |
+
|
155 |
+
if insert_result:
|
156 |
+
logger.info(f"[{test_id}] Test user inserted successfully")
|
157 |
+
|
158 |
+
# Get the last inserted ID
|
159 |
+
id_query = "SELECT last_insert_rowid()"
|
160 |
+
id_result = execute_sql(id_query, [])
|
161 |
+
|
162 |
+
if id_result and "rows" in id_result and len(id_result["rows"]) > 0:
|
163 |
+
user_id = id_result["rows"][0]["values"][0]
|
164 |
+
logger.info(f"[{test_id}] Got user ID: {user_id}")
|
165 |
+
else:
|
166 |
+
logger.warning(f"[{test_id}] Could not get user ID")
|
167 |
+
user_id = None
|
168 |
+
|
169 |
+
# Verify the insert
|
170 |
+
verify_query = "SELECT id, email, created_at FROM users WHERE email = ?"
|
171 |
+
verify_result = execute_sql(verify_query, ["[email protected]"])
|
172 |
+
|
173 |
+
if verify_result and "rows" in verify_result and len(verify_result["rows"]) > 0:
|
174 |
+
user_data = verify_result["rows"][0]["values"]
|
175 |
+
user_id = user_data[0]
|
176 |
+
logger.info(f"[{test_id}] Verified test user with ID: {user_id}")
|
177 |
+
return {
|
178 |
+
"success": True,
|
179 |
+
"user_id": user_id,
|
180 |
+
"email": "[email protected]",
|
181 |
+
"created_at": user_data[2] if len(user_data) > 2 else None,
|
182 |
+
"status": "created"
|
183 |
+
}
|
184 |
+
else:
|
185 |
+
logger.error(f"[{test_id}] Failed to verify test user after insert")
|
186 |
+
return {
|
187 |
+
"success": False,
|
188 |
+
"error": "Failed to verify user after insert"
|
189 |
+
}
|
190 |
+
else:
|
191 |
+
logger.error(f"[{test_id}] Failed to insert test user")
|
192 |
+
return {
|
193 |
+
"success": False,
|
194 |
+
"error": "Failed to insert test user"
|
195 |
+
}
|
196 |
+
|
197 |
+
def list_all_users():
|
198 |
+
"""List all users in the database."""
|
199 |
+
# Generate a unique test ID
|
200 |
+
test_id = f"test_{int(time.time())}"
|
201 |
+
logger.info(f"[{test_id}] Listing all users")
|
202 |
+
query = "SELECT id, email, created_at FROM users"
|
203 |
+
result = execute_sql(query, [])
|
204 |
+
|
205 |
+
if result and "rows" in result and len(result["rows"]) > 0:
|
206 |
+
users = []
|
207 |
+
for row in result["rows"]:
|
208 |
+
users.append({
|
209 |
+
"id": row["values"][0],
|
210 |
+
"email": row["values"][1],
|
211 |
+
"created_at": row["values"][2]
|
212 |
+
})
|
213 |
+
logger.info(f"[{test_id}] Found {len(users)} users")
|
214 |
+
return users
|
215 |
+
else:
|
216 |
+
logger.info(f"[{test_id}] No users found")
|
217 |
+
return []
|
218 |
+
|
219 |
+
def main():
|
220 |
+
"""Main function."""
|
221 |
+
if len(sys.argv) < 2:
|
222 |
+
print("Usage: python direct_sql.py [create_test_user|list_users]")
|
223 |
+
sys.exit(1)
|
224 |
+
|
225 |
+
command = sys.argv[1]
|
226 |
+
|
227 |
+
if command == "create_test_user":
|
228 |
+
result = create_test_user()
|
229 |
+
print(json.dumps(result, indent=2))
|
230 |
+
elif command == "list_users":
|
231 |
+
users = list_all_users()
|
232 |
+
print(json.dumps(users, indent=2))
|
233 |
+
else:
|
234 |
+
print(f"Unknown command: {command}")
|
235 |
+
sys.exit(1)
|
236 |
+
|
237 |
+
if __name__ == "__main__":
|
238 |
+
main()
|
main.py
CHANGED
@@ -837,76 +837,261 @@ async def create_test_user():
|
|
837 |
dict: Information about the created test user.
|
838 |
"""
|
839 |
import time
|
|
|
|
|
840 |
|
841 |
# Generate a unique test ID
|
842 |
test_id = f"test_{int(time.time())}"
|
843 |
logger.info(f"[{test_id}] Starting test user creation (direct SQL)")
|
844 |
|
845 |
-
|
846 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
847 |
return {
|
848 |
"success": False,
|
849 |
-
"error": "
|
|
|
|
|
|
|
|
|
|
|
|
|
850 |
}
|
851 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
852 |
try:
|
853 |
-
#
|
854 |
-
|
855 |
-
|
856 |
-
|
|
|
|
|
|
|
|
|
857 |
|
858 |
-
if
|
859 |
-
logger.
|
860 |
return {
|
861 |
-
"success":
|
862 |
-
"
|
863 |
-
"email": "[email protected]",
|
864 |
-
"status": "already_exists"
|
865 |
}
|
866 |
|
867 |
-
#
|
868 |
-
|
869 |
-
|
870 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
871 |
|
872 |
-
|
873 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
874 |
insert_query = "INSERT INTO users (email, hashed_password) VALUES (?, ?)"
|
875 |
-
cursor = app.db_conn.execute(insert_query, ("[email protected]", hashed_password))
|
876 |
-
app.db_conn.commit()
|
877 |
-
logger.info(f"[{test_id}] Committed test user insert")
|
878 |
|
879 |
-
#
|
880 |
-
|
881 |
-
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
886 |
|
887 |
-
#
|
888 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
889 |
verify_query = "SELECT id, email, created_at FROM users WHERE email = ?"
|
890 |
-
verify_result = app.db_conn.execute(verify_query, ("[email protected]",)).fetchone()
|
891 |
|
892 |
-
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
900 |
-
|
901 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
902 |
else:
|
903 |
-
logger.error(f"[{
|
904 |
return {
|
905 |
"success": False,
|
906 |
"error": "Failed to verify user after insert"
|
907 |
}
|
908 |
except Exception as e:
|
909 |
-
logger.error(f"[{
|
910 |
return {
|
911 |
"success": False,
|
912 |
"error": str(e)
|
|
|
837 |
dict: Information about the created test user.
|
838 |
"""
|
839 |
import time
|
840 |
+
import subprocess
|
841 |
+
import json
|
842 |
|
843 |
# Generate a unique test ID
|
844 |
test_id = f"test_{int(time.time())}"
|
845 |
logger.info(f"[{test_id}] Starting test user creation (direct SQL)")
|
846 |
|
847 |
+
try:
|
848 |
+
# Run the direct SQL script
|
849 |
+
logger.info(f"[{test_id}] Running direct SQL script")
|
850 |
+
result = subprocess.run(
|
851 |
+
["python", "direct_sql.py", "create_test_user"],
|
852 |
+
cwd=".",
|
853 |
+
capture_output=True,
|
854 |
+
text=True,
|
855 |
+
check=True
|
856 |
+
)
|
857 |
+
|
858 |
+
# Parse the output
|
859 |
+
try:
|
860 |
+
output = json.loads(result.stdout)
|
861 |
+
logger.info(f"[{test_id}] Direct SQL script result: {output}")
|
862 |
+
return output
|
863 |
+
except json.JSONDecodeError:
|
864 |
+
logger.error(f"[{test_id}] Failed to parse direct SQL script output: {result.stdout}")
|
865 |
+
return {
|
866 |
+
"success": False,
|
867 |
+
"error": f"Failed to parse direct SQL script output: {result.stdout}"
|
868 |
+
}
|
869 |
+
except subprocess.CalledProcessError as e:
|
870 |
+
logger.error(f"[{test_id}] Direct SQL script failed: {e.stderr}")
|
871 |
return {
|
872 |
"success": False,
|
873 |
+
"error": f"Direct SQL script failed: {e.stderr}"
|
874 |
+
}
|
875 |
+
except Exception as e:
|
876 |
+
logger.error(f"[{test_id}] Error creating test user: {str(e)}")
|
877 |
+
return {
|
878 |
+
"success": False,
|
879 |
+
"error": str(e)
|
880 |
}
|
881 |
|
882 |
+
# Direct HTTP API endpoint for user registration
|
883 |
+
@app.post("/direct-register", tags=["Authentication"])
|
884 |
+
async def direct_register(request: Request):
|
885 |
+
"""
|
886 |
+
Register a new user using direct HTTP API.
|
887 |
+
This is a workaround for issues with the libsql-experimental driver.
|
888 |
+
"""
|
889 |
+
import time
|
890 |
+
import json
|
891 |
+
from pydantic import BaseModel, EmailStr
|
892 |
+
|
893 |
+
class UserCreate(BaseModel):
|
894 |
+
email: EmailStr
|
895 |
+
password: str
|
896 |
+
|
897 |
+
# Generate a unique request ID
|
898 |
+
request_id = f"direct_reg_{int(time.time())}"
|
899 |
+
logger.info(f"[{request_id}] Starting direct registration")
|
900 |
+
|
901 |
try:
|
902 |
+
# Parse the request body
|
903 |
+
body = await request.json()
|
904 |
+
user = UserCreate(**body)
|
905 |
+
logger.info(f"[{request_id}] Registering user with email: {user.email}")
|
906 |
+
|
907 |
+
# Get Turso database connection details
|
908 |
+
db_url = os.getenv("TURSO_DATABASE_URL")
|
909 |
+
auth_token = os.getenv("TURSO_AUTH_TOKEN")
|
910 |
|
911 |
+
if not db_url or not auth_token:
|
912 |
+
logger.error(f"[{request_id}] Missing Turso credentials")
|
913 |
return {
|
914 |
+
"success": False,
|
915 |
+
"error": "Missing Turso credentials"
|
|
|
|
|
916 |
}
|
917 |
|
918 |
+
# Clean the auth token
|
919 |
+
auth_token = auth_token.strip()
|
920 |
+
|
921 |
+
# Convert URL from libsql:// to https://
|
922 |
+
if db_url.startswith("libsql://"):
|
923 |
+
http_url = db_url.replace("libsql://", "https://")
|
924 |
+
else:
|
925 |
+
http_url = db_url
|
926 |
+
|
927 |
+
# Ensure the URL doesn't have a trailing slash
|
928 |
+
http_url = http_url.rstrip('/')
|
929 |
+
|
930 |
+
# Verify the URL format
|
931 |
+
if not http_url.startswith("https://"):
|
932 |
+
if "://" not in http_url:
|
933 |
+
http_url = f"https://{http_url}"
|
934 |
|
935 |
+
logger.info(f"[{request_id}] Using HTTP URL: {http_url}")
|
936 |
+
|
937 |
+
# Check if user already exists
|
938 |
+
logger.info(f"[{request_id}] Checking if user already exists")
|
939 |
+
check_query = "SELECT id FROM users WHERE email = ?"
|
940 |
+
|
941 |
+
# Format the request for checking if user exists
|
942 |
+
check_data = {
|
943 |
+
"requests": [
|
944 |
+
{
|
945 |
+
"type": "execute",
|
946 |
+
"stmt": {
|
947 |
+
"sql": check_query,
|
948 |
+
"args": [
|
949 |
+
{"type": "text", "value": user.email}
|
950 |
+
]
|
951 |
+
}
|
952 |
+
},
|
953 |
+
{"type": "close"}
|
954 |
+
]
|
955 |
+
}
|
956 |
+
|
957 |
+
# Send the request
|
958 |
+
headers = {
|
959 |
+
"Authorization": f"Bearer {auth_token}",
|
960 |
+
"Content-Type": "application/json"
|
961 |
+
}
|
962 |
+
|
963 |
+
pipeline_url = f"{http_url}/v2/pipeline"
|
964 |
+
check_response = requests.post(pipeline_url, headers=headers, json=check_data, timeout=10)
|
965 |
+
check_response.raise_for_status()
|
966 |
+
check_result = check_response.json()
|
967 |
+
|
968 |
+
if "results" in check_result and len(check_result["results"]) > 0:
|
969 |
+
result = check_result["results"][0]
|
970 |
+
if "rows" in result and len(result["rows"]) > 0:
|
971 |
+
logger.warning(f"[{request_id}] User with email {user.email} already exists")
|
972 |
+
return {
|
973 |
+
"success": False,
|
974 |
+
"error": "Email already registered"
|
975 |
+
}
|
976 |
+
|
977 |
+
# Hash the password
|
978 |
+
logger.info(f"[{request_id}] Hashing password")
|
979 |
+
from passlib.context import CryptContext
|
980 |
+
pwd_context = CryptContext(schemes=["argon2"], deprecated="auto")
|
981 |
+
hashed_password = pwd_context.hash(user.password)
|
982 |
+
logger.info(f"[{request_id}] Password hashed successfully")
|
983 |
+
|
984 |
+
# Insert the user
|
985 |
+
logger.info(f"[{request_id}] Inserting user")
|
986 |
insert_query = "INSERT INTO users (email, hashed_password) VALUES (?, ?)"
|
|
|
|
|
|
|
987 |
|
988 |
+
# Format the request for inserting the user
|
989 |
+
insert_data = {
|
990 |
+
"requests": [
|
991 |
+
{
|
992 |
+
"type": "execute",
|
993 |
+
"stmt": {
|
994 |
+
"sql": insert_query,
|
995 |
+
"args": [
|
996 |
+
{"type": "text", "value": user.email},
|
997 |
+
{"type": "text", "value": hashed_password}
|
998 |
+
]
|
999 |
+
}
|
1000 |
+
},
|
1001 |
+
{
|
1002 |
+
"type": "execute",
|
1003 |
+
"stmt": {
|
1004 |
+
"sql": "SELECT last_insert_rowid()"
|
1005 |
+
}
|
1006 |
+
},
|
1007 |
+
{"type": "close"}
|
1008 |
+
]
|
1009 |
+
}
|
1010 |
+
|
1011 |
+
# Send the request
|
1012 |
+
insert_response = requests.post(pipeline_url, headers=headers, json=insert_data, timeout=10)
|
1013 |
+
insert_response.raise_for_status()
|
1014 |
+
insert_result = insert_response.json()
|
1015 |
|
1016 |
+
# Get the user ID
|
1017 |
+
user_id = None
|
1018 |
+
if "results" in insert_result and len(insert_result["results"]) > 1:
|
1019 |
+
id_result = insert_result["results"][1]
|
1020 |
+
if "rows" in id_result and len(id_result["rows"]) > 0:
|
1021 |
+
user_id = id_result["rows"][0]["values"][0]
|
1022 |
+
logger.info(f"[{request_id}] User inserted with ID: {user_id}")
|
1023 |
+
|
1024 |
+
# Verify the insert
|
1025 |
+
logger.info(f"[{request_id}] Verifying user was created")
|
1026 |
verify_query = "SELECT id, email, created_at FROM users WHERE email = ?"
|
|
|
1027 |
|
1028 |
+
# Format the request for verifying the user
|
1029 |
+
verify_data = {
|
1030 |
+
"requests": [
|
1031 |
+
{
|
1032 |
+
"type": "execute",
|
1033 |
+
"stmt": {
|
1034 |
+
"sql": verify_query,
|
1035 |
+
"args": [
|
1036 |
+
{"type": "text", "value": user.email}
|
1037 |
+
]
|
1038 |
+
}
|
1039 |
+
},
|
1040 |
+
{"type": "close"}
|
1041 |
+
]
|
1042 |
+
}
|
1043 |
+
|
1044 |
+
# Send the request
|
1045 |
+
verify_response = requests.post(pipeline_url, headers=headers, json=verify_data, timeout=10)
|
1046 |
+
verify_response.raise_for_status()
|
1047 |
+
verify_result = verify_response.json()
|
1048 |
+
|
1049 |
+
if "results" in verify_result and len(verify_result["results"]) > 0:
|
1050 |
+
result = verify_result["results"][0]
|
1051 |
+
if "rows" in result and len(result["rows"]) > 0:
|
1052 |
+
user_data = result["rows"][0]["values"]
|
1053 |
+
user_id = user_data[0]
|
1054 |
+
logger.info(f"[{request_id}] Verified user with ID: {user_id}")
|
1055 |
+
|
1056 |
+
# Generate access token
|
1057 |
+
from datetime import timedelta
|
1058 |
+
from app.api.routes.auth_router import create_access_token, create_refresh_token
|
1059 |
+
|
1060 |
+
access_token_expires = timedelta(minutes=30)
|
1061 |
+
refresh_token_expires = timedelta(days=7)
|
1062 |
+
|
1063 |
+
access_token = create_access_token(
|
1064 |
+
data={"sub": user.email},
|
1065 |
+
expires_delta=access_token_expires
|
1066 |
+
)
|
1067 |
+
|
1068 |
+
refresh_token = create_refresh_token(
|
1069 |
+
data={"sub": user.email},
|
1070 |
+
expires_delta=refresh_token_expires
|
1071 |
+
)
|
1072 |
+
|
1073 |
+
return {
|
1074 |
+
"success": True,
|
1075 |
+
"id": user_id,
|
1076 |
+
"email": user.email,
|
1077 |
+
"access_token": access_token,
|
1078 |
+
"refresh_token": refresh_token,
|
1079 |
+
"token_type": "bearer"
|
1080 |
+
}
|
1081 |
+
else:
|
1082 |
+
logger.error(f"[{request_id}] Failed to verify user after insert")
|
1083 |
+
return {
|
1084 |
+
"success": False,
|
1085 |
+
"error": "Failed to verify user after insert"
|
1086 |
+
}
|
1087 |
else:
|
1088 |
+
logger.error(f"[{request_id}] Failed to verify user after insert")
|
1089 |
return {
|
1090 |
"success": False,
|
1091 |
"error": "Failed to verify user after insert"
|
1092 |
}
|
1093 |
except Exception as e:
|
1094 |
+
logger.error(f"[{request_id}] Error during direct registration: {str(e)}")
|
1095 |
return {
|
1096 |
"success": False,
|
1097 |
"error": str(e)
|