diff --git a/E2ETest/StraightForwardTest.cs b/E2ETest/StraightForwardTest.cs index 0eb0df15fcf30a010be572d890acfdf1a7c1713e..19a3000b38c5d3a3d60fa82ef2dfff4c3d6f50e4 100644 --- a/E2ETest/StraightForwardTest.cs +++ b/E2ETest/StraightForwardTest.cs @@ -47,7 +47,7 @@ public class StraightForwardTest : EndToEndTestBase { status.ForEach( s => Logger.LogInformation("Status {When} {Event}", s.EventTime, s.EventType)); } - + [Test] [Order(40)] public void RequestSubmission() { diff --git a/FitConnect/Encryption/FitEncryption.cs b/FitConnect/Encryption/FitEncryption.cs index 620d281a6b834de69d2f9ec06f953ec8c22b7ebe..5fdbb0a41948cc4f62cc3698d0e9416d01b4bc4e 100644 --- a/FitConnect/Encryption/FitEncryption.cs +++ b/FitConnect/Encryption/FitEncryption.cs @@ -97,29 +97,27 @@ public class FitEncryption { _logger?.LogInformation("Generating authentication tags"); var attachmentDictionary = new Dictionary<string, string>(); submission.Attachments.ForEach(a => - attachmentDictionary.Add(a.Id, CalculateAuthenticationHash(a.Content))); - + attachmentDictionary.Add(a.Id, a.AttachmentAuthentication)); + + if (submission.Data != null) + return new { + authenticationTags = new { + data = submission.DataAuthentication, + metadata = submission.MetaAuthentication, + attachments = attachmentDictionary + } + }; return new { authenticationTags = new { - data = CalculateAuthenticationHash(submission?.Data ?? ""), - metadata = CalculateAuthenticationHash(submission?.Metadata?.ToString() ?? ""), + metadata = submission.MetaAuthentication, attachments = attachmentDictionary } }; } - private string CalculateAuthenticationHash(string data = "") { - return CalculateAuthenticationHash(Encoding.UTF8.GetBytes(data)); - } - - private string CalculateAuthenticationHash(byte[]? data = null) { - var result = MD5.Create().ComputeHash(data ?? Array.Empty<byte>()); - return System.Convert.ToHexString(result); - } - public string CreateAcceptSecurityEventToken(SubmissionForPickupDto submission, - dynamic payload = null) { + dynamic? payload = null) { if (submission?.Id == null || submission?.CaseId == null || submission?.DestinationId == null) { throw new ArgumentException("SubmissionId, CaseId and DestinationId are required"); diff --git a/FitConnect/Interfaces/Subscriber/ISubscriberWithSubmission.cs b/FitConnect/Interfaces/Subscriber/ISubscriberWithSubmission.cs index 6d82850af24e57431622e8f8a80cc54f900f903c..c7cd242a8b95c98145a98ff751ddb6a6600719b3 100644 --- a/FitConnect/Interfaces/Subscriber/ISubscriberWithSubmission.cs +++ b/FitConnect/Interfaces/Subscriber/ISubscriberWithSubmission.cs @@ -1,9 +1,10 @@ using FitConnect.Models; using FitConnect.Models.v1.Api; +using FitConnect.Services.Models; namespace FitConnect.Interfaces.Subscriber; -public interface ISubscriberWithSubmission { +public interface ISubscriberWithSubmission : WithSubmission { public Submission? Submission { get; } /// <summary> @@ -42,3 +43,12 @@ public interface ISubscriberWithSubmission { /// <param name="status">state the submission has to be set to</param> public void CompleteSubmission(FinishSubmissionStatus status); } + +public interface WithSubmission { + /// <summary> + /// Verifies the submission acceptance status + /// </summary> + /// <param name="acceptanceStatus"></param> + /// <returns></returns> + public bool VerifyStatus(AcceptanceStatus acceptanceStatus); +} diff --git a/FitConnect/Models/Attachment.cs b/FitConnect/Models/Attachment.cs index 86ed85f32c0fdafc7a38b9c8c001b08b88fceb1e..5450e7f35990ba68513bb19355b912d8bb3aac77 100644 --- a/FitConnect/Models/Attachment.cs +++ b/FitConnect/Models/Attachment.cs @@ -5,9 +5,10 @@ using FitConnect.Models.Api.Metadata; namespace FitConnect.Models; public class Attachment { - public Attachment(Api.Metadata.Attachment metadata, byte[] content) { + public Attachment(Api.Metadata.Attachment metadata, byte[] content, string attachmentAuthentication) { Filename = metadata.Filename; Content = content; + AttachmentAuthentication = attachmentAuthentication; MimeType = Path.GetExtension(metadata.Filename) switch { "pdf" => "application/pdf", "xml" => "application/xml", @@ -43,6 +44,7 @@ public class Attachment { public string Id { get; } = Guid.NewGuid().ToString(); public byte[]? Content { get; init; } + public string AttachmentAuthentication { get; } public string? Hash => CalculateHash(); diff --git a/FitConnect/Models/Submission.cs b/FitConnect/Models/Submission.cs index a1d78af9af1f570479fd6f10c22ef682eb148c52..c3027214c7ec3f28b906eaef6c649f05d0dbd4a7 100644 --- a/FitConnect/Models/Submission.cs +++ b/FitConnect/Models/Submission.cs @@ -1,3 +1,4 @@ +using System.Security.Cryptography.X509Certificates; using FitConnect.Services.Models; using FitConnect.Services.Models.v1.Submission; @@ -23,6 +24,8 @@ public class Submission { public string? Data { get; set; } public string? EncryptedMetadata { get; set; } public string? EncryptedData { get; set; } + public string? MetaAuthentication => EncryptedMetadata?.Split('.').Last(); + public string? DataAuthentication => EncryptedData?.Split('.').Last(); public bool IsSubmissionReadyToAdd(out string? error) { var innerError = ""; diff --git a/FitConnect/Services/Models/ServiceTypeDto.cs b/FitConnect/Services/Models/ServiceTypeDto.cs index c34a7521674d279968d1b07a9c36c8421563055b..4a2b55f2b758148d3af08b37f39ce58496e3bc7b 100644 --- a/FitConnect/Services/Models/ServiceTypeDto.cs +++ b/FitConnect/Services/Models/ServiceTypeDto.cs @@ -12,3 +12,14 @@ public class ServiceTypeDto { [JsonProperty("identifier")] public string? Identifier { get; set; } } + +public class AcceptanceStatus { + [JsonProperty("metadata")] + public string Metadata { get; set; } + + [JsonProperty("data")] + public string Data { get; set; } + + [JsonProperty("attachments")] + public Dictionary<string, string> Attachments { get; set; } +} diff --git a/FitConnect/Services/Models/v1/Api/Metadata.cs b/FitConnect/Services/Models/v1/Api/Metadata.cs index 3f8515902b5cfde3202fc9a8d5fc984498b74e1c..77fa78761a218643d7ada6cfa73899479c6af4e5 100644 --- a/FitConnect/Services/Models/v1/Api/Metadata.cs +++ b/FitConnect/Services/Models/v1/Api/Metadata.cs @@ -53,7 +53,7 @@ namespace FitConnect.Models.Api.Metadata [JsonProperty("replyChannel", NullValueHandling = NullValueHandling.Ignore)] public ReplyChannel ReplyChannel { get; set; } - + public override string ToString() => JsonConvert.SerializeObject(this); } diff --git a/FitConnect/Subscriber.cs b/FitConnect/Subscriber.cs index 05819659eb04a753dff17534de86396dc7a1efc9..1635bc5b9cb6db2d470318bfa19ddff327e92aba 100644 --- a/FitConnect/Subscriber.cs +++ b/FitConnect/Subscriber.cs @@ -8,6 +8,7 @@ using FitConnect.Encryption; using FitConnect.Interfaces.Subscriber; using FitConnect.Models; using FitConnect.Models.v1.Api; +using FitConnect.Services.Models; using FitConnect.Services.Models.v1.Submission; using IdentityModel; using Microsoft.AspNetCore.Http; @@ -25,9 +26,8 @@ namespace FitConnect; public class Subscriber : FitConnectClient, ISubscriber, ISubscriberWithSubmission { - public Submission? Submission { get; private set; } - + public Subscriber(FitConnectEnvironment environment, string clientId, string clientSecret, string privateKeyDecryption, @@ -95,7 +95,6 @@ public class Subscriber : FitConnectClient, submission.Metadata = JsonConvert.DeserializeObject<Metadata>(metaDataString); - if (submission.EncryptedData != null) { var (dataString, _, dataHash) = Encryption.Decrypt(submission.EncryptedData); submission.Data = dataString; @@ -113,7 +112,6 @@ public class Subscriber : FitConnectClient, return this; } - /// <summary> /// Reading attachments for a submission. @@ -130,7 +128,8 @@ public class Subscriber : FitConnectClient, var attachmentMeta = Submission.Metadata.ContentStructure.Attachments.First(a => a.AttachmentId == id); - attachments.Add(new Attachment(attachmentMeta, content)); + attachments.Add(new Attachment(attachmentMeta, content, + encryptedAttachment.Split('.').Last())); } Submission.Attachments = attachments; @@ -154,6 +153,18 @@ public class Subscriber : FitConnectClient, CompleteSubmission(Submission!, status); } + public bool VerifyStatus(AcceptanceStatus acceptanceStatus) { + if (Submission == null) + throw new NullReferenceException("Submission is null"); + var result = true; + result &= acceptanceStatus.Metadata == Submission.MetaAuthentication; + result &= acceptanceStatus.Data == Submission.DataAuthentication; + foreach (var attachment in Submission.Attachments) { + result &= acceptanceStatus.Attachments[attachment.Id] == attachment.AttachmentAuthentication; + } + + return result; + } private void CompleteSubmission(Submission submission,