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(serviceaccount):- Delete serviceaccount #69

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
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ public async Task<int> DeleteOwnCompanyServiceAccountAsync(Guid serviceAccountId
{
throw new ConflictException($"serviceAccount {serviceAccountId} not found for company {companyId}");
}
if (result.statusId == ConnectorStatusId.ACTIVE || result.statusId == ConnectorStatusId.PENDING)
{
throw new ConflictException($"Technical User is linked to an active connector. Change the link or deactivate the connector to delete the technical user.");
}

_portalRepositories.GetInstance<IUserRepository>().AttachAndModifyIdentity(serviceAccountId, null, i =>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,14 @@ public async Task<CreatedAtRouteResult> ExecuteCompanyUserCreation([FromBody] Se
/// <remarks>Example: DELETE: api/administration/serviceaccount/owncompany/serviceaccounts/7e85a0b8-0001-ab67-10d1-0ef508201000</remarks>
/// <response code="200">Successful if the service account was deleted.</response>
/// <response code="404">Record was not found. Service account is either not existing or not connected to the respective company.</response>
/// <response code="409">Technical User is linked to an active connector. Change the link or deactivate the connector to delete the technical user.</response>
[HttpDelete]
[Authorize(Roles = "delete_tech_user_management")]
[Authorize(Policy = PolicyTypes.ValidCompany)]
[Route("owncompany/serviceaccounts/{serviceAccountId}")]
[ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status404NotFound)]
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status409Conflict)]
public Task<int> DeleteServiceAccount([FromRoute] Guid serviceAccountId) =>
this.WithCompanyId(companyId => _logic.DeleteOwnCompanyServiceAccountAsync(serviceAccountId, companyId));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ CompanyServiceAccount CreateCompanyServiceAccount(Guid identityId,

void AttachAndModifyCompanyServiceAccount(Guid id, Action<CompanyServiceAccount>? initialize, Action<CompanyServiceAccount> modify);
Task<CompanyServiceAccountWithRoleDataClientId?> GetOwnCompanyServiceAccountWithIamClientIdAsync(Guid serviceAccountId, Guid userCompanyId);
Task<(IEnumerable<Guid> UserRoleIds, Guid? ConnectorId, string? ClientId)> GetOwnCompanyServiceAccountWithIamServiceAccountRolesAsync(Guid serviceAccountId, Guid companyId);
Task<(IEnumerable<Guid> UserRoleIds, Guid? ConnectorId, string? ClientId, ConnectorStatusId? statusId)> GetOwnCompanyServiceAccountWithIamServiceAccountRolesAsync(Guid serviceAccountId, Guid companyId);
Task<CompanyServiceAccountDetailedData?> GetOwnCompanyServiceAccountDetailedDataUntrackedAsync(Guid serviceAccountId, Guid companyId);
Func<int, int, Task<Pagination.Source<CompanyServiceAccountData>?>> GetOwnCompanyServiceAccountsUntracked(Guid userCompanyId);
Task<bool> CheckActiveServiceAccountExistsForCompanyAsync(Guid technicalUserId, Guid companyId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,16 +96,17 @@ public void AttachAndModifyCompanyServiceAccount(
userRole.UserRoleText))))
.SingleOrDefaultAsync();

public Task<(IEnumerable<Guid> UserRoleIds, Guid? ConnectorId, string? ClientId)> GetOwnCompanyServiceAccountWithIamServiceAccountRolesAsync(Guid serviceAccountId, Guid companyId) =>
public Task<(IEnumerable<Guid> UserRoleIds, Guid? ConnectorId, string? ClientId, ConnectorStatusId? statusId)> GetOwnCompanyServiceAccountWithIamServiceAccountRolesAsync(Guid serviceAccountId, Guid companyId) =>
_dbContext.CompanyServiceAccounts
.Where(serviceAccount =>
serviceAccount.Id == serviceAccountId &&
serviceAccount.Identity!.UserStatusId == UserStatusId.ACTIVE &&
serviceAccount.Identity!.CompanyId == companyId)
.Select(sa => new ValueTuple<IEnumerable<Guid>, Guid?, string?>(
.Select(sa => new ValueTuple<IEnumerable<Guid>, Guid?, string?, ConnectorStatusId?>(
sa.Identity!.IdentityAssignedRoles.Select(r => r.UserRoleId),
sa.Connector!.Id,
sa.ClientId))
sa.ClientId,
sa.Connector!.StatusId))
.SingleOrDefaultAsync();

