diff --git a/core/routers/router.py b/core/routers/router.py index 0d5bb3e..d44a941 100644 --- a/core/routers/router.py +++ b/core/routers/router.py @@ -8,6 +8,7 @@ change_user_status as change_user_status_on_server, delete_user_on_server, download_ovpn_file, + get_users_usage ) from core.setting.core import change_config @@ -15,7 +16,7 @@ router = APIRouter(prefix="/sync", tags=["node_sync"]) -@router.post("/get-status", response_model=ResponseModel) +@router.get("/status", response_model=ResponseModel) async def get_status(request: SetSettingsModel, api_key: str = Depends(check_api_key)): """Get the current status of the node and set ovpn settings""" if request.set_new_setting: @@ -36,8 +37,16 @@ async def get_status(request: SetSettingsModel, api_key: str = Depends(check_api success=True, msg="Node status retrieved successfully", data=status ) +@router.get("/usage", response_model=ResponseModel) +async def get_all_user_usage(api_key: str = Depends(check_api_key)): + usages = get_users_usage() + if usages: + return ResponseModel(success=True, msg="Latest user usage received", data=usages) + return ResponseModel(success=True, msg="No user is using it.",) -@router.post("/create-user", response_model=ResponseModel) + + +@router.post("/user", response_model=ResponseModel) async def create_user(user: User, api_key: str = Depends(check_api_key)): success = create_user_on_server(user.name) if success: @@ -49,19 +58,19 @@ async def create_user(user: User, api_key: str = Depends(check_api_key)): return ResponseModel(success=False, msg="Failed to create user") -@router.post("/delete-user", response_model=ResponseModel) -async def delete_user(user: User, api_key: str = Depends(check_api_key)): - result = delete_user_on_server(user.name) +@router.delete("/user/{name}", response_model=ResponseModel) +async def delete_user(name: str, api_key: str = Depends(check_api_key)): + result = delete_user_on_server(name) if result: return ResponseModel( success=True, msg="User deleted successfully", - data={"client_name": user.name}, + data={"client_name": name}, ) return ResponseModel(success=False, msg="Failed to delete user") -@router.post("/change-user-status", response_model=ResponseModel) +@router.put("/user", response_model=ResponseModel) async def change_user_status(user: User, api_key: str = Depends(check_api_key)): result = change_user_status_on_server(user.name, user.status) if result: diff --git a/core/schema/all_schemas.py b/core/schema/all_schemas.py index b429000..405467e 100644 --- a/core/schema/all_schemas.py +++ b/core/schema/all_schemas.py @@ -1,5 +1,5 @@ from pydantic import BaseModel -from typing import Any, Optional +from typing import Any, Optional, Dict class User(BaseModel): @@ -18,3 +18,6 @@ class SetSettingsModel(BaseModel): protocol: str ovpn_port: int set_new_setting: bool + +class UsersUsage(BaseModel): + users: Dict[str, float] \ No newline at end of file diff --git a/core/service/user_managment.py b/core/service/user_managment.py index 0c88da7..ed81ade 100644 --- a/core/service/user_managment.py +++ b/core/service/user_managment.py @@ -3,6 +3,7 @@ import os from core.logger import logger +from core.schema.all_schemas import UsersUsage script_path = "/root/openvpn-install.sh" @@ -174,3 +175,27 @@ async def download_ovpn_file(name: str) -> str | None: else: create_user_on_server(name) return await download_ovpn_file(name) + + +def get_users_usage() -> UsersUsage | None: + users = {} + file_path = "/var/log/openvpn-status.log" + with open(file_path) as f: + lines = f.readlines() + + for line in lines: + line = line.strip() + if line.startswith("CLIENT_LIST") and not line.startswith( + "CLIENT_LIST,Common Name" + ): + parts = line.split(",") + username = parts[1] + bytes_received = int(parts[5]) + bytes_sent = int(parts[6]) + total_bytes = bytes_received + bytes_sent + users[username] = total_bytes + + if users: + return UsersUsage(users=users) + else: + return None diff --git a/installer.py b/installer.py index 276711b..fc2eae6 100644 --- a/installer.py +++ b/installer.py @@ -20,12 +20,17 @@ def create_ccd() -> None: ccd_line = f"client-config-dir {ccd_dir}\n" ccd_exclusive_line = "ccd-exclusive\n" + statuses = "status /var/log/openvpn-status.log 10" if ccd_line not in lines: lines.append("\n" + ccd_line) if ccd_exclusive_line not in lines: lines.append(ccd_exclusive_line) + + if statuses not in lines: + lines.append(statuses) + with open(server_conf, "w") as f: f.writelines(lines) @@ -41,7 +46,8 @@ def install_ovnode(): menu() try: subprocess.run( - ["wget", "https://git.io/vpn", "-O", "/root/openvpn-install.sh"], check=True + ["wget", "-4", "https://git.io/vpn", "-O", "/root/openvpn-install.sh"], + check=True, ) # thanks to Nyr for ovpn installation script <3 https://github.com/Nyr/openvpn-install bash = pexpect.spawn( @@ -100,7 +106,9 @@ def install_ovnode(): f.writelines(lines) run_ovnode() - input("Successfully installed, Press Enter to return to the menu...") + input( + f"Successfully installed,\nApi key= {API_KEY}\nPort= {SERVICE_PORT}\nPress Enter to return to the menu..." + ) menu() except Exception as e: diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 54293ef..0000000 --- a/requirements.txt +++ /dev/null @@ -1,9 +0,0 @@ -fastapi -uvicorn -psutil -pydantic_settings -python-dotenv==1.1.0 -colorama -pexpect -requests -uuid \ No newline at end of file