gitscope
← marzneshin / nightly / 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.orm import Session
  6
  7from app.db import crud, User, GetDB
  8from app.db.models import Service
  9from app.models.admin import Admin, oauth2_scheme
 10from app.utils.auth import get_admin_payload
 11
 12
 13def get_db():
 14    with GetDB() as db:
 15        yield db
 16
 17
 18def get_admin(
 19    db: Annotated[Session, Depends(get_db)],
 20    token: Annotated[str, Depends(oauth2_scheme)],
 21):
 22    payload = get_admin_payload(token)
 23    if not payload:
 24        return
 25
 26    dbadmin = crud.get_admin(db, payload["username"])
 27    if not dbadmin:
 28        return
 29
 30    if dbadmin.password_reset_at:
 31        created_at = payload.get("created_at")
 32        if not created_at or dbadmin.password_reset_at > created_at:
 33            return
 34
 35    if not dbadmin.is_sudo and not dbadmin.enabled:
 36        return
 37
 38    return Admin.model_validate(dbadmin)
 39
 40
 41def get_current_admin(admin: Annotated[Admin, Depends(get_admin)]):
 42    if not admin:
 43        raise HTTPException(
 44            status_code=status.HTTP_401_UNAUTHORIZED,
 45            detail="Could not validate credentials",
 46            headers={"WWW-Authenticate": "Bearer"},
 47        )
 48
 49    return admin
 50
 51
 52def sudo_admin(admin: Annotated[Admin, Depends(get_current_admin)]):
 53    if not admin.is_sudo:
 54        raise HTTPException(
 55            status_code=status.HTTP_403_FORBIDDEN,
 56            detail="Access Denied",
 57        )
 58    return admin
 59
 60
 61def get_subscription_user(
 62    username: str, key: str, db: Annotated[Session, Depends(get_db)]
 63):
 64    try:
 65        int(key, 16)
 66    except ValueError:
 67        raise HTTPException(status_code=404)
 68
 69    db_user = crud.get_user(db, username)
 70    if db_user and db_user.key == key:
 71        return db_user
 72    else:
 73        raise HTTPException(status_code=404)
 74
 75
 76def get_user(
 77    username: str,
 78    admin: Annotated[Admin, Depends(get_current_admin)],
 79    db: Annotated[Session, Depends(get_db)],
 80):
 81    db_user = crud.get_user(db, username)
 82    if not (
 83        admin.is_sudo or (db_user and db_user.admin.username == admin.username)
 84    ):
 85        raise HTTPException(status_code=403, detail="You're not allowed")
 86
 87    if not db_user:
 88        raise HTTPException(status_code=404, detail="User not found")
 89
 90    return db_user
 91
 92
 93def user_modification_access(
 94    admin: Annotated[Admin, Depends(get_current_admin)],
 95):
 96    if not admin.is_sudo and not admin.modify_users_access:
 97        raise HTTPException(status_code=403, detail="You're not allowed")
 98
 99
100def parse_start_date(start: str | None = None):
101    if not start:
102        return datetime.fromtimestamp(
103            datetime.utcnow().timestamp() - 30 * 24 * 3600
104        )
105    else:
106        return datetime.fromisoformat(start)
107
108
109def parse_end_date(end: str | None = None):
110    if not end:
111        return datetime.utcnow()
112    else:
113        return datetime.fromisoformat(end)
114
115
116def get_service(id: int, db: Annotated[Session, Depends(get_db)]):
117    service = crud.get_service(db, id)
118    if not service:
119        raise HTTPException(status_code=404, detail="Service not found")
120    return service
121
122
123SubUserDep = Annotated[User, Depends(get_subscription_user)]
124UserDep = Annotated[User, Depends(get_user)]
125AdminDep = Annotated[Admin, Depends(get_current_admin)]
126SudoAdminDep = Annotated[Admin, Depends(sudo_admin)]
127DBDep = Annotated[Session, Depends(get_db)]
128StartDateDep = Annotated[datetime, Depends(parse_start_date)]
129EndDateDep = Annotated[datetime, Depends(parse_end_date)]
130ModifyUsersAccess = Annotated[None, Depends(user_modification_access)]
131ServiceDep = Annotated[Service, Depends(get_service)]