public Task<CompanyServiceAccountDetailedData?> GetOwnCompanyServiceAccountDetailedDataUntrackedAsync(Guid serviceAccountId, Guid companyId) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,22 @@ public async Task DeleteOwnCompanyServiceAccountAsync_WithNotExistingServiceAcco
ex.Message.Should().Be($"serviceAccount {serviceAccountId} not found for company {_identity.CompanyId}");
}

[Fact]
public async Task DeleteOwnCompanyServiceAccountAsync_WithInvalidConnectorStatus_ThrowsConflictException()
{
// Arrange
SetupDeleteOwnCompanyServiceAccountForInvalidConnectorStatus();

var sut = new ServiceAccountBusinessLogic(_provisioningManager, _portalRepositories, _options, null!);

// Act
async Task Act() => await sut.DeleteOwnCompanyServiceAccountAsync(ValidServiceAccountId, _identity.CompanyId).ConfigureAwait(false);

// Assert
var ex = await Assert.ThrowsAsync<ConflictException>(Act);
ex.Message.Should().Be($"Technical User is linked to an active connector. Change the link or deactivate the connector to delete the technical user.");
}

[Theory]
[InlineData(true, false)]
[InlineData(false, true)]
Expand Down Expand Up @@ -548,9 +564,9 @@ private void SetupGetOwnCompanyServiceAccount()
private void SetupDeleteOwnCompanyServiceAccount(bool withServiceAccount, bool withClient, Connector? connector = null, Identity? identity = null)
{
A.CallTo(() => _serviceAccountRepository.GetOwnCompanyServiceAccountWithIamServiceAccountRolesAsync(ValidServiceAccountId, _identity.CompanyId))
.Returns((_userRoleIds, withServiceAccount ? ValidConnectorId : null, withClient ? ClientId : null));
A.CallTo(() => _serviceAccountRepository.GetOwnCompanyServiceAccountWithIamServiceAccountRolesAsync(A<Guid>.That.Not.Matches(x => x == ValidServiceAccountId), _identity.CompanyId))
.Returns(((IEnumerable<Guid>, Guid?, string?))default);
.Returns((_userRoleIds, withServiceAccount ? ValidConnectorId : null, withClient ? ClientId : null, statusId: ConnectorStatusId.INACTIVE));
A.CallTo(() => _serviceAccountRepository.GetOwnCompanyServiceAccountWithIamServiceAccountRolesAsync(A<Guid>.That.Not.Matches(x => x == ValidServiceAccountId), A<Guid>._))
.Returns(((IEnumerable<Guid>, Guid?, string?, ConnectorStatusId?))default);

if (identity != null)
{
Expand All @@ -577,5 +593,16 @@ private void SetupDeleteOwnCompanyServiceAccount(bool withServiceAccount, bool w
A.CallTo(() => _portalRepositories.GetInstance<IUserRolesRepository>()).Returns(_userRolesRepository);
}

private void SetupDeleteOwnCompanyServiceAccountForInvalidConnectorStatus()
{
A.CallTo(() => _serviceAccountRepository.GetOwnCompanyServiceAccountWithIamServiceAccountRolesAsync(ValidServiceAccountId, _identity.CompanyId))
.Returns((_userRoleIds, null, null, statusId: ConnectorStatusId.ACTIVE));
A.CallTo(() => _serviceAccountRepository.GetOwnCompanyServiceAccountWithIamServiceAccountRolesAsync(A<Guid>.That.Not.Matches(x => x == ValidServiceAccountId), A<Guid>._))
.Returns(((IEnumerable<Guid>, Guid?, string?, ConnectorStatusId?))default);

A.CallTo(() => _portalRepositories.GetInstance<IServiceAccountRepository>()).Returns(_serviceAccountRepository);
A.CallTo(() => _portalRepositories.GetInstance<IUserRolesRepository>()).Returns(_userRolesRepository);
}

#endregion
}