"""Sicht fuer normale Nutzer: nur die Hosts/Aktionen, fuer die RBAC eine Rolle in der jeweiligen Hostgruppe vergeben hat -- entweder direkt (Konzept 4.6) oder ueber eine Benutzergruppe, in der der User Mitglied ist (volle Rollen-Vererbung, siehe app/rbac.py).""" from __future__ import annotations from fastapi import APIRouter, Depends from app.auth.deps import CurrentUser, get_current_user from app.db import get_db router = APIRouter(prefix="/catalog", tags=["catalog"]) @router.get("/hosts") async def my_hosts(user: CurrentUser = Depends(get_current_user)): conn = get_db() if user.is_admin: cursor = await conn.execute( "SELECT h.id, h.hostname, h.address, h.protocol, h.os_type, h.host_group_id, " "g.name, h.clipboard_enabled, h.file_transfer_enabled " "FROM hosts h JOIN host_groups g ON g.id = h.host_group_id " "WHERE h.is_active = 1 ORDER BY g.name, h.hostname" ) rows = await cursor.fetchall() hosts = [dict(zip( ("id", "hostname", "address", "protocol", "os_type", "host_group_id", "host_group_name", "clipboard_enabled", "file_transfer_enabled"), r )) for r in rows] for h in hosts: h["can_connect"] = True h["can_file_transfer"] = True h["can_view_credentials"] = True return hosts cursor = await conn.execute( """ SELECT h.id, h.hostname, h.address, h.protocol, h.os_type, h.host_group_id, g.name, h.clipboard_enabled, h.file_transfer_enabled FROM hosts h JOIN host_groups g ON g.id = h.host_group_id WHERE h.is_active = 1 AND ( EXISTS ( SELECT 1 FROM user_hostgroup_roles uhr JOIN roles r ON r.id = uhr.role_id WHERE uhr.user_id = ? AND uhr.host_group_id = h.host_group_id AND r.name IN ('ssh_connect', 'rdp_connect') AND (uhr.expires_at IS NULL OR uhr.expires_at > strftime('%Y-%m-%dT%H:%M:%fZ','now')) ) OR EXISTS ( SELECT 1 FROM group_hostgroup_roles ghr JOIN roles r ON r.id = ghr.role_id JOIN user_group_members ugm ON ugm.user_group_id = ghr.user_group_id WHERE ugm.user_id = ? AND ghr.host_group_id = h.host_group_id AND r.name IN ('ssh_connect', 'rdp_connect') AND (ghr.expires_at IS NULL OR ghr.expires_at > strftime('%Y-%m-%dT%H:%M:%fZ','now')) ) ) ORDER BY g.name, h.hostname """, (user.id, user.id), ) rows = await cursor.fetchall() hosts = [dict(zip( ("id", "hostname", "address", "protocol", "os_type", "host_group_id", "host_group_name", "clipboard_enabled", "file_transfer_enabled"), r )) for r in rows] ft_cursor = await conn.execute( """ SELECT uhr.host_group_id FROM user_hostgroup_roles uhr JOIN roles r ON r.id = uhr.role_id WHERE uhr.user_id = ? AND r.name = 'file_transfer' AND (uhr.expires_at IS NULL OR uhr.expires_at > strftime('%Y-%m-%dT%H:%M:%fZ','now')) UNION SELECT ghr.host_group_id FROM group_hostgroup_roles ghr JOIN roles r ON r.id = ghr.role_id JOIN user_group_members ugm ON ugm.user_group_id = ghr.user_group_id WHERE ugm.user_id = ? AND r.name = 'file_transfer' AND (ghr.expires_at IS NULL OR ghr.expires_at > strftime('%Y-%m-%dT%H:%M:%fZ','now')) """, (user.id, user.id), ) ft_groups = {row[0] for row in await ft_cursor.fetchall()} cred_cursor = await conn.execute( """ SELECT uhr.host_group_id FROM user_hostgroup_roles uhr JOIN roles r ON r.id = uhr.role_id WHERE uhr.user_id = ? AND r.name IN ('credentials_view', 'credentials_manage') AND (uhr.expires_at IS NULL OR uhr.expires_at > strftime('%Y-%m-%dT%H:%M:%fZ','now')) UNION SELECT ghr.host_group_id FROM group_hostgroup_roles ghr JOIN roles r ON r.id = ghr.role_id JOIN user_group_members ugm ON ugm.user_group_id = ghr.user_group_id WHERE ugm.user_id = ? AND r.name IN ('credentials_view', 'credentials_manage') AND (ghr.expires_at IS NULL OR ghr.expires_at > strftime('%Y-%m-%dT%H:%M:%fZ','now')) """, (user.id, user.id), ) cred_groups = {row[0] for row in await cred_cursor.fetchall()} for h in hosts: h["can_connect"] = True h["can_file_transfer"] = h["host_group_id"] in ft_groups and bool(h["file_transfer_enabled"]) h["can_view_credentials"] = h["host_group_id"] in cred_groups return hosts