Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
File size: 5,286 Bytes
1b7f275 8f85807 bdd7c79 1b7f275 8f85807 bdd7c79 8f85807 1b7f275 db9a3ad 1b7f275 43e42ab 1b7f275 bdd7c79 66ed339 1b7f275 db9a3ad 1b7f275 42f5e18 1b7f275 43e42ab 1b7f275 43e42ab 1b7f275 0636c9d 1b7f275 bdd7c79 3f4756d bdd7c79 3f4756d f73d61a bdd7c79 0636c9d 1b7f275 8f85807 bdd7c79 1b7f275 bdd7c79 8f85807 43e42ab 1b7f275 8f85807 1b7f275 0687906 1b7f275 0687906 1b7f275 0687906 1b7f275 0687906 1b7f275 0636c9d 1b7f275 0687906 1b7f275 | 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 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | from datetime import timedelta
import os
import random
from typing import Any
import uuid
from fastapi import (
APIRouter,
BackgroundTasks,
Depends,
Form,
HTTPException,
status,
Request,
UploadFile,
File,
)
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.ext.asyncio import AsyncSession
from app.api import deps
from app.core import security
from app.core.config import settings
from app.schemas.auth import LoginRequest
from app.schemas.token import Token
from app.schemas.user import UserResponse, UserCreate
from app.crud import user as user_crud
from app.services import email_service, redis_service
from app.services.storage_service import storage_service
router = APIRouter()
@router.post("/login", response_model=Token)
async def login_access_token(
login_data: LoginRequest,
db: AsyncSession = Depends(deps.get_db),
) -> Any:
user = await user_crud.authenticate_user(
db, email=login_data.email, password=login_data.password
)
if not user:
raise HTTPException(status_code=400, detail="Incorrect email or password")
access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
return {
"access_token": security.create_access_token(
subject=user.id,
role=user.role,
expires_delta=access_token_expires,
),
"refresh_token": security.create_refresh_token(user.id),
"token_type": "bearer",
"user": user,
}
@router.post("/request-otp")
async def request_otp(
email: str = Form(...),
background_tasks: BackgroundTasks = BackgroundTasks(),
db: AsyncSession = Depends(deps.get_db),
):
user_exists = await user_crud.get_user_by_email(db, email=email)
if user_exists:
raise HTTPException(
status_code=400,
detail="The user with this email already exists in the system.",
)
otp_code = str(random.randint(100000, 999999))
await redis_service.save_otp(email, otp_code)
background_tasks.add_task(email_service.send_otp_email, email, otp_code)
return {"message": "OTP sent to your email"}
@router.post("/register")
async def register_user(
*,
db: AsyncSession = Depends(deps.get_db),
first_name: str = Form(...),
last_name: str = Form(...),
email: str = Form(...),
password: str = Form(...),
file: UploadFile = File(...),
otp_code: str = Form(...),
) -> Any:
is_valid = await redis_service.verify_otp(email, otp_code)
if not is_valid:
raise HTTPException(status_code=400, detail="Invalid or expired OTP")
user_exists = await user_crud.get_user_by_email(db, email=email)
if user_exists:
raise HTTPException(
status_code=400,
detail="The user with this email already exists in the system.",
)
if not file.content_type.startswith("image/"):
raise HTTPException(status_code=400, detail="ไฟล์ต้องเป็นรูปภาพเท่านั้น")
file_extension = os.path.splitext(file.filename)[1]
new_file_name = f"{uuid.uuid4()}{file_extension}"
contents = await file.read()
try:
image_url = await storage_service.upload_file(
file_content=contents,
file_name=new_file_name,
content_type=file.content_type,
folder="profile",
)
except Exception as e:
raise HTTPException(
status_code=500, detail=f"เกิดข้อผิดพลาดในการอัปโหลดรูปภาพ: {str(e)}"
)
user_in = UserCreate(
first_name=first_name,
last_name=last_name,
email=email,
password=password,
profile_image_url=image_url,
)
user = await user_crud.register(db, user=user_in)
return user
@router.post("/refresh-token", response_model=Token)
async def refresh_token(
refresh_token: str,
db: AsyncSession = Depends(deps.get_db),
) -> Any:
try:
payload = security.jwt.decode(
refresh_token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM]
)
token_data = payload.get("sub")
if token_data is None:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
)
user_id = int(token_data)
except Exception:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
)
user = await user_crud.get_user_by_id(db, user_id=user_id)
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="User not found",
)
access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
return {
"access_token": security.create_access_token(
subject=user.id,
role=user.role,
expires_delta=access_token_expires,
),
"refresh_token": refresh_token,
"token_type": "bearer",
"user": user,
}
@router.post("/logout")
async def logout():
return {"message": "Successfully logged out"}
|