From a7ca1214f3074fbe4d1a53d2ebf684184d7bb719 Mon Sep 17 00:00:00 2001 From: triggermeelmo Date: Wed, 19 Nov 2025 14:21:22 +0100 Subject: [PATCH] Rootless User konfigurierbar + Doku --- Dockerfile | 8 +- Planung/TODO.md | 343 ++++++++++++++++++++++++++ README.md | 189 ++++---------- Watcher/Controllers/UserController.cs | 6 +- docker-compose.yaml | 20 +- 5 files changed, 408 insertions(+), 158 deletions(-) create mode 100644 Planung/TODO.md diff --git a/Dockerfile b/Dockerfile index 1cc1e0f..593615d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,11 +18,15 @@ FROM mcr.microsoft.com/dotnet/aspnet:8.0 # Build-Argument für Version (wird zur Build-Zeit vom CI/CD gesetzt) ARG VERSION=latest +# Build-Argumente für UID/GID (Standard: 1000) +ARG USER_UID=1000 +ARG USER_GID=1000 + # Install curl for health checks RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/* -# Create non-root user -RUN groupadd -r watcher -g 1000 && useradd -r -g watcher -u 1000 watcher +# Create non-root user with configurable UID/GID +RUN groupadd -r watcher -g ${USER_GID} && useradd -r -g watcher -u ${USER_UID} watcher WORKDIR /app COPY --from=build /app/publish . diff --git a/Planung/TODO.md b/Planung/TODO.md new file mode 100644 index 0000000..d20a282 --- /dev/null +++ b/Planung/TODO.md @@ -0,0 +1,343 @@ +# Watcher - Probleme und TODO-Liste + +**Stand:** 2025-11-19 +**Analyse:** Automatische Code-Review + +--- + +## 🔴 KRITISCHE PROBLEME (Sofort beheben!) + +### 1. Schwerwiegender Bug: Passwort überschreibt Username +- **Datei:** `Watcher/Controllers/UserController.cs:111` +- **Problem:** `user.Username = BCrypt.Net.BCrypt.HashPassword(model.NewPassword);` +- **Auswirkung:** Beim Passwort-Ändern wird der Username zerstört, Account wird unbrauchbar +- **Fix:** Muss `user.Password = ...` sein +- **Status:** ❌ Offen +- **Priorität:** KRITISCH + +### 2. Path Traversal Schwachstelle +- **Datei:** `Watcher/Controllers/DownloadController.cs:24-35` +- **Problem:** + - Keine Validierung gegen `../` Attacken + - Leerer String als Extension erlaubt + - Kommentar im Code: "TODO: aktuelles "" für Binaries ist das absolute Gegenteil von sicher" +- **Auswirkung:** Angreifer könnten beliebige Dateien herunterladen +- **Status:** ❌ Offen +- **Priorität:** KRITISCH + +### 3. Ungeschützte Monitoring-Endpoints +- **Dateien:** + - `Watcher/Controllers/MonitoringController.cs:112,155,173,237,365` + - `Watcher/Controllers/HeartbeatController.cs:31` + - `Watcher/Controllers/ApiController.cs:26` +- **Problem:** KEINE Authentifizierung +- **Auswirkung:** Jeder kann: + - Fake Server registrieren + - Monitoring-Daten manipulieren + - Alle Server-Informationen abrufen + - Heartbeats senden +- **Fix:** API-Key oder Token-basierte Authentifizierung implementieren +- **Status:** ❌ Offen +- **Priorität:** KRITISCH + +### 4. Command Injection +- **Datei:** `Watcher/Controllers/DatabaseController.cs:176-184` +- **Problem:** Unvalidierter `fileName` in `sqlite3` Prozess-Aufruf +- **Auswirkung:** Potenzielle Command Injection beim Database Restore +- **Fix:** Input-Validierung und Sanitization +- **Status:** ❌ Offen +- **Priorität:** KRITISCH + +--- + +## 🟠 HOHE PRIORITÄT + +### 5. HttpClient Resource Leak +- **Datei:** `Watcher/Services/UpdateCheckService.cs:24` +- **Problem:** `new HttpClient()` im Singleton-Konstruktor +- **Auswirkung:** Socket Exhaustion bei vielen Requests möglich +- **Fix:** `IHttpClientFactory` verwenden +- **Status:** ❌ Offen +- **Priorität:** HOCH + +### 6. Default Credentials in Production +- **Datei:** `Watcher/Program.cs:127-137` +- **Problem:** Standard-User "admin/changeme" wird immer erstellt +- **Auswirkung:** Bekannte Credentials, Sicherheitsrisiko +- **Fix:** + - Beim ersten Start Passwort abfragen + - Oder aus Environment Variable lesen + - Oder zufälliges Passwort generieren und loggen +- **Status:** ❌ Offen +- **Priorität:** HOCH + +### 7. Race Conditions in Singleton Stores +- **Dateien:** + - `Watcher/Services/DashboardStore.cs` + - `Watcher/Services/UpdateCheckStore.cs` +- **Problem:** Properties werden ohne Thread-Synchronisation von Background Services geschrieben und von Controllern gelesen +- **Fix:** Lock-Mechanismus oder Concurrent Collections verwenden +- **Status:** ❌ Offen +- **Priorität:** HOCH + +### 8. N+1 Query Problem +- **Datei:** `Watcher/Controllers/ServerController.cs:206-212` +- **Problem:** `SaveChangesAsync()` in foreach-Loop +- **Code:** + ```csharp + foreach (var server in servers) + { + server.IsOnline = (DateTime.UtcNow - server.LastSeen).TotalSeconds <= 120; + await _context.SaveChangesAsync(); // In Loop! + } + ``` +- **Auswirkung:** Ineffizient, potenzielle Database Locks +- **Fix:** Alle Änderungen sammeln, einmal am Ende speichern +- **Status:** ❌ Offen +- **Priorität:** HOCH + +### 9. Synchrone DB-Abfragen in async Methoden +- **Datei:** `Watcher/Controllers/UserController.cs:28,53,73,101` +- **Problem:** `FirstOrDefault()` statt `FirstOrDefaultAsync()` +- **Auswirkung:** Thread-Pool wird blockiert, reduziert Skalierbarkeit +- **Fix:** Async-Varianten verwenden +- **Status:** ❌ Offen +- **Priorität:** HOCH + +### 10. Ineffiziente Database Queries +- **Datei:** `Watcher/Controllers/HomeController.cs:77-78` +- **Problem:** `ToList()` lädt ALLE Daten vor Filterung +- **Code:** + ```csharp + var servers = _context.Servers.ToList(); + var containers = _context.Containers.ToList(); + ``` +- **Auswirkung:** Memory-Probleme bei vielen Datensätzen +- **Fix:** Filter in LINQ-Query vor `ToList()` +- **Status:** ❌ Offen +- **Priorität:** HOCH + +### 11. Database Connections nicht immer mit using +- **Datei:** `Watcher/Services/DatabaseCheck.cs:33-59` +- **Problem:** Connection wird manuell geschlossen, bei Exception könnte sie offen bleiben +- **Fix:** `using` Statement verwenden +- **Status:** ❌ Offen +- **Priorität:** HOCH + +--- + +## 🟡 MITTLERE PRIORITÄT + +### Code-Qualität + +#### 12. Generische catch-Blöcke ohne Exception-Logging +- **Dateien:** + - `Watcher/Services/NetworkCheck.cs:47` + - `Watcher/Controllers/MonitoringController.cs:222-228` +- **Problem:** Leere catch-Blöcke verschlucken alle Exceptions +- **Fix:** Spezifischen Exception-Typ verwenden und Exception loggen +- **Status:** ❌ Offen + +#### 13. Code-Duplikation in UserController +- **Datei:** `Watcher/Controllers/UserController.cs:64-90 und 93-119` +- **Problem:** Zwei fast identische Methoden `Edit()` und `UserSettings()` +- **Fix:** Gemeinsame Logik extrahieren +- **Status:** ❌ Offen + +#### 14. Sehr große Controller-Methode +- **Datei:** `Watcher/Controllers/MonitoringController.cs:237-362` +- **Problem:** ServiceDetection mit 125 Zeilen, viele Verantwortlichkeiten +- **Fix:** In kleinere Methoden aufteilen, Service-Klasse extrahieren +- **Status:** ❌ Offen + +#### 15. Magic Numbers +- **Dateien:** + - `Watcher/Controllers/ServerController.cs:210` - `120` Sekunden hardcodiert + - `Watcher/Services/NetworkCheck.cs:35` - `"8.8.8.8"` hardcodiert + - `Watcher/Services/NetworkCheck.cs:40` - `3000` ms Timeout hardcodiert +- **Fix:** Als Konstanten oder Konfiguration auslagern +- **Status:** ❌ Offen + +#### 16. Duplizierte Endpoint-Logik +- **Datei:** `Watcher/Controllers/MonitoringController.cs:421-481` +- **Problem:** GetCpuUsageData, GetRamUsageData, GetGpuUsageData sind nahezu identisch +- **Fix:** Generische Methode mit Parameter +- **Status:** ❌ Offen + +#### 17. Synchrone I/O in async Methoden +- **Datei:** `Watcher/Controllers/DatabaseController.cs:46,69,137,149,151,163,174` +- **Problem:** `File.ReadAllBytes()`, `File.Exists()` etc. sind synchron +- **Fix:** Async File I/O verwenden +- **Status:** ❌ Offen + +### Sicherheit + +#### 18. Kein Brute-Force Schutz +- **Datei:** `Watcher/Controllers/AuthController.cs:36-72` +- **Problem:** Login hat keine Rate-Limiting, Account Lockout oder CAPTCHA +- **Fix:** Rate-Limiting Middleware oder Account Lockout implementieren +- **Status:** ❌ Offen + +#### 19. SQL Injection Potential +- **Datei:** `Watcher/Controllers/DatabaseController.cs:91` +- **Problem:** String-Interpolation für SQL-Query: `$"SELECT * FROM {tableName}"` +- **Hinweis:** tableName kommt aus sqlite_master, aber schlechte Praxis +- **Fix:** Parametrisierte Queries verwenden +- **Status:** ❌ Offen + +#### 20. Fehlende IP-Adress-Validierung +- **Datei:** `Watcher/Controllers/MonitoringController.cs:129,159,262` +- **Problem:** IP-Adressen werden nicht validiert +- **Fix:** Regex oder IPAddress.TryParse verwenden +- **Status:** ❌ Offen + +### Architektur + +#### 21. Kein Repository Pattern +- **Problem:** DbContext direkt in allen Controllern +- **Auswirkung:** Schwer testbar, keine Abstraktionsschicht +- **Fix:** Repository Pattern oder CQRS implementieren +- **Status:** ❌ Offen + +#### 22. Hardcodierte Connection Strings +- **Dateien:** + - `Watcher/Services/DatabaseCheck.cs:33` + - `Watcher/Controllers/SystemController.cs:37` +- **Problem:** `"Data Source=./persistence/watcher.db"` hardcodiert +- **Fix:** Aus Configuration/appsettings.json lesen +- **Status:** ❌ Offen + +#### 23. Keine Dependency Inversion +- **Problem:** Keine Interfaces für Repositories, direkte DbContext-Abhängigkeit +- **Fix:** Interface-basierte Dependency Injection +- **Status:** ❌ Offen + +### Performanz + +#### 24. Fehlende Database Indizes +- **Problem:** Keine expliziten Indizes für häufig abgefragte Felder +- **Beispiele:** Server.IPAddress, Container.ContainerId +- **Fix:** Indizes in DbContext konfigurieren +- **Status:** ❌ Offen + +#### 25. Keine Caching-Strategie +- **Problem:** Metrics werden jedes Mal neu aus DB geladen +- **Fix:** In-Memory Cache für Current Metrics implementieren +- **Status:** ❌ Offen + +#### 26. Mehrfache SaveChanges in Loop +- **Datei:** `Watcher/Controllers/MonitoringController.cs:327,349,359` +- **Problem:** SaveChanges wird in Loop aufgerufen +- **Fix:** Batch-Updates am Ende +- **Status:** ❌ Offen + +--- + +## 🔵 NIEDRIGE PRIORITÄT / WARTBARKEIT + +### 27. Keine Unit Tests +- **Problem:** Keine Test-Dateien in der Codebase +- **Auswirkung:** Keine automatisierte Qualitätssicherung +- **Fix:** xUnit/NUnit Test-Suite aufbauen +- **Status:** ❌ Offen + +### 28. Fehlende Integration Tests +- **Problem:** Kritische Flows wie Login, Monitoring-Daten-Empfang sind ungetestet +- **Fix:** Integration Tests schreiben +- **Status:** ❌ Offen + +### 29. Unvollständige TODOs im Code +- **Dateien:** + - `MonitoringController.cs:287` - "TODO entfernen wenn fertig getestet" + - `MonitoringController.cs:352` - "//Todo" (Metrics für Container entfernen) + - `MonitoringController.cs:525` - "//TODO" (CalculateMegabit korrekt implementieren) + - `DownloadController.cs:28` - "TODO: aktuelles "" für Binaries ist das absolute Gegenteil von sicher" + - `DatabaseCheck.cs:61` - "// TODO: LogEvent erstellen" + - `SystemMangement.cs:20` - "// Todo: Umstellen auf einmal alle 24h" +- **Fix:** TODOs abarbeiten oder entfernen +- **Status:** ❌ Offen + +### 30. Fehlende XML-Dokumentation +- **Problem:** Keine `///` Kommentare für öffentliche APIs +- **Fix:** XML-Kommentare für Controllers und Services hinzufügen +- **Status:** ❌ Offen + +### 31. Console.WriteLine in Production +- **Dateien:** + - `Program.cs:121,125,137,141` + - `MonitoringController.cs:288-293` +- **Problem:** Console.WriteLine statt strukturiertes Logging +- **Fix:** ILogger verwenden +- **Status:** ❌ Offen + +### 32. Inkonsistente Namenskonventionen +- **Datei:** `MonitoringController.cs:53-81` +- **Problem:** MetricDto Properties in UPPERCASE (CPU_Load, RAM_Size) +- **Fix:** PascalCase verwenden (CpuLoad, RamSize) +- **Status:** ❌ Offen + +--- + +## 📊 STATISTIK + +- **Kritische Probleme:** 4 +- **Hohe Priorität:** 7 +- **Mittlere Priorität:** 18 +- **Niedrige Priorität:** 6 +- **Gesamt:** 35 Probleme + +--- + +## 🎯 EMPFOHLENE REIHENFOLGE + +### Sprint 1 - Kritische Sicherheit (Sofort) +1. Bug in UserController.cs Zeile 111 beheben +2. Authentifizierung für Monitoring-Endpoints +3. Path Traversal Validierung in DownloadController +4. Command Injection in DatabaseController beheben + +### Sprint 2 - Stabilität & Performance (Woche 1-2) +5. HttpClientFactory implementieren +6. N+1 Query Probleme beheben +7. Async/Await korrekt verwenden +8. Database Connection Management + +### Sprint 3 - Sicherheit & Konfiguration (Woche 3-4) +9. Default Credentials entfernen/anpassbar machen +10. Input-Validierung verbessern +11. Brute-Force Protection +12. Thread-Safety in Stores + +### Sprint 4 - Architektur (Monat 2) +13. Repository Pattern einführen +14. Code-Duplikation eliminieren +15. Große Methoden refactoren +16. Magic Numbers entfernen + +### Sprint 5 - Qualität (Monat 3) +17. Test-Suite aufbauen (Unit + Integration) +18. Statische Code-Analyse einrichten +19. TODOs abarbeiten +20. Dokumentation verbessern + +--- + +## 🔧 TOOLS & HILFSMITTEL + +### Empfohlene Tools +- **Statische Analyse:** SonarQube, Roslyn Analyzers +- **Security Scanning:** OWASP Dependency Check, Snyk +- **Testing:** xUnit, Moq, FluentAssertions +- **Code Coverage:** Coverlet, ReportGenerator +- **Performance:** BenchmarkDotNet, MiniProfiler + +### Code-Qualität Metriken +- **Zyklomatische Komplexität:** < 10 pro Methode +- **Zeilen pro Methode:** < 50 +- **Test Coverage:** > 80% +- **Code Duplication:** < 5% + +--- + +**Letzte Aktualisierung:** 2025-11-19 +**Erstellt durch:** Automatische Code-Analyse \ No newline at end of file diff --git a/README.md b/README.md index 6051e31..1efee19 100644 --- a/README.md +++ b/README.md @@ -12,66 +12,16 @@ Die Software besteht aus zwei Hauptkomponenten: - **Host Agent**: Sammelt Hardware-Metriken (CPU, GPU, RAM, Festplatte, Netzwerk) von den überwachten Servern -- **Zentrale Monitoring-Software**: Web-basiertes Dashboard zur Visualisierung und Verwaltung der gesammelten Daten mit konfigurierbaren Alarmschwellen +- **Zentrale Monitoring-Software**: Web-basiertes Dashboard zur Visualisierung und Verwaltung der gesammelten Daten -## ✨ Hauptfunktionen - -### Server-Management -- Hinzufügen, bearbeiten und löschen von Servern -- Hardware-Spezifikationen erfassen (CPU, GPU, RAM, Festplatte) -- Server-Verifikationssystem -- Online/Offline-Status-Tracking via Heartbeat -- Konfigurierbare Alarmschwellen pro Server - -### Monitoring & Metriken -- Echtzeit-Metrikerfassung: CPU, GPU, RAM, Festplatte, Netzwerk -- Automatische Datenaufbewahrung mit konfigurierbarer Retention (Standard: 30 Tage) -- Historische Datenspeicherung mit Zeitstempel -- REST API-Endpunkte für Metrik-Submission -- Swagger/OpenAPI-Dokumentation unter `/api/v1/swagger` - -### Container-Management -- Docker-Container-Tracking pro Server -- Container-Image-Registry -- Container-Status-Überwachung -- Service Discovery für Docker-Container - -### Sicherheit & Authentifizierung -- Lokale Benutzerauthentifizierung mit BCrypt-Hashing -- Cookie-basierte Session-Verwaltung -- Rollenbasierte Zugriffskontrolle -- Standard-Admin-Benutzer (Username: `admin`, Passwort: `changeme` - bitte ändern!) - -### Logging & Diagnostik -- Strukturiertes Logging mit Serilog -- Tägliche Log-Dateien: `logs/watcher-.log` -- Health-Check-Endpunkte -- Datenbank-Export-Funktionalität (SQL-Dumps) - -## 🛠️ Technologie-Stack - -**Backend:** -- ASP.NET Core 8.0 (C#) -- Entity Framework Core 8.0 -- Serilog 9.0 für Logging - -**Datenbank:** -- SQLite (Standard, dateibasiert) -- MySQL-Unterstützung (konfigurierbar) - -**Frontend:** -- Razor Views (CSHTML) -- Bootstrap / CSS -- jQuery, jQuery Validation - -**API & Dokumentation:** -- Swagger/Swashbuckle 9.0.6 -- REST API - -**Container & Deployment:** -- Docker (Multi-Arch: AMD64, ARM64) -- Docker Compose -- Gitea CI/CD +### Hauptfunktionen +- Echtzeit-Hardware-Monitoring (CPU, GPU, RAM, Festplatte, Netzwerk) +- Docker-Container-Überwachung mit Service Discovery +- Web-basiertes Dashboard mit historischen Daten +- Konfigurierbare Alarmschwellen +- REST API mit Swagger-Dokumentation +- Automatische Datenaufbewahrung (konfigurierbar) +- Rootless Container-Betrieb für erhöhte Sicherheit ## 🚀 Installation & Start @@ -81,111 +31,70 @@ Die Software besteht aus zwei Hauptkomponenten: ### Schnellstart -1. **docker-compose.yaml erstellen** oder die bereitgestellte verwenden: +1. **Repository klonen oder docker-compose.yaml herunterladen** + ```bash + git clone https://git.triggermeelmo.com/Watcher/watcher.git + cd watcher + ``` -```yaml -services: - watcher: - image: git.triggermeelmo.com/watcher/watcher-server:latest - container_name: watcher - deploy: - resources: - limits: - memory: 200M - restart: unless-stopped - environment: - - WATCHER_VERSION=latest - - UPDATE_CHECK_ENABLED=true - - UPDATE_CHECK_INTERVAL_HOURS=24 - - METRIC_RETENTION_DAYS=30 - - METRIC_CLEANUP_ENABLED=true - - METRIC_CLEANUP_INTERVAL_HOURS=24 - ports: - - "5000:5000" - volumes: - - ./watcher-volumes/data:/app/persistence - - ./watcher-volumes/dumps:/app/wwwroot/downloads/sqlite - - ./watcher-volumes/logs:/app/logs -``` +2. **Umgebungsvariablen konfigurieren (optional)** + ```bash + # .env Datei erstellen + cp .env.example .env -2. **Container starten:** + # Eigene UID/GID eintragen (für korrekte Dateiberechtigungen) + echo "USER_UID=$(id -u)" >> .env + echo "USER_GID=$(id -g)" >> .env + ``` + +3. **Verzeichnisse mit korrekten Rechten erstellen** + ```bash + mkdir -p data/db data/dumps data/logs + chown -R $(id -u):$(id -g) data/ + ``` + +4. **Container starten** ```bash docker compose up -d ``` -3. **Dashboard aufrufen:** +5. **Dashboard aufrufen** ``` http://localhost:5000 ``` -4. **Standardanmeldung:** +6. **Standardanmeldung** - Benutzername: `admin` - Passwort: `changeme` - - ⚠️ **Wichtig:** Bitte Passwort nach dem ersten Login ändern! + - ⚠️ **Wichtig:** Passwort nach dem ersten Login ändern! -## ⚙️ Konfiguration +### Konfiguration -### Umgebungsvariablen +#### Wichtige Umgebungsvariablen | Variable | Beschreibung | Standard | |----------|--------------|----------| -| `WATCHER_VERSION` | Anwendungsversion | `latest` | -| `UPDATE_CHECK_ENABLED` | Update-Prüfung aktivieren | `true` | -| `UPDATE_CHECK_INTERVAL_HOURS` | Update-Prüfungs-Intervall | `24` | +| `USER_UID` | User-ID für Container (Dateiberechtigungen) | `1000` | +| `USER_GID` | Gruppen-ID für Container | `1000` | +| `IMAGE_VERSION` | Docker Image Version | `latest` | | `METRIC_RETENTION_DAYS` | Datenspeicherdauer (Tage) | `30` | | `METRIC_CLEANUP_ENABLED` | Automatische Datenbereinigung | `true` | -| `METRIC_CLEANUP_INTERVAL_HOURS` | Bereinigungs-Intervall | `24` | -| `DATABASE:CONNECTIONSTRINGS:SQLITE` | Benutzerdefinierter SQLite-Pfad | - | +| `FRONTEND_REFRESH_INTERVAL_SECONDS` | Dashboard Aktualisierungsrate | `30` | -### Volumes +Vollständige Liste: siehe `docker-compose.yaml` -- `/app/persistence` - SQLite-Datenbank -- `/app/wwwroot/downloads/sqlite` - Datenbank-Exports -- `/app/logs` - Anwendungslogs +#### Volumes -## 🔧 Entwicklung +- `./data/db` → `/app/persistence` - SQLite-Datenbank +- `./data/dumps` → `/app/wwwroot/downloads/sqlite` - Datenbank-Exports +- `./data/logs` → `/app/logs` - Anwendungslogs -### Lokales Build +#### Sicherheit -```bash -# Dependencies wiederherstellen -dotnet restore - -# Build -dotnet build --configuration Release - -# Tests ausführen -dotnet test - -# Anwendung starten -dotnet run --project Watcher -``` - -### Docker-Build - -```bash -# Multi-Arch Build -docker buildx build \ - --platform linux/amd64,linux/arm64 \ - -t watcher-server:latest \ - --push . -``` - -## 📁 Projektstruktur - -``` -/Watcher -├── Controllers/ # MVC & API Controllers -├── Models/ # Entity-Modelle -├── Views/ # Razor-Templates -├── Services/ # Background-Services & Stores -├── Data/ # Entity Framework Context -├── Migrations/ # EF Core Migrations -├── ViewModels/ # View Models -├── wwwroot/ # Statische Assets -├── persistence/ # SQLite-Datenbank -└── logs/ # Anwendungslogs -``` +Der Container läuft als **non-root user** mit konfigurierbarer UID/GID: +- Standard: `1000:1000` +- Anpassbar über `USER_UID` und `USER_GID` in `.env` +- Empfehlung: Eigene UID/GID verwenden für korrekte Dateiberechtigungen ## 📝 Lizenz diff --git a/Watcher/Controllers/UserController.cs b/Watcher/Controllers/UserController.cs index 65272f5..3e9197c 100644 --- a/Watcher/Controllers/UserController.cs +++ b/Watcher/Controllers/UserController.cs @@ -25,7 +25,7 @@ public class UserController : Controller var claims = User.Claims.Select(c => new { c.Type, c.Value }).ToList(); var Identity_User = User.Identity?.Name; - var user = _context.Users.FirstOrDefault(u => u.Username == Identity_User); + var user = _context.Users.FirstOrDefaultAsync(u => u.Username == Identity_User); if (user == null) return NotFound(); // Anzeigedaten @@ -50,7 +50,7 @@ public class UserController : Controller public IActionResult Edit() { var username = User.Identity?.Name; - var user = _context.Users.FirstOrDefault(u => u.Username == username); + var user = _context.Users.FirstOrDefaultAsync(u => u.Username == username); if (user == null) return NotFound(); @@ -70,7 +70,7 @@ public class UserController : Controller if (!ModelState.IsValid) return View(model); var username = User.Identity?.Name; - var user = _context.Users.FirstOrDefault(u => u.Username == username); + var user = _context.Users.FirstOrDefaultAsync(u => u.Username == username); if (user == null) return NotFound(); user.Username = model.Username; diff --git a/docker-compose.yaml b/docker-compose.yaml index 18b2d9f..9c5b8cb 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,6 +1,6 @@ services: watcher: - image: git.triggermeelmo.com/watcher/watcher-server:${IMAGE_VERSION:-latest} + image: git.triggermeelmo.com/watcher/watcher-server:latest container_name: watcher # Resource Management @@ -9,14 +9,11 @@ services: limits: memory: 200M cpus: '0.5' - reservations: - memory: 100M - cpus: '0.25' restart: unless-stopped - # Security - user: "1000:1000" + # Security - User/Group ID aus Umgebungsvariablen + user: "${USER_UID:-1000}:${USER_GID:-1000}" # Health Check healthcheck: @@ -28,16 +25,13 @@ services: # Environment environment: + # Non-Root User + - USER_UID=1000 # Standard 1000 + - USER_GID=1000 # Standard 1000 + # Timezone - TZ=Europe/Berlin - # Application Version (wird aus Image-Tag übernommen) - - WATCHER_VERSION=${IMAGE_VERSION:-latest} - - # ASP.NET Core - - ASPNETCORE_ENVIRONMENT=Production - - ASPNETCORE_URLS=http://+:5000 - # Update Check - UPDATE_CHECK_ENABLED=true - UPDATE_CHECK_INTERVAL_HOURS=24