gitscope
← marzneshin / v0.3.0-alpha8 / app/dependencies.py
https://dev.kronoz.win/r/marzneshin.git
app/dependencies.py · Python
Blame Raw
  1from datetime import datetime
  2from typing import Annotated
  3
  4from fastapi import Depends, HTTPException, status
  5from sqlalchemy.exc import SQLAlchemyError
  6from sqlalchemy.orm import Session
  7
  8from app.db import crud, User, GetDB
  9from app.models.admin import Admin, oauth2_scheme
 10from app.utils.jwt import get_admin_payload
 11from config import SUDOERS
 12
 13
 14def get_db():  # Dependency
 15    with GetDB() as db:
 16        yield db
 17
 18
 19def get_admin(
 20    db: Annotated[Session, Depends(get_db)],
 21    token: Annotated[str, Depends(oauth2_scheme)],
 22):
 23    payload = get_admin_payload(token)
 24    if not payload:
 25        return
 26
 27    if payload["username"] in SUDOERS and payload["is_sudo"] is True:
 28        return Admin(username=payload["username"], is_sudo=True)
 29
 30    dbadmin = crud.get_admin(db, payload["username"])
 31    if not dbadmin:
 32        return
 33
 34    if dbadmin.password_reset_at:
 35        if not payload.get("created_at"):
 36            return
 37        if dbadmin.password_reset_at > payload.get("created_at"):
 38            return
 39
 40    return Admin.model_validate(dbadmin)
 41
 42
 43def get_current_admin(admin: Annotated[Admin, Depends(get_admin)]):
 44    if not admin:
 45        raise HTTPException(
 46            status_code=status.HTTP_401_UNAUTHORIZED,
 47            detail="Could not validate credentials",
 48            headers={"WWW-Authenticate": "Bearer"},
 49        )
 50
 51    return admin
 52
 53
 54def sudo_admin(admin: Annotated[Admin, Depends(get_current_admin)]):
 55    if not admin.is_sudo:
 56        raise HTTPException(
 57            status_code=status.HTTP_403_FORBIDDEN,
 58            detail="Access Denied",
 59        )
 60    return admin
 61
 62
 63def get_subscription_user(
 64    username: str, key: str, db: Annotated[Session, Depends(get_db)]
 65):
 66    try:
 67        int(key, 16)
 68    except ValueError:
 69        raise HTTPException(404)
 70
 71    db_user = crud.get_user(db, username)
 72    if not db_user or db_user.key != key:
 73        raise HTTPException(404)
 74    return db_user
 75
 76
 77def get_user(
 78    username: str,
 79    admin: Annotated[Admin, Depends(get_current_admin)],
 80    db: Annotated[Session, Depends(get_db)],
 81):
 82    db_user = crud.get_user(db, username)
 83    if not (
 84        admin.is_sudo or (db_user.admin and db_user.admin.username == admin.username)
 85    ):
 86        raise HTTPException(status_code=403, detail="You're not allowed")
 87
 88    if not db_user:
 89        raise HTTPException(status_code=404, detail="User not found")
 90
 91    return db_user
 92
 93
 94def parse_start_date(start: str | None = None):
 95    if not start:
 96        return datetime.fromtimestamp(datetime.utcnow().timestamp() - 30 * 24 * 3600)
 97    else:
 98        return datetime.fromisoformat(start)
 99
100
101def parse_end_date(end: str | None = None):
102    if not end:
103        return datetime.utcnow()
104    else:
105        return datetime.fromisoformat(end)
106
107
108SubUserDep = Annotated[User, Depends(get_subscription_user)]
109UserDep = Annotated[User, Depends(get_user)]
110AdminDep = Annotated[Admin, Depends(get_current_admin)]
111SudoAdminDep = Annotated[Admin, Depends(sudo_admin)]
112DBDep = Annotated[Session, Depends(get_db)]
113StartDateDep = Annotated[datetime, Depends(parse_start_date)]
114EndDateDep = Annotated[datetime, Depends(parse_end_date)]