Skip to content

Commit

Permalink
feat(connector)!: link managed connectors with offer subscription (#129)
Browse files Browse the repository at this point in the history
change request /api/administration/connectors/managed-daps to take a subscriptionId instead of the providerBpn
new mapping table to link connectors with offer subscriptions
add database view to see all offer subscription related links


---------

Refs: CPLP-2831
Co-authored-by: Norbert Truchsess <[email protected]>
Reviewed-by: Norbert Truchsess <[email protected]>
  • Loading branch information
Phil91 and ntruchsess authored Jul 12, 2023
1 parent 2619d15 commit dcbda19
Show file tree
Hide file tree
Showing 31 changed files with 7,830 additions and 130 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -163,37 +163,60 @@ private async Task<Guid> CreateConnectorInternalAsync(ConnectorInputModel connec
result.SelfDescriptionDocumentId.Value,
certificate,
identity.UserId,
null,
cancellationToken).ConfigureAwait(false);
}

private async Task<Guid> CreateManagedConnectorInternalAsync(ManagedConnectorInputModel connectorInputModel, (Guid UserId, Guid CompanyId) identity, CancellationToken cancellationToken)
{
var (name, connectorUrl, location, providerBpn, certificate, technicalUserId) = connectorInputModel;
var (name, connectorUrl, location, subscriptionId, certificate, technicalUserId) = connectorInputModel;
await CheckLocationExists(location).ConfigureAwait(false);

var result = await _portalRepositories
.GetInstance<ICompanyRepository>()
.GetCompanyIdAndSelfDescriptionDocumentByBpnAsync(providerBpn)
var result = await _portalRepositories.GetInstance<IOfferSubscriptionsRepository>()
.CheckOfferSubscriptionWithOfferProvider(subscriptionId, identity.CompanyId)
.ConfigureAwait(false);

if (result == default)
if (!result.Exists)
{
throw new NotFoundException($"OfferSubscription {subscriptionId} does not exist");
}

if (!result.IsOfferProvider)
{
throw new ControllerArgumentException($"Company {providerBpn} does not exist", nameof(providerBpn));
throw new ForbiddenException("Company is not the provider of the offer");
}

if (result.OfferSubscriptionAlreadyLinked)
{
throw new ConflictException("OfferSubscription is already linked to a connector");
}

if (result.OfferSubscriptionStatus != OfferSubscriptionStatusId.ACTIVE &&
result.OfferSubscriptionStatus != OfferSubscriptionStatusId.PENDING)
{
throw new ConflictException($"The offer subscription must be either {OfferSubscriptionStatusId.ACTIVE} or {OfferSubscriptionStatusId.PENDING}");
}

if (result.SelfDescriptionDocumentId is null)
{
throw new UnexpectedConditionException($"provider company {result.CompanyId} has no self description document");
throw new ConflictException($"provider company {result.CompanyId} has no self description document");
}

if (string.IsNullOrWhiteSpace(result.ProviderBpn))
{
throw new ConflictException($"The bpn of compay {result.CompanyId} must be set");
}

await ValidateTechnicalUser(technicalUserId, result.CompanyId).ConfigureAwait(false);

var connectorRequestModel = new ConnectorRequestModel(name, connectorUrl, ConnectorTypeId.CONNECTOR_AS_A_SERVICE, location, result.CompanyId, identity.CompanyId, technicalUserId);
return await CreateAndRegisterConnectorAsync(
connectorRequestModel,
providerBpn,
result.ProviderBpn,
result.SelfDescriptionDocumentId!.Value,
certificate,
identity.UserId,
subscriptionId,
cancellationToken).ConfigureAwait(false);
}

Expand Down Expand Up @@ -225,7 +248,8 @@ private async Task<Guid> CreateAndRegisterConnectorAsync(
string businessPartnerNumber,
Guid selfDescriptionDocumentId,
IFormFile? file,
Guid? userId,
Guid userId,
Guid? subscriptionId,
CancellationToken cancellationToken)
{
var (name, connectorUrl, type, location, provider, host, technicalUserId) = connectorInputModel;
Expand All @@ -248,6 +272,11 @@ private async Task<Guid> CreateAndRegisterConnectorAsync(
}
});

if (subscriptionId != null)
{
connectorsRepository.CreateConnectorAssignedSubscriptions(createdConnector.Id, subscriptionId.Value);
}

