Skip to content

Commit

Permalink
feat: add support for dataset aliases
Browse files Browse the repository at this point in the history
  • Loading branch information
SondreJDigdir committed Dec 5, 2024
1 parent 847c906 commit 20ec04e
Show file tree
Hide file tree
Showing 19 changed files with 435 additions and 24 deletions.
8 changes: 8 additions & 0 deletions Dan.Common/Models/EvidenceCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,12 @@ public class EvidenceCode
[DataMember(Name = "timeout")]
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public int? Timeout { get; set; }

/// <summary>
/// Optional setting for aliases. Key is service context, value is Dataset name
/// Allows for the same dataset to be shared between service contexts with different names.
/// </summary>
[DataMember(Name = "datasetAliases")]
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public Dictionary<string,string>? DatasetAliases { get; set; }
}
91 changes: 81 additions & 10 deletions Dan.Core.UnitTest/EvidenceHarvesterServiceTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public class EvidenceHarvesterServiceTest
private readonly Mock<IEvidenceStatusService> _mockEvidenceStatusService = new();
private readonly Mock<ITokenRequesterService> _mockTokenRequesterService = new();
private readonly Mock<IRequestContextService> _mockRequestContextService = new();
private readonly Mock<IAvailableEvidenceCodesService> _mockAvailableEvidenceCodesService = new();

private const string CONSENT_DENIED = "denied";

Expand Down Expand Up @@ -61,7 +62,14 @@ public async Task Harvest_Success_Open()
);

Accreditation accreditation = MakeAccreditation("aid", Certificates.DEFAULT_ORG);
var evidenceHarvesterService = new EvidenceHarvesterService(_loggerFactory, _mockHttpClientFactory.Object, _mockConsentService.Object, _mockEvidenceStatusService.Object, _mockTokenRequesterService.Object, _mockRequestContextService.Object);
var evidenceHarvesterService = new EvidenceHarvesterService(
_loggerFactory,
_mockHttpClientFactory.Object,
_mockConsentService.Object,
_mockEvidenceStatusService.Object,
_mockTokenRequesterService.Object,
_mockRequestContextService.Object,
_mockAvailableEvidenceCodesService.Object);

var response = await evidenceHarvesterService.Harvest(EVIDENCECODE_OPEN, accreditation);

Expand All @@ -84,7 +92,14 @@ public async Task Harvest_Success_Consent()
_mockConsentService.Setup(_ => _.GetJwt(It.IsAny<Accreditation>())).Returns(Task.FromResult("somejwt"));

Accreditation accreditation = MakeAccreditation("aid", Certificates.DEFAULT_ORG);
var evidenceHarvesterService = new EvidenceHarvesterService(_loggerFactory, _mockHttpClientFactory.Object, _mockConsentService.Object, _mockEvidenceStatusService.Object, _mockTokenRequesterService.Object, _mockRequestContextService.Object);
var evidenceHarvesterService = new EvidenceHarvesterService(
_loggerFactory,
_mockHttpClientFactory.Object,
_mockConsentService.Object,
_mockEvidenceStatusService.Object,
_mockTokenRequesterService.Object,
_mockRequestContextService.Object,
_mockAvailableEvidenceCodesService.Object);

var response = await evidenceHarvesterService.Harvest(EVIDENCECODE_CONSENT, accreditation);

Expand All @@ -106,7 +121,14 @@ public void Harvest_Failure_ConsentRequestPending()
);
Accreditation accreditation = MakeAccreditation("aid", Certificates.DEFAULT_ORG, null);

var evidenceHarvesterService = new EvidenceHarvesterService(_loggerFactory, _mockHttpClientFactory.Object, _mockConsentService.Object, _mockEvidenceStatusService.Object, _mockTokenRequesterService.Object, _mockRequestContextService.Object);
var evidenceHarvesterService = new EvidenceHarvesterService(
_loggerFactory,
_mockHttpClientFactory.Object,
_mockConsentService.Object,
_mockEvidenceStatusService.Object,
_mockTokenRequesterService.Object,
_mockRequestContextService.Object,
_mockAvailableEvidenceCodesService.Object);

