<br /> <div align="center"><img src="https://www.fitko.de/fileadmin/_processed_/b/9/csm_FIT-Connect_3e8e926015.jpg" alt="Logo" width="50%" height="50%"> </div> # FIT-Connect .NET SDK Für ein kurzes Beispiel zu Implementierung kann der [DemoRunner](DemoRunner/Program.cs) herangezogen werden. ## **!! IN DEVELOPMENT NOT FOR PRODUCTION USE !!** **FIT-Connect .NET SDK** ist eine .NET library for the FIT-Connect API. Das SDK ist als [NuGet Package](https://www.nuget.org/packages/FitConnect/) verfügbar. ## Einleitung Das FIT-Connect .NET SDK bietet eine einfache Möglichkeit, sowohl einen Antragsteller (Sender) als auch einen Antragsempfänger (Subscriber) an FIT-Connect anzubinden. ## Voraussetzungen ### Windows und Linux Sowohl Windows als auch Linux benötigen .NET 6 um das SDK nutzen zu können. Eine spezifische Installation ist nicht erforderlich. ### OSX Auch im OSX muss .NET 6 installiert sein. Zusätzlich dazu wird die OpenSSL-Bibliothek benötigt. Für die Installation von OpenSSL kann die [Homebrew](https://brew.sh/) Paketverwaltung verwendet werden. Die Installation von Homebrew erfolgt über die folgende Befehlszeile: ```bash /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" ``` Weitere Informationen zur Installation von Homebrew finden Sie [hier](https://docs.brew.sh/Installation). Zur Installation von OpenSSL mittels Homebrew wird der folgende Befehl verwendet: ```bash brew install openssl ``` Nach der erfolgreichen Installation von OpenSSL muss die Environment-Variable ```DYLD_LIBRARY_PATH``` auf den Pfad zu OpenSSL verweisen. _Beispiele:_ ```sh export DYLD_LIBRARY_PATH=/usr/local/opt/openssl/lib export DYLD_LIBRARY_PATH=/opt/homebrew/opt/openssl@3/lib ``` ## Weitere Informationen zu FIT-Connect finden Sie hier: * [SDK-Dokumentation](./documentation/documentation.de-DE.md) * [FIT-Connect Dokumentation](https://docs.fitko.de/FIT-Connect/docs) * [FIT-Connect Dokumentation](https://FIT-Connect.com/docs) # Allgemeines ## Environment Das FIT-Connect SDK kann an die folgenden Umgebungen angeschlossen werden: - Testing: ```FitConnectEnvironment.Testing``` - Staging: ```FitConnectEnvironment.Staging``` - Production: ```FitConnectEnvironment.Production``` [FIT Connect Umgebungen](https://docs.fitko.de/fit-connect/docs/getting-started/environments) Hierfür muss der Client die Environment auswählen oder einen eigenen Environment-Parameter übergeben. ## Credentials ClientId und ClientSecret sind die Grundlage, um einen Token vom OAuth-Server abfragen zu können. Die beiden Werte sind im [Self-Service-Portal der Testumgebung von FIT-Connect](https://portal.auth-testing.FIT-Connect.fitko.dev/clients) zu erstellen. # Sender Um einen Antrag mit dem SDK versenden zu können, werden eine ClientID und ein ClientSecret benötigt. [Hier](https://docs.fitko.de/fit-connect/docs/getting-started/account) ist beschrieben, wie Sie eine ClientID und ein ClientSecret erhalten. [Offizelle Dokumentation von FIT-Connect zum Versenden von Einreichungen (Anträgen)](https://docs.fitko.de/fit-connect/docs/sending/overview) ## Beispiel Das folgende Beispiel zeigt, wie Sie das SDK in einem sendenden System nutzen, um eine Submission (eine Einreichung) zu erzeugen und zu senden: ### Plain Submission Builder Wenn Antragsdaten im Backend des Senders (Onlinedienst) unverschlüsselt vorliegen, können diese mit dem `SubmissionBuilder` in ein verschlüsseltes Submission-Objekt umgewandelt werden. Diese Umsetzungsvariante bietet eine geringere Sicherheit als die Umsetzung der Ende-zu-Ende-Verschlüsselung ab dem Endgerät der Antragsteller:in. Zudem erhöhen sich in dieser Umsetzungsvariante die IT-Sicherheits- und Datenschutzanforderungen an den Betrieb des Onlinedienstes, da Antragsdaten in dieser Umsetzungsvariante im Klartext durch das Backend des Onlinedienstes verarbeitet werden. Eine Alternative stellt die Verschlüsselung von Antragsdaten im Frontend des Onlinedientes dar (siehe nächster Abschnitt *Encrypted Submission Builder*). Weitere Informationen finden sich im Artikel [Verschlüsselte Übertragung von Antragsdaten](https://docs.fitko.de/fit-connect/docs/getting-started/encryption/) der FIT-Connect-Dokumentation. ```csharp var client = Client.GetSender(FitConnectEnvironment.Testing, clientId, clientSecret, logger); var submission = SubmissionBuilder .WithDestination(destinationId) .WithServiceType(leikaKey, "FIT Connect Demo") .WithAttachments(new Attachment("Test.pdf", "Test Attachment")) .WithJsonData("{\"message\":\"Hello World\"}") .Build(); await client.SendAsync(submission); ``` Im Beispiel oben stellt das Argument "FitConnectEnvironment.Testing" die FIT-Connect-Endpunkte zur Verfügung, die aufgerufen werden sollen. Das Argument 'destinationId" enthält die eindeutige Adresse des empfangenden Systems (Fachverfahrens), das die Antragsdaten über FIT-Connect erhalten soll. Das Argument "leikaKey" stellt die ID der beantragten Leistung bereit. "Leika" ist die Abkürzung für "Leistungskatalog". Um `async/await` Aufrufe zu vermeiden, kann auch mit `.Result` gearbeitet werden: ```csharp Client.GetSender(FitConnectEnvironment.Testing, clientId, clientSecret, logger).SendAsync(submission).Result; ``` ### Encrypted Submission Builder Werden die Antragsdaten bereits [auf dem Endgerät der Anwender:in verschlüsselt (Ende-zu-Ende-Verschlüsselung)](https://docs.fitko.de/fit-connect/docs/getting-started/encryption/), so liegen diese im Backend des Senders (Onlinedienst) nur verschlüsselt vor. Das .NET-SDK bietet auch die Möglichkeit bereits verschlüsselte Submissions zu versenden. Zur Verschlüsselung von Antragsdaten im Frontend eines Onlinedienstes (im Browser auf dem Endgerät der Antragsteller:in) kann das FIT-Connect-JavaScript-SDK genutzt werden. Das JavaScript-SDK übernimmt dann die Verschlüsselung der Daten und das .NET-SDK im Backend des Onlinedienstes übermittelt die verschlüsselten Daten an den Zustelldienst. Der für die Verschlüsselung im JavaScript-SDK benötigte `PublicKey` MUSS hierbei vom .NET-SDK im Backend des Onlinedienstes [entsprechend der kryptographischen Anforderungen](https://docs.fitko.de/fit-connect/docs/details/crypto) validiert werden. Um den `PublicKey` des Zustellpunktes abzurufen, kann die Methode `GetPublicKeyForDestinationAsync` des .NET-SDK verwendet werden: ```csharp var publicKey = await Client .GetSender(FitConnectEnvironment.Testing, clientId, clientSecret, logger) .GetPublicKeyForDestinationAsync(destinationId); ``` Mit diesem `PublicKey` sind die Metadaten, die Fachdaten und die Anlagen im JavaScript-SDK zu verschlüsseln. Weitere Informationen finden sich im Artikel [Verschlüsselte Übertragung von Antragsdaten](https://docs.fitko.de/fit-connect/docs/getting-started/encryption/) der FIT-Connect-Dokumentation. Nachdem die bereits verschlüsselten Daten aus dem Browser an das Backend des Onlinedienstes übermittelt wurde, können diese mit dem `EncryptedSubmissionBuilder` zu einer Submission verbunden werden, die dann auf die gewohnte Weise versendet werden kann. ```csharp var encryptedSubmission = EncryptedSubmissionBuilder .WithDestination(destinationId) .WithServiceType("FIT Connect Demo", leikaKey) .WithEncryptedMetaData(encryptedMetadata!) .WithEncryptedData(encryptedData!) .WithEncryptedAttachments(encryptedAttachments!) .Build(); await Client.GetSender(FitConnectEnvironment.Testing, clientId, clientSecret, logger).SendAsync(encryptedSubmission); ``` | **Wichtig** | |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Bei der Übernahme der Destination-ID (`destinationId`) und des Leistungsschlüssels (`leikaKey`) aus dem Frontend MUSS im Backend geprüft werden, ob ein Versand von Einreichungen dieser Leistung an den angegebenen Zustellpunkt zulässig ist. | ## Details ```mermaid flowchart LR start([SubmissionBuilder]) destination(WithDestination) service(WithServiceType) attachments(WithAttachments) data(WithJsonData) encAttachments(WithEncryptedAttachments) encMetadata(WithEncryptedMetadata) encData(WithEncryptedData) build([Build]) sender([GetSender]) sendAsync([SendAsync]) sender-->sendAsync start-->destination-->service-->attachments-->data service-->encAttachments-->encMetadata-->encData data-->build encData-->build ``` Das SDK verhindert durch die FluentAPI, dass die Methoden in der falschen Reihenfolge aufgerufen werden können. ### SubmissionBuilder Der SubmissionBuilder ist für die Erstellung einer Submission zuständig. Das Senden der Submission an FIT-Connect übernimmt dann der Sender. Nachfolgend werden die einzelnen Methoden des SubmissionBuilders erklärt. ### .WithDestination(destinationId) Die `destinationId` des Zustellpunktes, an den die Submission geschickt werden soll, muss an dieser Stelle übergeben werden. _Noch nicht vollständig getestet!_<br> Eine Möglichkeit, die Destination ID zu ermitteln, geht über die Methode ``FindDestinationId()`` des Senders. ### .WithServiceType("FIT Connect Demo", leikaKey) Der Service Type muss an dieser Stelle übergeben werden. Hierfür wird ein Leistungsschlüssel (LeiKa-Schlüssel) benötigt. Leistungsschlüssel haben diese Form ```urn:de:fim:leika:leistung:99400048079000``` ### .WithAttachments(new Attachment("Test.pdf", "Test Attachment")) Die Anhänge zum Antrag werden mit ```.WithAttachments``` übergeben. Diese Methode erwartet ein Array von Attachment-Objekten, die als ```params``` übergeben werden können. Ein Attachment kann mit den folgenden Parametern erstellt werden: - Metadaten und byte[] content - Dateiname und Beschreibung Dazu werden zwei Konstruktoren bereitgestellt: - ```Attachment(Api.Metadata.Attachment metadata, byte[] content)``` - ```Attachment(string fileName, string description,)``` ### .WithData("{\"message\":\"Hello World\"}") Die Fachdaten werden als JSON-String übergeben. ### .Build() Die `Build`-Methode erzeugt eine `SendableSubmission`, die dann an den Sender übergeben werden kann. ### GetSender(FitConnectEnvironment.Testing, clientId, clientSecret, logger) Hier werden die FIT Connect Environment ausgewählt und die Credentials übergeben. Der Parameter ```logger``` ist optional und muss das Interface ```Microsoft.Extensions.Logging.ILogger``` implementieren. ### .SendAsync(submission) Das Abschicken der Submission erfolgt mit diesem Aufruf. ### Abrufen des Event-Logs und des Status' Der `sender` verfügt über eine Methode `GetEventLogAsync()` und `GetStatusForSubmissionAsync()` mit denen der aktuelle Status der Submission beim Zustelldienst abgefragt werden kann. ```csharp var (status, problems) = await sender.GetStatusForSubmission(sentSubmission); ``` Die SentSubmission enthält alle nottwendigen Informationen, um den Status abzufragen. Auch die `AthenticationTags` sind darin enthalten mit denen der Status überprüft werden kann. Der `status` beinhaltet den aktuellen _Zustand_ der Submission. In den `problems` sind Rückmeldungen vom _Subscriber_ enthalten. Das gesamte `EventLog` kann ebenfalls abgerufen werden. Dazu wird die Methode `sender.GetEventLogAsync(caseId, destinationId)` aufgerufen. Eine Überprüfung der Gültikeit des Statuses erfolgt hier **nicht**. # Subscriber Das folgende Beispiel zeigt, wie Sie das SDK in einem empfangenden System nutzen, um einen Subscriber zu erzeugen, der Einreichungen von sendenden Systemen erhält. ## Beispiel ```csharp var subscriber = Client.GetSubscriber(FitConnectEnvironment.Testing, clientId, clientSecret, privateKeyDecryption, privateKeySigning, publicKeyEncryption, publicKeySignatureVerification, logger); ``` Im Beispiel oben stellt das Argument "privateKeyDecryption" den JSON Web Key (JWK) für den privaten Schlüssel zum Entschlüsseln bereit. Das Argument 'privateKeySigning" enthält den JWK des privaten Schlüssels zum Signieren. Das Argument 'publicKeyEncryption" liefert den JWK des öffentlichen Schlüssels zum Verschlüsseln. Das Argument 'publicKeySignatureVerification" enthält den JWK des öffentlichen Schlüssels zum Überprüfen der Signatur. ### Abrufen der verfügbaren Submissions Das folgende Beispiel zeigt, wie Sie das SDK in einem empfangenden System nutzen, um beim Server (dem Zustelldienst von FIT-Connect) nachzufragen, welche Einreichungen (Submissions) zur Abholung bereitliegen. ```csharp var submissions = await subscriber.GetAvailableSubmissionsAsync(); ``` Das folgende Beispiel zeigt, wie Sie das SDK in einem empfangenden System nutzen, um bereitliegende Einreichungen mit ihren Anhängen vom Server (Zustelldienst) abzurufen. ### Abrufen der Submissions mit den Anhängen ```csharp foreach (var submission in submissions) { var requestedSubmission = await subscriber.RequestSubmissionAsync(submission.SubmissionId); var attachments = await requestedSubmission.GetAttachmentsAsync(); var data = requestedSubmission.GetDataJson(); // Additional custom checks var ok = AdditionalCustomChecksOutsideSDK(requestedSubmission, attachments, data); if (ok){ // Submission accept await requestedSubmission.AcceptSubmissionAsync(); } else { // or submission reject await requestedSubmission.RejectSubmissionAsync(); } } ``` ## Details ````mermaid flowchart LR start([GetSubscriber]) availableSub(GetAvailableSubmission) requestSub(RequestSubmission) subscriberWithSub([SubscriberWithSubmission]) subscriberWithSub_([SubscriberWithSubmission]) data(GetDataJson) attachments(GetAttachments) accept(AcceptSubmission) reject(RejectSubmission) forward(ForwardSubmission) finished{{Abgeschlossen}} rejected{{Zurueckgewiesen}} start-->availableSub-->requestSub-->subscriberWithSub subscriberWithSub_-->data-->attachments attachments-->accept-->finished attachments-->reject-->rejected attachments-->forward ```` ## .GetSubscriber(...) Hier werden die FIT-Connect-Environment, die Keys und die Credentials übergeben. Der Parameter ```logger``` ist optional und muss das Interface ```Microsoft.Extensions.Logging.ILogger``` implementieren. ## .GetAvailableSubmissionsAsync() Liefert eine Liste der verfügbaren Submissions zurück. ## .RequestSubmissionAsync(submissionId) Hiermit wird die Submission abgerufen und im Subscriber gespeichert. Der Rückgabewert der Funktion ist also _Subscriber mit einer Submission_ ## .GetDataJson() Liefert die Fachdaten als JSON-String zurück. ## .GetAttachmentsAsync() Gibt eine Liste mit den Attachments der Submission zurück. Die Attachments können so geprüft werden. ## .AcceptSubmissionAsync() Akzeptiert die Submission und löscht die Submission, die auf dem Server gespeichert ist. ## .RejectSubmissionAsync() Weist die Submission zurück. ## Beispiel ```csharp var subscriber = Client.GetSubscriber(FitConnectEnvironment.Testing, clientId, clientSecret, privateKeyDecryption, privateKeySigning, logger); var submissions = await subscriber.GetAvailableSubmissionsAsync(); // Alle verfügbaren Submissions laden foreach (var submission in submissions) { var subscriberWithSubmission = await subscriber.RequestSubmissionAsync(submission.SubmissionId); // Laden der Anhänge var attachments = await subscriberWithSubmission .GetAttachmentsAsync(); // Ausgabe der Fachdaten auf der Konsole logger.LogInformation("Fachdaten: {Data}", subscriberWithSubmission.GetDataJson()); // Submission akzeptieren und abschließen await subscriberWithSubmission.AcceptSubmissionAsync(); } ``` # Router Die Client-Implementierung der Routing-API ```csharp Client.GetRouter(FitConnectEnvironment.Development, logger); ``` [glossary](https://docs.fitko.de/fit-connect/docs/glossary/) ### License Source code is licensed under the [EUPL](LICENSES/EUPL-1.2.txt). Rechtlicher Hinweis: Dieses Software Development Kit (SDK) ist dazu bestimmt, die Anbindung einer Software an die FIT-Connect-Infrastruktur zu ermöglichen. Hierfür kann das SDK in die anzubindenden Software integriert werden. Erfolgt die Integration des SDK in unveränderter Form, liegt keine Bearbeitung im Sinne der EUPL bzw. des deutschen Urheberrechts vor. Die Art und Weise der Verlinkung des SDK führt insbesondere nicht zur Schaffung eines abgeleiteten Werkes. Die unveränderte Übernahme des SDK in eine anzubindende Software führt damit nicht dazu, dass die anzubindende Software unter den Bedingungen der EUPL zu lizenzieren ist. Für die Weitergabe des SDK selbst - in unveränderter oder bearbeiteter Form, als Quellcode oder ausführbares Programm - gelten die Lizenzbedingungen der EUPL in unveränderter Weise.