diff --git a/src/administration/Administration.Service/BusinessLogic/ConnectorsBusinessLogic.cs b/src/administration/Administration.Service/BusinessLogic/ConnectorsBusinessLogic.cs index 3b7e02a9b9..ea4da65f25 100644 --- a/src/administration/Administration.Service/BusinessLogic/ConnectorsBusinessLogic.cs +++ b/src/administration/Administration.Service/BusinessLogic/ConnectorsBusinessLogic.cs @@ -199,7 +199,7 @@ private async Task ValidateTechnicalUser(Guid? technicalUserId, Guid companyId) if (!await portalRepositories.GetInstance() .CheckActiveServiceAccountExistsForCompanyAsync(technicalUserId.Value, companyId).ConfigureAwait(ConfigureAwaitOptions.None)) { - throw ControllerArgumentException.Create(AdministrationConnectorErrors.CONNECTOR_ARGUMENT_TECH_USER_NOT_ACTIVE, [new("technicalUserId", technicalUserId.Value.ToString()), new("companyId", companyId.ToString())]); + throw ControllerArgumentException.Create(AdministrationConnectorErrors.CONNECTOR_ARGUMENT_TECH_USER_NOT_ACTIVE, [new ErrorParameter("technicalUserId", technicalUserId.Value.ToString()), new ErrorParameter("companyId", companyId.ToString())]); } } diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/DocumentRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/DocumentRepository.cs index be47ec475d..96861eae4b 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/DocumentRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/DocumentRepository.cs @@ -82,10 +82,10 @@ public Document CreateDocument(string documentName, byte[] documentContent, byte .SingleOrDefaultAsync(); /// - public Task<(Guid DocumentId, bool IsSameUser)> GetDocumentIdWithCompanyUserCheckAsync(Guid documentId, Guid companyUserId) => + public Task<(Guid DocumentId, bool IsSameUser, bool IsRoleOperator, bool IsStatusConfirmed)> GetDocumentIdWithCompanyUserCheckAsync(Guid documentId, Guid companyUserId) => dbContext.Documents .Where(x => x.Id == documentId) - .Select(x => new ValueTuple(x.Id, x.CompanyUserId == companyUserId)) + .Select(x => new ValueTuple(x.Id, x.CompanyUserId == companyUserId, x.CompanyUser!.Identity!.Company!.CompanyAssignedRoles.Any(x => x.CompanyRoleId == CompanyRoleId.OPERATOR), x.CompanyUser.Identity.Company.CompanyApplications.Any(x => x.ApplicationStatusId == CompanyApplicationStatusId.CONFIRMED))) .SingleOrDefaultAsync(); /// diff --git a/src/portalbackend/PortalBackend.DBAccess/Repositories/IDocumentRepository.cs b/src/portalbackend/PortalBackend.DBAccess/Repositories/IDocumentRepository.cs index 9337874f11..e9f2457aa2 100644 --- a/src/portalbackend/PortalBackend.DBAccess/Repositories/IDocumentRepository.cs +++ b/src/portalbackend/PortalBackend.DBAccess/Repositories/IDocumentRepository.cs @@ -65,7 +65,7 @@ public interface IDocumentRepository /// id of the document the user id should be selected for /// /// Returns the user id if a document is found for the given id, otherwise null - Task<(Guid DocumentId, bool IsSameUser)> GetDocumentIdWithCompanyUserCheckAsync(Guid documentId, Guid companyUserId); + Task<(Guid DocumentId, bool IsSameUser, bool IsRoleOperator, bool IsStatusConfirmed)> GetDocumentIdWithCompanyUserCheckAsync(Guid documentId, Guid companyUserId); /// /// Get the document data and checks if the user diff --git a/src/registration/Registration.Service/BusinessLogic/RegistrationBusinessLogic.cs b/src/registration/Registration.Service/BusinessLogic/RegistrationBusinessLogic.cs index 8bfac441db..815ca279bb 100644 --- a/src/registration/Registration.Service/BusinessLogic/RegistrationBusinessLogic.cs +++ b/src/registration/Registration.Service/BusinessLogic/RegistrationBusinessLogic.cs @@ -168,11 +168,16 @@ public async Task UploadDocumentAsync(Guid applicationId, IFormFile document, Do throw new NotFoundException($"document {documentId} does not exist."); } - if (!documentDetails.IsSameUser) + if (!documentDetails.IsSameUser && !documentDetails.IsRoleOperator) { throw new ForbiddenException($"The user is not permitted to access document {documentId}."); } + if (!documentDetails.IsStatusConfirmed) + { + throw new ForbiddenException($"Documents not accessible as onboarding process finished {documentId}."); + } + var document = await documentRepository.GetDocumentByIdAsync(documentId).ConfigureAwait(ConfigureAwaitOptions.None); if (document is null) { diff --git a/tests/registration/Registration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs b/tests/registration/Registration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs index adcb010543..0e7383de50 100644 --- a/tests/registration/Registration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs +++ b/tests/registration/Registration.Service.Tests/BusinessLogic/RegistrationBusinessLogicTest.cs @@ -2870,7 +2870,7 @@ public async Task GetDocumentAsync_WithValidData_ReturnsExpected() var documentId = Guid.NewGuid(); var content = new byte[7]; A.CallTo(() => _documentRepository.GetDocumentIdWithCompanyUserCheckAsync(documentId, _identity.IdentityId)) - .Returns((documentId, true)); + .Returns((documentId, true, true, true)); A.CallTo(() => _documentRepository.GetDocumentByIdAsync(documentId)) .Returns(new Document(documentId, content, content, "test.pdf", MediaTypeId.PDF, DateTimeOffset.UtcNow, DocumentStatusId.LOCKED, DocumentTypeId.APP_CONTRACT)); var sut = new RegistrationBusinessLogic(Options.Create(new RegistrationSettings()), null!, null!, null!, _portalRepositories, null!, _identityService, _dateTimeProvider, _mailingProcessCreation); @@ -2890,7 +2890,7 @@ public async Task GetDocumentAsync_WithoutDocument_ThrowsNotFoundException() // Arrange var documentId = Guid.NewGuid(); A.CallTo(() => _documentRepository.GetDocumentIdWithCompanyUserCheckAsync(documentId, _identity.IdentityId)) - .Returns((Guid.Empty, false)); + .Returns((Guid.Empty, false, false, false)); var sut = new RegistrationBusinessLogic(Options.Create(new RegistrationSettings()), null!, null!, null!, _portalRepositories, null!, _identityService, _dateTimeProvider, _mailingProcessCreation); // Act @@ -2907,7 +2907,7 @@ public async Task GetDocumentAsync_WithWrongUser_ThrowsForbiddenException() // Arrange var documentId = Guid.NewGuid(); A.CallTo(() => _documentRepository.GetDocumentIdWithCompanyUserCheckAsync(documentId, _identity.IdentityId)) - .Returns((documentId, false)); + .Returns((documentId, false, false, false)); var sut = new RegistrationBusinessLogic(Options.Create(new RegistrationSettings()), null!, null!, null!, _portalRepositories, null!, _identityService, _dateTimeProvider, _mailingProcessCreation); // Act @@ -2918,6 +2918,23 @@ public async Task GetDocumentAsync_WithWrongUser_ThrowsForbiddenException() ex.Message.Should().Be($"The user is not permitted to access document {documentId}."); } + [Fact] + public async Task GetDocumentAsync_WithConfirmedApplicationStatus_ThrowsForbiddenException() + { + // Arrange + var documentId = Guid.NewGuid(); + A.CallTo(() => _documentRepository.GetDocumentIdWithCompanyUserCheckAsync(documentId, _identity.IdentityId)) + .Returns((documentId, true, true, false)); + var sut = new RegistrationBusinessLogic(Options.Create(new RegistrationSettings()), null!, null!, null!, _portalRepositories, null!, _identityService, _dateTimeProvider, _mailingProcessCreation); + + // Act + Task Act() => sut.GetDocumentContentAsync(documentId); + + // Assert + var ex = await Assert.ThrowsAsync(Act); + ex.Message.Should().Be($"Documents not accessible as onboarding process finished {documentId}."); + } + #endregion #region SetInvitationStatus