Initial commit

This commit is contained in:
pptx704
2025-08-03 03:48:31 +03:00
commit 5a0e23cea8
23 changed files with 2551 additions and 0 deletions

0
app/__init__.py Normal file
View File

0
app/const.py Normal file
View File

25
app/database.py Normal file
View File

@ -0,0 +1,25 @@
from pymongo import AsyncMongoClient
from beanie import init_beanie
from app.models import User
from app.settings import settings
async def init_db():
"""Initialize database connection and Beanie ODM"""
try:
client = AsyncMongoClient(settings.MONGODB_URL)
await client.admin.command('ping')
await init_beanie(
database=client[settings.MONGODB_DATABASE],
document_models=[User]
)
except Exception as e:
raise
async def close_db():
"""Close database connection"""
client = AsyncMongoClient(settings.MONGODB_URL)
await client.close()

22
app/models.py Normal file
View File

@ -0,0 +1,22 @@
import uuid
from datetime import datetime, UTC
from beanie import Document, Indexed
from pydantic import Field
class User(Document):
id: uuid.UUID = Field(default_factory=uuid.uuid4)
username: str = Indexed(unique=True)
hashed_password: str
created_at: datetime = Field(default_factory=lambda: datetime.now(UTC))
updated_at: datetime = Field(default_factory=lambda: datetime.now(UTC))
class Settings:
name = "users"
class Config:
json_encoders = {
datetime: lambda v: v.isoformat(),
uuid.UUID: lambda v: str(v),
}

View File

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

@ -0,0 +1,6 @@
from fastapi import HTTPException, status
from beanie import PydanticObjectId
from app import schemas
from app.models import User
from app.security import create_jwt_token, get_password_hash, verify_password

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

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

@ -0,0 +1,8 @@
from fastapi import APIRouter, Depends, HTTPException, status
from app import schemas
from app.repositories import auth
from app.security import create_jwt_token
from app.settings import settings
router = APIRouter(prefix="", tags=["auth"])

14
app/schemas.py Normal file
View File

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

65
app/security.py Normal file
View File

@ -0,0 +1,65 @@
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.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)

18
app/settings.py Normal file
View File

@ -0,0 +1,18 @@
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
MONGODB_URL: str
MONGODB_DATABASE: str
settings = Settings()

0
app/utils.py Normal file
View File