This commit is contained in:
ilyastar9999
2025-12-04 14:36:23 +03:00
parent 1841c66600
commit 42aecacced
4 changed files with 51 additions and 10 deletions

View File

@@ -23,6 +23,7 @@ class ServiceCreate(BaseModel):
name: str name: str
path: str path: str
git_url: Optional[str] = None git_url: Optional[str] = None
alias: Optional[str] = None
class ServiceAction(BaseModel): class ServiceAction(BaseModel):
action: str action: str
@@ -215,8 +216,8 @@ async def create_service(service: ServiceCreate):
raise HTTPException(status_code=404, detail=f"docker-compose file not found in {service_path}") raise HTTPException(status_code=404, detail=f"docker-compose file not found in {service_path}")
service_id = await conn.fetchval( service_id = await conn.fetchval(
"INSERT INTO services (name, path, git_url, status) VALUES ($1, $2, $3, $4) RETURNING id", "INSERT INTO services (name, path, git_url, alias, status) VALUES ($1, $2, $3, $4, $5) RETURNING id",
service.name, service_path, service.git_url, "stopped" service.name, service_path, service.git_url, service.alias, "stopped"
) )
await log_service_action(conn, service_id, "register", "success", "Service registered") await log_service_action(conn, service_id, "register", "success", "Service registered")
@@ -278,6 +279,36 @@ async def get_service(service_id: int):
finally: finally:
await release_db(conn) await release_db(conn)
@app.patch("/services/{service_id}", dependencies=[Depends(verify_token)])
async def update_service(service_id: int, updates: dict):
"""Update service fields (alias, git_url, etc.)"""
conn = await get_db()
try:
service = await conn.fetchrow("SELECT * FROM services WHERE id = $1", service_id)
if not service:
raise HTTPException(status_code=404, detail="Service not found")
# Allowed fields to update
allowed_fields = {"alias", "git_url"}
update_fields = {k: v for k, v in updates.items() if k in allowed_fields and v is not None}
if not update_fields:
return dict(service)
# Build dynamic UPDATE query
set_clauses = [f"{field} = ${i+1}" for i, field in enumerate(update_fields.keys())]
values = list(update_fields.values()) + [service_id]
await conn.execute(
f"UPDATE services SET {', '.join(set_clauses)}, last_updated = ${ len(values)} WHERE id = ${len(values)+1}",
*values, datetime.utcnow(), service_id
)
updated_service = await conn.fetchrow("SELECT * FROM services WHERE id = $1", service_id)
return dict(updated_service)
finally:
await release_db(conn)
@app.post("/services/{service_id}/action", dependencies=[Depends(verify_token)]) @app.post("/services/{service_id}/action", dependencies=[Depends(verify_token)])
async def service_action(service_id: int, action: ServiceAction): async def service_action(service_id: int, action: ServiceAction):
"""Start, stop, or restart a service""" """Start, stop, or restart a service"""

View File

@@ -6,6 +6,7 @@ CREATE TABLE IF NOT EXISTS services (
name VARCHAR(255) NOT NULL UNIQUE, name VARCHAR(255) NOT NULL UNIQUE,
path VARCHAR(512) NOT NULL, path VARCHAR(512) NOT NULL,
git_url VARCHAR(512), git_url VARCHAR(512),
alias VARCHAR(255),
status VARCHAR(50) DEFAULT 'stopped', status VARCHAR(50) DEFAULT 'stopped',
last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP, last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

View File

@@ -131,18 +131,26 @@ async def socketio_listener():
print(f" Sending alert: points {attacker_delta:.2f} >= threshold {ALERT_THRESHOLD_POINTS}") print(f" Sending alert: points {attacker_delta:.2f} >= threshold {ALERT_THRESHOLD_POINTS}")
alert_message = f"🚨 ATTACK DETECTED!\nTeam {attacker_id} stole flag from {service_name}\nPoints lost: {attacker_delta:.2f} FP" alert_message = f"🚨 ATTACK DETECTED!\nTeam {attacker_id} stole flag from {service_name}\nPoints lost: {attacker_delta:.2f} FP"
# Get service_id from controller if available # Get service_id from controller by checking name first, then alias
service_id = None service_id = None
try: try:
# Try to find service by exact name match
service_row = await conn.fetchrow( service_row = await conn.fetchrow(
"SELECT id FROM services WHERE name = $1 LIMIT 1", "SELECT id FROM services WHERE name = $1 LIMIT 1",
service_name service_name
) )
if not service_row:
# Try to find service by alias
service_row = await conn.fetchrow(
"SELECT id FROM services WHERE alias = $1 LIMIT 1",
service_name
)
if service_row: if service_row:
service_id = service_row['id'] service_id = service_row['id']
print(f" Found service_id: {service_id} for service: {service_name}") print(f" Found service_id: {service_id} for service: {service_name}")
else: else:
print(f" Service {service_name} not found in services table, buttons will use service_name only") print(f" Service {service_name} not found by name or alias in services table, buttons will use service_name only")
except Exception as e: except Exception as e:
print(f" Error looking up service_id: {e}") print(f" Error looking up service_id: {e}")

View File

@@ -49,7 +49,7 @@ async def handle_button_click(callback_data: str, chat_id: int, message_id: int)
# Extract service name from identifier # Extract service name from identifier
service_name = identifier[5:] # Remove 'name_' prefix service_name = identifier[5:] # Remove 'name_' prefix
service_id = None service_id = None
print(f"[BUTTON] Looking up service by name: {service_name}") print(f"[BUTTON] Looking up service by name or alias: {service_name}")
# Look up service_id from controller API # Look up service_id from controller API
try: try:
@@ -60,16 +60,17 @@ async def handle_button_click(callback_data: str, chat_id: int, message_id: int)
print(f"[BUTTON] Controller response: HTTP {resp.status}") print(f"[BUTTON] Controller response: HTTP {resp.status}")
if resp.status == 200: if resp.status == 200:
services = await resp.json() services = await resp.json()
print(f"[BUTTON] Found {len(services)} services: {[s.get('name') for s in services]}") print(f"[BUTTON] Found {len(services)} services")
# Find service by name # Find service by name or alias
for svc in services: for svc in services:
if svc.get('name') == service_name: if svc.get('name') == service_name or svc.get('alias') == service_name:
service_id = svc.get('id') service_id = svc.get('id')
print(f"[BUTTON] Matched service '{service_name}' to ID {service_id}") matched_by = "name" if svc.get('name') == service_name else "alias"
print(f"[BUTTON] Matched service '{service_name}' to ID {service_id} (by {matched_by})")
break break
if not service_id: if not service_id:
error_msg = f"❌ Service '{service_name}' not registered in controller" error_msg = f"❌ Service '{service_name}' not registered in controller\nPlease add alias in web panel"
print(f"[BUTTON] {error_msg}") print(f"[BUTTON] {error_msg}")
await bot.edit_message_text( await bot.edit_message_text(
chat_id=chat_id, chat_id=chat_id,