Initial commit: Robot ökoszisztéma v2.0 - Stabilizált jármű és szerviz robotok
This commit is contained in:
132
backend/app/api/auth.py.old
Executable file
132
backend/app/api/auth.py.old
Executable file
@@ -0,0 +1,132 @@
|
||||
from datetime import timedelta
|
||||
from typing import Dict, Any
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from app.core.config import settings
|
||||
from app.core.security import create_token, decode_token
|
||||
|
||||
router = APIRouter(prefix="/auth", tags=["auth"])
|
||||
|
||||
@router.post("/login")
|
||||
def login(payload: Dict[str, Any]):
|
||||
"""
|
||||
payload:
|
||||
{
|
||||
"org_id": "<uuid>",
|
||||
"login": "<username or email>",
|
||||
"password": "<plain>"
|
||||
}
|
||||
"""
|
||||
from app.db.session import get_conn
|
||||
|
||||
conn = get_conn()
|
||||
try:
|
||||
cur = conn.cursor()
|
||||
cur.execute("BEGIN;")
|
||||
|
||||
org_id = (payload.get("org_id") or "").strip()
|
||||
login_id = (payload.get("login") or "").strip()
|
||||
password = payload.get("password") or ""
|
||||
|
||||
if not org_id or not login_id or not password:
|
||||
raise HTTPException(status_code=400, detail="org_id, login, password required")
|
||||
|
||||
# RLS miatt kötelező: org kontextus beállítás
|
||||
cur.execute("SELECT set_config('app.tenant_org_id', %s, false);", (org_id,))
|
||||
|
||||
# account + credential
|
||||
cur.execute(
|
||||
"""
|
||||
SELECT
|
||||
a.account_id::text,
|
||||
a.org_id::text,
|
||||
a.username::text,
|
||||
a.email::text,
|
||||
c.password_hash,
|
||||
c.is_active
|
||||
FROM app.account a
|
||||
JOIN app.account_credential c ON c.account_id = a.account_id
|
||||
WHERE a.org_id = %s::uuid
|
||||
AND (a.username = %s::citext OR a.email = %s::citext)
|
||||
AND c.is_active = true
|
||||
LIMIT 1;
|
||||
""",
|
||||
(org_id, login_id, login_id),
|
||||
)
|
||||
|
||||
row = cur.fetchone()
|
||||
if not row:
|
||||
raise HTTPException(status_code=401, detail="Invalid credentials")
|
||||
|
||||
account_id, org_id_db, username, email, password_hash, cred_active = row
|
||||
|
||||
# Jelszó ellenőrzés pgcrypto-val: crypt(plain, stored_hash) = stored_hash
|
||||
cur.execute("SELECT crypt(%s, %s) = %s;", (password, password_hash, password_hash))
|
||||
ok = cur.fetchone()[0]
|
||||
if not ok:
|
||||
raise HTTPException(status_code=401, detail="Invalid credentials")
|
||||
|
||||
# MVP: role később membershipből; most fixen tenant_admin
|
||||
role_code = "tenant_admin"
|
||||
is_platform_admin = False
|
||||
|
||||
access = create_token(
|
||||
{
|
||||
"sub": account_id,
|
||||
"org_id": org_id_db,
|
||||
"role": role_code,
|
||||
"is_platform_admin": is_platform_admin,
|
||||
"type": "access",
|
||||
},
|
||||
settings.JWT_SECRET,
|
||||
timedelta(minutes=settings.JWT_ACCESS_MINUTES),
|
||||
)
|
||||
|
||||
refresh = create_token(
|
||||
{
|
||||
"sub": account_id,
|
||||
"org_id": org_id_db,
|
||||
"role": role_code,
|
||||
"is_platform_admin": is_platform_admin,
|
||||
"type": "refresh",
|
||||
},
|
||||
settings.JWT_SECRET,
|
||||
timedelta(days=settings.JWT_REFRESH_DAYS),
|
||||
)
|
||||
|
||||
conn.commit()
|
||||
return {"access_token": access, "refresh_token": refresh, "token_type": "bearer"}
|
||||
except HTTPException:
|
||||
conn.rollback()
|
||||
raise
|
||||
except Exception as e:
|
||||
conn.rollback()
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
@router.post("/refresh")
|
||||
def refresh_token(payload: Dict[str, Any]):
|
||||
token = payload.get("refresh_token") or ""
|
||||
if not token:
|
||||
raise HTTPException(status_code=400, detail="refresh_token required")
|
||||
|
||||
try:
|
||||
claims = decode_token(token, settings.JWT_SECRET)
|
||||
if claims.get("type") != "refresh":
|
||||
raise HTTPException(status_code=401, detail="Invalid refresh token type")
|
||||
|
||||
access = create_token(
|
||||
{
|
||||
"sub": claims.get("sub"),
|
||||
"org_id": claims.get("org_id"),
|
||||
"role": claims.get("role"),
|
||||
"is_platform_admin": claims.get("is_platform_admin", False),
|
||||
"type": "access",
|
||||
},
|
||||
settings.JWT_SECRET,
|
||||
timedelta(minutes=settings.JWT_ACCESS_MINUTES),
|
||||
)
|
||||
return {"access_token": access, "token_type": "bearer"}
|
||||
except Exception:
|
||||
raise HTTPException(status_code=401, detail="Invalid or expired refresh token")
|
||||
Reference in New Issue
Block a user