Initial commit

This commit is contained in:
2025-07-03 05:37:33 +00:00
commit bcb64faf74
27 changed files with 2599 additions and 0 deletions

0
app/__init__.py Normal file
View File

0
app/const.py Normal file
View File

19
app/database.py Normal file
View File

@ -0,0 +1,19 @@
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from .const import SQLALCHEMY_DATABASE_URL
engine = create_engine(SQLALCHEMY_DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()

17
app/models.py Normal file
View File

@ -0,0 +1,17 @@
import uuid
from sqlalchemy import (
Boolean,
Column,
DateTime,
ForeignKey,
Integer,
PrimaryKeyConstraint,
String,
)
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import relationship
from sqlalchemy.schema import Index
from sqlalchemy.sql import func
from app.database import Base

View File

6
app/repositories/auth.py Normal file
View File

@ -0,0 +1,6 @@
from fastapi import HTTPException, status
from sqlalchemy.orm import Session
from .. import schemas
from ..models import User
from ..security import create_jwt_token, get_password_hash, verify_password

0
app/routers/__init__.py Normal file
View File

11
app/routers/auth.py Normal file
View File

@ -0,0 +1,11 @@
from fastapi import APIRouter, Depends, status
from sqlalchemy.orm import Session
from app import database, schemas
from .. import schemas
from ..database import get_db
from ..repositories import auth
from ..security import get_user
router = APIRouter(prefix="", tags=["auth"])

17
app/schemas.py Normal file
View File

@ -0,0 +1,17 @@
import datetime
import enum
import uuid
from typing import List, Optional
from pydantic import BaseModel, EmailStr
class BaseResponse(BaseModel):
message: str
class User(BaseModel):
id: uuid.UUID
class Config:
orm_mode = True

66
app/security.py Normal file
View File

@ -0,0 +1,66 @@
import os
from datetime import UTC, datetime, timedelta
import jwt
from bcrypt import checkpw, gensalt, hashpw
from fastapi import HTTPException, Security
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
from app import schemas
from app.database import SessionLocal
from app.models import User
from app.settings import settings
def get_password_hash(password: str) -> str:
return hashpw(password.encode("utf-8"), gensalt()).decode("utf-8")
def verify_password(plain_password: str, hashed_password: str) -> bool:
return checkpw(
plain_password.encode("utf-8"), hashed_password.encode("utf-8")
)
def create_jwt_token(data: dict) -> str:
_ed = timedelta(minutes=settings.JWT_EXPIRE_MINUTES)
iat = datetime.now(UTC)
exp = datetime.now(UTC) + _ed
token_payload = data
token_payload.update({"iat": iat, "exp": exp})
token = jwt.encode(
token_payload, settings.JWT_SECRET, algorithm=settings.JWT_ALGORITHM
)
return token
def get_user_from_token(token: str) -> schemas.User:
try:
payload = jwt.decode(
token, settings.JWT_SECRET, algorithms=[settings.JWT_ALGORITHM]
)
except jwt.ExpiredSignatureError:
raise HTTPException(status_code=401, detail="Token has expired")
except jwt.JWTError:
raise HTTPException(
status_code=401, detail="Invalid authentication credentials"
)
user_id = payload.get("user_id")
# Return user from database
...
def get_user(
authorization: HTTPAuthorizationCredentials = Security(HTTPBearer()),
) -> schemas.User:
if authorization.scheme.lower() != "bearer":
raise HTTPException(
status_code=401, detail="Invalid authentication scheme"
)
token = authorization.credentials
return get_user_from_token(token)

16
app/settings.py Normal file
View File

@ -0,0 +1,16 @@
import os
from dotenv import load_dotenv
from pydantic_settings import BaseSettings
load_dotenv()
class Settings(BaseSettings):
JWT_SECRET: str
JWT_ALGORITHM: str
JWT_EXPIRE_MINUTES: int
SQLALCHEMY_DATABASE_URL: str
settings = Settings()

0
app/utils.py Normal file
View File