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

Merged 0 Warning commit

parents b8112bb2 39c687a3
No related branches found
No related tags found
1 merge request!9.NET-SDK: SET-Empfang inkl. Signaturprüfung - Ticket 562
Showing
with 134 additions and 87 deletions
......@@ -23,7 +23,7 @@ public class SecurityEventTokenTests {
[Test]
public void CreateJwt_AcceptSubmission() {
var token = _encryption.CreateAcceptSecurityEventToken(new SubmissionForPickupDto() {
var token = _encryption.CreateAcceptSecurityEventToken(new SubmissionForPickupDto {
SubmissionId = Guid.NewGuid().ToString(), CaseId = Guid.NewGuid().ToString(),
DestinationId = Guid.NewGuid().ToString()
});
......
......@@ -8,8 +8,6 @@ using NUnit.Framework;
namespace FluentApiTest;
public class SubscriberReceiveTests {
private readonly string clientId = "clientId";
private readonly string clientSecret = "clientSecret";
private IContainer _container = null!;
private ILogger _logger = null!;
private MockSettings _mockSettings = null!;
......
......@@ -30,7 +30,7 @@ public static class SubscriberDemo {
var submissions = subscriber.GetAvailableSubmissions();
foreach (var submission in submissions) {
foreach (var submission in submissions)
try {
var subscriberWithSubmission =
subscriber.RequestSubmission(submission.SubmissionId);
......@@ -40,9 +40,9 @@ public static class SubscriberDemo {
logger.LogInformation("Fachdaten: {Data}", subscriberWithSubmission.GetDataJson());
subscriberWithSubmission
.AcceptSubmission();
} catch (Exception e) {
}
catch (Exception e) {
logger.LogError(e, "Fehler beim Abrufen der Einreichung");
}
}
}
}
......@@ -6,8 +6,8 @@ using Microsoft.Extensions.Logging;
namespace E2ETest;
public class RejectSubmissionTest : EndToEndTestBase {
private string? _caseId;
private string? _submissionId;
private string _caseId = null!;
private string _submissionId = null!;
[Order(10)]
[Test]
......@@ -18,8 +18,8 @@ public class RejectSubmissionTest : EndToEndTestBase {
.WithData(@"{""data"":""value""}")
.Submit();
_caseId = submission.CaseId;
_submissionId = submission.Id;
_caseId = submission.CaseId!;
_submissionId = submission.Id!;
_caseId.Should().NotBeNull();
_submissionId.Should().NotBeNull();
......@@ -29,7 +29,7 @@ public class RejectSubmissionTest : EndToEndTestBase {
[Order(20)]
public void Sender_GetSubmissionState() {
// Act
var status = Sender.GetStatusForSubmission(_caseId);
var status = Sender.GetStatusForSubmission(_caseId, Settings.DestinationId);
// Assert
status.Count.Should().BeGreaterThan(0);
......@@ -41,7 +41,7 @@ public class RejectSubmissionTest : EndToEndTestBase {
[Order(30)]
public void Subscriber_GetSubmissionState() {
// Act
var status = Subscriber.GetStatusForSubmission(_caseId);
var status = Subscriber.GetStatusForSubmission(_caseId, Settings.DestinationId);
// Assert
status.Count.Should().BeGreaterThan(0);
......@@ -64,14 +64,14 @@ public class RejectSubmissionTest : EndToEndTestBase {
subscriberWithSubmission.RejectSubmission(Problems.SchemaViolation
//,new Problems { Detail = "A critical problem" }
);
);
}
[Test]
[Order(50)]
public void Sender_GetSubmissionState_AfterRejecting() {
// Act
var status = Sender.GetStatusForSubmission(_caseId);
var status = Sender.GetStatusForSubmission(_caseId, Settings.DestinationId);
// Assert
status.Count.Should().BeGreaterThan(0);
......
using FitConnect.Models;
using FitConnect.Models.v1.Api;
using FluentAssertions;
using Microsoft.Extensions.Logging;
namespace E2ETest;
public class StraightForwardTest : EndToEndTestBase {
private string? _caseId;
private string? _submissionId;
private string _caseId = null!;
private string _submissionId = null!;
[Order(10)]
[Test]
......@@ -18,8 +17,8 @@ public class StraightForwardTest : EndToEndTestBase {
.WithData(@"{""data"":""value""}")
.Submit();
_caseId = submission.CaseId;
_submissionId = submission.Id;
_caseId = submission.CaseId!;
_submissionId = submission.Id!;
_caseId.Should().NotBeNull();
_submissionId.Should().NotBeNull();
......@@ -29,7 +28,7 @@ public class StraightForwardTest : EndToEndTestBase {
[Order(20)]
public void Sender_GetSubmissionState() {
// Act
var status = Sender.GetStatusForSubmission(_caseId);
var status = Sender.GetStatusForSubmission(_caseId, Settings.DestinationId);
// Assert
status.Count.Should().BeGreaterThan(0);
......@@ -41,7 +40,7 @@ public class StraightForwardTest : EndToEndTestBase {
[Order(30)]
public void Subscriber_GetSubmissionState() {
// Act
var status = Subscriber.GetStatusForSubmission(_caseId);
var status = Subscriber.GetStatusForSubmission(_caseId, Settings.DestinationId);
// Assert
status.Count.Should().BeGreaterThan(0);
......@@ -69,7 +68,7 @@ public class StraightForwardTest : EndToEndTestBase {
[Order(50)]
public void Sender_GetSubmissionState_AfterAccepting() {
// Act
var status = Sender.GetStatusForSubmission(_caseId);
var status = Sender.GetStatusForSubmission(_caseId, Settings.DestinationId);
// Assert
status.Count.Should().BeGreaterThan(0);
......
......@@ -10,13 +10,13 @@ using NUnit.Framework;
namespace SenderTest;
public class FileEncryptionTest {
private string _encryptedFile;
private FitEncryption _encryption;
private byte[] sourceFile = null!;
private string _encryptedFile = null!;
private FitEncryption _encryption = null!;
private byte[] _sourceFile = null!;
[SetUp]
public void Setup() {
sourceFile = RandomNumberGenerator.GetBytes(4096);
_sourceFile = RandomNumberGenerator.GetBytes(4096);
var container = Container.Create();
var keySet = container.Resolve<KeySet>();
_encryption = new FitEncryption(keySet, null);
......@@ -25,7 +25,7 @@ public class FileEncryptionTest {
[Test]
[Order(10)]
public void EncryptFile() {
_encryptedFile = _encryption.Encrypt(sourceFile);
_encryptedFile = _encryption.Encrypt(_sourceFile);
}
[Test]
......
......@@ -13,10 +13,10 @@ using NUnit.Framework;
namespace SenderTest;
public class JweTest {
private IContainer _container;
private ILogger<JweTest> _logger;
private Sender _sender;
private MockSettings _settings;
private IContainer _container = null!;
private ILogger<JweTest> _logger = null!;
private Sender _sender = null!;
private MockSettings _settings = null!;
[SetUp]
......
......@@ -4,11 +4,9 @@ using System.Text;
using FitConnect.Models.v1.Api;
using FitConnect.Services.Models.v1.Submission;
using IdentityModel;
using Jose;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
namespace FitConnect.Encryption;
......@@ -22,7 +20,7 @@ public class KeySet {
public class FitEncryption {
private readonly IEncryptor _encryptor = new JoseEncryptor();
private readonly ILogger? _logger;
private JwtHeader _jwtHeader;
private JwtHeader? _jwtHeader;
internal FitEncryption(ILogger? logger) {
_logger = logger;
......@@ -51,6 +49,7 @@ public class FitEncryption {
public string? PublicKeyEncryption { get; set; }
public string? PublicKeySignatureVerification { get; set; }
public (string plainText, byte[] plainBytes, byte[] tag)
Decrypt(string cypherText, string key) {
return _encryptor.Decrypt(key, cypherText);
......@@ -88,23 +87,30 @@ public class FitEncryption {
public string CreateRejectSecurityEventToken(string submissionId,
string caseId,
string destinationId, Problems[]? problemsArray) =>
CreateSecurityEventToken(submissionId, caseId, destinationId,
string destinationId, Problems[]? problemsArray) {
return CreateSecurityEventToken(submissionId, caseId, destinationId,
"https://schema.fitko.de/fit-connect/events/reject-submission",
new { problems = problemsArray });
}
public string CreateAcceptSecurityEventToken(SubmissionForPickupDto submission) {
// string submissionSubmissionId,string submissionCaseId, string submissionDestinationId) {
// NOMERGE Remove Dummy data
var payload = new {
authenticationTags = new {
data = "UCGiqJxhBI3IFVdPalHHvA", metadata = "XFBoMYUZodetZdvTiFvSkQ",
attachments = new Dictionary<string, string>() {
attachments = new Dictionary<string, string> {
{ "0b799252-deb9-42b0-98d3-c50d24bbafe0", "rT99rwrBTbTI7IJM8fU3El" }
}
}
};
// TODO Add payload
// NOMERGE Add payload
if (submission?.SubmissionId == null || submission?.CaseId == null ||
submission?.DestinationId == null)
throw new ArgumentException("SubmissionId, CaseId and DestinationId are required");
return CreateSecurityEventToken(submission.SubmissionId, submission.CaseId,
submission.DestinationId,
"https://schema.fitko.de/fit-connect/events/accept-submission", null);
......@@ -169,7 +175,7 @@ public class FitEncryption {
public static bool VerifyJwt(string signature, IEnumerable<JsonWebKey> keys,
ILogger? logger = null) {
foreach (var key in keys) {
foreach (var key in keys)
try {
var valid = VerifyJwt(signature, key, logger);
if (valid) return true;
......@@ -177,7 +183,6 @@ public class FitEncryption {
catch (Exception e) {
logger?.LogError(e, "Error verifying JWT");
}
}
return false;
}
......
......@@ -4,6 +4,7 @@ using FitConnect.Encryption;
using FitConnect.Models;
using FitConnect.Services;
using FitConnect.Services.Interfaces;
using FitConnect.Services.Models.v1.Submission;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
......@@ -64,16 +65,20 @@ public abstract class FitConnectClient {
private FitConnectClient() {
// Take care of OAuthService if make the constructor public
Encryption = new FitEncryption(Logger);
}
public IOAuthService OAuthService { get; }
public ISubmissionService SubmissionService { get; }
public IRouteService RouteService { get; }
public IDestinationService DestinationService { get; }
public ICasesService CasesService { get; }
public ILogger? Logger { get; }
public FitEncryption Encryption { get; set; }
public IOAuthService OAuthService { get; } =
null!; // To resolve the warning, is only applicable for the **private** constructor
protected ISubmissionService SubmissionService { get; } = null!;
protected IRouteService RouteService { get; } = null!;
protected IDestinationService DestinationService { get; } = null!;
protected ICasesService CasesService { get; } = null!;
protected ILogger? Logger { get; }
protected FitEncryption Encryption { get; set; }
public void SetProxy(WebProxy proxy) {
OAuthService.Proxy = proxy;
......@@ -91,12 +96,33 @@ public abstract class FitConnectClient {
/// Retrieve the events for the submission
/// </summary>
/// <param name="caseId"></param>
/// <param name="destinationId"></param>
/// <param name="skipTest"></param>
/// <returns></returns>
public List<SecurityEventToken> GetStatusForSubmission(string caseId, string destinationId,
bool skipTest = false) {
var events = SubmissionService.GetStatusForSubmissionAsync(caseId, destinationId, skipTest)
.Result;
return events?.Where(s => s != null)
.Select(e => new SecurityEventToken(e!)).ToList() ?? new List<SecurityEventToken>();
}
/// <summary>
/// Retrieve the events for the submission
/// </summary>
/// <param name="submission"></param>
/// <param name="skipTest"></param>
/// <returns></returns>
public List<SecurityEventToken> GetStatusForSubmission(string caseId, bool skipTest = false) {
var events = SubmissionService.GetStatusForSubmissionAsync(caseId, skipTest).Result;
return events.Where(s => s != null)
.Select(e => new SecurityEventToken(e!)).ToList();
public List<SecurityEventToken> GetStatusForSubmission(SubmissionForPickupDto submission,
bool skipTest = false) {
if (submission?.CaseId == null || submission.DestinationId == null)
throw new ArgumentNullException(nameof(submission));
var events = SubmissionService
.GetStatusForSubmissionAsync(submission.CaseId, submission.DestinationId, skipTest)
.Result;
return events?.Select(e => new SecurityEventToken(e)).ToList() ??
new List<SecurityEventToken>();
}
/// <summary>
......@@ -106,7 +132,7 @@ public abstract class FitConnectClient {
/// <param name="attachment"></param>
/// <returns></returns>
public KeyValuePair<string, string> Encrypt(string publicKey, Attachment attachment) {
var content = Encryption.Encrypt(attachment.Content, publicKey);
var content = Encryption.Encrypt(attachment.Content ?? Array.Empty<byte>(), publicKey);
return new KeyValuePair<string, string>(attachment.Id, content);
}
......
using FitConnect.Models;
using FitConnect.Services.Models.v1.Submission;
namespace FitConnect.Interfaces;
public interface IFitConnectClient {
// public List<SecurityEventToken> GetStatusForSubmission(string caseId, bool skipTest = false);
/// <summary>
/// Receives the SecurityEventTokens for a given case
/// </summary>
/// <param name="caseId">ID of the case</param>
/// <param name="destinationId">Skips signature validation if null!</param>
/// <param name="skipTest">Specifies if the SET signature test is skipped</param>
/// <returns>List of the <see cref="SecurityEventToken" /></returns>
public List<SecurityEventToken> GetStatusForSubmission(string caseId, string destinationId,
bool skipTest = false);
/// <summary>
/// </summary>
/// <param name="submission"></param>
/// <param name="skipTest"></param>
/// <returns></returns>
public List<SecurityEventToken> GetStatusForSubmission(SubmissionForPickupDto submission,
bool skipTest = false);
}
using FitConnect.Interfaces.Subscriber;
namespace FitConnect.Interfaces.Sender;
public interface ISender : IFitConnectClient {
public string PublicKey { get; }
public string? PublicKey { get; }
/// <summary>
/// Determines the destination id and configures the sender.
......
using FitConnect.Models;
namespace FitConnect.Interfaces.Sender;
public interface ISenderWithAttachments : ISenderReady {
public Submission Submission { get; }
/// <summary>
/// Data as string.
/// </summary>
......
......@@ -3,8 +3,6 @@ using FitConnect.Models;
namespace FitConnect.Interfaces.Sender;
public interface ISenderWithService {
public string PublicKey { get; set; }
/// <summary>
/// Sends the submission with a list of attachments
/// </summary>
......
......@@ -23,13 +23,3 @@ public interface ISubscriber : IFitConnectClient {
public ISubscriberWithSubmission RequestSubmission(string? submissionId,
bool skipSchemaTest = false);
}
public interface IFitConnectClient {
/// <summary>
/// Receives the SecurityEventTokens for a given case
/// </summary>
/// <param name="caseId">ID of the case</param>
/// <param name="skipTest">Specifies if the SET signature test is skipped</param>
/// <returns>List of the <see cref="SecurityEventToken" /></returns>
public List<SecurityEventToken> GetStatusForSubmission(string caseId, bool skipTest = false);
}
......@@ -4,14 +4,14 @@ using FitConnect.Models.v1.Api;
namespace FitConnect.Interfaces.Subscriber;
public interface ISubscriberWithSubmission {
public Submission Submission { get; }
public Submission? Submission { get; }
/// <summary>
/// Returns the data (Fachdaten) of the submission
/// </summary>
/// <returns></returns>
public string? GetDataJson() {
return Submission.Data;
return Submission?.Data;
}
/// <summary>
......
......@@ -57,7 +57,7 @@ public class Attachment {
public AttachmentSignature? Signature { get; }
private string CalculateHash() {
return ByteToHexString(SHA512.Create().ComputeHash(Content));
return ByteToHexString(SHA512.Create().ComputeHash(Content ?? Array.Empty<byte>()));
}
private static string ByteToHexString(IEnumerable<byte> data) {
......
......@@ -4,7 +4,7 @@ namespace FitConnect.Models;
public record Callback(string? Url, string? Secret) {
public static explicit operator Callback(CallbackDto dto) {
return new Callback(dto?.Url, null);
return new(dto.Url, null);
}
public static explicit operator CallbackDto(Callback model) {
......
namespace FitConnect.Models;
public class FitConnectEnvironment {
// List of Domains
// https://wiki.fit-connect.fitko.dev/de/Betrieb/Dokumentation/Domains
public static readonly FitConnectEnvironment Testing = new(
"https://auth-testing.fit-connect.fitko.dev/token",
new[] { "https://submission-api-testing.fit-connect.fitko.dev" },
......@@ -26,7 +25,12 @@ public class FitConnectEnvironment {
"https://portal.auth.fit-connect.fitko.net"
);
public FitConnectEnvironment() {
public FitConnectEnvironment(string sspUrl, string tokenUrl, string[] submissionUrl,
string routingUrl) {
SspUrl = sspUrl;
TokenUrl = tokenUrl;
SubmissionUrl = submissionUrl;
RoutingUrl = routingUrl;
}
/// <summary>
......
......@@ -24,7 +24,11 @@ public class SecurityEventToken {
public SecurityEventToken(string jwtEncodedString) {
Token = new JsonWebToken(jwtEncodedString);
EventType = DecodeEventType(Token.Claims);
var iat = Token.Claims.FirstOrDefault(c => c.Type == "iat").Value;
if (Token.Claims.All(c => c.Type != "iat"))
return;
var iat = Token.Claims.FirstOrDefault(c => c.Type == "iat")!.Value;
if (long.TryParse(iat, out var timeEpoch))
EventTime = DateTime.UnixEpoch.AddSeconds(timeEpoch);
}
......
......@@ -6,10 +6,10 @@ namespace FitConnect.Models;
public class Submission {
public string? Id { get; set; }
public string? CaseId { get; set; }
public Destination? Destination { get; set; } = new();
public Destination Destination { get; set; } = new();
public string DestinationId {
get => Destination.DestinationId;
get => Destination.DestinationId ?? throw new ArgumentNullException(nameof(DestinationId));
set => Destination.DestinationId = value;
}
......@@ -55,20 +55,23 @@ public class Submission {
return new Submission {
Id = dto.SubmissionId,
Callback = null,
DestinationId = dto.DestinationId,
ServiceType = null
DestinationId = dto.DestinationId ??
throw new NullReferenceException(nameof(dto.DestinationId)),
ServiceType = new ServiceType()
};
}
public static explicit operator Submission(SubmissionDto dto) {
return new Submission {
Id = dto.SubmissionId,
Callback = (Callback)dto.Callback,
DestinationId = dto.DestinationId,
ServiceType = (ServiceType)dto.ServiceType,
Callback = dto.Callback == null ? null : (Callback)dto.Callback,
DestinationId = dto.DestinationId ??
throw new NullReferenceException(nameof(dto.DestinationId)),
ServiceType =
dto.ServiceType == null ? new ServiceType() : (ServiceType)dto.ServiceType,
EncryptedData = dto.EncryptedData,
EncryptedMetadata = dto.EncryptedMetadata,
AttachmentIds = dto.Attachments,
AttachmentIds = dto.Attachments ?? new List<string>(),
CaseId = dto.CaseId
};
}
......
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