var actual = Assert.ThrowsExceptionAsync<RequiresConsentException>(() => evidenceHarvesterService.Harvest(EVIDENCECODE_CONSENT, accreditation));
StringAssert.Contains(actual.Result.Message, "pending a reply to the consent request");
Expand All @@ -126,7 +148,14 @@ public void Harvest_Failure_ConsentDenied()
);
Accreditation accreditation = MakeAccreditation("aid", Certificates.DEFAULT_ORG, null, CONSENT_DENIED);

var evidenceHarvesterService = new EvidenceHarvesterService(_loggerFactory, _mockHttpClientFactory.Object, _mockConsentService.Object, _mockEvidenceStatusService.Object, _mockTokenRequesterService.Object, _mockRequestContextService.Object);
var evidenceHarvesterService = new EvidenceHarvesterService(
_loggerFactory,
_mockHttpClientFactory.Object,
_mockConsentService.Object,
_mockEvidenceStatusService.Object,
_mockTokenRequesterService.Object,
_mockRequestContextService.Object,
_mockAvailableEvidenceCodesService.Object);

var actual = Assert.ThrowsExceptionAsync<RequiresConsentException>(() => evidenceHarvesterService.Harvest(EVIDENCECODE_CONSENT, accreditation));
StringAssert.Contains(actual.Result.Message, "evidence code has been denied or revoked");
Expand All @@ -146,7 +175,14 @@ public void Harvest_Failure_ConsentExpired()
);
Accreditation accreditation = MakeAccreditation("aid", Certificates.DEFAULT_ORG, DateTime.Now.AddDays(-1));

var evidenceHarvesterService = new EvidenceHarvesterService(_loggerFactory, _mockHttpClientFactory.Object, _mockConsentService.Object, _mockEvidenceStatusService.Object, _mockTokenRequesterService.Object, _mockRequestContextService.Object);
var evidenceHarvesterService = new EvidenceHarvesterService(
_loggerFactory,
_mockHttpClientFactory.Object,
_mockConsentService.Object,
_mockEvidenceStatusService.Object,
_mockTokenRequesterService.Object,
_mockRequestContextService.Object,
_mockAvailableEvidenceCodesService.Object);

var actual = Assert.ThrowsExceptionAsync<RequiresConsentException>(() => evidenceHarvesterService.Harvest(EVIDENCECODE_CONSENT, accreditation));
StringAssert.Contains(actual.Result.Message, "evidence code has expired");
Expand All @@ -167,7 +203,14 @@ public void Harvest_Failure_AsyncWaiting()

Accreditation accreditation = MakeAccreditation("aid", Certificates.DEFAULT_ORG);

var evidenceHarvesterService = new EvidenceHarvesterService(_loggerFactory, _mockHttpClientFactory.Object, _mockConsentService.Object, _mockEvidenceStatusService.Object, _mockTokenRequesterService.Object, _mockRequestContextService.Object);
var evidenceHarvesterService = new EvidenceHarvesterService(
_loggerFactory,
_mockHttpClientFactory.Object,
_mockConsentService.Object,
_mockEvidenceStatusService.Object,
_mockTokenRequesterService.Object,
_mockRequestContextService.Object,
_mockAvailableEvidenceCodesService.Object);

var actual = Assert.ThrowsExceptionAsync<AsyncEvidenceStillWaitingException>(() => evidenceHarvesterService.Harvest(EVIDENCECODE_ASYNC, accreditation));
StringAssert.Contains(actual.Result.Message, "The data for the requested evidence is not yet available");
Expand All @@ -191,7 +234,14 @@ public void Harvest_Failure_MissingScope()

Accreditation accreditation = MakeAccreditation("aid", Certificates.DEFAULT_ORG);

var evidenceHarvesterService = new EvidenceHarvesterService(_loggerFactory, _mockHttpClientFactory.Object, _mockConsentService.Object, _mockEvidenceStatusService.Object, _mockTokenRequesterService.Object, _mockRequestContextService.Object);
var evidenceHarvesterService = new EvidenceHarvesterService(
_loggerFactory,
_mockHttpClientFactory.Object,
_mockConsentService.Object,
_mockEvidenceStatusService.Object,
_mockTokenRequesterService.Object,
_mockRequestContextService.Object,
_mockAvailableEvidenceCodesService.Object);