DapsResponse? response = null;
if (file is not null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ public async Task<ServiceAccountConnectorOfferData> GetOwnCompanyServiceAccountD

public async Task<ServiceAccountDetails> ExecuteResetOwnCompanyServiceAccountSecretAsync(Guid serviceAccountId, Guid companyId)
{
if (!await _portalRepositories.GetInstance<IServiceAccountRepository>().IsCompanyServiceAccountLinkedCompany(companyId).ConfigureAwait(false))
if (!await _portalRepositories.GetInstance<IServiceAccountRepository>().IsCompanyServiceAccountLinkedCompany(serviceAccountId, companyId).ConfigureAwait(false))
{
throw new ForbiddenException($"The company ID is neither the owner nor the provider of the technical user");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ public record ConnectorInputModel(
/// <param name="Name">Display name of the connector.</param>
/// <param name="ConnectorUrl"> URL of the connector..</param>
/// <param name="Location">Connector's location country code.</param>
/// <param name="ProviderBpn">Providing company's BPN.</param>
/// <param name="SubscriptionId">Id of the offer subscription.</param>
/// <param name="Certificate">The certificate for the daps call.</param>
/// <param name="TechnicalUserId">Id of the technical user.</param>
public record ManagedConnectorInputModel(
[MaxLength(255)] string Name,
[MaxLength(255)] string ConnectorUrl,
[StringLength(2, MinimumLength = 2)] string Location,
string ProviderBpn,
Guid SubscriptionId,
IFormFile? Certificate,
Guid? TechnicalUserId
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,6 @@ public void CreateUpdateDeleteIdentifiers(Guid companyId, IEnumerable<(UniqueIde
company!.CompanyAssignedRoles.SelectMany(car => car.CompanyRole!.CompanyRoleAssignedRoleCollection!.UserRoleCollection!.UserRoles.Where(ur => ur.Offer!.AppInstances.Any(ai => ai.IamClient!.ClientClientId == technicalUserClientId)).Select(ur => ur.Id)).Distinct()))
.SingleOrDefaultAsync();

/// <inheritdoc />
public Task<(Guid CompanyId, Guid? SelfDescriptionDocumentId)> GetCompanyIdAndSelfDescriptionDocumentByBpnAsync(string businessPartnerNumber) =>
_context.Companies
.AsNoTracking()
.Where(company => company.BusinessPartnerNumber == businessPartnerNumber)
.Select(company => new ValueTuple<Guid, Guid?>(company.Id, company.SelfDescriptionDocumentId))
.SingleOrDefaultAsync();

public IAsyncEnumerable<string?> GetAllMemberCompaniesBPNAsync() =>
_context.Companies
.AsNoTracking()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,15 @@ public CompanySsiDetailsRepository(PortalDbContext portalDbContext)
/// <inheritdoc />
public IAsyncEnumerable<UseCaseParticipationTransferData> GetUseCaseParticipationForCompany(Guid companyId, string language) =>
_context.VerifiedCredentialTypes
.Where(types => types.VerifiedCredentialTypeAssignedKind!.VerifiedCredentialTypeKindId == VerifiedCredentialTypeKindId.USE_CASE)
.Where(types => types.VerifiedCredentialTypeAssignedKind!.VerifiedCredentialTypeKindId ==
VerifiedCredentialTypeKindId.USE_CASE)
.Select(types => new
{
UseCase = types.VerifiedCredentialTypeAssignedUseCase!.UseCase,
TypeId = types.Id,
ExternalTypeDetails = types.VerifiedCredentialTypeAssignedExternalType!.VerifiedCredentialExternalType!.VerifiedCredentialExternalTypeUseCaseDetailVersions,
ExternalTypeDetails =
types.VerifiedCredentialTypeAssignedExternalType!.VerifiedCredentialExternalType!
.VerifiedCredentialExternalTypeUseCaseDetailVersions,
})
.Select(x => new UseCaseParticipationTransferData(
x.UseCase!.Name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,8 @@ public void DeleteConnectorClientDetails(Guid connectorId) =>

public void DeleteConnector(Guid connectorId) =>
_context.Connectors.Remove(new Connector(connectorId, null!, null!, null!));

/// <inheritdoc />
public ConnectorAssignedOfferSubscription CreateConnectorAssignedSubscriptions(Guid connectorId, Guid subscriptionId) =>
_context.ConnectorAssignedOfferSubscriptions.Add(new ConnectorAssignedOfferSubscription(connectorId, subscriptionId)).Entity;
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,6 @@ public interface ICompanyRepository

Task<(string? Bpn, IEnumerable<Guid> TechnicalUserRoleIds)> GetBpnAndTechnicalUserRoleIds(Guid companyId, string technicalUserClientId);

/// <summary>
/// Checks the bpn for existence and returns the associated CompanyId
/// </summary>
/// <param name="businessPartnerNumber">The business partner number</param>
/// <returns>the company id or guid empty if not found</returns>
Task<(Guid CompanyId, Guid? SelfDescriptionDocumentId)> GetCompanyIdAndSelfDescriptionDocumentByBpnAsync(string businessPartnerNumber);

/// <summary>
/// Get all member companies bpn
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,6 @@ public interface IConnectorsRepository
/// </summary>
/// <param name="connectorId"></param>
void DeleteConnector(Guid connectorId);

ConnectorAssignedOfferSubscription CreateConnectorAssignedSubscriptions(Guid connectorId, Guid subscriptionId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -162,4 +162,5 @@ public interface IOfferSubscriptionsRepository
OfferSubscriptionProcessData CreateOfferSubscriptionProcessData(Guid offerSubscriptionId, string offerUrl);
void RemoveOfferSubscriptionProcessData(Guid offerSubscriptionId);
IAsyncEnumerable<ProcessStepData> GetProcessStepsForSubscription(Guid offerSubscriptionId);
Task<(bool Exists, bool IsOfferProvider, bool OfferSubscriptionAlreadyLinked, OfferSubscriptionStatusId OfferSubscriptionStatus, Guid? SelfDescriptionDocumentId, Guid CompanyId, string? ProviderBpn)> CheckOfferSubscriptionWithOfferProvider(Guid subscriptionId, Guid offerProvidingCompanyId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,5 @@ CompanyServiceAccount CreateCompanyServiceAccount(Guid identityId,
Task<CompanyServiceAccountDetailedData?> GetOwnCompanyServiceAccountDetailedDataUntrackedAsync(Guid serviceAccountId, Guid companyId);
Func<int, int, Task<Pagination.Source<CompanyServiceAccountData>?>> GetOwnCompanyServiceAccountsUntracked(Guid userCompanyId);
Task<bool> CheckActiveServiceAccountExistsForCompanyAsync(Guid technicalUserId, Guid companyId);
Task<bool> IsCompanyServiceAccountLinkedCompany(Guid companyId);
Task<bool> IsCompanyServiceAccountLinkedCompany(Guid serviceAccountId, Guid companyId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -468,4 +468,19 @@ public IAsyncEnumerable<ProcessStepData> GetProcessStepsForSubscription(Guid off
x.ProcessStepStatusId,
x.Message))
.ToAsyncEnumerable();

/// <inheritdoc />
public Task<(bool Exists, bool IsOfferProvider, bool OfferSubscriptionAlreadyLinked, OfferSubscriptionStatusId OfferSubscriptionStatus, Guid? SelfDescriptionDocumentId, Guid CompanyId, string? ProviderBpn)> CheckOfferSubscriptionWithOfferProvider(Guid subscriptionId, Guid offerProvidingCompanyId) =>
_context.OfferSubscriptions
.Where(x => x.Id == subscriptionId)
.Select(os => new ValueTuple<bool, bool, bool, OfferSubscriptionStatusId, Guid?, Guid, string?>(
true,
os.Offer!.ProviderCompanyId == offerProvidingCompanyId,
os.ConnectorAssignedOfferSubscriptions.Any(),
os.OfferSubscriptionStatusId,
os.Company!.SelfDescriptionDocumentId,
os.CompanyId,
os.Company.BusinessPartnerNumber
))
.SingleOrDefaultAsync();
}
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,8 @@ public Task<bool> CheckActiveServiceAccountExistsForCompanyAsync(Guid technicalU
sa.Identity.CompanyId == companyId)
.AnyAsync();

public Task<bool> IsCompanyServiceAccountLinkedCompany(Guid companyId) =>
public Task<bool> IsCompanyServiceAccountLinkedCompany(Guid serviceAccountId, Guid companyId) =>
_dbContext.CompanyLinkedServiceAccounts
.Where(x => x.Provider == companyId || x.Owners == companyId)
.Where(x => x.ServiceAccountId == serviceAccountId && (x.Provider == companyId || x.Owners == companyId))
.AnyAsync();
}
Loading

0 comments on commit dcbda19

Please sign in to comment.