sicherheitsupdate
This commit is contained in:
207
README.md
Normal file
207
README.md
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
# Wilcon Client Agent
|
||||||
|
|
||||||
|
**Version:** 0.3.3
|
||||||
|
**Letzte Aktualisierung:** 2025-06-29
|
||||||
|
|
||||||
|
## 🛍 Projektüberblick
|
||||||
|
|
||||||
|
Wilcon ist ein modularer Systemagent zur Überwachung von:
|
||||||
|
|
||||||
|
- **System- und Hardwareinformationen**
|
||||||
|
- **Netzwerkdaten**
|
||||||
|
- **Laufenden Prozessen**
|
||||||
|
- **Benutzeraktivität (inkl. Steuerung via CLI)**
|
||||||
|
|
||||||
|
Die Daten werden über eine REST-API bereitgestellt und in einem modernen Web-Dashboard dargestellt. Zusätzlich ist ein optionales CLI-Tool zur Benutzerkontrolle integriert (`Safe Kiddo Agent`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📁 Projektstruktur
|
||||||
|
|
||||||
|
```text
|
||||||
|
.
|
||||||
|
├── main.py # (Legacy) einfacher Info-Endpunkt
|
||||||
|
├── wilcon.py # FastAPI-Server mit API-Key-Schutz & CORS für 192.168.13.0/24
|
||||||
|
├── sysinfo.py # System- und Hardwareinfos (CPU, RAM, Disk, GPU, User)
|
||||||
|
├── netinf.py # Netzwerk- und Verbindungserfassung
|
||||||
|
├── proginfo.py # Prozessüberwachung mit Laufzeiten, CPU/RAM
|
||||||
|
├── user_control_agent.py # CLI-Tool zur Benutzersteuerung
|
||||||
|
├── index.html # Web-Dashboard (Frontend)
|
||||||
|
├── style.css # Design für das Frontend
|
||||||
|
├── requirements.txt # Abhängigkeiten (bereinigt, optional erweiterbar)
|
||||||
|
├── install_service.sh # Installer für systemd (nicht mitgeliefert)
|
||||||
|
├── deploy.sh # Optionales Deploy-Skript (nicht mitgeliefert)
|
||||||
|
├── safe_kiddo_user_control.sh # Hilfsskript für SafeKiddo CLI-Tool
|
||||||
|
└── tests/ # Testverzeichnis mit pytest-Skripten
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Installation
|
||||||
|
|
||||||
|
### Voraussetzungen
|
||||||
|
|
||||||
|
- Python 3.9+
|
||||||
|
- Linux empfohlen (getestet unter Ubuntu)
|
||||||
|
- Root-Rechte für `user_control_agent.py`
|
||||||
|
|
||||||
|
### Schritt 1 – Projekt klonen
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://dein-git-repo/wilcon-agent.git
|
||||||
|
cd wilcon-agent
|
||||||
|
```
|
||||||
|
|
||||||
|
### Schritt 2 – Virtuelle Umgebung (optional, empfohlen)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 -m venv venv
|
||||||
|
source venv/bin/activate
|
||||||
|
```
|
||||||
|
|
||||||
|
### Schritt 3 – Abhängigkeiten installieren
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Optional:
|
||||||
|
|
||||||
|
Falls GPU-Informationen oder erweiterte CPU-/OS-Erkennung benötigt werden:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install gputil py-cpuinfo distro
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ▶️ Anwendung starten
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export WILCON_API_KEY=test123
|
||||||
|
uvicorn wilcon:app --host 0.0.0.0 --port 8080
|
||||||
|
```
|
||||||
|
|
||||||
|
Rufe dann das Webinterface auf unter:
|
||||||
|
[http://localhost:5500/index.html](http://localhost:5500/index.html)
|
||||||
|
(**Tipp:** Live Server in VS Code verwenden)
|
||||||
|
|
||||||
|
**Hinweis:** Alle API-Endpunkte erfordern den HTTP-Header `x-api-key`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -H "x-api-key: test123" http://localhost:8080/sysinfo
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🌐 API-Endpunkte
|
||||||
|
|
||||||
|
| Endpunkt | Beschreibung |
|
||||||
|
| ----------- | --------------------------------------- |
|
||||||
|
| `/sysinfo` | Hardware- und OS-Informationen |
|
||||||
|
| `/netinfo` | Netzwerk-Interfaces, IPs, Gateways, DNS |
|
||||||
|
| `/procinfo` | Laufende Prozesse mit CPU, RAM & Zeit |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💡 Web-Dashboard
|
||||||
|
|
||||||
|
Das HTML-Dashboard bietet:
|
||||||
|
|
||||||
|
- Übersicht über Systemdaten
|
||||||
|
- Scrollbare und filterbare Tabellen
|
||||||
|
- Sortierbare Spalten (Prozesse, Netzwerk)
|
||||||
|
- GPU- und Benutzerinformationen
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔐 Safe Kiddo CLI (user_control_agent.py)
|
||||||
|
|
||||||
|
Ein Werkzeug zur lokalen Benutzerkontrolle, das u. a. folgende Funktionen bietet:
|
||||||
|
|
||||||
|
- **Benutzer sperren/entsperren**
|
||||||
|
- **Countdown mit Sound & Benachrichtigung**
|
||||||
|
- **Shutdown nach Ablauf**
|
||||||
|
|
||||||
|
### Beispiel:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo python3 user_control_agent.py testuser disable --countdown --sound --time 30 --debug
|
||||||
|
```
|
||||||
|
|
||||||
|
> Hinweis: `notify-send`, `paplay` o. ä. müssen installiert sein.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💠 Entwicklerhinweise
|
||||||
|
|
||||||
|
### Logging
|
||||||
|
|
||||||
|
Jedes Modul loggt separat:
|
||||||
|
|
||||||
|
- `~/hardware_info.log`
|
||||||
|
- `~/netinf.log`
|
||||||
|
- `~/process_monitor.log`
|
||||||
|
- `~/safe_kiddo_user_control.log`
|
||||||
|
|
||||||
|
### Debug-Modus
|
||||||
|
|
||||||
|
Alle CLI-Module und das Backend unterstützen `--debug`.
|
||||||
|
|
||||||
|
### Hinweis zu `hardware.py`
|
||||||
|
|
||||||
|
Die Datei `hardware.py` war eine frühe Version von `sysinfo.py` und wurde durch letztere vollständig ersetzt. Sie kann aus dem Projekt entfernt werden.
|
||||||
|
|
||||||
|
### Erweiterungsideen
|
||||||
|
|
||||||
|
- Authentifizierung (JWT, API-Key ✅)
|
||||||
|
- Langzeit-Logging (Prometheus, SQLite)
|
||||||
|
- Dockerisierung
|
||||||
|
- Web-Control für Safe Kiddo
|
||||||
|
- IP-basierte Netzwerkfilterung via `allow_origin_regex` ✅
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧪 Tests & Qualitätssicherung
|
||||||
|
|
||||||
|
Das Projekt nutzt [pytest](https://pytest.org) für automatisierte Tests.
|
||||||
|
|
||||||
|
### Struktur
|
||||||
|
|
||||||
|
```text
|
||||||
|
tests/
|
||||||
|
├── test_sysinfo.py # Tests für System- und Hardwaredaten
|
||||||
|
├── test_netinf.py # Tests für Netzwerkfunktionen
|
||||||
|
├── test_proginfo.py # Tests für Prozessinformationen
|
||||||
|
└── test_api.py # Tests für die FastAPI-Endpunkte
|
||||||
|
```
|
||||||
|
|
||||||
|
### Beispiel-Test
|
||||||
|
|
||||||
|
```python
|
||||||
|
from sysinfo import get_hardware_info
|
||||||
|
|
||||||
|
def test_sysinfo_contains_required_keys():
|
||||||
|
data = get_hardware_info()
|
||||||
|
assert "cpu" in data
|
||||||
|
assert "ram" in data
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ausführung
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pytest -v
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧑💻 Lizenz
|
||||||
|
|
||||||
|
Dieses Projekt ist derzeit privat. Für Open-Source-Freigabe bitte Lizenz ergänzen.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📞 Kontakt
|
||||||
|
|
||||||
|
Erstellt von \[Dein Name]
|
||||||
|
Kontakt: \[[email@example.com](mailto:email@example.com)]
|
||||||
BIN
agent_mvp.zip
Normal file
BIN
agent_mvp.zip
Normal file
Binary file not shown.
179
hardware.py
179
hardware.py
@ -1,179 +0,0 @@
|
|||||||
#sysinfo.py
|
|
||||||
#Version : 0.1.0
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import subprocess
|
|
||||||
import cpuinfo
|
|
||||||
import json
|
|
||||||
import psutil
|
|
||||||
import platform
|
|
||||||
import distro
|
|
||||||
import socket
|
|
||||||
import logging
|
|
||||||
import argparse
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
try:
|
|
||||||
import GPUtil
|
|
||||||
gpu_available = True
|
|
||||||
except ImportError:
|
|
||||||
gpu_available = False
|
|
||||||
|
|
||||||
# Farben für Debug-Logging
|
|
||||||
class LogColors:
|
|
||||||
INFO = "\033[94m"
|
|
||||||
DEBUG = "\033[92m"
|
|
||||||
WARNING = "\033[93m"
|
|
||||||
ERROR = "\033[91m"
|
|
||||||
RESET = "\033[0m"
|
|
||||||
|
|
||||||
# Logging einrichten
|
|
||||||
LOG_FILE = os.path.expanduser("~/hardware_info.log")
|
|
||||||
logging.basicConfig(
|
|
||||||
filename=LOG_FILE,
|
|
||||||
level=logging.INFO,
|
|
||||||
format="%(asctime)s - %(levelname)s - %(message)s"
|
|
||||||
)
|
|
||||||
|
|
||||||
def log_message(level, message):
|
|
||||||
"""Loggt Nachrichten mit Farben für die CLI, falls Debug aktiv ist."""
|
|
||||||
if level == "info":
|
|
||||||
logging.info(message)
|
|
||||||
if args.debug:
|
|
||||||
print(f"{LogColors.INFO}[INFO]{LogColors.RESET} {message}")
|
|
||||||
elif level == "debug":
|
|
||||||
logging.debug(message)
|
|
||||||
if args.debug:
|
|
||||||
print(f"{LogColors.DEBUG}[DEBUG]{LogColors.RESET} {message}")
|
|
||||||
elif level == "warning":
|
|
||||||
logging.warning(message)
|
|
||||||
if args.debug:
|
|
||||||
print(f"{LogColors.WARNING}[WARNING]{LogColors.RESET} {message}")
|
|
||||||
elif level == "error":
|
|
||||||
logging.error(message)
|
|
||||||
if args.debug:
|
|
||||||
print(f"{LogColors.ERROR}[ERROR]{LogColors.RESET} {message}")
|
|
||||||
|
|
||||||
def get_hardware_info():
|
|
||||||
"""Sammelt die relevanten Hardware- und Systeminformationen."""
|
|
||||||
hardware_info = {}
|
|
||||||
|
|
||||||
# Betriebssystem
|
|
||||||
log_message("info", "Sammle Betriebssystem-Daten...")
|
|
||||||
try:
|
|
||||||
os_info = {
|
|
||||||
"name": platform.system(),
|
|
||||||
"distribution": distro.name(pretty=True)
|
|
||||||
}
|
|
||||||
log_message("info", f"OS: {os_info['name']} - {os_info['distribution']}")
|
|
||||||
except Exception as e:
|
|
||||||
os_info = {}
|
|
||||||
log_message("warning", f"Konnte Betriebssystem-Daten nicht ermitteln: {str(e)}")
|
|
||||||
hardware_info["os"] = os_info
|
|
||||||
|
|
||||||
# CPU
|
|
||||||
log_message("info", "Sammle CPU-Daten...")
|
|
||||||
try:
|
|
||||||
cpu_info = {
|
|
||||||
"model": cpuinfo.get_cpu_info().get('brand_raw', 'Unbekannt'),
|
|
||||||
"cores": psutil.cpu_count(logical=False),
|
|
||||||
"threads": psutil.cpu_count(logical=True),
|
|
||||||
"usage": psutil.cpu_percent(interval=1)
|
|
||||||
}
|
|
||||||
log_message("info", f"CPU: {cpu_info['model']} - {cpu_info['cores']} Cores, {cpu_info['threads']} Threads - {cpu_info['usage']}% Auslastung")
|
|
||||||
except Exception as e:
|
|
||||||
cpu_info = {}
|
|
||||||
log_message("warning", f"Konnte CPU-Daten nicht ermitteln: {str(e)}")
|
|
||||||
hardware_info["cpu"] = cpu_info
|
|
||||||
|
|
||||||
# RAM
|
|
||||||
log_message("info", "Sammle RAM-Daten...")
|
|
||||||
try:
|
|
||||||
ram_info = {
|
|
||||||
"total": round(psutil.virtual_memory().total / (1024**3), 2),
|
|
||||||
"used": round(psutil.virtual_memory().used / (1024**3), 2),
|
|
||||||
"available": round(psutil.virtual_memory().available / (1024**3), 2)
|
|
||||||
}
|
|
||||||
log_message("info", f"RAM: {ram_info['total']}GB gesamt, {ram_info['used']}GB genutzt, {ram_info['available']}GB verfügbar")
|
|
||||||
except Exception as e:
|
|
||||||
ram_info = {}
|
|
||||||
log_message("warning", f"Konnte RAM-Daten nicht ermitteln: {str(e)}")
|
|
||||||
hardware_info["ram"] = ram_info
|
|
||||||
|
|
||||||
# Festplatte
|
|
||||||
log_message("info", "Sammle Festplattendaten...")
|
|
||||||
try:
|
|
||||||
disk_info = {
|
|
||||||
"total": round(psutil.disk_usage('/').total / (1024**3), 2),
|
|
||||||
"used": round(psutil.disk_usage('/').used / (1024**3), 2),
|
|
||||||
"free": round(psutil.disk_usage('/').free / (1024**3), 2)
|
|
||||||
}
|
|
||||||
log_message("info", f"Disk: {disk_info['total']}GB gesamt, {disk_info['used']}GB genutzt, {disk_info['free']}GB frei")
|
|
||||||
except Exception as e:
|
|
||||||
disk_info = {}
|
|
||||||
log_message("warning", f"Konnte Festplatten-Daten nicht ermitteln: {str(e)}")
|
|
||||||
hardware_info["disk"] = disk_info
|
|
||||||
|
|
||||||
log_message("info", "Sammle Netzwerkinformationen...")
|
|
||||||
try:
|
|
||||||
network_info = {
|
|
||||||
"hostname": socket.gethostname(),
|
|
||||||
"ip_address": socket.gethostbyname(socket.gethostname())
|
|
||||||
}
|
|
||||||
log_message("info", f"Netzwerk: Hostname {network_info['hostname']}, IP {network_info['ip_address']}")
|
|
||||||
except Exception as e:
|
|
||||||
network_info = {}
|
|
||||||
log_message("warning", f"Konnte Netzwerkinformationen nicht ermitteln: {str(e)}")
|
|
||||||
hardware_info["network"] = network_info
|
|
||||||
|
|
||||||
log_message("info", "Sammle Benutzerinformationen...")
|
|
||||||
try:
|
|
||||||
user_info = {
|
|
||||||
"logged_in": [user.name for user in psutil.users()],
|
|
||||||
"active_user": os.getlogin()
|
|
||||||
}
|
|
||||||
log_message("info", f"Benutzer: {', '.join(user_info['logged_in'])}, Aktiver User: {user_info['active_user']}")
|
|
||||||
except Exception as e:
|
|
||||||
user_info = {}
|
|
||||||
log_message("warning", f"Konnte Benutzerinformationen nicht ermitteln: {str(e)}")
|
|
||||||
hardware_info["users"] = user_info
|
|
||||||
|
|
||||||
log_message("info", "Sammle dedizierte GPU-Daten...")
|
|
||||||
gpu_info = []
|
|
||||||
try:
|
|
||||||
if gpu_available:
|
|
||||||
gpus = GPUtil.getGPUs()
|
|
||||||
for gpu in gpus:
|
|
||||||
gpu_info.append({
|
|
||||||
"name": gpu.name,
|
|
||||||
"memory_total": f"{gpu.memoryTotal}MB",
|
|
||||||
"memory_used": f"{gpu.memoryUsed}MB",
|
|
||||||
"memory_free": f"{gpu.memoryFree}MB",
|
|
||||||
"load": f"{gpu.load * 100:.1f}%"
|
|
||||||
})
|
|
||||||
log_message("info", f"Gefundene GPUs: {len(gpus)}")
|
|
||||||
else:
|
|
||||||
log_message("warning", "GPUtil nicht installiert oder keine dedizierte GPU vorhanden.")
|
|
||||||
except Exception as e:
|
|
||||||
log_message("warning", f"Konnte GPU-Daten nicht ermitteln: {str(e)}")
|
|
||||||
hardware_info["gpu"] = gpu_info
|
|
||||||
|
|
||||||
log_message("info", "Hardware-Informationen erfolgreich erfasst.")
|
|
||||||
return hardware_info
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
parser = argparse.ArgumentParser(description="Ermittelt Hardware- und Systeminformationen.")
|
|
||||||
parser.add_argument("--debug", action="store_true", help="Aktiviert Debug-Logging auf der CLI.")
|
|
||||||
parser.add_argument("--json", type=str, help="Speichert die Ausgabe in einer JSON-Datei.")
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
# Hardware-Informationen abrufen
|
|
||||||
hardware_info = get_hardware_info()
|
|
||||||
|
|
||||||
if args.json:
|
|
||||||
try:
|
|
||||||
with open(args.json, "w") as json_file:
|
|
||||||
json.dump(hardware_info, json_file, indent=4)
|
|
||||||
log_message("info", f"Hardware-Infos in JSON gespeichert: {args.json}")
|
|
||||||
except Exception as e:
|
|
||||||
log_message("error", f"Fehler beim Speichern der JSON-Datei: {str(e)}")
|
|
||||||
@ -1,42 +1,8 @@
|
|||||||
annotated-types==0.7.0
|
|
||||||
anyio==4.9.0
|
|
||||||
certifi==2025.6.15
|
|
||||||
click==8.2.1
|
|
||||||
dnspython==2.7.0
|
|
||||||
email_validator==2.2.0
|
|
||||||
exceptiongroup==1.3.0
|
|
||||||
fastapi==0.115.13
|
fastapi==0.115.13
|
||||||
fastapi-cli==0.0.7
|
|
||||||
h11==0.16.0
|
|
||||||
httpcore==1.0.9
|
|
||||||
httptools==0.6.4
|
|
||||||
httpx==0.28.1
|
|
||||||
idna==3.10
|
|
||||||
itsdangerous==2.2.0
|
|
||||||
Jinja2==3.1.6
|
|
||||||
markdown-it-py==3.0.0
|
|
||||||
MarkupSafe==3.0.2
|
|
||||||
mdurl==0.1.2
|
|
||||||
orjson==3.10.18
|
|
||||||
psutil==7.0.0
|
|
||||||
pydantic==2.11.7
|
|
||||||
pydantic-extra-types==2.10.5
|
|
||||||
pydantic-settings==2.9.1
|
|
||||||
pydantic_core==2.33.2
|
|
||||||
Pygments==2.19.1
|
|
||||||
python-dotenv==1.1.0
|
|
||||||
python-multipart==0.0.20
|
|
||||||
PyYAML==6.0.2
|
|
||||||
rich==14.0.0
|
|
||||||
rich-toolkit==0.14.7
|
|
||||||
shellingham==1.5.4
|
|
||||||
sniffio==1.3.1
|
|
||||||
starlette==0.46.2
|
|
||||||
typer==0.16.0
|
|
||||||
typing-inspection==0.4.1
|
|
||||||
typing_extensions==4.14.0
|
|
||||||
ujson==5.10.0
|
|
||||||
uvicorn==0.34.3
|
uvicorn==0.34.3
|
||||||
uvloop==0.21.0
|
psutil==7.0.0
|
||||||
watchfiles==1.1.0
|
httpx==0.28.1
|
||||||
websockets==15.0.1
|
pytest>=7.0.0
|
||||||
|
GPUtil # Für GPU-Infos
|
||||||
|
cpuinfo # Für exakte CPU-Namen
|
||||||
|
distro # Für Distributionserkennung
|
||||||
|
|||||||
19
tests/test_api.py
Normal file
19
tests/test_api.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
from fastapi.testclient import TestClient
|
||||||
|
from wilcon import app
|
||||||
|
|
||||||
|
client = TestClient(app)
|
||||||
|
|
||||||
|
def test_sysinfo_endpoint():
|
||||||
|
response = client.get("/sysinfo")
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert "cpu" in response.json()
|
||||||
|
|
||||||
|
def test_netinfo_endpoint():
|
||||||
|
response = client.get("/netinfo")
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert "ip_address" in response.json()
|
||||||
|
|
||||||
|
def test_procinfo_endpoint():
|
||||||
|
response = client.get("/procinfo")
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert isinstance(response.json(), list)
|
||||||
8
tests/test_netinf.py
Normal file
8
tests/test_netinf.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
from netinf import get_network_info
|
||||||
|
|
||||||
|
def test_network_info_contains_expected_keys():
|
||||||
|
data = get_network_info(debug=False)
|
||||||
|
assert isinstance(data, dict)
|
||||||
|
|
||||||
|
for key in ["hostname", "ip_address", "interfaces", "gateway", "dns_servers", "connections"]:
|
||||||
|
assert key in data
|
||||||
9
tests/test_proginfo.py
Normal file
9
tests/test_proginfo.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
from proginfo import get_process_info
|
||||||
|
|
||||||
|
def test_process_info_returns_list():
|
||||||
|
data = get_process_info()
|
||||||
|
assert isinstance(data, list)
|
||||||
|
if data: # Teste nur, wenn Prozesse vorhanden sind
|
||||||
|
proc = data[0]
|
||||||
|
for key in ["pid", "name", "user", "cpu", "memory", "status", "start_time", "runtime_seconds"]:
|
||||||
|
assert key in proc
|
||||||
15
tests/test_sysinfo.py
Normal file
15
tests/test_sysinfo.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
from sysinfo import get_hardware_info
|
||||||
|
|
||||||
|
def test_sysinfo_contains_required_keys():
|
||||||
|
data = get_hardware_info()
|
||||||
|
assert isinstance(data, dict)
|
||||||
|
|
||||||
|
for key in ["cpu", "ram", "disk", "os", "network_basic", "user_accounts", "gpu"]:
|
||||||
|
assert key in data
|
||||||
|
|
||||||
|
def test_cpu_info_structure():
|
||||||
|
cpu = get_hardware_info()["cpu"]
|
||||||
|
assert "model" in cpu
|
||||||
|
assert "cores" in cpu
|
||||||
|
assert "threads" in cpu
|
||||||
|
assert "usage" in cpu
|
||||||
48
wilcon.py
48
wilcon.py
@ -1,7 +1,8 @@
|
|||||||
# wilcon.py
|
# wilcon.py
|
||||||
# version 0.3.1 (aktualisiert)
|
# Version 0.3.4 – mit API-Key-Schutz + CORS für 192.168.13.0/24
|
||||||
|
|
||||||
from fastapi import FastAPI
|
import os
|
||||||
|
from fastapi import FastAPI, Header, HTTPException, Depends
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
from sysinfo import get_hardware_info, set_debug_mode as set_sysinfo_debug_mode
|
from sysinfo import get_hardware_info, set_debug_mode as set_sysinfo_debug_mode
|
||||||
from netinf import get_network_info, set_debug_mode as set_netinf_debug_mode
|
from netinf import get_network_info, set_debug_mode as set_netinf_debug_mode
|
||||||
@ -10,46 +11,39 @@ from proginfo import get_process_info, set_debug_mode as set_proginfo_debug_mode
|
|||||||
app = FastAPI(
|
app = FastAPI(
|
||||||
title="Wilcon Client Agent",
|
title="Wilcon Client Agent",
|
||||||
description="API für Client-System-, Netzwerk- und Prozessinformationen.",
|
description="API für Client-System-, Netzwerk- und Prozessinformationen.",
|
||||||
version="0.3.1"
|
version="0.3.4"
|
||||||
)
|
)
|
||||||
|
|
||||||
# CORS-Konfiguration für wilcon.py (auf Port 8080)
|
# --- API-Key-Schutz ---
|
||||||
origins = [
|
API_KEY = os.getenv("WILCON_API_KEY", "test123") # In .env oder als Umgebungsvariable setzen
|
||||||
"http://localhost:5500", # Für Live Server in VS Code
|
|
||||||
"http://127.0.0.1:5500", # Für Live Server in VS Code
|
|
||||||
"http://localhost:8080", # Wenn du später das Frontend direkt über Uvicorn ausliefern willst
|
|
||||||
"http://127.0.0.1:8080",
|
|
||||||
# Füge hier die IP-Adresse oder den Hostnamen deines Client-Rechners hinzu,
|
|
||||||
# wenn du von einem anderen Gerät im Netzwerk zugreifen möchtest, z.B. "http://192.168.1.100:5500"
|
|
||||||
]
|
|
||||||
|
|
||||||
|
def verify_api_key(x_api_key: str = Header(...)):
|
||||||
|
if x_api_key != API_KEY:
|
||||||
|
raise HTTPException(status_code=403, detail="Zugriff verweigert")
|
||||||
|
|
||||||
|
# --- CORS-Konfiguration für gesamtes 192.168.13.0/24-Netzwerk ---
|
||||||
app.add_middleware(
|
app.add_middleware(
|
||||||
CORSMiddleware,
|
CORSMiddleware,
|
||||||
allow_origins=origins,
|
allow_origin_regex=r"http://192\.168\.13\.\d{1,3}(:\d+)?",
|
||||||
allow_credentials=True,
|
allow_credentials=True,
|
||||||
allow_methods=["*"],
|
allow_methods=["*"],
|
||||||
allow_headers=["*"],
|
allow_headers=["*"],
|
||||||
)
|
)
|
||||||
|
|
||||||
# Optional: Setze den Debug-Modus für die importierten Module.
|
# --- Endpunkte ---
|
||||||
# Dies wird die farbige CLI-Ausgabe in dem Terminal aktivieren, in dem uvicorn läuft.
|
|
||||||
# Nützlich für die Entwicklung.
|
|
||||||
# set_sysinfo_debug_mode(True)
|
|
||||||
# set_netinf_debug_mode(True)
|
|
||||||
# set_proginfo_debug_mode(True)
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/sysinfo")
|
@app.get("/sysinfo")
|
||||||
async def get_sysinfo_endpoint(): # Umbenannt, um Konflikt mit importierter Funktion zu vermeiden
|
async def get_sysinfo_endpoint(_: str = Depends(verify_api_key)):
|
||||||
"""API-Endpunkt für Hardware- und Systeminformationen"""
|
|
||||||
return get_hardware_info()
|
return get_hardware_info()
|
||||||
|
|
||||||
@app.get("/netinfo")
|
@app.get("/netinfo")
|
||||||
async def get_netinfo_endpoint(): # Umbenannt
|
async def get_netinfo_endpoint(_: str = Depends(verify_api_key)):
|
||||||
"""API-Endpunkt für Netzwerkinformationen"""
|
|
||||||
return get_network_info()
|
return get_network_info()
|
||||||
|
|
||||||
@app.get("/procinfo")
|
@app.get("/procinfo")
|
||||||
async def get_procinfo_endpoint(): # Umbenannt
|
async def get_procinfo_endpoint(_: str = Depends(verify_api_key)):
|
||||||
"""API-Endpunkt für Prozessinformationen"""
|
|
||||||
return get_process_info()
|
return get_process_info()
|
||||||
|
|
||||||
|
# Optional Debug-Modus einschalten
|
||||||
|
# set_sysinfo_debug_mode(True)
|
||||||
|
# set_netinf_debug_mode(True)
|
||||||
|
# set_proginfo_debug_mode(True)
|
||||||
|
|||||||
Reference in New Issue
Block a user