diff --git a/Models/Models.csproj b/Models/Models.csproj index 42326e5c3ec81e82a29317e741d328d2d68ef0b9..245b8c8d902f44288fb973cbc21b2653b5342dcf 100644 --- a/Models/Models.csproj +++ b/Models/Models.csproj @@ -7,4 +7,8 @@ <RootNamespace>FitConnect.Models</RootNamespace> </PropertyGroup> + <ItemGroup> + <PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> + </ItemGroup> + </Project> diff --git a/Services/Models/Api/Metadata.cs b/Services/Models/Api/Metadata.cs new file mode 100644 index 0000000000000000000000000000000000000000..adb00423acc5f7729507d4e42e6db8773aa5bd57 --- /dev/null +++ b/Services/Models/Api/Metadata.cs @@ -0,0 +1,1122 @@ +// <auto-generated /> +// +// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do: +// +// using FitConnect; +// +// var metadata = Metadata.FromJson(jsonString); + +namespace FitConnect.Models.Api.Metadata +{ + using System; + using System.Collections.Generic; + + using System.Globalization; + using Newtonsoft.Json; + using Newtonsoft.Json.Converters; + + public partial class Metadata + { + /// <summary> + /// Eine Struktur, um zusätzliche Informationen zu hinterlegen + /// </summary> + [JsonProperty("additionalReferenceInfo", NullValueHandling = NullValueHandling.Ignore)] + public AdditionalReferenceInfo AdditionalReferenceInfo { get; set; } + + /// <summary> + /// Eine Liste aller Identifikationsnachweise der Einreichung. + /// </summary> + [JsonProperty("authenticationInformation", NullValueHandling = NullValueHandling.Ignore)] + public List<AuthenticationInformation> AuthenticationInformation { get; set; } + + /// <summary> + /// Beschreibt die Struktur der zusätzlichen Inhalte der Einreichung, wie Anlagen oder + /// Fachdaten. + /// </summary> + [JsonProperty("contentStructure")] + public ContentStructure ContentStructure { get; set; } + + /// <summary> + /// Dieses Objekt enthält die Informationen vom Bezahldienst. + /// </summary> + [JsonProperty("paymentInformation", NullValueHandling = NullValueHandling.Ignore)] + public PaymentInformation PaymentInformation { get; set; } + + /// <summary> + /// Beschreibung der Art der Verwaltungsleistung. Eine Verwaltungsleistung sollte immer mit + /// einer LeiKa-Id beschrieben werden. Ist für die gegebene Verwaltungsleistung keine + /// LeiKa-Id vorhanden, kann die Verwaltungsleistung übergangsweise über die Angabe einer + /// anderen eindeutigen Schema-URN beschrieben werden. + /// </summary> + [JsonProperty("publicServiceType", NullValueHandling = NullValueHandling.Ignore)] + public Verwaltungsleistung PublicServiceType { get; set; } + + [JsonProperty("replyChannel", NullValueHandling = NullValueHandling.Ignore)] + public ReplyChannel ReplyChannel { get; set; } + } + + /// <summary> + /// Eine Struktur, um zusätzliche Informationen zu hinterlegen + /// </summary> + public partial class AdditionalReferenceInfo + { + /// <summary> + /// Das Datum der Antragstellung. Das Datum muss nicht zwingend identisch mit dem Datum der + /// Einreichung des Antrags über FIT-Connect sein. + /// </summary> + [JsonProperty("applicationDate", NullValueHandling = NullValueHandling.Ignore)] + public DateTimeOffset? ApplicationDate { get; set; } + + /// <summary> + /// Eine Referenz zum Vorgang im sendenden System, um bei Problemen und Rückfragen + /// außerhalb von FIT-Connect den Vorgang im dortigen System schneller zu identifizieren. + /// </summary> + [JsonProperty("senderReference", NullValueHandling = NullValueHandling.Ignore)] + public string SenderReference { get; set; } + } + + /// <summary> + /// Eine Struktur, die einen Identifikationsnachweis beschreibt. + /// </summary> + public partial class AuthenticationInformation + { + /// <summary> + /// Der Nachweis wird als Base64Url-kodierte Zeichenkette angegeben. + /// </summary> + [JsonProperty("content")] + public string Content { get; set; } + + /// <summary> + /// Definiert die Art des Identifikationsnachweises. + /// </summary> + [JsonProperty("type")] + public AuthenticationInformationType Type { get; set; } + + /// <summary> + /// semver kompatible Versionsangabe des genutzten Nachweistyps. + /// </summary> + [JsonProperty("version")] + public string Version { get; set; } + } + + /// <summary> + /// Beschreibt die Struktur der zusätzlichen Inhalte der Einreichung, wie Anlagen oder + /// Fachdaten. + /// </summary> + public partial class ContentStructure + { + [JsonProperty("attachments")] + public List<Attachment> Attachments { get; set; } + + /// <summary> + /// Definiert das Schema und die Signatur(-art), die für die Fachdaten verwendet werden. + /// </summary> + [JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)] + public Data Data { get; set; } + } + + /// <summary> + /// Eine in der Einreichung enthaltene Anlage. + /// </summary> + public partial class Attachment + { + /// <summary> + /// Innerhalb einer Einreichung eindeutige Id der Anlage im Format einer UUIDv4. + /// </summary> + [JsonProperty("attachmentId")] + public Guid AttachmentId { get; set; } + + /// <summary> + /// Optionale Beschreibung der Anlage + /// </summary> + [JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)] + public string Description { get; set; } + + /// <summary> + /// Ursprünglicher Dateiname bei Erzeugung oder Upload + /// </summary> + [JsonProperty("filename", NullValueHandling = NullValueHandling.Ignore)] + public string Filename { get; set; } + + /// <summary> + /// Der Hashwert der unverschlüsselten Anlage. Die Angabe des Hashwertes dient der + /// Integritätssicherung des Gesamtantrags und schützt vor einem Austausch der Anlage durch + /// Systeme zwischen Sender und Subscriber (z.B. dem Zustelldienst). + /// </summary> + [JsonProperty("hash")] + public AttachmentHash Hash { get; set; } + + /// <summary> + /// Internet Media Type gemäß RFC 2045, z. B. application/pdf. + /// </summary> + [JsonProperty("mimeType")] + public string MimeType { get; set; } + + /// <summary> + /// Zweck/Art der Anlage + /// - form: Automatisch generierte PDF-Repräsentation des vollständigen Antragsformulars + /// - attachment: Anlage, die von einem Bürger hochgeladen wurde + /// - report: Vom Onlinedienst, nachträglich erzeugte Unterlage + /// </summary> + [JsonProperty("purpose")] + public Purpose Purpose { get; set; } + + [JsonProperty("signature", NullValueHandling = NullValueHandling.Ignore)] + public AttachmentSignature Signature { get; set; } + } + + /// <summary> + /// Der Hashwert der unverschlüsselten Anlage. Die Angabe des Hashwertes dient der + /// Integritätssicherung des Gesamtantrags und schützt vor einem Austausch der Anlage durch + /// Systeme zwischen Sender und Subscriber (z.B. dem Zustelldienst). + /// </summary> + public partial class AttachmentHash + { + /// <summary> + /// Der Hex-kodierte Hashwert gemäß des angegebenen Algorithmus. + /// </summary> + [JsonProperty("content")] + public string Content { get; set; } + + /// <summary> + /// Der verwendete Hash-Algorithmus. Derzeit ist nur `sha512` erlaubt. + /// </summary> + [JsonProperty("type")] + public HashType Type { get; set; } + } + + /// <summary> + /// Beschreibt das Signaturformt und Profile + /// </summary> + public partial class AttachmentSignature + { + /// <summary> + /// Hier wird die Signatur im Falle einer Detached-Signatur als Base64- oder + /// Base64Url-kodierte Zeichenkette hinterlegt. Eine Base64Url-Kodierung kommt nur bei + /// Einsatz von JSON Web Signatures (JWS / JAdES) zum Einsatz. + /// </summary> + [JsonProperty("content", NullValueHandling = NullValueHandling.Ignore)] + public string Content { get; set; } + + /// <summary> + /// Beschreibt, ob die Signatur als seperate (detached) Signatur (`true`) oder als Teil des + /// Fachdatensatzes bzw. der Anlage (`false`) übertragen wird. Wenn der Wert `true` ist, + /// dann wird die Signatur Base64- oder Base64Url-kodiert im Feld `content` übertragen. + /// </summary> + [JsonProperty("detachedSignature")] + public bool DetachedSignature { get; set; } + + /// <summary> + /// Referenziert ein eindeutiges Profil einer AdES (advanced electronic signature/seal) + /// gemäß eIDAS-Verordnung über eine URI gemäß [ETSI TS 119 + /// 192](https://www.etsi.org/deliver/etsi_ts/119100_119199/119192/01.01.01_60/ts_119192v010101p.pdf). + /// + /// Für die Details zur Verwendung und Validierung von Profilen siehe auch + /// https://ec.europa.eu/cefdigital/DSS/webapp-demo/doc/dss-documentation.html#_signatures_profile_simplification + /// </summary> + [JsonProperty("eidasAdesProfile", NullValueHandling = NullValueHandling.Ignore)] + public EidasAdesProfile? EidasAdesProfile { get; set; } + + /// <summary> + /// Beschreibt, welches Signaturformat die genutzte Signatur / das genutzte Siegel nutzt. + /// Aktuell wird die Hinterlegung folgender Signaturformate unterstützt: CMS = Cryptographic + /// Message Syntax, Asic = Associated Signature Containers, PDF = PDF Signatur, XML = + /// XML-Signature, JSON = JSON Web Signature. + /// </summary> + [JsonProperty("signatureFormat")] + public SignatureFormat SignatureFormat { get; set; } + } + + /// <summary> + /// Definiert das Schema und die Signatur(-art), die für die Fachdaten verwendet werden. + /// </summary> + public partial class Data + { + /// <summary> + /// Der Hashwert der unverschlüsselten Fachdaten. Die Angabe des Hashwertes dient der + /// Integritätssicherung des Gesamtantrags und schützt vor einem Austausch der Fachdaten + /// durch Systeme zwischen Sender und Subscriber (z.B. dem Zustelldienst). + /// </summary> + [JsonProperty("hash")] + public DataHash Hash { get; set; } + + /// <summary> + /// Beschreibt das Signaturformt und Profile + /// </summary> + [JsonProperty("signature", NullValueHandling = NullValueHandling.Ignore)] + public DataSignature Signature { get; set; } + + /// <summary> + /// Referenz auf ein Schema, das die Struktur der Fachdaten einer Einreichung beschreibt. + /// </summary> + [JsonProperty("submissionSchema")] + public Fachdatenschema SubmissionSchema { get; set; } + } + + /// <summary> + /// Der Hashwert der unverschlüsselten Fachdaten. Die Angabe des Hashwertes dient der + /// Integritätssicherung des Gesamtantrags und schützt vor einem Austausch der Fachdaten + /// durch Systeme zwischen Sender und Subscriber (z.B. dem Zustelldienst). + /// </summary> + public partial class DataHash + { + /// <summary> + /// Der Hex-kodierte Hashwert gemäß des angegebenen Algorithmus. + /// </summary> + [JsonProperty("content")] + public string Content { get; set; } + + /// <summary> + /// Der verwendete Hash-Algorithmus. Derzeit ist nur `sha512` erlaubt. + /// </summary> + [JsonProperty("type")] + public HashType Type { get; set; } + } + + /// <summary> + /// Beschreibt das Signaturformt und Profile + /// </summary> + public partial class DataSignature + { + /// <summary> + /// Hier wird die Signatur im Falle einer Detached-Signatur als Base64- oder + /// Base64Url-kodierte Zeichenkette hinterlegt. Eine Base64Url-Kodierung kommt nur bei + /// Einsatz von JSON Web Signatures (JWS / JAdES) zum Einsatz. + /// </summary> + [JsonProperty("content", NullValueHandling = NullValueHandling.Ignore)] + public string Content { get; set; } + + /// <summary> + /// Beschreibt, ob die Signatur als seperate (detached) Signatur (`true`) oder als Teil des + /// Fachdatensatzes bzw. der Anlage (`false`) übertragen wird. Wenn der Wert `true` ist, + /// dann wird die Signatur Base64- oder Base64Url-kodiert im Feld `content` übertragen. + /// </summary> + [JsonProperty("detachedSignature")] + public bool DetachedSignature { get; set; } + + /// <summary> + /// Referenziert ein eindeutiges Profil einer AdES (advanced electronic signature/seal) + /// gemäß eIDAS-Verordnung über eine URI gemäß [ETSI TS 119 + /// 192](https://www.etsi.org/deliver/etsi_ts/119100_119199/119192/01.01.01_60/ts_119192v010101p.pdf). + /// + /// Für die Details zur Verwendung und Validierung von Profilen siehe auch + /// https://ec.europa.eu/cefdigital/DSS/webapp-demo/doc/dss-documentation.html#_signatures_profile_simplification + /// </summary> + [JsonProperty("eidasAdesProfile", NullValueHandling = NullValueHandling.Ignore)] + public EidasAdesProfile? EidasAdesProfile { get; set; } + + /// <summary> + /// Beschreibt, welches Signaturformat die genutzte Signatur / das genutzte Siegel nutzt. + /// Aktuell wird die Hinterlegung folgender Signaturformate unterstützt: CMS = Cryptographic + /// Message Syntax, Asic = Associated Signature Containers, PDF = PDF Signatur, XML = + /// XML-Signature, JSON = JSON Web Signature. + /// </summary> + [JsonProperty("signatureFormat")] + public SignatureFormat SignatureFormat { get; set; } + } + + /// <summary> + /// Referenz auf ein Schema, das die Struktur der Fachdaten einer Einreichung beschreibt. + /// </summary> + public partial class Fachdatenschema + { + /// <summary> + /// Mimetype (z.B. application/json oder application/xml) des referenzierten Schemas (z.B. + /// XSD- oder JSON-Schema). + /// </summary> + [JsonProperty("mimeType")] + public MimeType MimeType { get; set; } + + /// <summary> + /// URI des Fachschemas. Wird hier eine URL verwendet, sollte das Schema unter der + /// angegebenen URL abrufbar sein. Eine Verfügbarkeit des Schemas unter der angegebenen URL + /// darf jedoch nicht vorausgesetzt werden. + /// </summary> + [JsonProperty("schemaUri")] + public Uri SchemaUri { get; set; } + } + + /// <summary> + /// Dieses Objekt enthält die Informationen vom Bezahldienst. + /// </summary> + public partial class PaymentInformation + { + /// <summary> + /// Bruttobetrag + /// </summary> + [JsonProperty("grossAmount", NullValueHandling = NullValueHandling.Ignore)] + [JsonConverter(typeof(MinMaxValueCheckConverter))] + public double? GrossAmount { get; set; } + + /// <summary> + /// Die vom Benutzer ausgewählte Zahlart. Das Feld ist nur bei einer erfolgreichen Zahlung + /// vorhanden / befüllt. + /// </summary> + [JsonProperty("paymentMethod")] + public PaymentMethod PaymentMethod { get; set; } + + /// <summary> + /// Weitere Erläuterung zur gewählten Zahlart. + /// </summary> + [JsonProperty("paymentMethodDetail", NullValueHandling = NullValueHandling.Ignore)] + [JsonConverter(typeof(PurpleMinMaxLengthCheckConverter))] + public string PaymentMethodDetail { get; set; } + + /// <summary> + /// - INITIAL - der Einreichung hat einen Payment-Request ausgelöst und eine + /// Payment-Transaction wurde angelegt. Der Nutzer hat aber im Bezahldienst noch keine + /// Wirkung erzeugt. + /// - BOOKED - der Nutzer hat die Bezahlung im Bezahldienst autorisiert. + /// - FAILED - der Vorgang wurde vom Bezahldienst aufgrund der Nutzereingaben abgebrochen. + /// - CANCELED - der Nutzer hat die Bezahlung im Bezahldienst abgebrochen. + /// </summary> + [JsonProperty("status")] + public Status Status { get; set; } + + /// <summary> + /// Eine vom Bezahldienst vergebene Transaktions-Id. + /// </summary> + [JsonProperty("transactionId")] + [JsonConverter(typeof(PurpleMinMaxLengthCheckConverter))] + public string TransactionId { get; set; } + + /// <summary> + /// Bezahlreferenz bzw. Verwendungszweck, wie z. B. ein Kassenzeichen. + /// </summary> + [JsonProperty("transactionReference")] + public string TransactionReference { get; set; } + + /// <summary> + /// Zeitstempel der erfolgreichen Durchführung der Bezahlung. + /// </summary> + [JsonProperty("transactionTimestamp", NullValueHandling = NullValueHandling.Ignore)] + public DateTimeOffset? TransactionTimestamp { get; set; } + + /// <summary> + /// Die Rest-URL der Payment Transaction für die Statusabfrage. + /// </summary> + [JsonProperty("transactionUrl", NullValueHandling = NullValueHandling.Ignore)] + public Uri TransactionUrl { get; set; } + } + + /// <summary> + /// Beschreibung der Art der Verwaltungsleistung. Eine Verwaltungsleistung sollte immer mit + /// einer LeiKa-Id beschrieben werden. Ist für die gegebene Verwaltungsleistung keine + /// LeiKa-Id vorhanden, kann die Verwaltungsleistung übergangsweise über die Angabe einer + /// anderen eindeutigen Schema-URN beschrieben werden. + /// </summary> + public partial class Verwaltungsleistung + { + /// <summary> + /// (Kurz-)Beschreibung der Verwaltungsleistung + /// </summary> + [JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)] + public string Description { get; set; } + + /// <summary> + /// URN einer Leistung. Im Falle einer Leistung aus dem Leistungskatalog sollte hier + /// `urn:de:fim:leika:leistung:` vorangestellt werden. + /// </summary> + [JsonProperty("identifier")] + [JsonConverter(typeof(FluffyMinMaxLengthCheckConverter))] + public string Identifier { get; set; } + + /// <summary> + /// Name/Bezeichnung der Verwaltungsleistung + /// </summary> + [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] + public string Name { get; set; } + } + + public partial class ReplyChannel + { + /// <summary> + /// Akkreditierte Anbieter siehe + /// https://www.bsi.bund.de/DE/Themen/Oeffentliche-Verwaltung/Moderner-Staat/De-Mail/Akkreditierte-DMDA/akkreditierte-dmda_node.html + /// </summary> + [JsonProperty("deMail", NullValueHandling = NullValueHandling.Ignore)] + public DeMail DeMail { get; set; } + + /// <summary> + /// Siehe https://www.elster.de/elsterweb/infoseite/elstertransfer_hilfe_schnittstellen + /// </summary> + [JsonProperty("elster", NullValueHandling = NullValueHandling.Ignore)] + public Elster Elster { get; set; } + + [JsonProperty("eMail", NullValueHandling = NullValueHandling.Ignore)] + public EMail EMail { get; set; } + + /// <summary> + /// Postfachadresse in einem interoperablen Servicekonto (FINK.PFISK) + /// </summary> + [JsonProperty("fink", NullValueHandling = NullValueHandling.Ignore)] + public Fink Fink { get; set; } + } + + /// <summary> + /// Akkreditierte Anbieter siehe + /// https://www.bsi.bund.de/DE/Themen/Oeffentliche-Verwaltung/Moderner-Staat/De-Mail/Akkreditierte-DMDA/akkreditierte-dmda_node.html + /// </summary> + public partial class DeMail + { + [JsonProperty("address")] + public string Address { get; set; } + } + + public partial class EMail + { + [JsonProperty("address")] + public string Address { get; set; } + + /// <summary> + /// Hilfe zur Erstellung gibt es in der Dokumentation unter + /// https://docs.fitko.de/fit-connect/details/pgp-export + /// </summary> + [JsonProperty("pgpPublicKey", NullValueHandling = NullValueHandling.Ignore)] + public string PgpPublicKey { get; set; } + } + + /// <summary> + /// Siehe https://www.elster.de/elsterweb/infoseite/elstertransfer_hilfe_schnittstellen + /// </summary> + public partial class Elster + { + [JsonProperty("accountId")] + public string AccountId { get; set; } + + [JsonProperty("geschaeftszeichen", NullValueHandling = NullValueHandling.Ignore)] + [JsonConverter(typeof(TentacledMinMaxLengthCheckConverter))] + public string Geschaeftszeichen { get; set; } + + [JsonProperty("lieferTicket", NullValueHandling = NullValueHandling.Ignore)] + public string LieferTicket { get; set; } + } + + /// <summary> + /// Postfachadresse in einem interoperablen Servicekonto (FINK.PFISK) + /// </summary> + public partial class Fink + { + /// <summary> + /// FINK Postfachadresse + /// </summary> + [JsonProperty("finkPostfachRef")] + [JsonConverter(typeof(StickyMinMaxLengthCheckConverter))] + public string FinkPostfachRef { get; set; } + + /// <summary> + /// URL des Servicekontos, in dem das Ziel-Postfach liegt + /// </summary> + [JsonProperty("host", NullValueHandling = NullValueHandling.Ignore)] + public Uri Host { get; set; } + } + + /// <summary> + /// Definiert die Art des Identifikationsnachweises. + /// </summary> + public enum AuthenticationInformationType { IdentificationReport }; + + /// <summary> + /// Der verwendete Hash-Algorithmus. Derzeit ist nur `sha512` erlaubt. + /// </summary> + public enum HashType { Sha512 }; + + /// <summary> + /// Zweck/Art der Anlage + /// - form: Automatisch generierte PDF-Repräsentation des vollständigen Antragsformulars + /// - attachment: Anlage, die von einem Bürger hochgeladen wurde + /// - report: Vom Onlinedienst, nachträglich erzeugte Unterlage + /// </summary> + public enum Purpose { Attachment, Form, Report }; + + /// <summary> + /// Referenziert ein eindeutiges Profil einer AdES (advanced electronic signature/seal) + /// gemäß eIDAS-Verordnung über eine URI gemäß [ETSI TS 119 + /// 192](https://www.etsi.org/deliver/etsi_ts/119100_119199/119192/01.01.01_60/ts_119192v010101p.pdf). + /// + /// Für die Details zur Verwendung und Validierung von Profilen siehe auch + /// https://ec.europa.eu/cefdigital/DSS/webapp-demo/doc/dss-documentation.html#_signatures_profile_simplification + /// </summary> + public enum EidasAdesProfile { HttpUriEtsiOrgAdes191X2LevelBaselineBB, HttpUriEtsiOrgAdes191X2LevelBaselineBLt, HttpUriEtsiOrgAdes191X2LevelBaselineBLta, HttpUriEtsiOrgAdes191X2LevelBaselineBT }; + + /// <summary> + /// Beschreibt, welches Signaturformat die genutzte Signatur / das genutzte Siegel nutzt. + /// Aktuell wird die Hinterlegung folgender Signaturformate unterstützt: CMS = Cryptographic + /// Message Syntax, Asic = Associated Signature Containers, PDF = PDF Signatur, XML = + /// XML-Signature, JSON = JSON Web Signature. + /// </summary> + public enum SignatureFormat { Asic, Cms, Json, Pdf, Xml }; + + /// <summary> + /// Mimetype (z.B. application/json oder application/xml) des referenzierten Schemas (z.B. + /// XSD- oder JSON-Schema). + /// </summary> + public enum MimeType { ApplicationJson, ApplicationXml }; + + /// <summary> + /// Die vom Benutzer ausgewählte Zahlart. Das Feld ist nur bei einer erfolgreichen Zahlung + /// vorhanden / befüllt. + /// </summary> + public enum PaymentMethod { Creditcard, Giropay, Invoice, Other, Paydirect, Paypal }; + + /// <summary> + /// - INITIAL - der Einreichung hat einen Payment-Request ausgelöst und eine + /// Payment-Transaction wurde angelegt. Der Nutzer hat aber im Bezahldienst noch keine + /// Wirkung erzeugt. + /// - BOOKED - der Nutzer hat die Bezahlung im Bezahldienst autorisiert. + /// - FAILED - der Vorgang wurde vom Bezahldienst aufgrund der Nutzereingaben abgebrochen. + /// - CANCELED - der Nutzer hat die Bezahlung im Bezahldienst abgebrochen. + /// </summary> + public enum Status { Booked, Canceled, Failed, Initial }; + + public partial class Metadata + { + public static Metadata FromJson(string json) => JsonConvert.DeserializeObject<Metadata>(json, FitConnect.Models.Api.Metadata.Converter.Settings); + } + + public static class Serialize + { + public static string ToJson(this Metadata self) => JsonConvert.SerializeObject(self, FitConnect.Models.Api.Metadata.Converter.Settings); + } + + internal static class Converter + { + public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings + { + MetadataPropertyHandling = MetadataPropertyHandling.Ignore, + DateParseHandling = DateParseHandling.None, + Converters = + { + AuthenticationInformationTypeConverter.Singleton, + HashTypeConverter.Singleton, + PurposeConverter.Singleton, + EidasAdesProfileConverter.Singleton, + SignatureFormatConverter.Singleton, + MimeTypeConverter.Singleton, + PaymentMethodConverter.Singleton, + StatusConverter.Singleton, + new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal } + }, + }; + } + + internal class AuthenticationInformationTypeConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(AuthenticationInformationType) || t == typeof(AuthenticationInformationType?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize<string>(reader); + if (value == "identificationReport") + { + return AuthenticationInformationType.IdentificationReport; + } + throw new Exception("Cannot unmarshal type AuthenticationInformationType"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (AuthenticationInformationType)untypedValue; + if (value == AuthenticationInformationType.IdentificationReport) + { + serializer.Serialize(writer, "identificationReport"); + return; + } + throw new Exception("Cannot marshal type AuthenticationInformationType"); + } + + public static readonly AuthenticationInformationTypeConverter Singleton = new AuthenticationInformationTypeConverter(); + } + + internal class HashTypeConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(HashType) || t == typeof(HashType?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize<string>(reader); + if (value == "sha512") + { + return HashType.Sha512; + } + throw new Exception("Cannot unmarshal type HashType"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (HashType)untypedValue; + if (value == HashType.Sha512) + { + serializer.Serialize(writer, "sha512"); + return; + } + throw new Exception("Cannot marshal type HashType"); + } + + public static readonly HashTypeConverter Singleton = new HashTypeConverter(); + } + + internal class PurposeConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(Purpose) || t == typeof(Purpose?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize<string>(reader); + switch (value) + { + case "attachment": + return Purpose.Attachment; + case "form": + return Purpose.Form; + case "report": + return Purpose.Report; + } + throw new Exception("Cannot unmarshal type Purpose"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (Purpose)untypedValue; + switch (value) + { + case Purpose.Attachment: + serializer.Serialize(writer, "attachment"); + return; + case Purpose.Form: + serializer.Serialize(writer, "form"); + return; + case Purpose.Report: + serializer.Serialize(writer, "report"); + return; + } + throw new Exception("Cannot marshal type Purpose"); + } + + public static readonly PurposeConverter Singleton = new PurposeConverter(); + } + + internal class EidasAdesProfileConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(EidasAdesProfile) || t == typeof(EidasAdesProfile?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize<string>(reader); + switch (value) + { + case "http://uri.etsi.org/ades/191x2/level/baseline/B-B#": + return EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBB; + case "http://uri.etsi.org/ades/191x2/level/baseline/B-LT#": + return EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBLt; + case "http://uri.etsi.org/ades/191x2/level/baseline/B-LTA#": + return EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBLta; + case "http://uri.etsi.org/ades/191x2/level/baseline/B-T#": + return EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBT; + } + throw new Exception("Cannot unmarshal type EidasAdesProfile"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (EidasAdesProfile)untypedValue; + switch (value) + { + case EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBB: + serializer.Serialize(writer, "http://uri.etsi.org/ades/191x2/level/baseline/B-B#"); + return; + case EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBLt: + serializer.Serialize(writer, "http://uri.etsi.org/ades/191x2/level/baseline/B-LT#"); + return; + case EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBLta: + serializer.Serialize(writer, "http://uri.etsi.org/ades/191x2/level/baseline/B-LTA#"); + return; + case EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBT: + serializer.Serialize(writer, "http://uri.etsi.org/ades/191x2/level/baseline/B-T#"); + return; + } + throw new Exception("Cannot marshal type EidasAdesProfile"); + } + + public static readonly EidasAdesProfileConverter Singleton = new EidasAdesProfileConverter(); + } + + internal class SignatureFormatConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(SignatureFormat) || t == typeof(SignatureFormat?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize<string>(reader); + switch (value) + { + case "asic": + return SignatureFormat.Asic; + case "cms": + return SignatureFormat.Cms; + case "json": + return SignatureFormat.Json; + case "pdf": + return SignatureFormat.Pdf; + case "xml": + return SignatureFormat.Xml; + } + throw new Exception("Cannot unmarshal type SignatureFormat"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (SignatureFormat)untypedValue; + switch (value) + { + case SignatureFormat.Asic: + serializer.Serialize(writer, "asic"); + return; + case SignatureFormat.Cms: + serializer.Serialize(writer, "cms"); + return; + case SignatureFormat.Json: + serializer.Serialize(writer, "json"); + return; + case SignatureFormat.Pdf: + serializer.Serialize(writer, "pdf"); + return; + case SignatureFormat.Xml: + serializer.Serialize(writer, "xml"); + return; + } + throw new Exception("Cannot marshal type SignatureFormat"); + } + + public static readonly SignatureFormatConverter Singleton = new SignatureFormatConverter(); + } + + internal class MimeTypeConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(MimeType) || t == typeof(MimeType?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize<string>(reader); + switch (value) + { + case "application/json": + return MimeType.ApplicationJson; + case "application/xml": + return MimeType.ApplicationXml; + } + throw new Exception("Cannot unmarshal type MimeType"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (MimeType)untypedValue; + switch (value) + { + case MimeType.ApplicationJson: + serializer.Serialize(writer, "application/json"); + return; + case MimeType.ApplicationXml: + serializer.Serialize(writer, "application/xml"); + return; + } + throw new Exception("Cannot marshal type MimeType"); + } + + public static readonly MimeTypeConverter Singleton = new MimeTypeConverter(); + } + + internal class MinMaxValueCheckConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(double) || t == typeof(double?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize<double>(reader); + if (value >= 0.01) + { + return value; + } + throw new Exception("Cannot unmarshal type double"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (double)untypedValue; + if (value >= 0.01) + { + serializer.Serialize(writer, value); + return; + } + throw new Exception("Cannot marshal type double"); + } + + public static readonly MinMaxValueCheckConverter Singleton = new MinMaxValueCheckConverter(); + } + + internal class PaymentMethodConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(PaymentMethod) || t == typeof(PaymentMethod?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize<string>(reader); + switch (value) + { + case "CREDITCARD": + return PaymentMethod.Creditcard; + case "GIROPAY": + return PaymentMethod.Giropay; + case "INVOICE": + return PaymentMethod.Invoice; + case "OTHER": + return PaymentMethod.Other; + case "PAYDIRECT": + return PaymentMethod.Paydirect; + case "PAYPAL": + return PaymentMethod.Paypal; + } + throw new Exception("Cannot unmarshal type PaymentMethod"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (PaymentMethod)untypedValue; + switch (value) + { + case PaymentMethod.Creditcard: + serializer.Serialize(writer, "CREDITCARD"); + return; + case PaymentMethod.Giropay: + serializer.Serialize(writer, "GIROPAY"); + return; + case PaymentMethod.Invoice: + serializer.Serialize(writer, "INVOICE"); + return; + case PaymentMethod.Other: + serializer.Serialize(writer, "OTHER"); + return; + case PaymentMethod.Paydirect: + serializer.Serialize(writer, "PAYDIRECT"); + return; + case PaymentMethod.Paypal: + serializer.Serialize(writer, "PAYPAL"); + return; + } + throw new Exception("Cannot marshal type PaymentMethod"); + } + + public static readonly PaymentMethodConverter Singleton = new PaymentMethodConverter(); + } + + internal class PurpleMinMaxLengthCheckConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(string); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + var value = serializer.Deserialize<string>(reader); + if (value.Length >= 1 && value.Length <= 36) + { + return value; + } + throw new Exception("Cannot unmarshal type string"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + var value = (string)untypedValue; + if (value.Length >= 1 && value.Length <= 36) + { + serializer.Serialize(writer, value); + return; + } + throw new Exception("Cannot marshal type string"); + } + + public static readonly PurpleMinMaxLengthCheckConverter Singleton = new PurpleMinMaxLengthCheckConverter(); + } + + internal class StatusConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(Status) || t == typeof(Status?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize<string>(reader); + switch (value) + { + case "BOOKED": + return Status.Booked; + case "CANCELED": + return Status.Canceled; + case "FAILED": + return Status.Failed; + case "INITIAL": + return Status.Initial; + } + throw new Exception("Cannot unmarshal type Status"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (Status)untypedValue; + switch (value) + { + case Status.Booked: + serializer.Serialize(writer, "BOOKED"); + return; + case Status.Canceled: + serializer.Serialize(writer, "CANCELED"); + return; + case Status.Failed: + serializer.Serialize(writer, "FAILED"); + return; + case Status.Initial: + serializer.Serialize(writer, "INITIAL"); + return; + } + throw new Exception("Cannot marshal type Status"); + } + + public static readonly StatusConverter Singleton = new StatusConverter(); + } + + internal class FluffyMinMaxLengthCheckConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(string); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + var value = serializer.Deserialize<string>(reader); + if (value.Length >= 7 && value.Length <= 255) + { + return value; + } + throw new Exception("Cannot unmarshal type string"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + var value = (string)untypedValue; + if (value.Length >= 7 && value.Length <= 255) + { + serializer.Serialize(writer, value); + return; + } + throw new Exception("Cannot marshal type string"); + } + + public static readonly FluffyMinMaxLengthCheckConverter Singleton = new FluffyMinMaxLengthCheckConverter(); + } + + internal class TentacledMinMaxLengthCheckConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(string); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + var value = serializer.Deserialize<string>(reader); + if (value.Length <= 10) + { + return value; + } + throw new Exception("Cannot unmarshal type string"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + var value = (string)untypedValue; + if (value.Length <= 10) + { + serializer.Serialize(writer, value); + return; + } + throw new Exception("Cannot marshal type string"); + } + + public static readonly TentacledMinMaxLengthCheckConverter Singleton = new TentacledMinMaxLengthCheckConverter(); + } + + internal class StickyMinMaxLengthCheckConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(string); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + var value = serializer.Deserialize<string>(reader); + if (value.Length <= 150) + { + return value; + } + throw new Exception("Cannot unmarshal type string"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + var value = (string)untypedValue; + if (value.Length <= 150) + { + serializer.Serialize(writer, value); + return; + } + throw new Exception("Cannot marshal type string"); + } + + public static readonly StickyMinMaxLengthCheckConverter Singleton = new StickyMinMaxLengthCheckConverter(); + } +} diff --git a/Services/Models/Api/SecurityEventToken.cs b/Services/Models/Api/SecurityEventToken.cs new file mode 100644 index 0000000000000000000000000000000000000000..fccc4762f5ab79409b498649117f7fc057fd6979 --- /dev/null +++ b/Services/Models/Api/SecurityEventToken.cs @@ -0,0 +1,1122 @@ +// <auto-generated /> +// +// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do: +// +// using FitConnect; +// +// var metadata = Metadata.FromJson(jsonString); + +namespace FitConnect.Models.Api.Set +{ + using System; + using System.Collections.Generic; + + using System.Globalization; + using Newtonsoft.Json; + using Newtonsoft.Json.Converters; + + public partial class Metadata + { + /// <summary> + /// Eine Struktur, um zusätzliche Informationen zu hinterlegen + /// </summary> + [JsonProperty("additionalReferenceInfo", NullValueHandling = NullValueHandling.Ignore)] + public AdditionalReferenceInfo AdditionalReferenceInfo { get; set; } + + /// <summary> + /// Eine Liste aller Identifikationsnachweise der Einreichung. + /// </summary> + [JsonProperty("authenticationInformation", NullValueHandling = NullValueHandling.Ignore)] + public List<AuthenticationInformation> AuthenticationInformation { get; set; } + + /// <summary> + /// Beschreibt die Struktur der zusätzlichen Inhalte der Einreichung, wie Anlagen oder + /// Fachdaten. + /// </summary> + [JsonProperty("contentStructure")] + public ContentStructure ContentStructure { get; set; } + + /// <summary> + /// Dieses Objekt enthält die Informationen vom Bezahldienst. + /// </summary> + [JsonProperty("paymentInformation", NullValueHandling = NullValueHandling.Ignore)] + public PaymentInformation PaymentInformation { get; set; } + + /// <summary> + /// Beschreibung der Art der Verwaltungsleistung. Eine Verwaltungsleistung sollte immer mit + /// einer LeiKa-Id beschrieben werden. Ist für die gegebene Verwaltungsleistung keine + /// LeiKa-Id vorhanden, kann die Verwaltungsleistung übergangsweise über die Angabe einer + /// anderen eindeutigen Schema-URN beschrieben werden. + /// </summary> + [JsonProperty("publicServiceType", NullValueHandling = NullValueHandling.Ignore)] + public Verwaltungsleistung PublicServiceType { get; set; } + + [JsonProperty("replyChannel", NullValueHandling = NullValueHandling.Ignore)] + public ReplyChannel ReplyChannel { get; set; } + } + + /// <summary> + /// Eine Struktur, um zusätzliche Informationen zu hinterlegen + /// </summary> + public partial class AdditionalReferenceInfo + { + /// <summary> + /// Das Datum der Antragstellung. Das Datum muss nicht zwingend identisch mit dem Datum der + /// Einreichung des Antrags über FIT-Connect sein. + /// </summary> + [JsonProperty("applicationDate", NullValueHandling = NullValueHandling.Ignore)] + public DateTimeOffset? ApplicationDate { get; set; } + + /// <summary> + /// Eine Referenz zum Vorgang im sendenden System, um bei Problemen und Rückfragen + /// außerhalb von FIT-Connect den Vorgang im dortigen System schneller zu identifizieren. + /// </summary> + [JsonProperty("senderReference", NullValueHandling = NullValueHandling.Ignore)] + public string SenderReference { get; set; } + } + + /// <summary> + /// Eine Struktur, die einen Identifikationsnachweis beschreibt. + /// </summary> + public partial class AuthenticationInformation + { + /// <summary> + /// Der Nachweis wird als Base64Url-kodierte Zeichenkette angegeben. + /// </summary> + [JsonProperty("content")] + public string Content { get; set; } + + /// <summary> + /// Definiert die Art des Identifikationsnachweises. + /// </summary> + [JsonProperty("type")] + public AuthenticationInformationType Type { get; set; } + + /// <summary> + /// semver kompatible Versionsangabe des genutzten Nachweistyps. + /// </summary> + [JsonProperty("version")] + public string Version { get; set; } + } + + /// <summary> + /// Beschreibt die Struktur der zusätzlichen Inhalte der Einreichung, wie Anlagen oder + /// Fachdaten. + /// </summary> + public partial class ContentStructure + { + [JsonProperty("attachments")] + public List<Attachment> Attachments { get; set; } + + /// <summary> + /// Definiert das Schema und die Signatur(-art), die für die Fachdaten verwendet werden. + /// </summary> + [JsonProperty("data", NullValueHandling = NullValueHandling.Ignore)] + public Data Data { get; set; } + } + + /// <summary> + /// Eine in der Einreichung enthaltene Anlage. + /// </summary> + public partial class Attachment + { + /// <summary> + /// Innerhalb einer Einreichung eindeutige Id der Anlage im Format einer UUIDv4. + /// </summary> + [JsonProperty("attachmentId")] + public Guid AttachmentId { get; set; } + + /// <summary> + /// Optionale Beschreibung der Anlage + /// </summary> + [JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)] + public string Description { get; set; } + + /// <summary> + /// Ursprünglicher Dateiname bei Erzeugung oder Upload + /// </summary> + [JsonProperty("filename", NullValueHandling = NullValueHandling.Ignore)] + public string Filename { get; set; } + + /// <summary> + /// Der Hashwert der unverschlüsselten Anlage. Die Angabe des Hashwertes dient der + /// Integritätssicherung des Gesamtantrags und schützt vor einem Austausch der Anlage durch + /// Systeme zwischen Sender und Subscriber (z.B. dem Zustelldienst). + /// </summary> + [JsonProperty("hash")] + public AttachmentHash Hash { get; set; } + + /// <summary> + /// Internet Media Type gemäß RFC 2045, z. B. application/pdf. + /// </summary> + [JsonProperty("mimeType")] + public string MimeType { get; set; } + + /// <summary> + /// Zweck/Art der Anlage + /// - form: Automatisch generierte PDF-Repräsentation des vollständigen Antragsformulars + /// - attachment: Anlage, die von einem Bürger hochgeladen wurde + /// - report: Vom Onlinedienst, nachträglich erzeugte Unterlage + /// </summary> + [JsonProperty("purpose")] + public Purpose Purpose { get; set; } + + [JsonProperty("signature", NullValueHandling = NullValueHandling.Ignore)] + public AttachmentSignature Signature { get; set; } + } + + /// <summary> + /// Der Hashwert der unverschlüsselten Anlage. Die Angabe des Hashwertes dient der + /// Integritätssicherung des Gesamtantrags und schützt vor einem Austausch der Anlage durch + /// Systeme zwischen Sender und Subscriber (z.B. dem Zustelldienst). + /// </summary> + public partial class AttachmentHash + { + /// <summary> + /// Der Hex-kodierte Hashwert gemäß des angegebenen Algorithmus. + /// </summary> + [JsonProperty("content")] + public string Content { get; set; } + + /// <summary> + /// Der verwendete Hash-Algorithmus. Derzeit ist nur `sha512` erlaubt. + /// </summary> + [JsonProperty("type")] + public HashType Type { get; set; } + } + + /// <summary> + /// Beschreibt das Signaturformt und Profile + /// </summary> + public partial class AttachmentSignature + { + /// <summary> + /// Hier wird die Signatur im Falle einer Detached-Signatur als Base64- oder + /// Base64Url-kodierte Zeichenkette hinterlegt. Eine Base64Url-Kodierung kommt nur bei + /// Einsatz von JSON Web Signatures (JWS / JAdES) zum Einsatz. + /// </summary> + [JsonProperty("content", NullValueHandling = NullValueHandling.Ignore)] + public string Content { get; set; } + + /// <summary> + /// Beschreibt, ob die Signatur als seperate (detached) Signatur (`true`) oder als Teil des + /// Fachdatensatzes bzw. der Anlage (`false`) übertragen wird. Wenn der Wert `true` ist, + /// dann wird die Signatur Base64- oder Base64Url-kodiert im Feld `content` übertragen. + /// </summary> + [JsonProperty("detachedSignature")] + public bool DetachedSignature { get; set; } + + /// <summary> + /// Referenziert ein eindeutiges Profil einer AdES (advanced electronic signature/seal) + /// gemäß eIDAS-Verordnung über eine URI gemäß [ETSI TS 119 + /// 192](https://www.etsi.org/deliver/etsi_ts/119100_119199/119192/01.01.01_60/ts_119192v010101p.pdf). + /// + /// Für die Details zur Verwendung und Validierung von Profilen siehe auch + /// https://ec.europa.eu/cefdigital/DSS/webapp-demo/doc/dss-documentation.html#_signatures_profile_simplification + /// </summary> + [JsonProperty("eidasAdesProfile", NullValueHandling = NullValueHandling.Ignore)] + public EidasAdesProfile? EidasAdesProfile { get; set; } + + /// <summary> + /// Beschreibt, welches Signaturformat die genutzte Signatur / das genutzte Siegel nutzt. + /// Aktuell wird die Hinterlegung folgender Signaturformate unterstützt: CMS = Cryptographic + /// Message Syntax, Asic = Associated Signature Containers, PDF = PDF Signatur, XML = + /// XML-Signature, JSON = JSON Web Signature. + /// </summary> + [JsonProperty("signatureFormat")] + public SignatureFormat SignatureFormat { get; set; } + } + + /// <summary> + /// Definiert das Schema und die Signatur(-art), die für die Fachdaten verwendet werden. + /// </summary> + public partial class Data + { + /// <summary> + /// Der Hashwert der unverschlüsselten Fachdaten. Die Angabe des Hashwertes dient der + /// Integritätssicherung des Gesamtantrags und schützt vor einem Austausch der Fachdaten + /// durch Systeme zwischen Sender und Subscriber (z.B. dem Zustelldienst). + /// </summary> + [JsonProperty("hash")] + public DataHash Hash { get; set; } + + /// <summary> + /// Beschreibt das Signaturformt und Profile + /// </summary> + [JsonProperty("signature", NullValueHandling = NullValueHandling.Ignore)] + public DataSignature Signature { get; set; } + + /// <summary> + /// Referenz auf ein Schema, das die Struktur der Fachdaten einer Einreichung beschreibt. + /// </summary> + [JsonProperty("submissionSchema")] + public Fachdatenschema SubmissionSchema { get; set; } + } + + /// <summary> + /// Der Hashwert der unverschlüsselten Fachdaten. Die Angabe des Hashwertes dient der + /// Integritätssicherung des Gesamtantrags und schützt vor einem Austausch der Fachdaten + /// durch Systeme zwischen Sender und Subscriber (z.B. dem Zustelldienst). + /// </summary> + public partial class DataHash + { + /// <summary> + /// Der Hex-kodierte Hashwert gemäß des angegebenen Algorithmus. + /// </summary> + [JsonProperty("content")] + public string Content { get; set; } + + /// <summary> + /// Der verwendete Hash-Algorithmus. Derzeit ist nur `sha512` erlaubt. + /// </summary> + [JsonProperty("type")] + public HashType Type { get; set; } + } + + /// <summary> + /// Beschreibt das Signaturformt und Profile + /// </summary> + public partial class DataSignature + { + /// <summary> + /// Hier wird die Signatur im Falle einer Detached-Signatur als Base64- oder + /// Base64Url-kodierte Zeichenkette hinterlegt. Eine Base64Url-Kodierung kommt nur bei + /// Einsatz von JSON Web Signatures (JWS / JAdES) zum Einsatz. + /// </summary> + [JsonProperty("content", NullValueHandling = NullValueHandling.Ignore)] + public string Content { get; set; } + + /// <summary> + /// Beschreibt, ob die Signatur als seperate (detached) Signatur (`true`) oder als Teil des + /// Fachdatensatzes bzw. der Anlage (`false`) übertragen wird. Wenn der Wert `true` ist, + /// dann wird die Signatur Base64- oder Base64Url-kodiert im Feld `content` übertragen. + /// </summary> + [JsonProperty("detachedSignature")] + public bool DetachedSignature { get; set; } + + /// <summary> + /// Referenziert ein eindeutiges Profil einer AdES (advanced electronic signature/seal) + /// gemäß eIDAS-Verordnung über eine URI gemäß [ETSI TS 119 + /// 192](https://www.etsi.org/deliver/etsi_ts/119100_119199/119192/01.01.01_60/ts_119192v010101p.pdf). + /// + /// Für die Details zur Verwendung und Validierung von Profilen siehe auch + /// https://ec.europa.eu/cefdigital/DSS/webapp-demo/doc/dss-documentation.html#_signatures_profile_simplification + /// </summary> + [JsonProperty("eidasAdesProfile", NullValueHandling = NullValueHandling.Ignore)] + public EidasAdesProfile? EidasAdesProfile { get; set; } + + /// <summary> + /// Beschreibt, welches Signaturformat die genutzte Signatur / das genutzte Siegel nutzt. + /// Aktuell wird die Hinterlegung folgender Signaturformate unterstützt: CMS = Cryptographic + /// Message Syntax, Asic = Associated Signature Containers, PDF = PDF Signatur, XML = + /// XML-Signature, JSON = JSON Web Signature. + /// </summary> + [JsonProperty("signatureFormat")] + public SignatureFormat SignatureFormat { get; set; } + } + + /// <summary> + /// Referenz auf ein Schema, das die Struktur der Fachdaten einer Einreichung beschreibt. + /// </summary> + public partial class Fachdatenschema + { + /// <summary> + /// Mimetype (z.B. application/json oder application/xml) des referenzierten Schemas (z.B. + /// XSD- oder JSON-Schema). + /// </summary> + [JsonProperty("mimeType")] + public MimeType MimeType { get; set; } + + /// <summary> + /// URI des Fachschemas. Wird hier eine URL verwendet, sollte das Schema unter der + /// angegebenen URL abrufbar sein. Eine Verfügbarkeit des Schemas unter der angegebenen URL + /// darf jedoch nicht vorausgesetzt werden. + /// </summary> + [JsonProperty("schemaUri")] + public Uri SchemaUri { get; set; } + } + + /// <summary> + /// Dieses Objekt enthält die Informationen vom Bezahldienst. + /// </summary> + public partial class PaymentInformation + { + /// <summary> + /// Bruttobetrag + /// </summary> + [JsonProperty("grossAmount", NullValueHandling = NullValueHandling.Ignore)] + [JsonConverter(typeof(MinMaxValueCheckConverter))] + public double? GrossAmount { get; set; } + + /// <summary> + /// Die vom Benutzer ausgewählte Zahlart. Das Feld ist nur bei einer erfolgreichen Zahlung + /// vorhanden / befüllt. + /// </summary> + [JsonProperty("paymentMethod")] + public PaymentMethod PaymentMethod { get; set; } + + /// <summary> + /// Weitere Erläuterung zur gewählten Zahlart. + /// </summary> + [JsonProperty("paymentMethodDetail", NullValueHandling = NullValueHandling.Ignore)] + [JsonConverter(typeof(PurpleMinMaxLengthCheckConverter))] + public string PaymentMethodDetail { get; set; } + + /// <summary> + /// - INITIAL - der Einreichung hat einen Payment-Request ausgelöst und eine + /// Payment-Transaction wurde angelegt. Der Nutzer hat aber im Bezahldienst noch keine + /// Wirkung erzeugt. + /// - BOOKED - der Nutzer hat die Bezahlung im Bezahldienst autorisiert. + /// - FAILED - der Vorgang wurde vom Bezahldienst aufgrund der Nutzereingaben abgebrochen. + /// - CANCELED - der Nutzer hat die Bezahlung im Bezahldienst abgebrochen. + /// </summary> + [JsonProperty("status")] + public Status Status { get; set; } + + /// <summary> + /// Eine vom Bezahldienst vergebene Transaktions-Id. + /// </summary> + [JsonProperty("transactionId")] + [JsonConverter(typeof(PurpleMinMaxLengthCheckConverter))] + public string TransactionId { get; set; } + + /// <summary> + /// Bezahlreferenz bzw. Verwendungszweck, wie z. B. ein Kassenzeichen. + /// </summary> + [JsonProperty("transactionReference")] + public string TransactionReference { get; set; } + + /// <summary> + /// Zeitstempel der erfolgreichen Durchführung der Bezahlung. + /// </summary> + [JsonProperty("transactionTimestamp", NullValueHandling = NullValueHandling.Ignore)] + public DateTimeOffset? TransactionTimestamp { get; set; } + + /// <summary> + /// Die Rest-URL der Payment Transaction für die Statusabfrage. + /// </summary> + [JsonProperty("transactionUrl", NullValueHandling = NullValueHandling.Ignore)] + public Uri TransactionUrl { get; set; } + } + + /// <summary> + /// Beschreibung der Art der Verwaltungsleistung. Eine Verwaltungsleistung sollte immer mit + /// einer LeiKa-Id beschrieben werden. Ist für die gegebene Verwaltungsleistung keine + /// LeiKa-Id vorhanden, kann die Verwaltungsleistung übergangsweise über die Angabe einer + /// anderen eindeutigen Schema-URN beschrieben werden. + /// </summary> + public partial class Verwaltungsleistung + { + /// <summary> + /// (Kurz-)Beschreibung der Verwaltungsleistung + /// </summary> + [JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)] + public string Description { get; set; } + + /// <summary> + /// URN einer Leistung. Im Falle einer Leistung aus dem Leistungskatalog sollte hier + /// `urn:de:fim:leika:leistung:` vorangestellt werden. + /// </summary> + [JsonProperty("identifier")] + [JsonConverter(typeof(FluffyMinMaxLengthCheckConverter))] + public string Identifier { get; set; } + + /// <summary> + /// Name/Bezeichnung der Verwaltungsleistung + /// </summary> + [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] + public string Name { get; set; } + } + + public partial class ReplyChannel + { + /// <summary> + /// Akkreditierte Anbieter siehe + /// https://www.bsi.bund.de/DE/Themen/Oeffentliche-Verwaltung/Moderner-Staat/De-Mail/Akkreditierte-DMDA/akkreditierte-dmda_node.html + /// </summary> + [JsonProperty("deMail", NullValueHandling = NullValueHandling.Ignore)] + public DeMail DeMail { get; set; } + + /// <summary> + /// Siehe https://www.elster.de/elsterweb/infoseite/elstertransfer_hilfe_schnittstellen + /// </summary> + [JsonProperty("elster", NullValueHandling = NullValueHandling.Ignore)] + public Elster Elster { get; set; } + + [JsonProperty("eMail", NullValueHandling = NullValueHandling.Ignore)] + public EMail EMail { get; set; } + + /// <summary> + /// Postfachadresse in einem interoperablen Servicekonto (FINK.PFISK) + /// </summary> + [JsonProperty("fink", NullValueHandling = NullValueHandling.Ignore)] + public Fink Fink { get; set; } + } + + /// <summary> + /// Akkreditierte Anbieter siehe + /// https://www.bsi.bund.de/DE/Themen/Oeffentliche-Verwaltung/Moderner-Staat/De-Mail/Akkreditierte-DMDA/akkreditierte-dmda_node.html + /// </summary> + public partial class DeMail + { + [JsonProperty("address")] + public string Address { get; set; } + } + + public partial class EMail + { + [JsonProperty("address")] + public string Address { get; set; } + + /// <summary> + /// Hilfe zur Erstellung gibt es in der Dokumentation unter + /// https://docs.fitko.de/fit-connect/details/pgp-export + /// </summary> + [JsonProperty("pgpPublicKey", NullValueHandling = NullValueHandling.Ignore)] + public string PgpPublicKey { get; set; } + } + + /// <summary> + /// Siehe https://www.elster.de/elsterweb/infoseite/elstertransfer_hilfe_schnittstellen + /// </summary> + public partial class Elster + { + [JsonProperty("accountId")] + public string AccountId { get; set; } + + [JsonProperty("geschaeftszeichen", NullValueHandling = NullValueHandling.Ignore)] + [JsonConverter(typeof(TentacledMinMaxLengthCheckConverter))] + public string Geschaeftszeichen { get; set; } + + [JsonProperty("lieferTicket", NullValueHandling = NullValueHandling.Ignore)] + public string LieferTicket { get; set; } + } + + /// <summary> + /// Postfachadresse in einem interoperablen Servicekonto (FINK.PFISK) + /// </summary> + public partial class Fink + { + /// <summary> + /// FINK Postfachadresse + /// </summary> + [JsonProperty("finkPostfachRef")] + [JsonConverter(typeof(StickyMinMaxLengthCheckConverter))] + public string FinkPostfachRef { get; set; } + + /// <summary> + /// URL des Servicekontos, in dem das Ziel-Postfach liegt + /// </summary> + [JsonProperty("host", NullValueHandling = NullValueHandling.Ignore)] + public Uri Host { get; set; } + } + + /// <summary> + /// Definiert die Art des Identifikationsnachweises. + /// </summary> + public enum AuthenticationInformationType { IdentificationReport }; + + /// <summary> + /// Der verwendete Hash-Algorithmus. Derzeit ist nur `sha512` erlaubt. + /// </summary> + public enum HashType { Sha512 }; + + /// <summary> + /// Zweck/Art der Anlage + /// - form: Automatisch generierte PDF-Repräsentation des vollständigen Antragsformulars + /// - attachment: Anlage, die von einem Bürger hochgeladen wurde + /// - report: Vom Onlinedienst, nachträglich erzeugte Unterlage + /// </summary> + public enum Purpose { Attachment, Form, Report }; + + /// <summary> + /// Referenziert ein eindeutiges Profil einer AdES (advanced electronic signature/seal) + /// gemäß eIDAS-Verordnung über eine URI gemäß [ETSI TS 119 + /// 192](https://www.etsi.org/deliver/etsi_ts/119100_119199/119192/01.01.01_60/ts_119192v010101p.pdf). + /// + /// Für die Details zur Verwendung und Validierung von Profilen siehe auch + /// https://ec.europa.eu/cefdigital/DSS/webapp-demo/doc/dss-documentation.html#_signatures_profile_simplification + /// </summary> + public enum EidasAdesProfile { HttpUriEtsiOrgAdes191X2LevelBaselineBB, HttpUriEtsiOrgAdes191X2LevelBaselineBLt, HttpUriEtsiOrgAdes191X2LevelBaselineBLta, HttpUriEtsiOrgAdes191X2LevelBaselineBT }; + + /// <summary> + /// Beschreibt, welches Signaturformat die genutzte Signatur / das genutzte Siegel nutzt. + /// Aktuell wird die Hinterlegung folgender Signaturformate unterstützt: CMS = Cryptographic + /// Message Syntax, Asic = Associated Signature Containers, PDF = PDF Signatur, XML = + /// XML-Signature, JSON = JSON Web Signature. + /// </summary> + public enum SignatureFormat { Asic, Cms, Json, Pdf, Xml }; + + /// <summary> + /// Mimetype (z.B. application/json oder application/xml) des referenzierten Schemas (z.B. + /// XSD- oder JSON-Schema). + /// </summary> + public enum MimeType { ApplicationJson, ApplicationXml }; + + /// <summary> + /// Die vom Benutzer ausgewählte Zahlart. Das Feld ist nur bei einer erfolgreichen Zahlung + /// vorhanden / befüllt. + /// </summary> + public enum PaymentMethod { Creditcard, Giropay, Invoice, Other, Paydirect, Paypal }; + + /// <summary> + /// - INITIAL - der Einreichung hat einen Payment-Request ausgelöst und eine + /// Payment-Transaction wurde angelegt. Der Nutzer hat aber im Bezahldienst noch keine + /// Wirkung erzeugt. + /// - BOOKED - der Nutzer hat die Bezahlung im Bezahldienst autorisiert. + /// - FAILED - der Vorgang wurde vom Bezahldienst aufgrund der Nutzereingaben abgebrochen. + /// - CANCELED - der Nutzer hat die Bezahlung im Bezahldienst abgebrochen. + /// </summary> + public enum Status { Booked, Canceled, Failed, Initial }; + + public partial class Metadata + { + public static Metadata FromJson(string json) => JsonConvert.DeserializeObject<Metadata>(json, FitConnect.Models.Api.Set.Converter.Settings); + } + + public static class Serialize + { + public static string ToJson(this Metadata self) => JsonConvert.SerializeObject(self, FitConnect.Models.Api.Set.Converter.Settings); + } + + internal static class Converter + { + public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings + { + MetadataPropertyHandling = MetadataPropertyHandling.Ignore, + DateParseHandling = DateParseHandling.None, + Converters = + { + AuthenticationInformationTypeConverter.Singleton, + HashTypeConverter.Singleton, + PurposeConverter.Singleton, + EidasAdesProfileConverter.Singleton, + SignatureFormatConverter.Singleton, + MimeTypeConverter.Singleton, + PaymentMethodConverter.Singleton, + StatusConverter.Singleton, + new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal } + }, + }; + } + + internal class AuthenticationInformationTypeConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(AuthenticationInformationType) || t == typeof(AuthenticationInformationType?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize<string>(reader); + if (value == "identificationReport") + { + return AuthenticationInformationType.IdentificationReport; + } + throw new Exception("Cannot unmarshal type AuthenticationInformationType"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (AuthenticationInformationType)untypedValue; + if (value == AuthenticationInformationType.IdentificationReport) + { + serializer.Serialize(writer, "identificationReport"); + return; + } + throw new Exception("Cannot marshal type AuthenticationInformationType"); + } + + public static readonly AuthenticationInformationTypeConverter Singleton = new AuthenticationInformationTypeConverter(); + } + + internal class HashTypeConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(HashType) || t == typeof(HashType?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize<string>(reader); + if (value == "sha512") + { + return HashType.Sha512; + } + throw new Exception("Cannot unmarshal type HashType"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (HashType)untypedValue; + if (value == HashType.Sha512) + { + serializer.Serialize(writer, "sha512"); + return; + } + throw new Exception("Cannot marshal type HashType"); + } + + public static readonly HashTypeConverter Singleton = new HashTypeConverter(); + } + + internal class PurposeConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(Purpose) || t == typeof(Purpose?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize<string>(reader); + switch (value) + { + case "attachment": + return Purpose.Attachment; + case "form": + return Purpose.Form; + case "report": + return Purpose.Report; + } + throw new Exception("Cannot unmarshal type Purpose"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (Purpose)untypedValue; + switch (value) + { + case Purpose.Attachment: + serializer.Serialize(writer, "attachment"); + return; + case Purpose.Form: + serializer.Serialize(writer, "form"); + return; + case Purpose.Report: + serializer.Serialize(writer, "report"); + return; + } + throw new Exception("Cannot marshal type Purpose"); + } + + public static readonly PurposeConverter Singleton = new PurposeConverter(); + } + + internal class EidasAdesProfileConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(EidasAdesProfile) || t == typeof(EidasAdesProfile?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize<string>(reader); + switch (value) + { + case "http://uri.etsi.org/ades/191x2/level/baseline/B-B#": + return EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBB; + case "http://uri.etsi.org/ades/191x2/level/baseline/B-LT#": + return EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBLt; + case "http://uri.etsi.org/ades/191x2/level/baseline/B-LTA#": + return EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBLta; + case "http://uri.etsi.org/ades/191x2/level/baseline/B-T#": + return EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBT; + } + throw new Exception("Cannot unmarshal type EidasAdesProfile"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (EidasAdesProfile)untypedValue; + switch (value) + { + case EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBB: + serializer.Serialize(writer, "http://uri.etsi.org/ades/191x2/level/baseline/B-B#"); + return; + case EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBLt: + serializer.Serialize(writer, "http://uri.etsi.org/ades/191x2/level/baseline/B-LT#"); + return; + case EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBLta: + serializer.Serialize(writer, "http://uri.etsi.org/ades/191x2/level/baseline/B-LTA#"); + return; + case EidasAdesProfile.HttpUriEtsiOrgAdes191X2LevelBaselineBT: + serializer.Serialize(writer, "http://uri.etsi.org/ades/191x2/level/baseline/B-T#"); + return; + } + throw new Exception("Cannot marshal type EidasAdesProfile"); + } + + public static readonly EidasAdesProfileConverter Singleton = new EidasAdesProfileConverter(); + } + + internal class SignatureFormatConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(SignatureFormat) || t == typeof(SignatureFormat?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize<string>(reader); + switch (value) + { + case "asic": + return SignatureFormat.Asic; + case "cms": + return SignatureFormat.Cms; + case "json": + return SignatureFormat.Json; + case "pdf": + return SignatureFormat.Pdf; + case "xml": + return SignatureFormat.Xml; + } + throw new Exception("Cannot unmarshal type SignatureFormat"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (SignatureFormat)untypedValue; + switch (value) + { + case SignatureFormat.Asic: + serializer.Serialize(writer, "asic"); + return; + case SignatureFormat.Cms: + serializer.Serialize(writer, "cms"); + return; + case SignatureFormat.Json: + serializer.Serialize(writer, "json"); + return; + case SignatureFormat.Pdf: + serializer.Serialize(writer, "pdf"); + return; + case SignatureFormat.Xml: + serializer.Serialize(writer, "xml"); + return; + } + throw new Exception("Cannot marshal type SignatureFormat"); + } + + public static readonly SignatureFormatConverter Singleton = new SignatureFormatConverter(); + } + + internal class MimeTypeConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(MimeType) || t == typeof(MimeType?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize<string>(reader); + switch (value) + { + case "application/json": + return MimeType.ApplicationJson; + case "application/xml": + return MimeType.ApplicationXml; + } + throw new Exception("Cannot unmarshal type MimeType"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (MimeType)untypedValue; + switch (value) + { + case MimeType.ApplicationJson: + serializer.Serialize(writer, "application/json"); + return; + case MimeType.ApplicationXml: + serializer.Serialize(writer, "application/xml"); + return; + } + throw new Exception("Cannot marshal type MimeType"); + } + + public static readonly MimeTypeConverter Singleton = new MimeTypeConverter(); + } + + internal class MinMaxValueCheckConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(double) || t == typeof(double?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize<double>(reader); + if (value >= 0.01) + { + return value; + } + throw new Exception("Cannot unmarshal type double"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (double)untypedValue; + if (value >= 0.01) + { + serializer.Serialize(writer, value); + return; + } + throw new Exception("Cannot marshal type double"); + } + + public static readonly MinMaxValueCheckConverter Singleton = new MinMaxValueCheckConverter(); + } + + internal class PaymentMethodConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(PaymentMethod) || t == typeof(PaymentMethod?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize<string>(reader); + switch (value) + { + case "CREDITCARD": + return PaymentMethod.Creditcard; + case "GIROPAY": + return PaymentMethod.Giropay; + case "INVOICE": + return PaymentMethod.Invoice; + case "OTHER": + return PaymentMethod.Other; + case "PAYDIRECT": + return PaymentMethod.Paydirect; + case "PAYPAL": + return PaymentMethod.Paypal; + } + throw new Exception("Cannot unmarshal type PaymentMethod"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (PaymentMethod)untypedValue; + switch (value) + { + case PaymentMethod.Creditcard: + serializer.Serialize(writer, "CREDITCARD"); + return; + case PaymentMethod.Giropay: + serializer.Serialize(writer, "GIROPAY"); + return; + case PaymentMethod.Invoice: + serializer.Serialize(writer, "INVOICE"); + return; + case PaymentMethod.Other: + serializer.Serialize(writer, "OTHER"); + return; + case PaymentMethod.Paydirect: + serializer.Serialize(writer, "PAYDIRECT"); + return; + case PaymentMethod.Paypal: + serializer.Serialize(writer, "PAYPAL"); + return; + } + throw new Exception("Cannot marshal type PaymentMethod"); + } + + public static readonly PaymentMethodConverter Singleton = new PaymentMethodConverter(); + } + + internal class PurpleMinMaxLengthCheckConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(string); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + var value = serializer.Deserialize<string>(reader); + if (value.Length >= 1 && value.Length <= 36) + { + return value; + } + throw new Exception("Cannot unmarshal type string"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + var value = (string)untypedValue; + if (value.Length >= 1 && value.Length <= 36) + { + serializer.Serialize(writer, value); + return; + } + throw new Exception("Cannot marshal type string"); + } + + public static readonly PurpleMinMaxLengthCheckConverter Singleton = new PurpleMinMaxLengthCheckConverter(); + } + + internal class StatusConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(Status) || t == typeof(Status?); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) return null; + var value = serializer.Deserialize<string>(reader); + switch (value) + { + case "BOOKED": + return Status.Booked; + case "CANCELED": + return Status.Canceled; + case "FAILED": + return Status.Failed; + case "INITIAL": + return Status.Initial; + } + throw new Exception("Cannot unmarshal type Status"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + if (untypedValue == null) + { + serializer.Serialize(writer, null); + return; + } + var value = (Status)untypedValue; + switch (value) + { + case Status.Booked: + serializer.Serialize(writer, "BOOKED"); + return; + case Status.Canceled: + serializer.Serialize(writer, "CANCELED"); + return; + case Status.Failed: + serializer.Serialize(writer, "FAILED"); + return; + case Status.Initial: + serializer.Serialize(writer, "INITIAL"); + return; + } + throw new Exception("Cannot marshal type Status"); + } + + public static readonly StatusConverter Singleton = new StatusConverter(); + } + + internal class FluffyMinMaxLengthCheckConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(string); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + var value = serializer.Deserialize<string>(reader); + if (value.Length >= 7 && value.Length <= 255) + { + return value; + } + throw new Exception("Cannot unmarshal type string"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + var value = (string)untypedValue; + if (value.Length >= 7 && value.Length <= 255) + { + serializer.Serialize(writer, value); + return; + } + throw new Exception("Cannot marshal type string"); + } + + public static readonly FluffyMinMaxLengthCheckConverter Singleton = new FluffyMinMaxLengthCheckConverter(); + } + + internal class TentacledMinMaxLengthCheckConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(string); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + var value = serializer.Deserialize<string>(reader); + if (value.Length <= 10) + { + return value; + } + throw new Exception("Cannot unmarshal type string"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + var value = (string)untypedValue; + if (value.Length <= 10) + { + serializer.Serialize(writer, value); + return; + } + throw new Exception("Cannot marshal type string"); + } + + public static readonly TentacledMinMaxLengthCheckConverter Singleton = new TentacledMinMaxLengthCheckConverter(); + } + + internal class StickyMinMaxLengthCheckConverter : JsonConverter + { + public override bool CanConvert(Type t) => t == typeof(string); + + public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer) + { + var value = serializer.Deserialize<string>(reader); + if (value.Length <= 150) + { + return value; + } + throw new Exception("Cannot unmarshal type string"); + } + + public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer) + { + var value = (string)untypedValue; + if (value.Length <= 150) + { + serializer.Serialize(writer, value); + return; + } + throw new Exception("Cannot marshal type string"); + } + + public static readonly StickyMinMaxLengthCheckConverter Singleton = new StickyMinMaxLengthCheckConverter(); + } +} diff --git a/Services/Services.csproj b/Services/Services.csproj index 9532ca430385e7c6b1f9774a9064d4bcfebbb013..a7e0e4428d4d28e78ac79e675b28c5102e5ba1ad 100644 --- a/Services/Services.csproj +++ b/Services/Services.csproj @@ -8,12 +8,12 @@ </PropertyGroup> <ItemGroup> - <ProjectReference Include="..\Models\Models.csproj"/> - <ProjectReference Include="..\RestService\RestService.csproj"/> + <ProjectReference Include="..\Models\Models.csproj" /> + <ProjectReference Include="..\RestService\RestService.csproj" /> </ItemGroup> <ItemGroup> - <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.1"/> + <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.1" /> </ItemGroup> </Project> diff --git a/working_notes.md b/working_notes.md index 91b76b4a0db6dd3058c0fe7392d4bf4edd2a3c84..089b933e93f1064fa4bc9dc0825798d333bf6d8c 100644 --- a/working_notes.md +++ b/working_notes.md @@ -25,13 +25,24 @@ ## Links +### Documentation + - [SDK-Konzept im Wiki](https://wiki.fit-connect.fitko.dev/de/Konzeption/Konzeption_SDK) - [inoffizielles Python-SDK](https://github.com/codedust/fitconnect-sdk-python) - [Project management](https://wiki.fit-connect.fitko.dev/de/PM_PUBLIC/Projektvorgehensmodell) - [Wiki SDK Description](https://wiki.fit-connect.fitko.dev/de/PM_PUBLIC/Epics/SDK_Initialisierung) - [Containing GitLab](https://git.fitko.de/) - [Board filtered for SDK](https://git.fitko.de/fit-connect/planning/-/boards/44?label_name%5B%5D=component%3A%3ASDK) -- [Documentation](https://docs.fitko.de/fit-connect/docs/getting-started/first-steps/) +- [FitConnect First Steps](https://docs.fitko.de/fit-connect/docs/getting-started/first-steps/) - [Security Event Token Requirements](https://wiki.fit-connect.fitko.dev/de/Konzeption/Security_Event_Token_Future) - [glossary](https://docs.fitko.de/fit-connect/docs/glossary/) +### Helper +- [Create C# class from JSON schema](https://app.quicktype.io/?l=csharp) + +## Values for testing + +| Topic | Value | Description | +|:-------------------|:---------------|:----------------------------------------| +| Leika Key | 99099002067003 | Deutsche Staatsangehörigkeit beantragen | +| Gemeinde Schlüssel | 09 3 72 126 | Furth im Wald | \ No newline at end of file