Sprint 0: Backend, Docker, KI-Layer mit Free/Premium-Trennung
This commit is contained in:
parent
84f49fafcf
commit
00be2bbcd5
17 changed files with 1107 additions and 0 deletions
87
backend/routes/auth.py
Normal file
87
backend/routes/auth.py
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
"""BAN YARO — Auth Routes"""
|
||||
|
||||
from fastapi import APIRouter, HTTPException, Response, Depends
|
||||
from pydantic import BaseModel, EmailStr
|
||||
from database import db
|
||||
from auth import (
|
||||
hash_password, verify_password, create_token,
|
||||
get_current_user
|
||||
)
|
||||
|
||||
router = APIRouter()
|
||||
COOKIE_NAME = "by_token"
|
||||
|
||||
|
||||
class LoginRequest(BaseModel):
|
||||
email: EmailStr
|
||||
password: str
|
||||
|
||||
class RegisterRequest(BaseModel):
|
||||
email: EmailStr
|
||||
password: str
|
||||
name: str
|
||||
|
||||
|
||||
def _set_cookie(response: Response, token: str):
|
||||
response.set_cookie(
|
||||
key=COOKIE_NAME, value=token,
|
||||
httponly=True, secure=True, samesite="lax",
|
||||
max_age=30 * 24 * 3600
|
||||
)
|
||||
|
||||
|
||||
@router.post("/register")
|
||||
async def register(data: RegisterRequest, response: Response):
|
||||
with db() as conn:
|
||||
if conn.execute("SELECT 1 FROM users WHERE email=?", (data.email,)).fetchone():
|
||||
raise HTTPException(400, "E-Mail bereits registriert.")
|
||||
conn.execute(
|
||||
"INSERT INTO users (email, pw_hash, name) VALUES (?,?,?)",
|
||||
(data.email, hash_password(data.password), data.name)
|
||||
)
|
||||
user = conn.execute(
|
||||
"SELECT id, rolle FROM users WHERE email=?", (data.email,)
|
||||
).fetchone()
|
||||
|
||||
token = create_token(user["id"], user["rolle"])
|
||||
_set_cookie(response, token)
|
||||
return {"token": token, "name": data.name}
|
||||
|
||||
|
||||
@router.post("/login")
|
||||
async def login(data: LoginRequest, response: Response):
|
||||
with db() as conn:
|
||||
user = conn.execute(
|
||||
"SELECT id, pw_hash, name, rolle, is_premium FROM users WHERE email=?",
|
||||
(data.email,)
|
||||
).fetchone()
|
||||
|
||||
if not user or not verify_password(data.password, user["pw_hash"]):
|
||||
raise HTTPException(401, "E-Mail oder Passwort falsch.")
|
||||
|
||||
token = create_token(user["id"], user["rolle"])
|
||||
_set_cookie(response, token)
|
||||
|
||||
with db() as conn:
|
||||
conn.execute(
|
||||
"UPDATE users SET last_login=datetime('now') WHERE id=?", (user["id"],)
|
||||
)
|
||||
|
||||
return {"token": token, "name": user["name"], "is_premium": bool(user["is_premium"])}
|
||||
|
||||
|
||||
@router.post("/logout")
|
||||
async def logout(response: Response):
|
||||
response.delete_cookie(COOKIE_NAME)
|
||||
return {"ok": True}
|
||||
|
||||
|
||||
@router.get("/me")
|
||||
async def me(user=Depends(get_current_user)):
|
||||
return {
|
||||
"id": user["id"],
|
||||
"name": user["name"],
|
||||
"email": user["email"],
|
||||
"rolle": user["rolle"],
|
||||
"is_premium": bool(user["is_premium"]),
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue