Prüfung von Events im Zustelldienst
Zur Prüfbarkeit der Datenübermittlung erhält ein Case einen Event Log, das Security Event Token (SET) gemäß [RFC 8417](https://datatracker.ietf.org/doc/html/rfc8417) und dem Dokument [Event Log](https://docs.fitko.de/fit-connect/details/event-log) speichert. Manche der Events werden vom Zustelldienst erzeugt, manche werden extern über die API zugeliefert.
Anmerkung: Dieses Issue ist teilweise schon umgesetzt. Ziel dieses Issue ist die Prüfung der Akzeptanzkriterien.
## Akzeptanzkriterien
- [ ] Die SET werden persistent gespeichert
- :heavy_check_mark: [`EventService.writeEventLogEntry`](https://git.fitko.de/fit-connect/zustelldienst/-/blob/main/src/main/java/de/fiep/zustelldienst/service/EventService.java#L50)
- [ ] Der Zustelldienst erzeugt bei allen definierten Events ein SET und speichert sie
- [ ] https://schema.fitko.de/fit-connect/events/create-submission
- :heavy_check_mark: [`SubmissionService.createSubmission`](https://git.fitko.de/fit-connect/zustelldienst/-/blob/main/src/main/java/de/fiep/zustelldienst/service/SubmissionService.java#L52): `eventService.createAndWriteEvent(submission, CREATE_SUBMISSION);`
- [ ] https://schema.fitko.de/fit-connect/events/submit-submission
- :heavy_check_mark: [`SubmissionService.addSubmissionDataAndSubmit`](https://git.fitko.de/fit-connect/zustelldienst/-/blob/main/src/main/java/de/fiep/zustelldienst/service/SubmissionService.java#L90): `eventService.createAndWriteEvent(submission, event, payload);`
- [ ] https://schema.fitko.de/fit-connect/events/notify-submission
- :heavy_check_mark: [`CallbackService.asyncCallbackForNewSubmissionsAndLogEvent`](https://git.fitko.de/fit-connect/zustelldienst/-/blob/main/src/main/java/de/fiep/zustelldienst/callbacks/CallbackService.java#L82): `eventService.createAndWriteEvent(submission, NOTIFY_SUBMISSION, NotifyType.NOTIFY_TYPE_CALLBACK.asMap());`
- :heavy_check_mark: [`SubmissionService.getSubmittedSubmissionsForDestinations`](https://git.fitko.de/fit-connect/zustelldienst/-/blob/main/src/main/java/de/fiep/zustelldienst/service/SubmissionService.java#L145): `eventService.writeNotifyEventIfRequired(submission);`
- [ ] Neu: https://schema.fitko.de/fit-connect/events/deliver-submission
- :arrow_right: Das Event gibt es noch nicht -> #292
- [x] ~~https://schema.fitko.de/fit-connect/events/forward-submission~~ (wird durch den Subscriber erstellt)
- [x] ~~https://schema.fitko.de/fit-connect/events/reject-submission~~ (wird durch den Subscriber erstellt)
- [x] ~~https://schema.fitko.de/fit-connect/events/accept-submission~~ (wird durch den Subscriber erstellt)
- [ ] https://schema.fitko.de/fit-connect/events/delete-submission
- :arrow_right: Es wird derzeit noch nicht gelöscht -> #91
- [ ] Der Zustelldienst nimmt über die API die definierten Events an und speichert sie. Aktuell ist das die Übermittlung von SETs durch den Subscriber für die Events forward, accept und reject
- :heavy_check_mark: [`CasesAPI.processCaseEvent`](https://git.fitko.de/fit-connect/zustelldienst/-/blob/main/src/main/java/de/fiep/zustelldienst/controller/CasesAPI.java#L52)
- [ ] Es werden nur SET angenommen, deren Schema und Signatur erfolgreich geprüft wurden
- [ ] Der Zustelldienst prüft Signaturen auf Gültigkeit
- :heavy_check_mark: [`SecurityEventTokenValidator.validateSignature`](https://git.fitko.de/fit-connect/zustelldienst/-/blob/main/src/main/java/de/fitko/fitconnect/event/SecurityEventTokenValidator.java#L136)
- [ ] `jti` ist eindeutig
- :heavy_check_mark: [`SecurityEventTokenValidator.validateJtiClaim`](https://git.fitko.de/fit-connect/zustelldienst/-/blob/main/src/main/java/de/fitko/fitconnect/event/SecurityEventTokenValidator.java#L161): `eventLogRepository.findByTokenId(setParseResult.getJti()).isPresent()`
- [ ] Zusätzliche Prüfungen für Subscriber
- [ ] Im SET Header sind die drei Angaben `typ`, `alg`und `kid`enthalten und keine weiteren Angaben.
- :heavy_check_mark: [`SecurityEventTokenValidator.validateHeader`](https://git.fitko.de/fit-connect/zustelldienst/-/blob/main/src/main/java/de/fitko/fitconnect/event/SecurityEventTokenValidator.java#L97)
- [ ] `typ` hat den Wert `secevent+jwt`
- [ ] `alg` hat den Wert `PS512`
- [ ] `kid` entspricht einem vorliegenden Schlüssel
- [ ] Der von `kid`referenzierte Schlüssel …
- [ ] … hat den Eintrag `"alg":"PS512"`
- :heavy_check_mark: [`SecurityEventTokenValidator.validateSignKey`](https://git.fitko.de/fit-connect/zustelldienst/-/blob/main/src/main/java/de/fitko/fitconnect/event/SecurityEventTokenValidator.java#L131): `rsaKey.getAlgorithm().equals(JWSAlgorithm.PS512)`
- [ ] … hat den Eintrag `key_ops":["verify"]` (das Array darf weitere Werte enthalten)
- :heavy_check_mark: [`SecurityEventTokenValidator.validateSignKey`](https://git.fitko.de/fit-connect/zustelldienst/-/blob/main/src/main/java/de/fitko/fitconnect/event/SecurityEventTokenValidator.java#L131): `rsaKey.getKeyOperations().size() == 1 && rsaKey.getKeyOperations().contains(KeyOperation.VERIFY)`
- [ ] … hat eine gültige Zertifikatkette aus der V-PKI (Abschaltbar in der Testumgebung) (**Wird auch in #119 gebraucht. Dort sind auch die entsprechenden Vorgaben in den Akzeptanzkriterien definiert**)
- :arrow_right: -> #119
- [ ] Die SET Signatur konnte mit dem Schlüssel verifiziert werden
- [`SecurityEventTokenValidator.validateSignature`](https://git.fitko.de/fit-connect/zustelldienst/-/blob/main/src/main/java/de/fitko/fitconnect/event/SecurityEventTokenValidator.java#L136): `signedJWT.verify(jwsVerifier)`
- [ ] SET Payload:
- [ ] Entscheidung vom 17.1.22: Wenn `$schema` gesetzt ist, dann wird auch das Schema des Events durch den Zustelldienst geprüft.
- [ ] Der SET Payload ist valide gemäß dem angegebenen (`$schema`) JSON Schema
- [`SecurityEventTokenValidator.validateSetPayloadSchema`](https://git.fitko.de/fit-connect/zustelldienst/-/blob/main/src/main/java/de/fitko/fitconnect/event/SecurityEventTokenValidator.java#L120)
- [ ] Die in `iss` enthaltene Destination-ID ist die der Destination, an die die Submission gesendet wurde.
- :heavy_check_mark: [`SecurityEventTokenValidator.validateIssClaim`](https://git.fitko.de/fit-connect/zustelldienst/-/blob/main/src/main/java/de/fitko/fitconnect/event/SecurityEventTokenValidator.java#L169)
- [ ] `iat`: Ist ein UNIX-Timestamp der in der Vergangenheit liegen, aber nach dem letzten status-verändernden Event der Submission.
- :heavy_check_mark: [`SecurityEventTokenValidator.validateIatClaim`](https://git.fitko.de/fit-connect/zustelldienst/-/blob/main/src/main/java/de/fitko/fitconnect/event/SecurityEventTokenValidator.java#L195)
- [ ] Die in `sub` enthaltene Submission-ID gehört zu dem Case, der in der URL angegeben ist
- :heavy_check_mark: [`SecurityEventTokenValidator.validateSubClaimAndFetchSubmission`](https://git.fitko.de/fit-connect/zustelldienst/-/blob/main/src/main/java/de/fitko/fitconnect/event/SecurityEventTokenValidator.java#L209)
- [ ] Die in `txn` enthaltene Case-ID gehört zu einem Vorgang, auf den der Subscriber Zugriff hat
- [`CasesAPI.processCaseEvent`](https://git.fitko.de/fit-connect/zustelldienst/-/blob/main/src/main/java/de/fiep/zustelldienst/controller/CasesAPI.java#L51): `@PreAuthorize("@auth.canSubscribeToDestinationOfCase(authentication, #caseId)")`
- [ ] und entspricht der Case-ID in der URL.
- :heavy_check_mark: [`SecurityEventTokenValidator.validateTxnClaim`](https://git.fitko.de/fit-connect/zustelldienst/-/blob/main/src/main/java/de/fitko/fitconnect/event/SecurityEventTokenValidator.java#L231): `transactionId.equalsIgnoreCase(caseId.toString())`
- [ ] Enthaltenes Event existiert und darf vom Subscriber angelegt werden
- :heavy_check_mark: [`EventService.parseAndValidateSecurityEventToken`](https://git.fitko.de/fit-connect/zustelldienst/-/blob/main/src/main/java/de/fiep/zustelldienst/service/EventService.java#L131): `if (set.getEvent().getIssuer() == FitConnectEventIssuer.ZUSTELLDIENST) {`
**Legende:**
- :heavy_check_mark: Prüfung ist bereits vorhanden oder wurde ergänzt
- :construction: Offene Aufgabe
- :arrow_right: Aufgabe in/Abhängig von einer anderen Story
## Durchführungsplan
- Branch: https://git.fitko.de/fit-connect/zustelldienst/-/commits/297-validate-events
issue