Skip to content
Snippets Groups Projects
Verified Commit e7bed4a3 authored by Jonas Gröger's avatar Jonas Gröger :palm_tree:
Browse files

feat: bidirectional communication (planning#460)

parent c285ff1f
No related branches found
No related tags found
1 merge request!167BiDiKo Teil 2 - The attack (planning#460)
Showing
with 671 additions and 84 deletions
......@@ -16,7 +16,7 @@ install:
print-version:
swagger-cli --version
bundle: print-version
bundle: print-version backup
swagger-cli bundle \
--type yaml \
--outfile dist/submission-api.yaml \
......@@ -28,13 +28,16 @@ validate: print-version
validate-build: bundle
swagger-cli validate dist/submission-api.yaml
bundle-dereferenced: print-version
bundle-dereferenced: print-version backup
swagger-cli bundle \
--type yaml \
--outfile dist/submission-api.yaml \
--dereference \
spec/submission-api.yaml
backup:
if [ -f dist/submission-api.yaml ]; then cp dist/submission-api.yaml dist/submission-api-before.yaml; fi
pwd := $(shell pwd)
spectral: bundle
......
......@@ -51,3 +51,16 @@ Attachments:
- `2d8cef0c-62e1-4936-925c-2da79377d29c`
- `fa9e16fc-0cb1-4d14-9a9a-4130fa51083f`
## Callback locations
The callbacks are located at the locations where the callback URLs can be changed.
Even though the callbacks might take place later. Rationale:
The OpenAPI spec in https://spec.openapis.org/oas/v3.1.0#callback-object says:
> 4.8.18 Callback Object
>
> A map of possible out-of band callbacks related to the parent operation.
We interpret the "related" as: the callback URL that will be called is defined here.
const RESPONSE_ATTRIBUTES = ['offset', 'totalCount', 'count']
const QUERY_PARAMS = ['limit', 'offset']
const MINIMUM_ATTR_COUNT = 4
module.exports = (operation, _opts, paths) => {
// operation should be a get or post operation
if (operation === null || typeof operation !== 'object') {
return []
}
const path = paths.given || []
// responses is required property of an operation in OpenAPI 2.0, so if
// isn't present this will be flagged elsewhere -- just return
if (!operation.responses || typeof operation.responses !== 'object') {
return []
}
// Find success response code
const resp = Object.keys(operation.responses)
.find((code) => code.startsWith('2'))
// No success response will be flagged elsewhere, just return
if (!resp) {
return []
}
// available content types
const content = operation.responses[resp].content
// Get the schema of the success response
const responseSchema = content[Object.keys(content)[0]].schema || {}
const errors = []
const responseHasArray = Object.values(responseSchema.properties || {})
.some((prop) => prop.type === 'array')
const operationId = operation.operationId ? `'${operation.operationId }'` : ''
if (responseHasArray && Object.keys(responseSchema.properties).length <= MINIMUM_ATTR_COUNT) {
RESPONSE_ATTRIBUTES.forEach((entry) => {
if (!Object.keys(responseSchema.properties).includes(entry)) {
errors.push({
message: `Operation ${operationId} might be pageable. Property '${entry}' is missing.`,
path,
})
}
})
if (operation.parameters) {
const queryParams = operation.parameters.filter((param) => param.in === 'query')
if (queryParams) {
const names = queryParams.map((param) => param.name)
QUERY_PARAMS.forEach((e) => {
if (!names.includes(e)) {
errors.push({
message: `Operation ${operationId} might be pageable. Query parameter '${e}' is missing.`,
path,
})
}
})
}
} else {
errors.push({
message: `Operation ${operationId} might be pageable. Query parameters are missing.`,
path,
})
}
}
return errors
}
Note 1:
Wenn ein Subscriber weiterhin Callbacks erhalten will, so muss er diesen bei jeder Submission immer wieder angeben.
Sendet ein Subscriber keinen Callback menr, werden keine Callbacks für diese Submission mehr verschickt.
See: https://git.fitko.de/fit-connect/submission-api/-/merge_requests/167#note_82366
\ No newline at end of file
'https://example.org/callback':
post:
summary: Callback für die Ankündigung des Schließens eines Vorgangs (case-closure-announcement)
description: >
Bevor ein Vorgang durch den Zustelldienst geschlossen wird, sendet dieser einen Callback an das sendende und empfangende System.
operationId: callback-case-closure-announcement
parameters:
- $ref: '../headers/hmac-cb-authentication.yaml'
- $ref: '../headers/hmac-cb-timestamp.yaml'
requestBody:
required: true
content:
application/json:
schema:
$ref: '../schemas/callbacks/callback-case-closure-announcement.yaml'
responses:
'200':
description: OK
......@@ -13,7 +13,7 @@
content:
application/json:
schema:
$ref: '../schemas/callback-new-events.yaml'
$ref: '../schemas/callbacks/callback-new-events.yaml'
responses:
'200':
description: OK
'https://example.org/callback':
post:
summary: Callback für eine neue Antwort
description: >
Bei neu eintreffenden Antworten wird das sendende System der Einreichung mit Hilfe dieses Callbacks benachrichtigt.
Voraussetzung ist die vorherige Konfiguration des Callbacks mit `url` und `secret`.
operationId: callback-new-replies
parameters:
- $ref: '../headers/hmac-cb-authentication.yaml'
- $ref: '../headers/hmac-cb-timestamp.yaml'
requestBody:
required: true
content:
application/json:
schema:
$ref: '../schemas/callbacks/callback-new-replies.yaml'
responses:
'200':
description: OK
......@@ -13,7 +13,7 @@
content:
application/json:
schema:
$ref: '../schemas/callback-new-submissions.yaml'
$ref: '../schemas/callbacks/callback-new-submissions.yaml'
responses:
'200':
description: OK
......@@ -19,7 +19,7 @@ get:
content:
application/jose:
schema:
$ref: '../../schemas/attachment.yaml'
$ref: '../../schemas/jwe.yaml'
examples:
Beispiel:
$ref: '../../examples/encrypted-message.yaml'
......@@ -66,7 +66,7 @@ put:
content:
application/jose:
schema:
$ref: '../../schemas/create-attachment.yaml'
$ref: '../../schemas/jwe.yaml'
examples:
Beispiel:
$ref: '../../examples/encrypted-message.yaml'
......
......@@ -8,8 +8,7 @@ get:
Über diesen Endpunkt kann der [Event Log](https://docs.fitko.de/fit-connect/docs/getting-started/event-log/overview) eines Vorgangs
abgerufen werden, um z.B. den Status des Vorgangs zu überprüfen.
tags:
- Einreichungsempfang
- Einreichungsübermittlung
- Vorgangsverwaltung
security:
- OAuth2:
- 'subscribe:destination:<id>'
......@@ -63,7 +62,7 @@ post:
Dieses Event kann nach der Validierung der Rahmenstruktur der Einreichung versendet werden, wie
[hier](https://docs.fitko.de/fit-connect/docs/receiving/process-and-acknowledge) beschrieben ist.
tags:
- Einreichungsempfang
- Vorgangsverwaltung
security:
- OAuth2:
- 'subscribe:destination:<id>'
......
get:
operationId: get-active-cases
summary: Aktive Vorgänge auflisten
description: >
Mit diesem Request werden alle aktiven Vorgänge aufgelistet.
Bei Autorisierung als Onlinedienst (`sender`) werden alle Vorgänge gelistet, die vom API-Client auf Basis der OAuth Client-ID initiiert wurden.
Bei Autorisierung als Fachverfahren (`subscriber`) werden alle Vorgänge gelistet, die an dessen Destination-ID gesendet wurden.
tags:
- Vorgangsverwaltung
security:
- OAuth2:
- 'send:region:DE<region-id>+send:service:<service-uri>'
- 'send:region:DE<region-id>'
- 'subscribe:destination:<id>'
- 'manage:destination:<id>'
parameters:
- $ref: '../../parameters/pagination/limit.yaml'
- $ref: '../../parameters/pagination/offset.yaml'
responses:
'200':
description: OK
headers:
Cache-Control:
$ref: '../../headers/cache-control-no-cache.yaml'
content:
application/json:
schema:
$ref: '../../schemas/case/cases.yaml'
examples:
Beispiel:
$ref: '../../examples/case/cases.yaml'
'401':
description: Unauthorized
content:
application/problem+json:
schema:
$ref: '../../schemas/error.yaml'
'403':
description: Forbidden
content:
application/problem+json:
schema:
$ref: '../../schemas/error.yaml'
parameters:
- $ref: '../../parameters/caseId.yaml'
patch:
operationId: patch-case
summary: Vorgang partiell aktualisieren
description: Über diesen Endpunkt kann ein Vorgang partiell aktualisiert werden.
tags:
- Vorgangsverwaltung
security:
- OAuth2:
- 'subscribe:destination:<id>'
- 'manage:destination:<id>'
- 'send:region:DE<region-id>+send:service:<service-uri>'
- 'send:region:DE<region-id>'
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/case/patch-case.yaml'
examples:
Vorgang offen halten:
$ref: '../../examples/case/patch-case-active.yaml'
Vorgang schließen:
$ref: '../../examples/case/patch-case-closed.yaml'
responses:
'202':
description: Accepted
content:
application/json:
schema:
$ref: '../../schemas/case/case.yaml'
examples:
Offener Vorgang:
$ref: '../../examples/case/case-active.yaml'
Geschlossener Vorgang:
$ref: '../../examples/case/case-closed.yaml'
'400':
description: Bad Request
content:
application/problem+json:
schema:
$ref: ../../schemas/error.yaml
'401':
description: Unauthorized
content:
application/problem+json:
schema:
$ref: ../../schemas/error.yaml
'403':
description: Forbidden
content:
application/problem+json:
schema:
$ref: ../../schemas/error.yaml
'404':
description: Not Found
content:
application/problem+json:
schema:
$ref: ../../schemas/error.yaml
get:
summary: Vorgang abrufen
operationId: get-case
description: >
Mit diesem Endpunkt kann ein Vorgang abgerufen werden.
tags:
- Vorgangsverwaltung
security:
- OAuth2:
- 'subscribe:destination:<id>'
- 'manage:destination:<id>'
- 'send:region:DE<region-id>+send:service:<service-uri>'
- 'send:region:DE<region-id>'
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '../../schemas/case/case.yaml'
examples:
Offener Vorgang:
$ref: '../../examples/case/case-active.yaml'
Geschlossener Vorgang:
$ref: '../../examples/case/case-closed.yaml'
'400':
description: Bad Request
content:
application/problem+json:
schema:
$ref: ../../schemas/error.yaml
'401':
description: Unauthorized
content:
application/problem+json:
schema:
$ref: ../../schemas/error.yaml
'403':
description: Forbidden
content:
application/problem+json:
schema:
$ref: ../../schemas/error.yaml
'404':
description: Case not found
content:
application/problem+json:
schema:
$ref: ../../schemas/error.yaml
......@@ -64,8 +64,13 @@ post:
Beispiel:
$ref: '../../examples/create-destination.yaml'
callbacks:
# Why are all callbacks located here? Check the README for details.
NewEvents:
$ref: '../../callbacks/new-events.yaml'
NewSubmissions:
$ref: '../../callbacks/new-submissions.yaml'
CaseClosureAnnouncement:
$ref: '../../callbacks/case-closure-announcement.yaml'
responses:
'201':
description: Created
......
......@@ -74,8 +74,13 @@ put:
Beispiel:
$ref: '../../examples/update-destination.yaml'
callbacks:
# Why are all callbacks located here? Check the README for details.
NewEvents:
$ref: '../../callbacks/new-events.yaml'
NewSubmissions:
$ref: '../../callbacks/new-submissions.yaml'
CaseClosureAnnouncement:
$ref: '../../callbacks/case-closure-announcement.yaml'
responses:
'200':
description: OK
......@@ -137,8 +142,12 @@ patch:
Patch Contact:
$ref: '../../examples/patch-destination-contact.yaml'
callbacks:
NewEvents:
$ref: '../../callbacks/new-events.yaml'
NewSubmissions:
$ref: '../../callbacks/new-submissions.yaml'
CaseClosureAnnouncement:
$ref: '../../callbacks/case-closure-announcement.yaml'
responses:
'200':
description: OK
......
parameters:
- $ref: '../../../parameters/replyId.yaml'
put:
summary: Rückantwort akzeptieren
description: >
Mit der Übermittlung der empfangenen Authentication-Tags wird der Empfang der Antwort dokumentiert.
Sofern die Antwort trotz Fehlern empfangen wurde, können diese in der Liste `problems` protokolliert werden.
tags:
- Antwort empfangen
security:
- OAuth2:
- 'send:region:DE<region-id>+send:service:<service-uri>'
- 'send:region:DE<region-id>'
operationId: put-reply-accept
requestBody:
content:
application/json:
schema:
$ref: '../../../schemas/event-payload-accept.yaml'
examples:
Einfaches Beispiel:
$ref: '../../../examples/replies/accept-reply.yaml'
Beispiel mit Problemen:
$ref: '../../../examples/replies/accept-reply-with-nonfatal-problems.yaml'
responses:
'202':
description: Accepted
content:
application/jose:
schema:
$ref: ../../../schemas/security-event-token.yaml
examples:
Beispiel:
$ref: '../../../examples/security-event-token.yaml'
'400':
description: Bad Request
content:
application/problem+json:
schema:
$ref: ../../../schemas/error.yaml
'401':
description: Unauthorized
content:
application/problem+json:
schema:
$ref: ../../../schemas/error.yaml
'403':
description: Forbidden
content:
application/problem+json:
schema:
$ref: ../../../schemas/error.yaml
'404':
description: Reply Not Found
content:
application/problem+json:
schema:
$ref: ../../../schemas/error.yaml
parameters:
- $ref: '../../../parameters/replyId.yaml'
- $ref: '../../../parameters/attachmentId.yaml'
get:
operationId: get-reply-attachment
summary: Anlage einer Antwort abrufen
description: >
Ruft eine Anlage einer Einreichung im JOSE-Format ab.
Genaueres ist in der Dokumentation beschrieben.
tags:
- Antwort empfangen
security:
- OAuth2:
- 'send:region:DE<region-id>+send:service:<service-uri>'
- 'send:region:DE<region-id>'
responses:
'200':
description: OK
content:
application/jose:
schema:
$ref: '../../../schemas/jwe.yaml'
examples:
Beispiel:
$ref: '../../../examples/encrypted-message.yaml'
'401':
description: Unauthorized
content:
application/problem+json:
schema:
$ref: ../../../schemas/error.yaml
'403':
description: Forbidden
content:
application/problem+json:
schema:
$ref: ../../../schemas/error.yaml
'404':
description: Reply or Attachment Not Found
content:
application/problem+json:
schema:
$ref: ../../../schemas/error.yaml
put:
operationId: add-reply-attachment
summary: Anlage einer Antwort hinzufügen
description: >
Hochladen der in `announcedAttachments` angekündigten Anlage im JOSE-Format unter der mitgeteilten UUID.
Genaueres ist in der Dokumentation beschrieben.
tags:
- Antwort senden
security:
- OAuth2:
- 'subscribe:destination:<id>'
requestBody:
required: true
content:
application/jose:
schema:
$ref: '../../../schemas/jwe.yaml'
examples:
Beispiel:
$ref: '../../../examples/encrypted-message.yaml'
responses:
'204':
description: 'No Content: Anlage erfolgreich hinzugefügt/überschrieben'
'400':
description: Bad Request
content:
application/problem+json:
schema:
$ref: ../../../schemas/error.yaml
'401':
description: Unauthorized
content:
application/problem+json:
schema:
$ref: ../../../schemas/error.yaml
'403':
description: Forbidden
content:
application/problem+json:
schema:
$ref: ../../../schemas/error.yaml
'413': # TODO: Check
description: Request Entity Too Large
content:
application/problem+json:
schema:
$ref: ../../../schemas/error.yaml
'415':
description: Unsupported Media Type (wrong content type sent)
content:
application/problem+json:
schema:
$ref: ../../../schemas/error.yaml
'422':
description: Attachment not announced. Must upload attachments under their announced UUIDs.
content:
application/problem+json:
schema:
$ref: ../../../schemas/error.yaml
get:
operationId: get-replies-for-pickup
summary: Abholbereite Antworten auflisten
description: Mit diesem Request werden alle abholbereiten Antworten aufgelistet.
tags:
- Antwort empfangen
security:
- OAuth2:
- 'send:region:DE<region-id>+send:service:<service-uri>'
- 'send:region:DE<region-id>'
parameters:
- $ref: '../../parameters/caseIdInQuery.yaml'
- $ref: '../../parameters/pagination/limit.yaml'
- $ref: '../../parameters/pagination/offset.yaml'
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '../../schemas/replies/replies-for-pickup.yaml'
examples:
Beispiel:
$ref: '../../examples/replies/replies-for-pickup.yaml'
'401':
description: Unauthorized
content:
application/problem+json:
schema:
$ref: '../../schemas/error.yaml'
'403':
description: Forbidden
content:
application/problem+json:
schema:
$ref: '../../schemas/error.yaml'
post:
operationId: create-reply
summary: Antwort erstellen
description: >
Über diesen Endpunkt kann das empfangende System dem sendenden System eine Antwort zukommen zu lassen.
tags:
- Antwort senden
security:
- OAuth2:
- 'subscribe:destination:<id>'
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/replies/create-reply.yaml'
examples:
Beispiel:
$ref: '../../examples/replies/create-reply.yaml'
responses:
'201':
description: Created
content:
application/json:
schema:
$ref: '../../schemas/replies/reply-created.yaml'
examples:
Beispiel:
$ref: '../../examples/replies/reply-created.yaml'
'400':
description: Bad Request
content:
application/problem+json:
schema:
$ref: ../../schemas/error.yaml
'401':
description: Unauthorized
content:
application/problem+json:
schema:
$ref: ../../schemas/error.yaml
'403':
description: Forbidden
content:
application/problem+json:
schema:
$ref: ../../schemas/error.yaml
'404':
description: Case Not Found
content:
application/problem+json:
schema:
$ref: ../../schemas/error.yaml
parameters:
- $ref: '../../../parameters/replyId.yaml'
put:
summary: Rückantwort ablehnen
description: >
Konnte die Antwort wegen technischen Fehlern nicht empfangen werden, so wird sie zurückgewiesen.
Die Fehler werden in der Liste `problems` protokolliert.
tags:
- Antwort empfangen
security:
- OAuth2:
- 'send:region:DE<region-id>+send:service:<service-uri>'
- 'send:region:DE<region-id>'
operationId: put-reply-reject
requestBody:
content:
application/json:
schema:
$ref: '../../../schemas/event-payload-reject.yaml'
examples:
Beispiel:
$ref: '../../../examples/replies/reject-reply.yaml'
responses:
'202':
description: Accepted
content:
application/jose:
schema:
$ref: ../../../schemas/security-event-token.yaml
examples:
Beispiel:
$ref: '../../../examples/security-event-token.yaml'
'400':
description: Bad Request
content:
application/problem+json:
schema:
$ref: ../../../schemas/error.yaml
'401':
description: Unauthorized
content:
application/problem+json:
schema:
$ref: ../../../schemas/error.yaml
'403':
description: Forbidden
content:
application/problem+json:
schema:
$ref: ../../../schemas/error.yaml
'404':
description: reply not found
content:
application/problem+json:
schema:
$ref: ../../../schemas/error.yaml
parameters:
- $ref: '../../parameters/replyId.yaml'
get:
operationId: get-reply
summary: Antwort abrufen
description: >
Hierüber können die Fachdaten, Metadaten und Strukturinformation einer Antwort abgefragt und dann ausgewertet werden.
Eine Beschreibung, wie diese Daten weiter verarbeitet werden, ist in der Dokumentation zu finden.
tags:
- Antwort empfangen
security:
- OAuth2:
- 'send:region:DE<region-id>+send:service:<service-uri>'
- 'send:region:DE<region-id>'
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '../../schemas/replies/reply.yaml'
examples:
Beispiel:
$ref: '../../examples/replies/reply.yaml'
'401':
description: Unauthorized
content:
application/problem+json:
schema:
$ref: ../../schemas/error.yaml
'403':
description: Forbidden
content:
application/problem+json:
schema:
$ref: ../../schemas/error.yaml
'404':
description: Reply Not Found
content:
application/problem+json:
schema:
$ref: ../../schemas/error.yaml
put:
operationId: submit-reply
summary: Antwort versenden
description: >
Mit der Übermittlung der Meta- und Fachdaten wird die Antwort an das sendende System (Empfänger der Antwort) abgesendet.
Im Ereignisprotokoll (event log) des zugehörigen Vorgangs (case) kann geprüft werden, ob die Antwort den Empfänger erreicht hat bzw. von diesem akzeptiert wurde.
tags:
- Antwort senden
security:
- OAuth2:
- 'subscribe:destination:<id>'
requestBody:
required: true
content:
application/json:
schema:
$ref: '../../schemas/replies/submit-reply.yaml'
examples:
Beispiel: # Hier kann das Submission-Beispiel wiederverwendet werden.
$ref: '../../examples/submit-submission.yaml'
responses:
'202':
description: Accepted
content:
application/json:
schema:
$ref: '../../schemas/replies/reply-reduced.yaml'
examples:
Beispiel:
$ref: '../../examples/replies/reply-reduced.yaml'
'400':
description: Bad Request
content:
application/problem+json:
schema:
$ref: ../../schemas/error.yaml
'401':
description: Unauthorized
content:
application/problem+json:
schema:
$ref: ../../schemas/error.yaml
'403':
description: Forbidden
content:
application/problem+json:
schema:
$ref: ../../schemas/error.yaml
'404':
description: Reply Not Found
content:
application/problem+json:
schema:
$ref: ../../schemas/error.yaml
'413': # TODO: Check
description: Request Entity Too Large
content:
application/problem+json:
schema:
$ref: ../../schemas/error.yaml
'415':
description: Unsupported Media Type (wrong content type sent)
content:
application/problem+json:
schema:
$ref: ../../schemas/error.yaml
'422':
description: Gesamtantrag unvollständig. Angekündigte Anlagen noch nicht hochgeladen.
content:
application/problem+json:
schema:
$ref: ../../schemas/error.yaml
......@@ -46,6 +46,11 @@ post:
description: >
Dieser Endpunkt ist der erste, initiale Schritt zum Erstellen einer Einreichung. Danach können Anlagen hochgeladen
und schließlich die Einreichung an den Zustellpunkt versendet werden, der in diesem Endpunkt angegeben wurde.
**Hinweis:** Der Callback für das sendende System wird in den Vorgang (case) übernommen und mit jeder weiteren
Einreichung überschrieben.
Sofern mit einer Einreichung keine Callback-Informationen übermittelt werden, wird ein vorhandener Callback des
Vorgangs entfernt.
tags:
- Einreichungsübermittlung
security:
......@@ -62,8 +67,13 @@ post:
Beispiel:
$ref: '../../examples/create-submission.yaml'
callbacks:
# Why are all callbacks located here? Check the README for details.
NewEvents:
$ref: '../../callbacks/new-events.yaml'
NewReplies:
$ref: '../../callbacks/new-replies.yaml'
CaseClosureAnnouncement:
$ref: '../../callbacks/case-closure-announcement.yaml'
responses:
'201':
description: Created
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment