File size: 2,644 Bytes
71b4454
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import os
import hashlib
import asyncpg
from fastapi import HTTPException
from pydantic import BaseModel

import app_part1
from app_part1 import app

SECRET_KEY = os.environ.get("DOLOR3V_SECRET_KEY", "dev-secret-change-me")
IN_MEMORY_USERS = {}

def hash_password(password: str) -> str:
    return hashlib.sha256((password + SECRET_KEY).encode()).hexdigest()

class UserCreateRequest(BaseModel):
    email: str
    password: str
    name: str

class UserLoginRequest(BaseModel):
    email: str
    password: str

USERS_TABLE_SQL = "CREATE TABLE IF NOT EXISTS dolor3v_users (id SERIAL PRIMARY KEY, email TEXT UNIQUE NOT NULL, password_hash TEXT NOT NULL, name TEXT NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT now())"

@app.post("/v1/auth/register")
async def register_user(req: UserCreateRequest):
    password_hash = hash_password(req.password)
    if app_part1.db_pool is not None:
        try:
            async with app_part1.db_pool.acquire() as conn:
                await conn.execute(USERS_TABLE_SQL)
                row = await conn.fetchrow(
                    "INSERT INTO dolor3v_users (email, password_hash, name) VALUES ($1, $2, $3) RETURNING id, email, name",
                    req.email, password_hash, req.name
                )
            return {"user": dict(row), "token": f"user_{row['id']}"}
        except asyncpg.UniqueViolationError:
            raise HTTPException(status_code=400, detail="Email already exists")
    if req.email in IN_MEMORY_USERS:
        raise HTTPException(status_code=400, detail="Email already exists")
    user_id = len(IN_MEMORY_USERS) + 1
    IN_MEMORY_USERS[req.email] = {"id": user_id, "email": req.email, "password_hash": password_hash, "name": req.name}
    return {"user": {"id": user_id, "email": req.email, "name": req.name}, "token": f"user_{user_id}"}

@app.post("/v1/auth/login")
async def login_user(req: UserLoginRequest):
    password_hash = hash_password(req.password)
    if app_part1.db_pool is not None:
        async with app_part1.db_pool.acquire() as conn:
            row = await conn.fetchrow("SELECT id, email, name FROM dolor3v_users WHERE email = $1 AND password_hash = $2", req.email, password_hash)
        if not row:
            raise HTTPException(status_code=401, detail="Invalid credentials")
        return {"user": dict(row), "token": f"user_{row['id']}"}
    user = IN_MEMORY_USERS.get(req.email)
    if not user or user["password_hash"] != password_hash:
        raise HTTPException(status_code=401, detail="Invalid credentials")
    return {"user": {"id": user["id"], "email": user["email"], "name": user["name"]}, "token": f"user_{user['id']}"}