Added Daemon system and fixed interface
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
113
backend/main.py
113
backend/main.py
@@ -332,7 +332,7 @@ async def register(data: dict):
|
||||
|
||||
save_users(users)
|
||||
|
||||
access_token = create_access_token(data={"sub": username})
|
||||
access_token = create_access_token(data={"sub": username, "role": role})
|
||||
return {
|
||||
"access_token": access_token,
|
||||
"token_type": "bearer",
|
||||
@@ -353,7 +353,7 @@ async def login(data: dict):
|
||||
if not verify_password(password, user["password"]):
|
||||
raise HTTPException(401, "Неверное имя пользователя или пароль")
|
||||
|
||||
access_token = create_access_token(data={"sub": username})
|
||||
access_token = create_access_token(data={"sub": username, "role": user["role"]})
|
||||
return {
|
||||
"access_token": access_token,
|
||||
"token_type": "bearer",
|
||||
@@ -838,12 +838,12 @@ async def get_servers(user: dict = Depends(get_current_user)):
|
||||
servers = []
|
||||
try:
|
||||
# Владелец и администратор видят все серверы
|
||||
can_view_all = user.get("role") in ["owner", "admin"] or user.get("permissions", {}).get("view_all_resources", False)
|
||||
is_admin_or_owner = user.get("role") in ["owner", "admin"]
|
||||
|
||||
for server_dir in SERVERS_DIR.iterdir():
|
||||
if server_dir.is_dir():
|
||||
# Проверка доступа: владелец/админ видят всё, остальные только свои
|
||||
if not can_view_all and server_dir.name not in user.get("servers", []):
|
||||
if not is_admin_or_owner and server_dir.name not in user.get("servers", []):
|
||||
continue
|
||||
|
||||
config = load_server_config(server_dir.name)
|
||||
@@ -859,9 +859,14 @@ async def get_servers(user: dict = Depends(get_current_user)):
|
||||
servers.append({
|
||||
"name": server_dir.name,
|
||||
"displayName": config.get("displayName", server_dir.name),
|
||||
"status": "running" if is_running else "stopped"
|
||||
"status": "running" if is_running else "stopped",
|
||||
"owner": config.get("owner", "unknown")
|
||||
})
|
||||
print(f"Найдено серверов для {user['username']} ({user.get('role', 'user')}): {len(servers)}")
|
||||
|
||||
print(f"[DEBUG] User: {user['username']} (role: {user.get('role', 'user')})")
|
||||
print(f"[DEBUG] Is admin/owner: {is_admin_or_owner}")
|
||||
print(f"[DEBUG] Servers found: {len(servers)}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Ошибка загрузки серверов: {e}")
|
||||
return servers
|
||||
@@ -869,34 +874,84 @@ async def get_servers(user: dict = Depends(get_current_user)):
|
||||
@app.post("/api/servers/create")
|
||||
async def create_server(data: dict, user: dict = Depends(get_current_user)):
|
||||
server_name = data.get("name", "").strip()
|
||||
daemon_id = data.get("daemonId", "local")
|
||||
|
||||
if not server_name or not server_name.replace("_", "").replace("-", "").isalnum():
|
||||
raise HTTPException(400, "Недопустимое имя сервера")
|
||||
|
||||
server_path = SERVERS_DIR / server_name
|
||||
if server_path.exists():
|
||||
raise HTTPException(400, "Сервер с таким именем уже существует")
|
||||
# Если создаем на демоне
|
||||
if daemon_id != "local":
|
||||
# Загружаем демоны
|
||||
from daemons import load_daemons
|
||||
daemons = load_daemons()
|
||||
|
||||
if daemon_id not in daemons:
|
||||
raise HTTPException(404, "Демон не найден")
|
||||
|
||||
daemon = daemons[daemon_id]
|
||||
|
||||
# Отправляем запрос на создание сервера на демоне
|
||||
url = f"http://{daemon['address']}:{daemon['port']}/api/servers/create"
|
||||
headers = {"Authorization": f"Bearer {daemon['key']}"}
|
||||
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=10.0) as client:
|
||||
response = await client.post(url, json={
|
||||
"name": server_name,
|
||||
"displayName": data.get("displayName", server_name),
|
||||
"startCommand": data.get("startCommand", "java -Xmx2G -Xms1G -jar server.jar nogui"),
|
||||
"owner": user["username"]
|
||||
}, headers=headers)
|
||||
|
||||
if response.status_code != 200:
|
||||
raise HTTPException(400, f"Ошибка создания сервера на демоне: {response.text}")
|
||||
except httpx.RequestError as e:
|
||||
raise HTTPException(400, f"Ошибка подключения к демону: {str(e)}")
|
||||
|
||||
# Сохраняем информацию о сервере локально
|
||||
config = {
|
||||
"name": server_name,
|
||||
"displayName": data.get("displayName", server_name),
|
||||
"startCommand": data.get("startCommand", "java -Xmx2G -Xms1G -jar server.jar nogui"),
|
||||
"owner": user["username"],
|
||||
"daemonId": daemon_id,
|
||||
"daemonName": daemon["name"]
|
||||
}
|
||||
|
||||
# Создаем локальную запись о сервере
|
||||
server_path = SERVERS_DIR / f"{daemon_id}_{server_name}"
|
||||
server_path.mkdir(parents=True, exist_ok=True)
|
||||
save_server_config(f"{daemon_id}_{server_name}", config)
|
||||
|
||||
else:
|
||||
# Создаем локально
|
||||
server_path = SERVERS_DIR / server_name
|
||||
if server_path.exists():
|
||||
raise HTTPException(400, "Сервер с таким именем уже существует")
|
||||
|
||||
server_path.mkdir(parents=True)
|
||||
|
||||
config = {
|
||||
"name": server_name,
|
||||
"displayName": data.get("displayName", server_name),
|
||||
"startCommand": data.get("startCommand", "java -Xmx2G -Xms1G -jar server.jar nogui"),
|
||||
"owner": user["username"],
|
||||
"daemonId": "local"
|
||||
}
|
||||
save_server_config(server_name, config)
|
||||
|
||||
server_path.mkdir(parents=True)
|
||||
|
||||
config = {
|
||||
"name": server_name,
|
||||
"displayName": data.get("displayName", server_name),
|
||||
"startCommand": data.get("startCommand", "java -Xmx2G -Xms1G -jar server.jar nogui"),
|
||||
"owner": user["username"] # Сохраняем владельца
|
||||
}
|
||||
save_server_config(server_name, config)
|
||||
|
||||
# Если пользователь не админ, автоматически выдаем ему доступ
|
||||
if user["role"] != "admin":
|
||||
# Если пользователь не админ/owner, автоматически выдаем ему доступ
|
||||
if user["role"] not in ["admin", "owner"]:
|
||||
users = load_users()
|
||||
if user["username"] in users:
|
||||
if "servers" not in users[user["username"]]:
|
||||
users[user["username"]]["servers"] = []
|
||||
if server_name not in users[user["username"]]["servers"]:
|
||||
users[user["username"]]["servers"].append(server_name)
|
||||
server_key = f"{daemon_id}_{server_name}" if daemon_id != "local" else server_name
|
||||
if server_key not in users[user["username"]]["servers"]:
|
||||
users[user["username"]]["servers"].append(server_key)
|
||||
save_users(users)
|
||||
|
||||
return {"message": "Сервер создан", "name": server_name}
|
||||
return {"message": "Сервер создан", "name": server_name, "daemonId": daemon_id}
|
||||
|
||||
@app.get("/api/servers/{server_name}/config")
|
||||
async def get_server_config(server_name: str, user: dict = Depends(get_current_user)):
|
||||
@@ -1869,6 +1924,16 @@ async def update_user_permissions(username: str, perms: PermissionsUpdate, curre
|
||||
return {"message": f"Права пользователя {username} обновлены", "permissions": perms.permissions}
|
||||
|
||||
|
||||
# ============================================
|
||||
# API для управления демонами
|
||||
# ============================================
|
||||
|
||||
from daemons import router as daemons_router
|
||||
|
||||
# Подключаем роутер демонов
|
||||
app.include_router(daemons_router)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import uvicorn
|
||||
uvicorn.run(app, host="0.0.0.0", port=8000)
|
||||
|
||||
Reference in New Issue
Block a user