Wächter auflösen: Zugangsprüfung im Service mit CurrentUser/Caller und Prüfern in domain/ #152

Open
opened 2026-10-25 08:36:28 +00:00 by claude · 0 comments
Collaborator

Die Zugangsprüfungen sind über Resources und Services verstreut. Bei jedem neuen Weg muss jemand daran denken, die Prüfung selbst aufzurufen. Vergisst er es, kann jeder eingeloggte Nutzer den Weg mit seinem Token direkt aufrufen.

Entschieden (Olli, 21.10.2026): docs/2026-10-20-service-verantwortlichkeiten.md, Abschnitt „Wächter“ (Z. 220-258). Kurz:

  • Wer fragt: CurrentUser in shared/service, eine Instanz je Anfrage, liefert den Wert Caller(personId, clubId, isVerband).
  • Die Regeln: Prüfer in domain/ ohne Datenbank und ohne Login: MatchAccessValidator (heute CaptainAccessGuard.checkAccess), ClubAccessValidator (heute ClubAccessGuard), ein SeasonPhaseValidator (Meldefenster heute RegistrationWindowGuard, abgeschlossene Saison heute SeasonResolver.requireWritable, „Saison läuft“ heute SeasonPhaseRules).
  • Wo geprüft wird: im Service, am Anfang jedes Vorgangs. Die Resource reicht nur weiter.
  • Verworfen: Annotation an der Resource-Methode (@RequireHomeCaptain).
  • Folgen für ADR 0033: Fehlerart „nicht erlaubt“ (403), Caller.isVerband statt Rollenliste, Endung Guard entfällt.

Stand heute (25.10.2026, main 67413ac), gezählt: 18 Aufrufe eines Wächters in Resources, 10 in Services (grep -rn "clubAccessGuard\.\|accessGuard\.\|guard\.require" backend/src/main/java). Laut Analyse betrifft der Umbau 66 Endpunkte, die einen Wächter oder SeasonResolver aufrufen.

Beim Umbau zu entscheiden: Bekommt jede Service-Operation den Caller als Parameter (saveOfficials(caller, clubId, request)), oder holt der Service ihn selbst über CurrentUser? Für den Parameter spricht (Gespräch 25.10.):

  • Keine öffentliche Service-Methode ohne Prüfung, auch keine „innere Schicht“ nur für Tests.
  • Tests bauen den Caller selbst („Spielleiter von Verein 17“), ohne Login. Das Projekt hat kein Werkzeug, um in Service-Tests ein Login vorzutäuschen (kein quarkus-test-security-jwt, kein Mockito).
  • Eine Methode ohne Caller ist gar nicht aufrufbar.

Was danach wegfallen kann (aus Etappe 5a der URL-Neuordnung): 5a baut für Ämter, Spiellokale und PDF je eine öffentliche innere Schicht ohne Zugangsprüfung (ClubRegistrationService.writeOfficials, writeHomeVenues, PdfService.renderClubPdf), weil die Service-Tests kein Login haben. Olli hat das am 25.10. als bewusste Lücke hingenommen, sie steht im ADR 0038. Mit diesem Umbau verschwinden die inneren Schichten wieder.

Bezug: #122 und der Service-Zuschnitt (gleiches Analyse-Dokument). Login-Schutz ist eine andere Baustelle: #151.

Die Zugangsprüfungen sind über Resources und Services verstreut. Bei jedem neuen Weg muss jemand daran denken, die Prüfung selbst aufzurufen. Vergisst er es, kann jeder eingeloggte Nutzer den Weg mit seinem Token direkt aufrufen. **Entschieden (Olli, 21.10.2026):** `docs/2026-10-20-service-verantwortlichkeiten.md`, Abschnitt „Wächter“ (Z. 220-258). Kurz: - **Wer fragt:** `CurrentUser` in `shared/service`, eine Instanz je Anfrage, liefert den Wert `Caller(personId, clubId, isVerband)`. - **Die Regeln:** Prüfer in `domain/` ohne Datenbank und ohne Login: `MatchAccessValidator` (heute `CaptainAccessGuard.checkAccess`), `ClubAccessValidator` (heute `ClubAccessGuard`), **ein** `SeasonPhaseValidator` (Meldefenster heute `RegistrationWindowGuard`, abgeschlossene Saison heute `SeasonResolver.requireWritable`, „Saison läuft“ heute `SeasonPhaseRules`). - **Wo geprüft wird:** im Service, am Anfang jedes Vorgangs. Die Resource reicht nur weiter. - **Verworfen:** Annotation an der Resource-Methode (`@RequireHomeCaptain`). - **Folgen für ADR 0033:** Fehlerart „nicht erlaubt“ (403), `Caller.isVerband` statt Rollenliste, Endung `Guard` entfällt. **Stand heute (25.10.2026, `main` `67413ac`), gezählt:** 18 Aufrufe eines Wächters in Resources, 10 in Services (`grep -rn "clubAccessGuard\.\|accessGuard\.\|guard\.require" backend/src/main/java`). Laut Analyse betrifft der Umbau 66 Endpunkte, die einen Wächter oder `SeasonResolver` aufrufen. **Beim Umbau zu entscheiden:** Bekommt jede Service-Operation den `Caller` als Parameter (`saveOfficials(caller, clubId, request)`), oder holt der Service ihn selbst über `CurrentUser`? Für den Parameter spricht (Gespräch 25.10.): - Keine öffentliche Service-Methode ohne Prüfung, auch keine „innere Schicht“ nur für Tests. - Tests bauen den `Caller` selbst („Spielleiter von Verein 17“), ohne Login. Das Projekt hat kein Werkzeug, um in Service-Tests ein Login vorzutäuschen (kein `quarkus-test-security-jwt`, kein Mockito). - Eine Methode ohne `Caller` ist gar nicht aufrufbar. **Was danach wegfallen kann (aus Etappe 5a der URL-Neuordnung):** 5a baut für Ämter, Spiellokale und PDF je eine öffentliche innere Schicht ohne Zugangsprüfung (`ClubRegistrationService.writeOfficials`, `writeHomeVenues`, `PdfService.renderClubPdf`), weil die Service-Tests kein Login haben. Olli hat das am 25.10. als bewusste Lücke hingenommen, sie steht im ADR 0038. Mit diesem Umbau verschwinden die inneren Schichten wieder. **Bezug:** #122 und der Service-Zuschnitt (gleiches Analyse-Dokument). Login-Schutz ist eine andere Baustelle: #151.
Sign in to join this conversation.
No description provided.