Skip to content

Commit

Permalink
build(2.0.0-rc9): merge release into main (#756)
Browse files Browse the repository at this point in the history
* feat(document): enhance companyDetailsWithAddress endpoint (#732)

* add documents section to endpoint companydetailaddress
* remove documents section from applications endpoint
* adjust unit tests
---------
Co-authored-by: Norbert Truchsess <[email protected]>

* fix(decline): add decline url for invite process (#727)

Refs: #701

* feat(app): add roleId for exitisting activeRoleDetails (#744)

Ref : #705

* fix(seeding-data): add self description document for Catena-X (#707)

Reviewed-By: Phil Schneider <[email protected]>
Refs: #702

* fix(dim) don't create keycloak sa for dim (#745)

* fix(role-management): fix query selecting role-data for core-offer role assignement (#749)

* feat(services): update permission for api endpoints added (#751)

* fix(keycloak): set clockSkew to 5 min (#753)

* chore: fix file header
#752

* fix(offersubscription): fix queries throwing a system exception instead of returning default value (#755)

* fix 'System.InvalidOperationException: Nullable object must have a value' caused by queries selecting a (non-nullable) guid from a joined table where the joined table does not have a matching dataset resulting in 'null' being returned from the database.

* build(2.0.0-rc9): bump version and update docs

---------

Co-authored-by: AnuragNagpure <[email protected]>
Co-authored-by: Phil Schneider <[email protected]>
Co-authored-by: VPrasannaK94 <[email protected]>
Co-authored-by: Norbert Truchsess <[email protected]>
  • Loading branch information
5 people authored May 22, 2024
1 parent 1b23544 commit 028d6b1
Show file tree
Hide file tree
Showing 43 changed files with 501 additions and 178 deletions.
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,30 @@

New features, fixed bugs, known defects and other noteworthy changes to each release of the Catena-X Portal Backend.

## 2.0.0-RC9

### Changes
* **Administration Service**
* enhanced companyDetailsWithAddress endpoint
* **Apps Service**
* added roleId for existing activeRoleDetails
* **Services Service**
* updated permissions for api endpoints

### Bugfix
* **Invitation**
* added decline url for invite process
* **Seeding**
* added self description document to initial company
* **DIM Process Worker**
* stopped creating technical users for dim
* **Role assignment**
* fixed query for core offer to prevent role assignment triggering cascading role assignments
* **Token lifetime**
* set ClockSkew (security configuration jwtBearerOptions) to 5 minutes for token expiration
* **Offersubscription**
* fixed queries throwing a system exception instead of returning default value

## 2.0.0-RC8

### Changes
Expand Down
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@
<Project>
<PropertyGroup>
<VersionPrefix>2.0.0</VersionPrefix>
<VersionSuffix>RC8</VersionSuffix>
<VersionSuffix>RC9</VersionSuffix>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,10 @@ public Task<CompanyWithAddressData> GetCompanyWithAddressAsync(Guid applicationI

private async Task<CompanyWithAddressData> GetCompanyWithAddressAsyncInternal(Guid applicationId)
{
var companyWithAddress = await _portalRepositories.GetInstance<IApplicationRepository>().GetCompanyUserRoleWithAddressUntrackedAsync(applicationId).ConfigureAwait(ConfigureAwaitOptions.None);
var companyWithAddress = await _portalRepositories.GetInstance<IApplicationRepository>().GetCompanyUserRoleWithAddressUntrackedAsync(applicationId, _settings.DocumentTypeIds).ConfigureAwait(ConfigureAwaitOptions.None);
if (companyWithAddress == null)
{
throw NotFoundException.Create(AdministrationRegistrationErrors.APPLICATION_NOT_FOUND, new ErrorParameter[] { new("applicationId", applicationId.ToString()) });
throw NotFoundException.Create(AdministrationRegistrationErrors.APPLICATION_NOT_FOUND, [new("applicationId", applicationId.ToString())]);
}
if (!string.IsNullOrEmpty(companyWithAddress.Name) && !Company.IsMatch(companyWithAddress.Name))
{
Expand Down Expand Up @@ -134,7 +134,10 @@ private async Task<CompanyWithAddressData> GetCompanyWithAddressAsyncInternal(Gu
x.FirstName ?? "",
x.LastName ?? "",
x.Email ?? "")),
companyWithAddress.CompanyIdentifiers.Select(identifier => new CompanyUniqueIdData(identifier.UniqueIdentifierId, identifier.Value))
companyWithAddress.CompanyIdentifiers.Select(identifier => new CompanyUniqueIdData(identifier.UniqueIdentifierId, identifier.Value)),
companyWithAddress.DocumentData.Select(data => new DocumentDetails(data.DocumentId, data.DocumentTypeId)),
companyWithAddress.Created,
companyWithAddress.LastChanged
);
}

Expand Down Expand Up @@ -165,9 +168,6 @@ private async Task<CompanyWithAddressData> GetCompanyWithAddressAsyncInternal(Gu
application.ApplicationStatusId,
application.DateCreated,
application.Company!.Name,
application.Invitations.SelectMany(invitation =>
invitation.CompanyUser!.Documents.Where(document => _settings.DocumentTypeIds.Contains(document.DocumentTypeId)).Select(document =>
new DocumentDetails(document.Id, document.DocumentTypeId))),
application.Company!.CompanyAssignedRoles.Select(companyAssignedRoles => companyAssignedRoles.CompanyRoleId),
application.ApplicationChecklistEntries.Where(x => x.ApplicationChecklistEntryTypeId != ApplicationChecklistEntryTypeId.APPLICATION_ACTIVATION).OrderBy(x => x.ApplicationChecklistEntryTypeId).Select(x => new ApplicationChecklistEntryDetails(x.ApplicationChecklistEntryTypeId, x.ApplicationChecklistEntryStatusId)),
application.Invitations
Expand Down Expand Up @@ -268,22 +268,22 @@ private async Task UpdateCompanyBpnInternal(Guid applicationId, string bpn)
.VerifyChecklistEntryAndProcessSteps(
applicationId,
ApplicationChecklistEntryTypeId.BUSINESS_PARTNER_NUMBER,
new[] {
[
ApplicationChecklistEntryStatusId.TO_DO,
ApplicationChecklistEntryStatusId.IN_PROGRESS,
ApplicationChecklistEntryStatusId.FAILED
},
],
ProcessStepTypeId.CREATE_BUSINESS_PARTNER_NUMBER_MANUAL,
entryTypeIds: new[] {
entryTypeIds: [
ApplicationChecklistEntryTypeId.REGISTRATION_VERIFICATION
},
processStepTypeIds: new[] {
],
processStepTypeIds: [
ProcessStepTypeId.CREATE_BUSINESS_PARTNER_NUMBER_PUSH,
ProcessStepTypeId.CREATE_BUSINESS_PARTNER_NUMBER_PULL,
ProcessStepTypeId.RETRIGGER_BUSINESS_PARTNER_NUMBER_PULL,
ProcessStepTypeId.RETRIGGER_BUSINESS_PARTNER_NUMBER_PUSH,
ProcessStepTypeId.CREATE_IDENTITY_WALLET
})
])
.ConfigureAwait(ConfigureAwaitOptions.None);

_portalRepositories.GetInstance<ICompanyRepository>().AttachAndModifyCompany(applicationCompanyData.CompanyId, null,
Expand All @@ -293,12 +293,12 @@ private async Task UpdateCompanyBpnInternal(Guid applicationId, string bpn)

_checklistService.SkipProcessSteps(
context,
new[] {
[
ProcessStepTypeId.CREATE_BUSINESS_PARTNER_NUMBER_PUSH,
ProcessStepTypeId.CREATE_BUSINESS_PARTNER_NUMBER_PULL,
ProcessStepTypeId.RETRIGGER_BUSINESS_PARTNER_NUMBER_PULL,
ProcessStepTypeId.RETRIGGER_BUSINESS_PARTNER_NUMBER_PUSH
});
]);

_checklistService.FinalizeChecklistEntryAndProcessSteps(
context,
Expand Down Expand Up @@ -386,9 +386,9 @@ private async Task TriggerChecklistInternal(Guid applicationId, ApplicationCheck
.VerifyChecklistEntryAndProcessSteps(
applicationId,
entryTypeId,
new[] { ApplicationChecklistEntryStatusId.FAILED },
[ApplicationChecklistEntryStatusId.FAILED],
processStepTypeId,
processStepTypeIds: new[] { nextProcessStepTypeId })
processStepTypeIds: [nextProcessStepTypeId])
.ConfigureAwait(ConfigureAwaitOptions.None);

_checklistService.FinalizeChecklistEntryAndProcessSteps(
Expand All @@ -405,7 +405,7 @@ private async Task TriggerChecklistInternal(Guid applicationId, ApplicationCheck
item.ApplicationChecklistEntryStatusId = checklistEntryStatusId;
item.Comment = null;
},
new[] { nextProcessStepTypeId });
[nextProcessStepTypeId]);
await _portalRepositories.SaveAsync().ConfigureAwait(ConfigureAwaitOptions.None);
}

Expand Down Expand Up @@ -438,10 +438,10 @@ public async Task ApproveRegistrationVerification(Guid applicationId)
.VerifyChecklistEntryAndProcessSteps(
applicationId,
ApplicationChecklistEntryTypeId.REGISTRATION_VERIFICATION,
new[] { ApplicationChecklistEntryStatusId.TO_DO },
[ApplicationChecklistEntryStatusId.TO_DO],
ProcessStepTypeId.VERIFY_REGISTRATION,
new[] { ApplicationChecklistEntryTypeId.BUSINESS_PARTNER_NUMBER },
new[] { CreateWalletStep() })
[ApplicationChecklistEntryTypeId.BUSINESS_PARTNER_NUMBER],
[CreateWalletStep()])
.ConfigureAwait(ConfigureAwaitOptions.None);

var businessPartnerSuccess = context.Checklist[ApplicationChecklistEntryTypeId.BUSINESS_PARTNER_NUMBER] == new ValueTuple<ApplicationChecklistEntryStatusId, string?>(ApplicationChecklistEntryStatusId.DONE, null);
Expand Down Expand Up @@ -474,13 +474,13 @@ public async Task DeclineRegistrationVerification(Guid applicationId, string com
.VerifyChecklistEntryAndProcessSteps(
applicationId,
ApplicationChecklistEntryTypeId.REGISTRATION_VERIFICATION,
new[] { ApplicationChecklistEntryStatusId.TO_DO, ApplicationChecklistEntryStatusId.DONE },
[ApplicationChecklistEntryStatusId.TO_DO, ApplicationChecklistEntryStatusId.DONE],
ProcessStepTypeId.DECLINE_APPLICATION,
null,
new[] { ProcessStepTypeId.VERIFY_REGISTRATION, })
[ProcessStepTypeId.VERIFY_REGISTRATION,])
.ConfigureAwait(ConfigureAwaitOptions.None);

_checklistService.SkipProcessSteps(context, new[] { ProcessStepTypeId.VERIFY_REGISTRATION });
_checklistService.SkipProcessSteps(context, [ProcessStepTypeId.VERIFY_REGISTRATION]);

var identityProviderRepository = _portalRepositories.GetInstance<IIdentityProviderRepository>();
var userRepository = _portalRepositories.GetInstance<IUserRepository>();
Expand Down Expand Up @@ -572,15 +572,15 @@ private static IEnumerable<CompanyApplicationStatusId> GetCompanyApplicationStat
{
case CompanyApplicationStatusFilter.Closed:
{
return new[] { CompanyApplicationStatusId.CONFIRMED, CompanyApplicationStatusId.DECLINED };
return [CompanyApplicationStatusId.CONFIRMED, CompanyApplicationStatusId.DECLINED];
}
case CompanyApplicationStatusFilter.InReview:
{
return new[] { CompanyApplicationStatusId.SUBMITTED };
return [CompanyApplicationStatusId.SUBMITTED];
}
default:
{
return new[] { CompanyApplicationStatusId.SUBMITTED, CompanyApplicationStatusId.CONFIRMED, CompanyApplicationStatusId.DECLINED };
return [CompanyApplicationStatusId.SUBMITTED, CompanyApplicationStatusId.CONFIRMED, CompanyApplicationStatusId.DECLINED];
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,12 @@ public record CompanyApplicationDetails(
[property: JsonPropertyName("applicationStatus")] CompanyApplicationStatusId CompanyApplicationStatusId,
[property: JsonPropertyName("dateCreated")] DateTimeOffset DateCreated,
[property: JsonPropertyName("companyName")] string CompanyName,
[property: JsonPropertyName("documents")] IEnumerable<DocumentDetails> Documents,
[property: JsonPropertyName("companyRoles")] IEnumerable<CompanyRoleId> CompanyRoles,
[property: JsonPropertyName("applicationChecklist")] IEnumerable<ApplicationChecklistEntryDetails> ApplicationChecklist,
[property: JsonPropertyName("email")] string? Email,
[property: JsonPropertyName("bpn")] string? BusinessPartnerNumber
);

public record DocumentDetails(
[property: JsonPropertyName("documentId")] Guid DocumentId,
[property: JsonPropertyName("documentType")] DocumentTypeId? DocumentTypeId
);

public record ApplicationChecklistEntryDetails(
ApplicationChecklistEntryTypeId TypeId,
ApplicationChecklistEntryStatusId StatusId
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2022 Contributors to the CatenaX (ng) GitHub Organisation.
* Copyright (c) 2022 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
Expand Down Expand Up @@ -40,6 +40,9 @@ namespace Org.Eclipse.TractusX.Portal.Backend.Administration.Service.Models;
/// <param name="AgreementsRoleData"></param>
/// <param name="InvitedUserData"></param>
/// <param name="UniqueIds"></param>
/// <param name="Documents"></param>
/// <param name="Created"></param>
/// <param name="LastChanged"></param>
/// <returns></returns>

public record CompanyWithAddressData(
Expand All @@ -56,7 +59,10 @@ public record CompanyWithAddressData(
string ZipCode,
[property: JsonPropertyName("companyRoles")] IEnumerable<AgreementsRoleData> AgreementsRoleData,
[property: JsonPropertyName("companyUser")] IEnumerable<InvitedUserData> InvitedUserData,
IEnumerable<CompanyUniqueIdData> UniqueIds
IEnumerable<CompanyUniqueIdData> UniqueIds,
[property: JsonPropertyName("documents")] IEnumerable<DocumentDetails> Documents,
DateTimeOffset? Created,
DateTimeOffset? LastChanged
);

/// <summary>
Expand Down Expand Up @@ -95,3 +101,14 @@ public record InvitedUserData(
string LastName,
string Email
);

/// <summary>
///
/// </summary>
/// <param name="DocumentId"></param>
/// <param name="DocumentTypeId"></param>
/// <returns></returns>
public record DocumentDetails(
[property: JsonPropertyName("documentId")] Guid DocumentId,
[property: JsonPropertyName("documentType")] DocumentTypeId? DocumentTypeId
);
2 changes: 1 addition & 1 deletion src/administration/Administration.Service/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
"ValidAudience": "",
"ValidateAudience": true,
"ValidateLifetime": true,
"ClockSkew": 600000
"ClockSkew": "00:05:00"
}
},
"Provisioning": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ public async Task<FileResult> GetServiceDocumentContentAsync([FromRoute] Guid se
/// <response code="403">User's company does not provide the service.</response>
/// <response code="404">No service or subscription found.</response>
[HttpGet]
[Authorize(Roles = "add_service_offering")]
[Authorize(Roles = "service_management")]
[Authorize(Policy = PolicyTypes.ValidCompany)]
[Route("{serviceId}/subscription/{subscriptionId}/provider")]
[ProducesResponseType(typeof(ProviderSubscriptionDetailData), StatusCodes.Status200OK)]
Expand All @@ -282,7 +282,7 @@ public Task<ProviderSubscriptionDetailData> GetSubscriptionDetailForProvider([Fr
/// <response code="403">User's company does not provide the service.</response>
/// <response code="404">No service or subscription found.</response>
[HttpGet]
[Authorize(Roles = "add_service_offering")]
[Authorize(Roles = "subscribe_service")]
[Authorize(Policy = PolicyTypes.ValidCompany)]
[Route("{serviceId}/subscription/{subscriptionId}/subscriber")]
[ProducesResponseType(typeof(SubscriberSubscriptionDetailData), StatusCodes.Status200OK)]
Expand All @@ -299,7 +299,7 @@ public Task<SubscriberSubscriptionDetailData> GetSubscriptionDetailForSubscriber
/// <response code="400">If sub claim is empty/invalid or user does not exist.</response>
[HttpGet]
[Route("subscribed/subscription-status")]
[Authorize(Roles = "view_subscription")]
[Authorize(Roles = "view_service_subscriptions")]
[Authorize(Policy = PolicyTypes.ValidCompany)]
[ProducesResponseType(typeof(Pagination.Response<OfferSubscriptionStatusDetailData>), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status400BadRequest)]
Expand Down
2 changes: 1 addition & 1 deletion src/notifications/Notifications.Service/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"ValidAudience": "",
"ValidateAudience": true,
"ValidateLifetime": true,
"ClockSkew": 600000
"ClockSkew": "00:05:00"
}
},
"Notifications": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/********************************************************************************
* Copyright (c) 2022 BMW Group AG
* Copyright (c) 2022 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
Expand Down Expand Up @@ -37,7 +36,10 @@ public record CompanyUserRoleWithAddress(
string? CountryDe,
IEnumerable<AgreementsData> AgreementsData,
IEnumerable<InvitedCompanyUserData> InvitedCompanyUserData,
IEnumerable<(UniqueIdentifierId UniqueIdentifierId, string Value)> CompanyIdentifiers
IEnumerable<(UniqueIdentifierId UniqueIdentifierId, string Value)> CompanyIdentifiers,
IEnumerable<(Guid DocumentId, DocumentTypeId DocumentTypeId)> DocumentData,
DateTimeOffset? Created,
DateTimeOffset? LastChanged
);

public record AgreementsData(CompanyRoleId CompanyRoleId, Guid AgreementId, ConsentStatusId? ConsentStatusId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public record OfferRoleInfos(
[property: JsonPropertyName("roles")] IEnumerable<OfferRoleInfo> RoleInfos);

public record ActiveAppRoleDetails(
[property: JsonPropertyName("roleId")] Guid RoleId,
[property: JsonPropertyName("role")] string Role,
[property: JsonPropertyName("descriptions")] IEnumerable<ActiveAppUserRoleDescription> Descriptions);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/********************************************************************************
* Copyright (c) 2022 BMW Group AG
* Copyright (c) 2022 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
Expand All @@ -18,7 +17,6 @@
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums;
using System.Text.Json.Serialization;

namespace Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Models;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ public IQueryable<CompanyApplication> GetAllCompanyApplicationsDetailsQuery(stri
.AsNoTracking()
.Where(application => companyName == null || EF.Functions.ILike(application.Company!.Name, $"%{companyName.EscapeForILike()}%"));

public Task<CompanyUserRoleWithAddress?> GetCompanyUserRoleWithAddressUntrackedAsync(Guid companyApplicationId) =>
public Task<CompanyUserRoleWithAddress?> GetCompanyUserRoleWithAddressUntrackedAsync(Guid companyApplicationId, IEnumerable<DocumentTypeId> documentTypeIds) =>
portalDbContext.CompanyApplications
.AsSplitQuery()
.Where(companyApplication => companyApplication.Id == companyApplicationId)
Expand Down Expand Up @@ -294,7 +294,12 @@ public IQueryable<CompanyApplication> GetAllCompanyApplicationsDetailsQuery(stri
x.CompanyUser!.Firstname,
x.CompanyUser.Lastname,
x.CompanyUser.Email)),
companyApplication.Company.CompanyIdentifiers.Select(identifier => new ValueTuple<UniqueIdentifierId, string>(identifier.UniqueIdentifierId, identifier.Value))))
companyApplication.Company.CompanyIdentifiers.Select(identifier => new ValueTuple<UniqueIdentifierId, string>(identifier.UniqueIdentifierId, identifier.Value)),
companyApplication.Invitations.SelectMany(invitation =>
invitation.CompanyUser!.Documents.Where(document => documentTypeIds.Contains(document.DocumentTypeId)).Select(document =>
new ValueTuple<Guid, DocumentTypeId>(document.Id, document.DocumentTypeId))),
companyApplication.DateCreated,
companyApplication.DateLastChanged))
.AsNoTracking()
.SingleOrDefaultAsync();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,10 @@ public CompanyInvitation CreateCompanyInvitation(string firstName, string lastNa
}

public Task<Guid> GetCompanyInvitationForProcessId(Guid processId) =>
_context.Processes
.Where(process => process.Id == processId)
.Select(process => process.CompanyInvitation!.Id)
_context.CompanyInvitations
.AsNoTracking()
.Where(i => i.ProcessId == processId)
.Select(i => i.Id)
.SingleOrDefaultAsync();

public Task<string?> GetOrganisationNameForInvitation(Guid invitationId) =>
Expand Down
Loading

0 comments on commit 028d6b1

Please sign in to comment.