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