var actual = Assert.ThrowsExceptionAsync<ServiceNotAvailableException>(() => evidenceHarvesterService.Harvest(EVIDENCECODE_OPEN, accreditation));
StringAssert.Contains(actual.Result.Message, "unable to retrieve authentication token");
Expand All @@ -216,7 +266,14 @@ public void Harvest_Failure_AsyncWaitingWithRetry()

Accreditation accreditation = MakeAccreditation("aid", Certificates.DEFAULT_ORG, DateTime.Now.AddDays(-1));

var evidenceHarvesterService = new EvidenceHarvesterService(_loggerFactory, _mockHttpClientFactory.Object, _mockConsentService.Object, _mockEvidenceStatusService.Object, _mockTokenRequesterService.Object, _mockRequestContextService.Object);
var evidenceHarvesterService = new EvidenceHarvesterService(
_loggerFactory,
_mockHttpClientFactory.Object,
_mockConsentService.Object,
_mockEvidenceStatusService.Object,
_mockTokenRequesterService.Object,
_mockRequestContextService.Object,
_mockAvailableEvidenceCodesService.Object);

var actual = Assert.ThrowsExceptionAsync<AsyncEvidenceStillWaitingException>(() => evidenceHarvesterService.Harvest(EVIDENCECODE_ASYNC, accreditation));
StringAssert.Contains(actual.Result.Message, "The data for the requested evidence is not yet available");
Expand All @@ -237,7 +294,14 @@ public async Task Harvest_Success_AsyncOpen()

Accreditation accreditation = MakeAccreditation("aid", Certificates.DEFAULT_ORG, DateTime.Now.AddDays(-1));

var evidenceHarvesterService = new EvidenceHarvesterService(_loggerFactory, _mockHttpClientFactory.Object, _mockConsentService.Object, _mockEvidenceStatusService.Object, _mockTokenRequesterService.Object, _mockRequestContextService.Object);
var evidenceHarvesterService = new EvidenceHarvesterService(
_loggerFactory,
_mockHttpClientFactory.Object,
_mockConsentService.Object,
_mockEvidenceStatusService.Object,
_mockTokenRequesterService.Object,
_mockRequestContextService.Object,
_mockAvailableEvidenceCodesService.Object);
var response = await evidenceHarvesterService.Harvest(EVIDENCECODE_ASYNC, accreditation);

Assert.AreEqual((int)StatusCodeId.Available, response.EvidenceStatus.Status.Code);
Expand All @@ -259,7 +323,14 @@ public async Task Harvest_Success_Stream()

Accreditation accreditation = MakeAccreditation("aid", Certificates.DEFAULT_ORG, DateTime.Now.AddDays(-1));

var evidenceHarvesterService = new EvidenceHarvesterService(_loggerFactory, _mockHttpClientFactory.Object, _mockConsentService.Object, _mockEvidenceStatusService.Object, _mockTokenRequesterService.Object, _mockRequestContextService.Object);
var evidenceHarvesterService = new EvidenceHarvesterService(
_loggerFactory,
_mockHttpClientFactory.Object,
_mockConsentService.Object,
_mockEvidenceStatusService.Object,
_mockTokenRequesterService.Object,
_mockRequestContextService.Object,
_mockAvailableEvidenceCodesService.Object);
var response = await evidenceHarvesterService.HarvestStream(EVIDENCECODE_STREAM, accreditation);

