Skip to content
Snippets Groups Projects
Commit 3205b6cd authored by Klaus Fischer's avatar Klaus Fischer
Browse files

Added SET schema

parent 0de46cdb
No related branches found
No related tags found
1 merge request!52Issue/608 set schema
......@@ -4,6 +4,7 @@ using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Schema;
using JsonSchema = NJsonSchema.JsonSchema;
using ValidationError = NJsonSchema.Validation.ValidationError;
namespace FitConnect.Encryption;
......@@ -21,7 +22,7 @@ public static class JsonHelper {
/// <returns></returns>
public static async Task<bool> VerifyMetadata(string metadataString, JsonSchema? schema,
ILogger? logger = null) {
var schemaString = LoadContentOfResource("metadata.schema.json");
var schemaString = LoadJsonSchemaFromResource("metadata.schema.json");
schema ??= await JsonSchema.FromJsonAsync(schemaString);
var schemaName = schema.ExtensionData["$id"].ToString();
......@@ -39,6 +40,10 @@ public static class JsonHelper {
}
internal static string LoadJsonSchemaFromResource(string schemaName)
=> LoadContentOfResource($"JsonSchemas.{schemaName}");
private static string LoadContentOfResource(string resourceName) {
var assembly = Assembly.GetExecutingAssembly();
var fullQualifiedName = $"{assembly.GetName().Name}.{resourceName}";
......@@ -49,10 +54,28 @@ public static class JsonHelper {
return reader.ReadToEnd();
}
public static async Task<bool> ValidateJsonSchema(Uri schema, string jsonData) {
internal static async Task<bool> ValidateJsonSchema(Uri schema, string jsonData) {
var schemaResponse = await new HttpClient()
.GetAsync(schema);
return ValidateJsonSchema(await schemaResponse.Content.ReadAsStringAsync(), jsonData);
}
/// <summary>
/// Validates <paramref name="dataString" /> against <paramref name="schemaString" /> and returns
/// the validation errors if any appear
/// </summary>
internal static async Task<ICollection<ValidationError>> ValidateSchemaAsync(
string dataString, string schemaString) {
var schema = await JsonSchema.FromJsonAsync(schemaString);
return schema.Validate(dataString);
}
internal static async Task<ICollection<ValidationError>> ValidateSchemaFromResourceAsync(
string dataString, string schemaResourceName) {
var schema =
await JsonSchema.FromJsonAsync(
(JsonHelper.LoadJsonSchemaFromResource(schemaResourceName)));
return schema.Validate(dataString);
}
}
......@@ -40,8 +40,8 @@
<None Include="./nuget-readme.md" Pack="true" PackagePath="\" />
<None Include="icon.png" Pack="true" Visible="false" PackagePath="" />
<None Remove="metadata.schema.json" />
<EmbeddedResource Include="metadata.schema.json" />
<None Remove="Certificates\PCA-1-Verwaltung-14.pem" />
<EmbeddedResource Include="JsonSchemas\metadata.schema.json" />
<EmbeddedResource Include="TrustedRootCertificates\PCA-1-Verwaltung-14.pem" />
<None Remove="Certificates\PCA-1-Verwaltung-15.pem" />
<EmbeddedResource Include="TrustedRootCertificates\PCA-1-Verwaltung-15.pem" />
......@@ -51,6 +51,8 @@
<EmbeddedResource Include="TrustedRootCertificates\PCA-1-Verwaltung-20.pem" />
<None Remove="TrustedRootCertificates\PCA-1-Verwaltung-23.pem" />
<EmbeddedResource Include="TrustedRootCertificates\PCA-1-Verwaltung-23.pem" />
<None Remove="JsonSchemas\set-payload.schema.json" />
<EmbeddedResource Include="JsonSchemas\set-payload.schema.json" />
</ItemGroup>
<ItemGroup>
......
......@@ -7,8 +7,7 @@ using FitConnect.Services.Interfaces;
using FitConnect.Services.Models.v1.Submission;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using NJsonSchema;
using NJsonSchema.Validation;
namespace FitConnect;
......@@ -89,15 +88,6 @@ public abstract class FitConnectClient {
protected ILogger? Logger { get; }
protected FitEncryption Encryption { get; set; }
/// <summary>
/// Validates <paramref name="dataString" /> against <paramref name="schemaString" /> and returns
/// the validation errors if any appear
/// </summary>
public static async Task<ICollection<ValidationError>> ValidateSchemaAsync(
string dataString, string schemaString) {
var schema = await JsonSchema.FromJsonAsync(schemaString);
return schema.Validate(dataString);
}
public void SetProxy(WebProxy proxy) {
OAuthService.Proxy = proxy;
......
{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://schema.fitko.de/fit-connect/set-payload/1.0.0/set-payload.schema.json","title":"Security Event Token (SET)","description":"Security Event Token (SET) nach RFC 8417","type":"object","properties":{"$schema":{"description":"URI des Schemas, dem dieser Security Event Token entspricht.","type":"string","enum":["https://schema.fitko.de/fit-connect/set-payload/1.0.0/set-payload.schema.json"]},"jti":{"description":"Die JWT ID (jti) ist eine eindeutige UUID für das SET.","type":"string","format":"uuid"},"iss":{"description":"Als Issuer ('iss') wird die UUID der Destination eingetragen. Bei vom Zustelldienst ausgestellten SETs steht dort die Basis-URL des Zustelldienstes.","type":"string"},"iat":{"description":"The 'iat' (issued at) claim identifies the time at which the JWT was issued.","type":"integer","minimum":1577833200},"sub":{"description":"Das Subject ('sub') enthält 'submission:' und die UUID der Submission.","type":"string","pattern":"^submission:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"},"txn":{"description":"Der Transaction Identifier ('txn') enthält 'case:' und die UUID des Cases.","type":"string","pattern":"^case:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"},"events":{"description":"Enthält genau eines der spezifizierten Events als Unterobjekt.","type":"object","properties":{"https://schema.fitko.de/fit-connect/events/create-submission":{"description":"Mit diesem Event dokumentiert der Zustelldienst, dass eine Einreichung angelegt wurde.","type":"object"},"https://schema.fitko.de/fit-connect/events/submit-submission":{"description":"Mit diesem Event dokumentiert der Zustelldienst, dass die Einreichung abgesendet wurde.","type":"object","properties":{"authenticationTags":{"title":"Authentication Tags","description":"Authentication Tags des Meta- und Fachdatensatzes sowie der Anlagen","type":"object","properties":{"metadata":{"$ref":"#/properties/events/properties/https%3A~1~1schema.fitko.de~1fit-connect~1events~1submit-submission/properties/authenticationTags/properties/data"},"data":{"title":"Authentication Tag","description":"Struktur eines einzelnen Authentication Tags","type":"string","pattern":"^[a-zA-Z0-9-_=]+$","minLength":22,"maxLength":86},"attachments":{"type":"object","patternProperties":{"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$":{"$ref":"#/properties/events/properties/https%3A~1~1schema.fitko.de~1fit-connect~1events~1submit-submission/properties/authenticationTags/properties/data"}},"additionalProperties":false}},"additionalProperties":false,"required":["metadata"]}},"required":["authenticationTags"]},"https://schema.fitko.de/fit-connect/events/notify-submission":{"description":"Mit diesem Event dokumentiert der Zustelldienst, dass das empfangende System Kenntnis von der Einreichung erlangt hat. Wie dies erfolgt ist, wird mit dem Eintrag `notifyType` dokumentiert.","type":"object","properties":{"notifyType":{"type":"string","enum":["callback","polling"]}},"required":["notifyType"]},"https://schema.fitko.de/fit-connect/events/forward-submission":{"description":"Mit diesem Event dokumentiert ein nachgelagertes System, dass es die Einreichung zur Weiterleitung übernommen hat.","type":"object"},"https://schema.fitko.de/fit-connect/events/reject-submission":{"description":"Mit diesem Event dokumentiert das empfangende System, dass die Einreichung zurückgewiesen wird.","type":"object","properties":{"problems":{"title":"Problems","description":"Liste der Probleme bei der Validierung einer Submission.","type":"array","items":{"type":"object","properties":{"type":{"description":"Fehlercode in Form einer URI.","type":"string","pattern":"^https:\\/\\/schema\\.fitko\\.de\\/fit-connect\\/events\\/problems\\/[-a-z]+$"},"title":{"description":"Für Menschen verständliche Fehlermeldung","type":"string"},"detail":{"description":"Details zum Fehler, z.B. eine technische Fehlermeldung (optional)","type":"string"},"instance":{"description":"Betroffener Teil der Übertragung. Mögliche Werte: `submission`, `metadata`, `data`, `attachment:` + UUID des Attachments oder `other`","type":"string","pattern":"^(submission|metadata|data|attachment:.+|other)$"}},"required":["type","title","instance"]}}},"required":["problems"]},"https://schema.fitko.de/fit-connect/events/accept-submission":{"description":"Mit diesem Event dokumentiert das empfangende System, dass die Einreichung akzeptiert wurde.","type":"object","properties":{"problems":{"$ref":"#/properties/events/properties/https%3A~1~1schema.fitko.de~1fit-connect~1events~1reject-submission/properties/problems"},"authenticationTags":{"$ref":"#/properties/events/properties/https%3A~1~1schema.fitko.de~1fit-connect~1events~1submit-submission/properties/authenticationTags"}},"required":["authenticationTags"]},"https://schema.fitko.de/fit-connect/events/delete-submission":{"description":"Mit diesem Event dokumentiert der Zustelldienst, dass die Einreichung gelöscht wurde.","type":"object"}},"additionalProperties":false,"minProperties":1,"maxProperties":1}},"additionalProperties":false,"required":["$schema","jti","iss","iat","sub","txn","events"]}
\ No newline at end of file
using System.Security.Claims;
using FitConnect.Encryption;
using FitConnect.Models.v1.Api;
using IdentityModel;
using Microsoft.IdentityModel.JsonWebTokens;
......@@ -55,6 +56,7 @@ public class SecurityEventToken {
}
public static SecurityEventToken FromJson(string json) {
JsonHelper.LoadJsonSchemaFromResource("set-payload.schema.json");
var result = JsonConvert.DeserializeObject<SecurityEventToken>(json) ??
throw new ArgumentException("Not a valid SET json");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment