diff --git a/app/db/crud.py b/app/db/crud.py index fcf8cd7..45f1669 100644 --- a/app/db/crud.py +++ b/app/db/crud.py @@ -2,7 +2,7 @@ import json import secrets from datetime import datetime from enum import Enum -from typing import Dict, List, Optional, Tuple, Union +from typing import List, Optional, Tuple, Union from sqlalchemy import and_, delete from sqlalchemy.orm import Session @@ -10,31 +10,31 @@ from sqlalchemy.orm import Session from app.db.models import (JWT, TLS, Admin, Node, NodeUsage, NodeUserUsage, NotificationReminder, InboundHost, Service, - Inbound, ProxyTypes, System, User, + Inbound, System, User, UserUsageResetLogs) from app.models.admin import AdminCreate, AdminModify, AdminPartialModify from app.models.node import (NodeCreate, NodeModify, NodeStatus, NodeUsageResponse) from app.models.proxy import InboundHost as InboundHostModify +from app.models.service import Service as ServiceModify, ServiceCreate from app.models.user import (ReminderType, UserCreate, UserDataLimitResetStrategy, UserModify, - UserResponse, UserStatus, UserUsageResponse) -from app.models.service import Service as ServiceModify, ServiceCreate -# from app.models.user_template import UserTemplateCreate, UserTemplateModify + UserStatus, UserUsageResponse) from app.utils.helpers import (calculate_expiration_days, calculate_usage_percent) -from app.utils.notification import Notification from config import NOTIFY_DAYS_LEFT, NOTIFY_REACHED_USAGE_PERCENT def add_default_hosts(db: Session, inbounds: List[Inbound]): - hosts = [InboundHost(remark="🚀 Marz ({USERNAME}) [{PROTOCOL} - {TRANSPORT}]", address="{SERVER_IP}", inbound=i) for i in inbounds] + hosts = [InboundHost(remark="🚀 Marz ({USERNAME}) [{PROTOCOL} - {TRANSPORT}]", address="{SERVER_IP}", inbound=i) for + i in inbounds] db.add_all(hosts) db.commit() def assure_node_inbounds(db: Session, inbounds: List[Inbound], node_id: int): - existing_inbounds = set((i.protocol, i.tag, i.config) for i in db.query(Inbound).filter(Inbound.node_id == node_id).all()) + existing_inbounds = set( + (i.protocol, i.tag, i.config) for i in db.query(Inbound).filter(Inbound.node_id == node_id).all()) inbounds_set = set((json.loads(i.config)["protocol"], i.tag, i.config) for i in list(inbounds)) new_inbounds = inbounds_set - existing_inbounds deleted_inbounds = existing_inbounds - inbounds_set @@ -51,26 +51,22 @@ def assure_node_inbounds(db: Session, inbounds: List[Inbound], node_id: int): db.add_all(new_inbounds) db.flush() for i in new_inbounds: - db.refresh(i) + db.refresh(i) add_default_hosts(db, new_inbounds) db.commit() def get_node_users(db: Session, node_id: Optional[int], statuses: Optional[List[UserStatus]] = None): query = db.query(User.id, User.username, User.key, Inbound).distinct( - ).join(Inbound.services).join(Service.users).filter(Inbound.node_id == node_id) + ).join(Inbound.services).join(Service.users).filter(Inbound.node_id == node_id) if isinstance(statuses, list): query = query.filter(User.status.in_(statuses)) return query.all() def get_user_hosts(db: Session, user_id: int): - return db.query(InboundHost).distinct().join(User.services).join(Service.inbounds).join(Inbound.hosts).filter( User.id == user_id ).all() - - -def get_all_hosts(db: Session) -> Dict[int, InboundHost]: - all_inbounds = db.query(Inbound).all() - return {i.id: i.hosts for i in all_inbounds} + return db.query(InboundHost).distinct().join(User.services).join(Service.inbounds).join(Inbound.hosts).filter( + User.id == user_id).all() def get_inbound_hosts(db: Session, inbound_id: int) -> List[InboundHost]: @@ -80,44 +76,47 @@ def get_inbound_hosts(db: Session, inbound_id: int) -> List[InboundHost]: def get_all_inbounds(db: Session): return db.query(Inbound).all() -""" -def get_or_create_inbound(db: Session, inbound_tag: Inbound): - inbound = db.query(ProxyInbound).filter(ProxyInbound.tag == inbound_tag).first() - if not inbound: - inbound = ProxyInbound(tag=inbound_tag) - db.add(inbound) - db.commit() - add_default_host(db, inbound) - db.refresh(inbound) - return inbound +def get_inbound(db: Session, inbound_id: int) -> Inbound | None: + return db.query(Inbound).filter(Inbound.id == inbound_id).first() -def get_hosts(db: Session, inbound: Inbound): - inbound = get_or_create_inbound(db, inbound_tag) - return inbound.hosts +def get_host(db: Session, host_id) -> InboundHost: + return db.query(InboundHost).filter(InboundHost.id == host_id).first() -""" def add_host(db: Session, inbound: Inbound, host: InboundHostModify): - # inbound = get_or_create_inbound(db, inbound_tag) - inbound.hosts.append( - InboundHost( - remark=host.remark, - address=host.address, - port=host.port, - path=host.path, - sni=host.sni, - host=host.host, - inbound=inbound, - security=host.security, - alpn=host.alpn, - fingerprint=host.fingerprint - ) + host = InboundHost( + remark=host.remark, + address=host.address, + port=host.port, + path=host.path, + sni=host.sni, + host=host.host, + inbound=inbound, + security=host.security, + alpn=host.alpn, + fingerprint=host.fingerprint ) + inbound.hosts.append(host) db.commit() - db.refresh(inbound) - return inbound.hosts + db.refresh(host) + return host + + +def update_host(db: Session, db_host: InboundHost, host: InboundHostModify): + db_host.remark = host.remark + db_host.address = host.address + db_host.port = host.port + db_host.path = host.path + db_host.sni = host.sni + db_host.host = host.host + db_host.security = host.security + db_host.alpn = host.alpn + db_host.fingerprint = host.fingerprint + db.commit() + db.refresh(db_host) + return db_host def update_hosts(db: Session, inbound_tag: str, modified_hosts: List[InboundHostModify]): @@ -249,25 +248,11 @@ def get_users_count(db: Session, status: UserStatus = None, admin: Admin = None) def create_user(db: Session, user: UserCreate, admin: Admin = None): - """ - excluded_inbounds_tags = user.excluded_inbounds - proxies = [] - for proxy_type, settings in user.proxies.items(): - excluded_inbounds = [ - get_or_create_inbound(db, tag) for tag in excluded_inbounds_tags[proxy_type] - ] - proxies.append( - Proxy(type=proxy_type.value, - settings=settings.dict(no_obj=True), - excluded_inbounds=excluded_inbounds) - ) - """ - dbuser = User( username=user.username, # proxies=proxies, key=user.key, - services=db.query(Service).filter(Service.id.in_(user.services)).all(),# user.services, + services=db.query(Service).filter(Service.id.in_(user.services)).all(), # user.services, status=user.status, data_limit=(user.data_limit or None), expire=(user.expire or None), @@ -328,7 +313,7 @@ def update_user(db: Session, dbuser: User, modify: UserModify): if modify.on_hold_expire_duration is not None: dbuser.on_hold_expire_duration = modify.on_hold_expire_duration - + if modify.services is not None: dbuser.services = db.query(Service).filter(Service.id.in_(modify.services)).all() dbuser.edit_at = datetime.utcnow() @@ -404,7 +389,6 @@ def set_owner(db: Session, dbuser: User, admin: Admin): def start_user_expire(db: Session, dbuser: User): - expire = int(datetime.utcnow().timestamp()) + dbuser.on_hold_expire_duration dbuser.expire = expire db.commit() @@ -447,7 +431,7 @@ def update_admin(db: Session, dbadmin: Admin, modified_admin: AdminModify): dbadmin.password_reset_at = datetime.utcnow() db.commit() db.refresh(dbadmin) - return dbadmin + return dbadmin def partial_update_admin(db: Session, dbadmin: Admin, modified_admin: AdminPartialModify): @@ -487,7 +471,7 @@ def create_service(db: Session, service: ServiceCreate) -> Service: name=service.name, inbounds=db.query(Inbound).filter(Inbound.id.in_(service.inbounds)).all(), users=db.query(User).filter(User.id.in_(service.users)).all() - ) + ) db.add(dbservice) db.commit() db.refresh(dbservice) diff --git a/app/marzneshin.py b/app/marzneshin.py index a15236a..0340bed 100644 --- a/app/marzneshin.py +++ b/app/marzneshin.py @@ -23,7 +23,7 @@ from . import __version__, telegram from .dashboard import build_dir, build, base_dir from .tasks import record_user_usages, review_users, reset_user_data_usage, nodes_health_check, \ record_realtime_bandwidth, send_notifications, delete_expired_reminders, nodes_startup -from .routes import admin, node, service, subscription, system, user +from .routes import api_router logger = logging.getLogger(__name__) dashboard_path = "/dashboard/" @@ -36,16 +36,11 @@ app = FastAPI( redoc_url="/redoc" if DOCS else None, ) -app.include_router(admin.router) -app.include_router(node.router) -app.include_router(service.router) -app.include_router(subscription.router) -app.include_router(system.router) -app.include_router(user.router) +app.include_router(api_router) @app.get("/", response_class=HTMLResponse) -def home(): +def home_page(): return render_template(HOME_PAGE_TEMPLATE) diff --git a/app/marznode/operations.py b/app/marznode/operations.py index a09e144..7a4f7d1 100644 --- a/app/marznode/operations.py +++ b/app/marznode/operations.py @@ -43,9 +43,9 @@ async def update_user_inbounds(user: "DBUser", new_inbounds: set, old_inbounds: node_inbounds = defaultdict(lambda: tuple((list(), list()))) for inbound_addition in inbound_additions: - node_inbounds[inbound_addition[0]][0].append(inbound_addition[3]) + node_inbounds[inbound_addition[0]][0].append(inbound_addition[2]) for inbound_reduction in inbound_reductions: - node_inbounds[inbound_reduction[0]][1].append(inbound_reduction[3]) + node_inbounds[inbound_reduction[0]][1].append(inbound_reduction[2]) for node, inbound_change in node_inbounds.items(): await marznode.nodes[node].update_user_inbounds(user, inbound_change[0], inbound_change[1]) diff --git a/app/models/proxy.py b/app/models/proxy.py index ff33de7..1b538b4 100644 --- a/app/models/proxy.py +++ b/app/models/proxy.py @@ -156,6 +156,10 @@ class InboundHost(BaseModel): return v +class InboundHostResponse(InboundHost): + id: int + + class InboundBase(BaseModel): id: Optional[int] = Field(None) tag: str = Field() diff --git a/app/routes/__init__.py b/app/routes/__init__.py index 3ee40bc..a0cdb36 100644 --- a/app/routes/__init__.py +++ b/app/routes/__init__.py @@ -1,12 +1,17 @@ -import logging +from fastapi import APIRouter -logger = logging.getLogger(__name__) +from . import admin, node, service, inbounds, subscription, system, user + +api_router = APIRouter() + +api_router.include_router(admin.router, prefix="/api") +api_router.include_router(node.router, prefix="/api") +api_router.include_router(service.router, prefix="/api") +api_router.include_router(inbounds.router, prefix="/api") +api_router.include_router(subscription.router) +api_router.include_router(system.router, prefix="/api") +api_router.include_router(user.router, prefix="/api") __all__ = [ - "admin", - "node", - "service", - "subscription", - "system", - "user" + "api_router" ] diff --git a/app/routes/admin.py b/app/routes/admin.py index 1297e96..b9012af 100644 --- a/app/routes/admin.py +++ b/app/routes/admin.py @@ -11,7 +11,7 @@ from app.models.admin import Admin, AdminCreate, AdminInDB, AdminModify, Token from app.utils.jwt import create_admin_token from config import SUDOERS -router = APIRouter(tags=["Admin"]) +router = APIRouter(tags=["Admin"], prefix="/admin") def authenticate_env_sudo(username: str, password: str) -> bool: @@ -29,7 +29,7 @@ def authenticate_admin(db: Session, username: str, password: str) -> Optional[Ad return dbadmin if AdminInDB.model_validate(dbadmin).verify_password(password) else None -@router.post("/api/admin/token", response_model=Token) +@router.post("/token", response_model=Token) def admin_token(form_data: Annotated[OAuth2PasswordRequestForm, Depends()], db: DBDep): if authenticate_env_sudo(form_data.username, form_data.password): @@ -45,7 +45,7 @@ def admin_token(form_data: Annotated[OAuth2PasswordRequestForm, Depends()], ) -@router.post("/api/admin", response_model=Admin) +@router.post("", response_model=Admin) def create_admin(new_admin: AdminCreate, db: DBDep, admin: SudoAdminDep): @@ -58,7 +58,7 @@ def create_admin(new_admin: AdminCreate, return dbadmin -@router.put("/api/admin/{username}", response_model=Admin) +@router.put("/{username}", response_model=Admin) def modify_admin(username: str, modified_admin: AdminModify, db: DBDep, @@ -85,7 +85,7 @@ def modify_admin(username: str, return dbadmin -@router.delete("/api/admin/{username}") +@router.delete("/{username}") def remove_admin(username: str, db: DBDep, admin: SudoAdminDep): @@ -103,12 +103,12 @@ def remove_admin(username: str, return {} -@router.get("/api/admin", response_model=Admin) +@router.get("", response_model=Admin) def get_current_admin(admin: AdminDep): return admin -@router.get("/api/admins", response_model=List[Admin]) +@router.get("s", response_model=List[Admin]) def get_admins(db: DBDep, admin: SudoAdminDep, offset: int = None, diff --git a/app/routes/inbounds.py b/app/routes/inbounds.py new file mode 100644 index 0000000..9fbb059 --- /dev/null +++ b/app/routes/inbounds.py @@ -0,0 +1,90 @@ +from fastapi import APIRouter, Depends +from fastapi import HTTPException + +from app.db import crud +from app.dependencies import DBDep, sudo_admin +from app.models.proxy import Inbound, InboundHost, InboundHostResponse +from app.db.models import InboundHost as DBInboundHost + +router = APIRouter(prefix="/inbounds", dependencies=[Depends(sudo_admin)], tags=['Inbounds']) + + +@router.get("", response_model=list[Inbound]) +def get_inbounds(db: DBDep): + """ + Get all inbounds + """ + inbounds = crud.get_all_inbounds(db) + + return inbounds + + +@router.get('/hosts', response_model=list[InboundHost]) +def get_hosts(db: DBDep): + return db.query(DBInboundHost).all() + + +@router.put("/hosts/{id}", response_model=InboundHostResponse) +def update_host(id: int, host: InboundHost, db: DBDep): + """ + Modify a host + """ + + db_host = crud.get_host(db, id) + if not db_host: + raise HTTPException(status_code=404, detail="Host not found") + + return crud.update_host(db, db_host, host) + + +@router.delete("/hosts/{id}") +def delete_host(id: int, db: DBDep): + """ + Remove a host + """ + db_host = crud.get_host(db, id) + if not db_host: + raise HTTPException(status_code=404, detail="Host not found") + + db.delete(db_host) + db.commit() + return {} + + +@router.get("/{id}", response_model=Inbound) +def get_inbound(id: int, db: DBDep): + """ + Get a specific inbound + """ + inbound = crud.get_inbound(db, id) + if not inbound: + raise HTTPException(status_code=404, detail="Inbound not found") + + return inbound + + +@router.get("/{id}/hosts", response_model=list[InboundHostResponse]) +def get_inbound_hosts(id: int | None, db: DBDep): + """ + Get hosts of a specific inbound + """ + if not id: + print() + return + inbound = crud.get_inbound(db, id) + if not inbound: + raise HTTPException(status_code=404, detail="Inbound not found") + + return inbound.hosts + + +@router.post("/{id}/hosts", response_model=InboundHostResponse) +def create_host(id: int, host: InboundHost, db: DBDep): + """ + Add a host to the inbound + """ + inbound = crud.get_inbound(db, id) + if not inbound: + raise HTTPException(status_code=404, detail="Inbound not found") + + return crud.add_host(db, inbound, host) diff --git a/app/routes/node.py b/app/routes/node.py index 070111b..917dba3 100644 --- a/app/routes/node.py +++ b/app/routes/node.py @@ -15,10 +15,10 @@ from app.models.node import (NodeCreate, NodeModify, NodeResponse, NodeSettings, NodeStatus, NodesUsageResponse) logger = logging.getLogger(__name__) -router = APIRouter(tags=['Node'], dependencies=[Depends(sudo_admin)]) +router = APIRouter(prefix="/node", tags=['Node'], dependencies=[Depends(sudo_admin)]) -@router.get("/api/node/settings", response_model=NodeSettings) +@router.get("/settings", response_model=NodeSettings) def get_node_settings(db: DBDep, admin: SudoAdminDep): tls = crud.get_tls_certificate(db) @@ -28,7 +28,7 @@ def get_node_settings(db: DBDep, ) -@router.post("/api/node", response_model=NodeResponse) +@router.post("", response_model=NodeResponse) async def add_node(new_node: NodeCreate, db: DBDep, admin: SudoAdminDep): @@ -48,7 +48,7 @@ async def add_node(new_node: NodeCreate, return db_node -@router.get("/api/node/{node_id}", response_model=NodeResponse) +@router.get("/{node_id}", response_model=NodeResponse) def get_node(node_id: int, db: DBDep, admin: SudoAdminDep): @@ -59,7 +59,7 @@ def get_node(node_id: int, return db_node -@router.websocket("/api/node/{node_id}/logs", dependencies=None) +@router.websocket("/{node_id}/logs", dependencies=None) async def node_logs(node_id: int, websocket: WebSocket, db: DBDep): @@ -95,13 +95,13 @@ async def node_logs(node_id: int, await websocket.send_text(l) -@router.get("/api/nodes", response_model=List[NodeResponse]) +@router.get("s", response_model=List[NodeResponse]) def get_nodes(db: DBDep, admin: SudoAdminDep): return crud.get_nodes(db) -@router.put("/api/node/{node_id}", response_model=NodeResponse) +@router.put("/{node_id}", response_model=NodeResponse) async def modify_node(node_id: int, modified_node: NodeModify, db: DBDep, @@ -123,7 +123,7 @@ async def modify_node(node_id: int, return db_node -@router.post("/api/node/{node_id}/resync") +@router.post("/{node_id}/resync") async def reconnect_node(node_id: int, db: DBDep, admin: SudoAdminDep): @@ -134,7 +134,7 @@ async def reconnect_node(node_id: int, return {} -@router.delete("/api/node/{node_id}") +@router.delete("/{node_id}") async def remove_node(node_id: int, db: DBDep, admin: SudoAdminDep): @@ -149,7 +149,7 @@ async def remove_node(node_id: int, return {} -@router.get("/api/nodes/usage", response_model=NodesUsageResponse) +@router.get("s/usage", response_model=NodesUsageResponse) def get_usage(db: DBDep, admin: SudoAdminDep, start_date: StartDateDep, diff --git a/app/routes/service.py b/app/routes/service.py index 752b219..5054be6 100644 --- a/app/routes/service.py +++ b/app/routes/service.py @@ -9,10 +9,10 @@ from app.dependencies import DBDep, sudo_admin from app.models.service import (ServiceCreate, ServiceModify, ServiceResponse) -router = APIRouter(dependencies=[Depends(sudo_admin)], tags=['Service']) +router = APIRouter(prefix="/service", dependencies=[Depends(sudo_admin)], tags=['Service']) -@router.post("/api/service", response_model=ServiceResponse) +@router.post("", response_model=ServiceResponse) def add_service(new_service: ServiceCreate, db: DBDep): """ @@ -30,7 +30,7 @@ def add_service(new_service: ServiceCreate, raise HTTPException(status_code=409, detail="Service by this name already exists") -@router.get("/api/service/{id}", response_model=ServiceResponse) +@router.get("/{id}", response_model=ServiceResponse) def get_service(id: int, db: DBDep): """ Get Service information with id @@ -42,7 +42,7 @@ def get_service(id: int, db: DBDep): return dbservice -@router.put("/api/service/{id}", response_model=ServiceResponse) +@router.put("/{id}", response_model=ServiceResponse) def modify_service(id: int, modification: ServiceModify, db: DBDep): @@ -67,7 +67,7 @@ def modify_service(id: int, raise HTTPException(status_code=409, detail="Service by this name already exists") -@router.delete("/api/service/{id}") +@router.delete("/{id}") def remove_service(id: int, db: DBDep): dbservice = crud.get_service(db, id) @@ -78,7 +78,7 @@ def remove_service(id: int, return dict() -@router.get("/api/services", response_model=List[ServiceResponse]) +@router.get("s", response_model=List[ServiceResponse]) def get_services(db: DBDep, offset: int = None, limit: int = None): diff --git a/app/routes/subscription.py b/app/routes/subscription.py index fe5bfb0..5d3bfce 100644 --- a/app/routes/subscription.py +++ b/app/routes/subscription.py @@ -16,7 +16,7 @@ from config import ( SUBSCRIPTION_PAGE_TEMPLATE ) -router = APIRouter(tags=['Subscription']) +router = APIRouter(prefix="/sub", tags=['Subscription']) def get_subscription_user_info(user: UserResponse) -> dict: @@ -28,8 +28,7 @@ def get_subscription_user_info(user: UserResponse) -> dict: } -@router.get("/sub/{username}/{key}/") -@router.get("/sub/{username}/{key}", include_in_schema=False) +@router.get("/{username}/{key}") def user_subscription(db_user: SubUserDep, request: Request, db: DBDep, @@ -90,12 +89,12 @@ def user_subscription(db_user: SubUserDep, return Response(content=conf, media_type="text/plain", headers=response_headers) -@router.get("/sub/{username}/{key}/info", response_model=UserResponse) +@router.get("/{username}/{key}/info", response_model=UserResponse) def user_subscription_info(db_user: SubUserDep): return db_user -@router.get("/sub/{username}/{key}/usage") +@router.get("/{username}/{key}/usage") def user_get_usage(db_user: SubUserDep, db: DBDep, start_date: StartDateDep, @@ -105,7 +104,7 @@ def user_get_usage(db_user: SubUserDep, return {"usages": usages, "username": db_user.username} -@router.get("/sub/{username}/{key}/{client_type}") +@router.get("/{username}/{key}/{client_type}") def user_subscription_with_client_type( db_user: SubUserDep, request: Request, diff --git a/app/routes/system.py b/app/routes/system.py index 0666a15..08017a3 100644 --- a/app/routes/system.py +++ b/app/routes/system.py @@ -15,7 +15,7 @@ from app.utils.system import memory_usage, cpu_usage, realtime_bandwidth router = APIRouter(tags=["System"]) -@router.get("/api/system", response_model=SystemStats) +@router.get("/system", response_model=SystemStats) def get_system_stats(db: DBDep, admin: AdminDep): mem = memory_usage() cpu = cpu_usage() @@ -41,13 +41,13 @@ def get_system_stats(db: DBDep, admin: AdminDep): ) -@router.get('/api/inbounds', response_model=List[Inbound]) +@router.get("/inbounds", response_model=List[Inbound]) def get_inbounds(db: DBDep, admin: SudoAdminDep): inbounds = crud.get_all_inbounds(db) return inbounds -@router.get('/api/hosts', response_model=Dict[int, List[InboundHost]]) +@router.get("/hosts", response_model=Dict[int, List[InboundHost]]) def get_hosts(db: DBDep, admin: SudoAdminDep): hosts = crud.get_all_hosts(db) diff --git a/app/routes/user.py b/app/routes/user.py index 49f9a13..ac8f629 100644 --- a/app/routes/user.py +++ b/app/routes/user.py @@ -18,7 +18,7 @@ logger = logging.getLogger(__name__) router = APIRouter(tags=['User']) -@router.post("/api/user", response_model=UserResponse) +@router.post("/user", response_model=UserResponse) async def add_user(new_user: UserCreate, db: DBDep, admin: AdminDep): @@ -51,7 +51,7 @@ async def add_user(new_user: UserCreate, return user -@router.get("/api/user/{username}", response_model=UserResponse) +@router.get("/user/{username}", response_model=UserResponse) def get_user(db_user: UserDep): """ Get users information @@ -59,7 +59,7 @@ def get_user(db_user: UserDep): return db_user -@router.put("/api/user/{username}", response_model=UserResponse) +@router.put("/user/{username}", response_model=UserResponse) async def modify_user(db_user: UserDep, modifications: UserModify, db: DBDep, @@ -112,7 +112,7 @@ async def modify_user(db_user: UserDep, return user -@router.delete("/api/user/{username}") +@router.delete("/user/{username}") async def remove_user(db_user: UserDep, db: DBDep, admin: AdminDep): @@ -133,7 +133,7 @@ async def remove_user(db_user: UserDep, return {} -@router.post("/api/user/{username}/reset", response_model=UserResponse) +@router.post("/user/{username}/reset", response_model=UserResponse) async def reset_user_data_usage(db_user: UserDep, db: DBDep, admin: AdminDep): @@ -156,7 +156,7 @@ async def reset_user_data_usage(db_user: UserDep, return user -@router.post("/api/user/{username}/revoke_sub", response_model=UserResponse) +@router.post("/user/{username}/revoke_sub", response_model=UserResponse) async def revoke_user_subscription(db_user: UserDep, db: DBDep, admin: AdminDep): @@ -180,7 +180,7 @@ async def revoke_user_subscription(db_user: UserDep, return user -@router.get("/api/users", response_model=UsersResponse) +@router.get("/users", response_model=UsersResponse) def get_users(db: DBDep, admin: AdminDep, offset: int = None, @@ -215,7 +215,7 @@ def get_users(db: DBDep, return {"users": users, "total": count} -@router.post("/api/users/reset") +@router.post("/users/reset") async def reset_users_data_usage(db: DBDep, admin: SudoAdminDep): """ @@ -231,7 +231,7 @@ async def reset_users_data_usage(db: DBDep, return {} -@router.get("/api/user/{username}/usage", response_model=UserUsagesResponse) +@router.get("/user/{username}/usage", response_model=UserUsagesResponse) def get_user_usage(db: DBDep, db_user: UserDep, start_date: StartDateDep, @@ -244,7 +244,7 @@ def get_user_usage(db: DBDep, return {"usages": usages, "username": db_user.username} -@router.put("/api/user/{username}/set-owner", response_model=UserResponse) +@router.put("/user/{username}/set-owner", response_model=UserResponse) def set_owner(username: str, admin_username: str, db: DBDep, @@ -265,7 +265,7 @@ def set_owner(username: str, return user -@router.delete("/api/users/expired") +@router.delete("/users/expired") def delete_expired(passed_time: int, db: DBDep, admin: AdminDep):