Skip to content

Commit

Permalink
Issue transfer ownership of service user (#2393)
Browse files Browse the repository at this point in the history
* Change ownership of service users

Signed-off-by: Aindriu Lavelle <[email protected]>

* Allow service accounts to be transfered between teams

Signed-off-by: Aindriu Lavelle <[email protected]>

* Additon of unit tests to check for various scenarios of transfer of ownership of a service account.

Signed-off-by: Aindriu Lavelle <[email protected]>

* Update to only transfer ownership when the last acl is transfered from the team

Signed-off-by: Aindriu Lavelle <[email protected]>

* Address PR comment move if statement up a level

Signed-off-by: Aindriu Lavelle <[email protected]>

---------

Signed-off-by: Aindriu Lavelle <[email protected]>
  • Loading branch information
aindriu-aiven authored Apr 4, 2024
1 parent 909e90c commit ed8e8f0
Show file tree
Hide file tree
Showing 7 changed files with 444 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ boolean validateIfConsumerGroupUsedByAnotherTeam(
boolean existsSpecificAclRequest(
String topicName, String requestStatus, String env, int tenantId, int associatedAclId);

boolean existsAclSslInTeam(int teamId, int tenantId, String aclSsl);

boolean existsSchemaRequest(String topicName, String requestStatus, String env, int tenantId);

boolean existsSchemaRequest(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,11 @@ public boolean existsSpecificAclRequest(
topicName, requestStatus, env, tenantId, associatedAclId);
}

@Override
public boolean existsAclSslInTeam(int teamId, int tenantId, String aclSsl) {
return jdbcSelectHelper.existsAclSslInTeam(teamId, tenantId, aclSsl);
}

@Override
public boolean existsSchemaRequest(
String topicName, String requestStatus, String env, int tenantId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ public boolean existsAclRequest(
tenantId, env, requestStatus, topicName);
}

public boolean existsAclSslInTeam(int teamId, int tenantId, String aclSsl) {
return aclRepo.existsAclSslInTeamInTenant(teamId, tenantId, aclSsl);
}

public boolean existsSpecificAclRequest(
String topicName, String requestStatus, String env, int tenantId, int associatedAclId) {
log.debug("associatedAclId = {}", associatedAclId);
Expand Down
6 changes: 6 additions & 0 deletions core/src/main/java/io/aiven/klaw/repository/AclRepo.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ boolean existsByTeamIdNotAndTenantIdAndConsumergroup(
boolean existsByEnvironmentAndTenantId(
@Param("envId") String envId, @Param("tenantId") Integer tenantId);

@Query(
value =
"select count(*) > 0 from kwacls where teamid = :teamId and tenantid = :tenantId and aclssl = :aclSsl",
nativeQuery = true)
boolean existsAclSslInTeamInTenant(Integer teamId, Integer tenantId, String aclSsl);

@Query(
value = "select count(*) from kwacls where env = :envId and tenantid = :tenantId",
nativeQuery = true)
Expand Down
64 changes: 64 additions & 0 deletions core/src/main/java/io/aiven/klaw/service/AclControllerService.java
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,16 @@ private ApiResponse approveClaimAcl(

acl.get().setTeamId(aclReq.getRequestingteam());
manageDatabase.getHandleDbRequests().updateAcl(acl.get());
if (Objects.equals(RequestOperationType.CLAIM.value, aclReq.getRequestOperationType())) {
if (!manageDatabase
.getHandleDbRequests()
.existsAclSslInTeam(aclReq.getTeamId(), aclReq.getTenantId(), aclReq.getAcl_ssl())) {
// Team has no other Acls left with service user so transfer ownership to the next
// team.
// Transfer Service Account ownership
transferServiceUserOwnership(aclReq);
}
}
}
aclReq.setApprovals(KlawResourceUtils.approvalsToAclApprovalsList(approvals));
String status =
Expand All @@ -770,11 +780,43 @@ private ApiResponse emailAndReturnClaimUpdate(
dbHandle,
notifyUserType,
commonUtilsService.getLoginUrl());

return ApiResultStatus.SUCCESS.value.equals(updateAclReqStatus)
? ApiResponse.ok(updateAclReqStatus)
: ApiResponse.notOk(updateAclReqStatus);
}

private void transferServiceUserOwnership(AclRequests aclReq) {
removeServiceAccountOnTransferOfOwnership(aclReq, aclReq.getTenantId());
Optional<Team> optionalTeam =
manageDatabase.getTeamObjForTenant(aclReq.getTenantId()).stream()
.filter(team -> Objects.equals(team.getTeamId(), aclReq.getRequestingteam()))
.findFirst();
optionalTeam.ifPresent(
team -> {
if (Objects.equals(RequestOperationType.CLAIM.value, aclReq.getRequestOperationType())) {
ServiceAccounts serviceAccounts = team.getServiceAccounts();
if (serviceAccounts != null
&& serviceAccounts.getServiceAccountsList() != null
&& !serviceAccounts.getServiceAccountsList().isEmpty()) {
// add to your team
serviceAccounts.getServiceAccountsList().add(aclReq.getAcl_ssl());
} else {
serviceAccounts = new ServiceAccounts();
serviceAccounts.setNumberOfAllowedAccounts(allowedServiceAccountsPerTeam);
serviceAccounts.setServiceAccountsList(new HashSet<>());
serviceAccounts.getServiceAccountsList().add(aclReq.getAcl_ssl());
team.setServiceAccounts(serviceAccounts);
}

// Update team with service account
manageDatabase.getHandleDbRequests().updateTeam(team);
commonUtilsService.updateMetadata(
aclReq.getTenantId(), EntityType.TEAM, MetadataOperationType.UPDATE, null);
}
});
}

private void saveToTopicHistory(String userDetails, int tenantId, AclRequests aclReq) {
String remarksAcl =
RequestEntityType.ACL.name()
Expand Down Expand Up @@ -905,13 +947,35 @@ private void updateServiceAccountsForTeam(AclRequests aclRequest, int tenantId)
serviceAccounts.getServiceAccountsList().add(aclRequest.getAcl_ssl());
optionalTeam.get().setServiceAccounts(serviceAccounts);
}

// Update team with service account
manageDatabase.getHandleDbRequests().updateTeam(optionalTeam.get());
commonUtilsService.updateMetadata(
tenantId, EntityType.TEAM, MetadataOperationType.UPDATE, null);
}
}

private void removeServiceAccountOnTransferOfOwnership(AclRequests aclRequest, int tenantId) {
if (Objects.equals(RequestOperationType.CLAIM.value, aclRequest.getRequestOperationType())) {
// remove the service account from the other team as they no longer have any acls using that
// service user left.
Optional<Team> origTeam =
manageDatabase.getTeamObjForTenant(tenantId).stream()
.filter(team -> Objects.equals(team.getTeamId(), aclRequest.getTeamId()))
.findFirst();
origTeam.ifPresent(
team -> {
ServiceAccounts origServiceAccounts = team.getServiceAccounts();
if (origServiceAccounts != null
&& origServiceAccounts.getServiceAccountsList() != null
&& origServiceAccounts.getServiceAccountsList().size() > 0) {
origServiceAccounts.getServiceAccountsList().remove(aclRequest.getAcl_ssl());
}
manageDatabase.getHandleDbRequests().updateTeam(team);
});
}
}

private ResponseEntity<ApiResponse> invokeClusterApiAclRequest(int tenantId, AclRequests aclReq)
throws KlawException {
ResponseEntity<ApiResponse> response = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -353,4 +353,31 @@ public static Stream<Arguments> doesAclExist() {
Arguments.of(101, "TEST", "Topic3", 19292, false),
Arguments.of(101, "TEST", "Topic4", 120202, false));
}

@ParameterizedTest
@MethodSource
public void doesAclSslExistInTeam(
int teamId, int tenantId, String aclSsl, boolean expectedResult) {

when(aclRepo.existsAclSslInTeamInTenant(teamId, tenantId, aclSsl)).thenReturn(expectedResult);

assertThat(selectData.existsAclSslInTeam(teamId, tenantId, aclSsl)).isEqualTo(expectedResult);

verify(aclRepo, times(1)).existsAclSslInTeamInTenant(teamId, tenantId, aclSsl);
}

public static Stream<Arguments> doesAclSslExistInTeam() {

return Stream.of(
Arguments.of(1002, 101, "Alice", true),
Arguments.of(1004, 101, "White-Queen", true),
Arguments.of(1002, 101, "Red-Queen", true),
Arguments.of(1004, 101, "Tarrant", true),
Arguments.of(1009, 101, "Hamish", false),
Arguments.of(1, 101, "Hatter", true),
Arguments.of(21, 101, "Caterpillar", false),
Arguments.of(1006, 101, "Cheshire", false),
Arguments.of(1009, 101, "Knave", false),
Arguments.of(1009, 101, "White-Rabbit", false));
}
}
Loading

0 comments on commit ed8e8f0

Please sign in to comment.