Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: enhance use case participant get credential endpoint by supporting filters #331

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 33 additions & 38 deletions docs/api/issuer-service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ paths:
tags:
- 'Org.Eclipse.TractusX.SsiCredentialIssuer.Service, Version=1.2.0.0, Culture=neutral, PublicKeyToken=null'
summary: Gets all use case frameworks and the participation status of the acting company
description: 'Example: GET: api/issuer/useCaseParticipation'
description: 'Example: GET: api/issuer/useCaseParticipation<br><h3>Available values:</h3> All, Active, Expired'
parameters:
- name: status
in: query
schema:
type: string
responses:
'200':
description: OK
Expand All @@ -30,6 +35,12 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'409':
description: Conflict
content:
Expand Down Expand Up @@ -288,10 +299,6 @@ paths:
type: string
format: uuid
responses:
'200':
description: OK
content:
application/json: { }
'401':
description: Unauthorized
content:
Expand Down Expand Up @@ -337,10 +344,6 @@ paths:
type: string
format: uuid
responses:
'200':
description: OK
content:
application/json: { }
'401':
description: Unauthorized
content:
Expand Down Expand Up @@ -392,10 +395,6 @@ paths:
schema:
$ref: '#/components/schemas/ProcessStepTypeId'
responses:
'200':
description: OK
content:
application/json: { }
'401':
description: Unauthorized
content:
Expand Down Expand Up @@ -441,13 +440,6 @@ paths:
type: string
format: uuid
responses:
'200':
description: OK
content:
application/json:
schema:
type: string
format: uuid
'401':
description: Unauthorized
content:
Expand All @@ -460,6 +452,13 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'200':
description: OK
content:
application/json:
schema:
type: string
format: uuid
'/api/revocation/credentials/{credentialId}':
post:
tags:
Expand All @@ -475,13 +474,6 @@ paths:
type: string
format: uuid
responses:
'200':
description: OK
content:
application/json:
schema:
type: string
format: uuid
'401':
description: Unauthorized
content:
Expand All @@ -494,6 +486,13 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'200':
description: OK
content:
application/json:
schema:
type: string
format: uuid
'/api/revocation/{processId}/retrigger-step/{processStepTypeId}':
post:
tags:
Expand All @@ -515,10 +514,6 @@ paths:
schema:
$ref: '#/components/schemas/ProcessStepTypeId'
responses:
'200':
description: OK
content:
application/json: { }
'401':
description: Unauthorized
content:
Expand Down Expand Up @@ -600,13 +595,6 @@ paths:
type: string
format: uuid
responses:
'200':
description: OK
content:
application/json:
schema:
type: string
format: binary
'401':
description: Unauthorized
content:
Expand All @@ -619,6 +607,13 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'200':
description: OK
content:
application/json:
schema:
type: string
format: binary
'409':
description: Conflict
content:
Expand Down
27 changes: 27 additions & 0 deletions src/database/SsiCredentialIssuer.DbAccess/Models/StatusType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/********************************************************************************
* Copyright (c) 2024 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

namespace Org.Eclipse.TractusX.SsiCredentialIssuer.DBAccess.Models;
leandro-cavalcante marked this conversation as resolved.
Show resolved Hide resolved

public enum StatusType
{
Active,
Expired,
All
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,19 @@ public class CompanySsiDetailsRepository(IssuerDbContext context)
: ICompanySsiDetailsRepository
{
/// <inheritdoc />
public IAsyncEnumerable<UseCaseParticipationData> GetUseCaseParticipationForCompany(string bpnl, DateTimeOffset minExpiry) =>
public IAsyncEnumerable<UseCaseParticipationData> GetUseCaseParticipationForCompany(string bpnl, DateTimeOffset minExpiry, StatusType? statusType) =>
context.VerifiedCredentialTypes
.Where(t => t.VerifiedCredentialTypeAssignedKind!.VerifiedCredentialTypeKindId == VerifiedCredentialTypeKindId.FRAMEWORK)
.Select(t => new
{
t.VerifiedCredentialTypeAssignedUseCase!.UseCase,
TypeId = t.Id,
ExternalTypeDetails = t.VerifiedCredentialTypeAssignedExternalType!.VerifiedCredentialExternalType!.VerifiedCredentialExternalTypeDetailVersions
.Where(x => !statusType.HasValue || statusType == StatusType.All
|| (statusType == StatusType.Active
&& (x.Expiry > minExpiry))
|| (statusType == StatusType.Expired && x.Expiry <= DateTimeOffset.UtcNow)
)
})
.Select(x => new UseCaseParticipationData(
x.UseCase!.Name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ public interface ICompanySsiDetailsRepository
/// </summary>
/// <param name="bpnl">Bpnl of the company</param>
/// <param name="minExpiry">The minimum datetime the expiry date should have</param>
/// <param name="statusType">the status type on how the credentials should be filtered</param>
/// <returns>AsyncEnumerable of UseCaseParticipation</returns>
IAsyncEnumerable<UseCaseParticipationData> GetUseCaseParticipationForCompany(string bpnl, DateTimeOffset minExpiry);
IAsyncEnumerable<UseCaseParticipationData> GetUseCaseParticipationForCompany(string bpnl, DateTimeOffset minExpiry, StatusType? statusType);

/// <summary>
/// Gets the company credential details for the given company id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace Org.Eclipse.TractusX.SsiCredentialIssuer.Service.BusinessLogic;

public interface IIssuerBusinessLogic
{
IAsyncEnumerable<UseCaseParticipationData> GetUseCaseParticipationAsync();
IAsyncEnumerable<UseCaseParticipationData> GetUseCaseParticipationAsync(string? status);

IAsyncEnumerable<CertificateParticipationData> GetSsiCertificatesAsync();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,22 @@ public IssuerBusinessLogic(
}

/// <inheritdoc />
public IAsyncEnumerable<UseCaseParticipationData> GetUseCaseParticipationAsync() =>
_repositories
public IAsyncEnumerable<UseCaseParticipationData> GetUseCaseParticipationAsync(string? status)
{
StatusType? statusTypeResult = null;
if (!string.IsNullOrEmpty(status))
{
if (!(Enum.TryParse<StatusType>(status, ignoreCase: true, out var statusType) || !Enum.IsDefined(typeof(StatusType), statusType)))
{
throw new ArgumentException($"Status value {status} is not valid; please use Active, Expired or All");
}
statusTypeResult = statusType;
}

return _repositories
.GetInstance<ICompanySsiDetailsRepository>()
.GetUseCaseParticipationForCompany(_identity.Bpnl, _dateTimeProvider.OffsetNow);
.GetUseCaseParticipationForCompany(_identity.Bpnl, _dateTimeProvider.OffsetNow, statusTypeResult);
}

/// <inheritdoc />
public IAsyncEnumerable<CertificateParticipationData> GetSsiCertificatesAsync() =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,18 @@ public static RouteGroupBuilder MapIssuerApi(this RouteGroupBuilder group)
{
var issuer = group.MapGroup("/issuer");

issuer.MapGet("useCaseParticipation", (IIssuerBusinessLogic logic) => logic.GetUseCaseParticipationAsync())
issuer.MapGet("useCaseParticipation", (IIssuerBusinessLogic logic,
[FromQuery(Name = "status")] string? status) => logic.GetUseCaseParticipationAsync(status))
.WithSwaggerDescription("Gets all use case frameworks and the participation status of the acting company",
"Example: GET: api/issuer/useCaseParticipation")
"Example: GET: api/issuer/useCaseParticipation<br><h3>Available values:</h3> All, Active, Expired")
.RequireAuthorization(r =>
{
r.RequireRole("view_use_case_participation");
r.AddRequirements(new MandatoryIdentityClaimRequirement(PolicyTypeId.ValidBpn));
})
.WithDefaultResponses()
.Produces(StatusCodes.Status200OK, typeof(IEnumerable<UseCaseParticipationData>), Constants.JsonContentType)
.Produces(StatusCodes.Status400BadRequest, typeof(ErrorResponse), Constants.JsonContentType)
.Produces(StatusCodes.Status409Conflict, typeof(ErrorResponse), Constants.JsonContentType);

issuer.MapGet("certificates", (IIssuerBusinessLogic logic) => logic.GetSsiCertificatesAsync())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,16 @@ public CompanySsiDetailsRepositoryTests(TestDbFixture testDbFixture)

#region GetDetailsForCompany

[Fact]
public async Task GetDetailsForCompany_WithValidData_ReturnsExpected()
[Theory]
[InlineData(null)]
[InlineData(StatusType.All)]
public async Task GetDetailsForCompany_WithValidData_And_StatusType_ReturnsExpected(StatusType? statusType)
{
// Arrange
var sut = await CreateSut();

// Act
var result = await sut.GetUseCaseParticipationForCompany(ValidBpnl, DateTimeOffset.MinValue).ToListAsync();
var result = await sut.GetUseCaseParticipationForCompany(ValidBpnl, DateTimeOffset.MinValue, statusType).ToListAsync();

// Assert
result.Should().HaveCount(10);
Expand Down Expand Up @@ -85,7 +87,7 @@ public async Task GetDetailsForCompany_WithExpiryFilter_ReturnsExpected()
var sut = await CreateSut();

// Act
var result = await sut.GetUseCaseParticipationForCompany(ValidBpnl, dt).ToListAsync();
var result = await sut.GetUseCaseParticipationForCompany(ValidBpnl, dt, null).ToListAsync();

// Assert
result.Should().HaveCount(10);
Expand All @@ -105,6 +107,56 @@ public async Task GetDetailsForCompany_WithExpiryFilter_ReturnsExpected()
x => x.ExternalDetailData.Version == "3.0" && !x.SsiDetailData.Any());
}

[Fact]
public async Task GetAllExternalTypeDetailDataWithValidData_WithValidData_and_StatusType_Active_ReturnsExpected()
{
// Arrange
var sut = await CreateSut();

//Act

var result = await sut.GetUseCaseParticipationForCompany(ValidBpnl, DateTimeOffset.UtcNow, StatusType.Active).ToListAsync();

// Assert
result.Should().HaveCount(10);
result.SelectMany(x => x.VerifiedCredentials)
.Select(x => x.ExternalDetailData)
.Should().HaveCount(1);
}

[Fact]
public async Task GetAllExternalTypeDetailDataWithValidData_and_StatusType_All_ReturnsExpected()
{
// Arrange
var sut = await CreateSut();

//Act

var result = await sut.GetUseCaseParticipationForCompany(ValidBpnl, DateTimeOffset.UtcNow, StatusType.All).ToListAsync();

// Assert
result.Should().HaveCount(10);
result.SelectMany(x => x.VerifiedCredentials)
.Select(x => x.ExternalDetailData)
.Should().HaveCount(11);
}

[Fact]
public async Task GetAllExternalTypeDetailDataWithValidData_WithValidData_and_StatusType_Expired_ReturnsExpected()
{
// Arrange
var sut = await CreateSut();
//Act

var result = await sut.GetUseCaseParticipationForCompany(ValidBpnl, DateTimeOffset.UtcNow, StatusType.Expired).ToListAsync();

// Assert
result.Should().HaveCount(10);
result.SelectMany(x => x.VerifiedCredentials)
.Select(x => x.ExternalDetailData)
.Should().HaveCount(10);
}

#endregion

#region GetAllCredentialDetails
Expand Down
Loading