var sr = new StreamReader(response);
Expand Down
6 changes: 4 additions & 2 deletions Dan.Core/Extensions/EvidenceCodeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ public static class EvidenceCodeExtensions
/// Gets the full URL to the evidence code
/// </summary>
/// <param name="evidenceCode">The evidence code instance</param>
/// <param name="aliases">Collection of evidence code aliases</param>
/// <returns>A fully qualified URL</returns>
public static string GetEvidenceSourceUrl(this EvidenceCode evidenceCode)
public static string GetEvidenceSourceUrl(this EvidenceCode evidenceCode, Dictionary<string, string> aliases)
{
return Settings.GetEvidenceSourceUrl(evidenceCode.EvidenceSource).Replace("/api/evidencecodes", $"/api/{evidenceCode.EvidenceCodeName}?code={Settings.FunctionKeyValue}");
var evidenceCodeName = aliases?.GetValueOrDefault(evidenceCode.EvidenceCodeName) ?? evidenceCode.EvidenceCodeName;
return Settings.GetEvidenceSourceUrl(evidenceCode.EvidenceSource).Replace("/api/evidencecodes", $"/api/{evidenceCodeName}?code={Settings.FunctionKeyValue}");
}

/// <summary>
Expand Down
8 changes: 6 additions & 2 deletions Dan.Core/FuncAuthorization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class FuncAuthorization
private readonly IAuthorizationRequestValidatorService _authorizationRequestValidatorService;
private readonly IRequestContextService _requestContextService;
private readonly IAccreditationRepository _accreditationRepository;
private readonly IAvailableEvidenceCodesService _availableEvidenceCodesService;
private readonly ILogger<FuncAuthorization> _logger;

public FuncAuthorization(
Expand All @@ -29,14 +30,16 @@ public FuncAuthorization(
IConsentService consentService,
IAuthorizationRequestValidatorService authorizationRequestValidatorService,
IRequestContextService requestContextService,
IAccreditationRepository accreditationRepository)
IAccreditationRepository accreditationRepository,
IAvailableEvidenceCodesService availableEvidenceCodesService)
{
_logger = loggerFactory.CreateLogger<FuncAuthorization>();
_client = httpClientFactory.CreateClient("SafeHttpClient");
_consentService = consentService;
_authorizationRequestValidatorService = authorizationRequestValidatorService;
_requestContextService = requestContextService;
_accreditationRepository = accreditationRepository;
_availableEvidenceCodesService = availableEvidenceCodesService;
}

/// <summary>
Expand Down Expand Up @@ -90,7 +93,8 @@ public async Task<HttpResponseData> RunAsync(
using (var t = _logger.Timer($"{evidenceCode.EvidenceCodeName}-init"))
{
_logger.LogInformation("Start init async evidenceCode={evidenceCode} aid={accreditationId}", evidenceCode.EvidenceCodeName, accreditation.AccreditationId);
await EvidenceSourceHelper.InitAsynchronousEvidenceCodeRequest(accreditation, evidenceCode, _client);
var aliases = _availableEvidenceCodesService.GetAliases();
await EvidenceSourceHelper.InitAsynchronousEvidenceCodeRequest(accreditation, evidenceCode, _client, aliases);
_logger.LogInformation("Completed init async evidenceCode={evidenceCode} aid={accreditationId} elapsedMs={elapsedMs}", evidenceCode.EvidenceCodeName, accreditation.AccreditationId, t.ElapsedMilliseconds);
}
}
Expand Down
5 changes: 3 additions & 2 deletions Dan.Core/Helpers/EvidenceSourceHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,11 @@ public static class EvidenceSourceHelper
/// <param name="accreditation">The associated accreditation</param>
/// <param name="evidenceCode">The evidence code to initialize</param>
/// <param name="client">The HTTP client</param>
/// <param name="aliases">Evidence code aliases</param>
/// <returns>Nothing, but will throw if the call fails or the evidence source reports and error</returns>
public static async Task InitAsynchronousEvidenceCodeRequest(Accreditation accreditation, EvidenceCode evidenceCode, HttpClient client)
public static async Task InitAsynchronousEvidenceCodeRequest(Accreditation accreditation, EvidenceCode evidenceCode, HttpClient client, Dictionary<string, string> aliases)
{
var url = evidenceCode.GetEvidenceSourceUrl();
var url = evidenceCode.GetEvidenceSourceUrl(aliases);

var request = new HttpRequestMessage(HttpMethod.Post, url);

Expand Down
Loading

0 comments on commit 20ec04e

Please sign in to comment.