ServiceAccountsService { public ResponseEntity<String> updateOnboardedServiceAccount(String token, ServiceAccount serviceAccount, UserDetails userDetails) { List<String> onboardedList = getOnboardedServiceAccountList(token, userDetails); if (!onboardedList.contains(serviceAccount.getName())) { log.error(JSONUtil.getJSON(ImmutableMap.<String, String>builder(). put(LogMessage.USER, ThreadLocalContext.getCurrentMap().get(LogMessage.USER).toString()). put(LogMessage.ACTION, "Update onboarded Service Account"). put(LogMessage.MESSAGE, "Failed to update onboarded Service Account. Service account not onboarded"). put(LogMessage.APIURL, ThreadLocalContext.getCurrentMap().get(LogMessage.APIURL).toString()). build())); return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("{\"errors\":[\"Failed to update onboarded Service Account. Please onboard this Service Account first and try again.\"]}"); } log.info(JSONUtil.getJSON(ImmutableMap.<String, String>builder(). put(LogMessage.USER, ThreadLocalContext.getCurrentMap().get(LogMessage.USER).toString()). put(LogMessage.ACTION, "Update onboarded Service Account"). put(LogMessage.MESSAGE, String.format("Update onboarded Service Account [%s]", serviceAccount.getName())). put(LogMessage.APIURL, ThreadLocalContext.getCurrentMap().get(LogMessage.APIURL).toString()). build())); List<ADServiceAccount> allServiceAccounts = getADServiceAccount(serviceAccount.getName()); if (allServiceAccounts == null || allServiceAccounts.isEmpty()) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("{\"errors\":[\"Failed to update onboarded Service Account. Unable to read Service account details\"]}"); } int maxPwdAge = allServiceAccounts.get(0).getMaxPwdAge(); if (serviceAccount.isAutoRotate()) { if (null == serviceAccount.getMax_ttl()) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("{\"errors\":[\"Invalid or no value has been provided for MAX_TTL\"]}"); } if (null == serviceAccount.getTtl()) { serviceAccount.setTtl(maxPwdAge-0L); } if (serviceAccount.getTtl() > maxPwdAge) { log.error(JSONUtil.getJSON(ImmutableMap.<String, String>builder(). put(LogMessage.USER, ThreadLocalContext.getCurrentMap().get(LogMessage.USER).toString()). put(LogMessage.ACTION, "Update onboarded Service Account"). put(LogMessage.MESSAGE, String.format ("Password Expiration Time [%s] is greater the Maximum expiration time (MAX_TTL) [%s]", serviceAccount.getTtl(), maxPwdAge)). put(LogMessage.APIURL, ThreadLocalContext.getCurrentMap().get(LogMessage.APIURL).toString()). build())); return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("{\"errors\":[\"Invalid value provided for Password Expiration Time. This can't be more than "+maxPwdAge+" for this Service Account\"]}"); } if (serviceAccount.getTtl() > serviceAccount.getMax_ttl()) { log.error(JSONUtil.getJSON(ImmutableMap.<String, String>builder(). put(LogMessage.USER, ThreadLocalContext.getCurrentMap().get(LogMessage.USER).toString()). put(LogMessage.ACTION, "Update onboarded Service Account"). put(LogMessage.MESSAGE, String.format ("Password Expiration Time [%s] is greater the Maximum expiration time (MAX_TTL) [%s]", serviceAccount.getTtl(), serviceAccount.getMax_ttl())). put(LogMessage.APIURL, ThreadLocalContext.getCurrentMap().get(LogMessage.APIURL).toString()). build())); return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("{\"errors\":[\"Password Expiration Time must be less than Maximum expiration time (MAX_TTL) for this Service Account\"]}"); } } if (!serviceAccount.isAutoRotate()) { serviceAccount.setTtl(TVaultConstants.MAX_TTL); } ResponseEntity<String> accountRoleDeletionResponse = createAccountRole(token, serviceAccount); if (accountRoleDeletionResponse!=null && HttpStatus.OK.equals(accountRoleDeletionResponse.getStatusCode())) { String path = new StringBuffer(TVaultConstants.SVC_ACC_ROLES_PATH).append(serviceAccount.getName()).toString(); Response metadataResponse = ControllerUtil.updateMetadataOnSvcUpdate(path, serviceAccount,token); if(metadataResponse != null && (HttpStatus.NO_CONTENT.equals(metadataResponse.getHttpstatus()) || HttpStatus.OK.equals(metadataResponse.getHttpstatus()))){ log.debug(JSONUtil.getJSON(ImmutableMap.<String, String>builder(). put(LogMessage.USER, ThreadLocalContext.getCurrentMap().get(LogMessage.USER).toString()). put(LogMessage.ACTION, "pdate onboarded Service Account"). put(LogMessage.MESSAGE, "Successfully updated onboarded Service Account."). put(LogMessage.APIURL, ThreadLocalContext.getCurrentMap().get(LogMessage.APIURL).toString()). build())); return ResponseEntity.status(HttpStatus.OK).body("{\"messages\":[\"Successfully updated onboarded Service Account.\"]}"); } return ResponseEntity.status(HttpStatus.OK).body("{\"messages\":[\"Successfully updated onboarded Service Account. However metadata update failed\"]}"); } else { log.error(JSONUtil.getJSON(ImmutableMap.<String, String>builder(). put(LogMessage.USER, ThreadLocalContext.getCurrentMap().get(LogMessage.USER).toString()). put(LogMessage.ACTION, "Update onboarded Service Account"). put(LogMessage.MESSAGE, "Failed to update onboarded Service Account."). put(LogMessage.STATUS, accountRoleDeletionResponse!=null?accountRoleDeletionResponse.getStatusCode().toString():HttpStatus.MULTI_STATUS.toString()). put(LogMessage.APIURL, ThreadLocalContext.getCurrentMap().get(LogMessage.APIURL).toString()). build())); return ResponseEntity.status(HttpStatus.MULTI_STATUS).body("{\"errors\":[\"Failed to update onboarded Service Account.\"]}"); } }  ResponseEntity<ADServiceAccountObjects> getADServiceAccounts(String token, UserDetails userDetails, String UserPrincipalName, boolean excludeOnboarded); ResponseEntity<String> onboardServiceAccount(String token, ServiceAccount serviceAccount, UserDetails userDetails); ResponseEntity<String> offboardServiceAccount(String token, OnboardedServiceAccount serviceAccount, UserDetails userDetails); ResponseEntity<String> addUserToServiceAccount(String token, ServiceAccountUser serviceAccountUser, UserDetails userDetails, boolean isPartOfSvcAccOnboard); ResponseEntity<String> removeUserFromServiceAccount(String token, ServiceAccountUser serviceAccountUser, UserDetails userDetails); ResponseEntity<String> resetSvcAccPassword(String token, String svcAccName, UserDetails userDetails); ResponseEntity<String> readSvcAccPassword(String token, String svcAccName, UserDetails userDetails); ResponseEntity<String> getOnboarderdServiceAccount(String token, String svcAccName, UserDetails userDetails); boolean canAddOrRemoveUser(UserDetails userDetails, ServiceAccountUser serviceAccountUser, String action); ResponseEntity<String> getOnboardedServiceAccounts(String token,  UserDetails userDetails); boolean hasAddOrRemovePermission(UserDetails userDetails, String serviceAccount, String token); boolean hasAddUserPermission(UserDetails userDetails, String serviceAccount, String token, boolean isPartOfSvcAccOnboard); static boolean isSvcaccPermissionInputValid(String access); ResponseEntity<String> addGroupToServiceAccount(String token, ServiceAccountGroup serviceAccountGroup, UserDetails userDetails); ResponseEntity<String> removeGroupFromServiceAccount(String token, ServiceAccountGroup serviceAccountGroup, UserDetails userDetails); ResponseEntity<String> associateApproletoSvcAcc(UserDetails userDetails, String token, ServiceAccountApprole serviceAccountApprole); ResponseEntity<String> getServiceAccountMeta(String token, UserDetails userDetails, String path); ResponseEntity<String> removeApproleFromSvcAcc(UserDetails userDetails, String token, ServiceAccountApprole serviceAccountApprole); ResponseEntity<String> addAwsRoleToSvcacc(UserDetails userDetails, String token, ServiceAccountAWSRole serviceAccountAWSRole); ResponseEntity<String> removeAWSRoleFromSvcacc(UserDetails userDetails, String token, ServiceAccountAWSRole serviceAccountAWSRole); ResponseEntity<String> createAWSRole(UserDetails userDetails, String token, AWSLoginRole awsLoginRole); ResponseEntity<String> createIAMRole(UserDetails userDetails, String token, AWSIAMRole awsiamRole); ResponseEntity<String> updateOnboardedServiceAccount(String token, ServiceAccount serviceAccount, UserDetails userDetails); ResponseEntity<String> transferSvcAccountOwner(UserDetails userDetails, String token, String svcAccName); ResponseEntity<String> getServiceAccounts(UserDetails userDetails, String userToken);  }
@Test public void test_updateOnboardedServiceAccount_success() throws Exception { ResponseEntity<String> responseEntityExpected = ResponseEntity.status(HttpStatus.OK).body("{\"messages\":[\"Successfully updated onboarded Service Account.\"]}"); String token = "5PDrOhsy4ig8L3EpsJZSLAMg"; UserDetails userDetails = getMockUser(true); ServiceAccount serviceAccount = generateServiceAccount("testacc02", "testacc01"); Response response = getMockResponse(HttpStatus.OK, true, "{\"keys\":[\"testacc02\"]}"); when(reqProcessor.process("/ad/serviceaccount/onboardedlist","{}",token)).thenReturn(response); Response onboardResponse = getMockResponse(HttpStatus.OK, true, "{\"messages\":[\"Successfully created service account role.\"]}"); when(reqProcessor.process(eq("/ad/serviceaccount/onboard"), Mockito.any(), eq(token))).thenReturn(onboardResponse); List<ADServiceAccount> allServiceAccounts = new ArrayList<>(); allServiceAccounts.add(generateADServiceAccount("testacc02")); ReflectionTestUtils.setField(serviceAccountsService, "ldapTemplate", ldapTemplate); when(ldapTemplate.search(Mockito.anyString(), Mockito.any(), Mockito.any(AttributesMapper.class))).thenReturn(allServiceAccounts); when(ControllerUtil.updateMetadataOnSvcUpdate(Mockito.anyString(), Mockito.any(), Mockito.anyString())).thenReturn(getMockResponse(HttpStatus.OK, true,"{}")); ResponseEntity<String> responseEntityActual = serviceAccountsService.updateOnboardedServiceAccount(token, serviceAccount, userDetails); assertEquals(HttpStatus.OK, responseEntityActual.getStatusCode()); assertEquals(responseEntityExpected, responseEntityActual); }
@Test public void test_updateOnboardedServiceAccount_failure_not_onboarded() throws Exception { ResponseEntity<String> responseEntityExpected = ResponseEntity.status(HttpStatus.BAD_REQUEST).body("{\"errors\":[\"Failed to update onboarded Service Account. Please onboard this Service Account first and try again.\"]}"); String token = "5PDrOhsy4ig8L3EpsJZSLAMg"; UserDetails userDetails = getMockUser(true); ServiceAccount serviceAccount = generateServiceAccount("testacc02", "testacc01"); Response response = getMockResponse(HttpStatus.OK, true, "{\"keys\":[\"testacc03\"]}"); when(reqProcessor.process("/ad/serviceaccount/onboardedlist","{}",token)).thenReturn(response); ResponseEntity<String> responseEntityActual = serviceAccountsService.updateOnboardedServiceAccount(token, serviceAccount, userDetails); assertEquals(HttpStatus.BAD_REQUEST, responseEntityActual.getStatusCode()); assertEquals(responseEntityExpected, responseEntityActual); }
@Test public void test_updateOnboardedServiceAccount_failure_to_read_ad_details() { UserDetails userDetails = getMockUser(true); String token = userDetails.getClientToken(); ServiceAccount serviceAccount = generateServiceAccount("testacc02","testacc01"); Response response = getMockResponse(HttpStatus.OK, true, "{\"keys\":[\"testacc02\"]}"); when(reqProcessor.process("/ad/serviceaccount/onboardedlist","{}",token)).thenReturn(response); String expectedResponse = "{\"errors\":[\"Failed to update onboarded Service Account. Unable to read Service account details\"]}"; ResponseEntity<String> responseEntityExpected = ResponseEntity.status(HttpStatus.BAD_REQUEST).body(expectedResponse); ReflectionTestUtils.setField(serviceAccountsService, "ldapTemplate", ldapTemplate); when(ldapTemplate.search(Mockito.anyString(), Mockito.any(), Mockito.any(AttributesMapper.class))).thenReturn(null); ResponseEntity<String> responseEntity = serviceAccountsService.updateOnboardedServiceAccount(token, serviceAccount, userDetails); assertEquals(HttpStatus.BAD_REQUEST, responseEntity.getStatusCode()); assertEquals(responseEntityExpected, responseEntity); }
@Test public void test_updateOnboardedServiceAccount_failure_invalid_ttl() throws Exception { ResponseEntity<String> responseEntityExpected = ResponseEntity.status(HttpStatus.BAD_REQUEST).body("{\"errors\":[\"Invalid value provided for Password Expiration Time. This can't be more than 31536000 for this Service Account\"]}"); String token = "5PDrOhsy4ig8L3EpsJZSLAMg"; UserDetails userDetails = getMockUser(true); ServiceAccount serviceAccount = new ServiceAccount(); serviceAccount.setName("testacc02"); serviceAccount.setAutoRotate(true); serviceAccount.setTtl(TVaultConstants.PASSWORD_AUTOROTATE_TTL_MAX_VALUE); serviceAccount.setMax_ttl(TVaultConstants.PASSWORD_AUTOROTATE_TTL_MAX_VALUE); serviceAccount.setOwner("testacc0`"); Response response = getMockResponse(HttpStatus.OK, true, "{\"keys\":[\"testacc02\"]}"); when(reqProcessor.process("/ad/serviceaccount/onboardedlist","{}",token)).thenReturn(response); List<ADServiceAccount> allServiceAccounts = new ArrayList<>(); allServiceAccounts.add(generateADServiceAccount("testacc02")); ReflectionTestUtils.setField(serviceAccountsService, "ldapTemplate", ldapTemplate); when(ldapTemplate.search(Mockito.anyString(), Mockito.any(), Mockito.any(AttributesMapper.class))).thenReturn(allServiceAccounts); ResponseEntity<String> responseEntityActual = serviceAccountsService.updateOnboardedServiceAccount(token, serviceAccount, userDetails); assertEquals(HttpStatus.BAD_REQUEST, responseEntityActual.getStatusCode()); assertEquals(responseEntityExpected, responseEntityActual); }
@Test public void test_updateOnboardedServiceAccount_failure_invalid_ttl_or_maxttl() throws Exception { ResponseEntity<String> responseEntityExpected = ResponseEntity.status(HttpStatus.BAD_REQUEST).body("{\"errors\":[\"Invalid or no value has been provided for MAX_TTL\"]}"); String token = "5PDrOhsy4ig8L3EpsJZSLAMg"; UserDetails userDetails = getMockUser(true); ServiceAccount serviceAccount = new ServiceAccount(); serviceAccount.setName("testacc02"); serviceAccount.setAutoRotate(true); serviceAccount.setOwner("testacc0`"); Response response = getMockResponse(HttpStatus.OK, true, "{\"keys\":[\"testacc02\"]}"); when(reqProcessor.process("/ad/serviceaccount/onboardedlist","{}",token)).thenReturn(response); List<ADServiceAccount> allServiceAccounts = new ArrayList<>(); allServiceAccounts.add(generateADServiceAccount("testacc02")); ReflectionTestUtils.setField(serviceAccountsService, "ldapTemplate", ldapTemplate); when(ldapTemplate.search(Mockito.anyString(), Mockito.any(), Mockito.any(AttributesMapper.class))).thenReturn(allServiceAccounts); ResponseEntity<String> responseEntityActual = serviceAccountsService.updateOnboardedServiceAccount(token, serviceAccount, userDetails); assertEquals(HttpStatus.BAD_REQUEST, responseEntityActual.getStatusCode()); assertEquals(responseEntityExpected, responseEntityActual); }
@Test public void test_updateOnboardedServiceAccount_failure_ttl_greaterthan_max() throws Exception { ResponseEntity<String> responseEntityExpected = ResponseEntity.status(HttpStatus.BAD_REQUEST).body("{\"errors\":[\"Password Expiration Time must be less than Maximum expiration time (MAX_TTL) for this Service Account\"]}"); String token = "5PDrOhsy4ig8L3EpsJZSLAMg"; UserDetails userDetails = getMockUser(true); ServiceAccount serviceAccount = new ServiceAccount(); serviceAccount.setName("testacc02"); serviceAccount.setAutoRotate(true); serviceAccount.setTtl(90L); serviceAccount.setMax_ttl(89L); serviceAccount.setOwner("testacc0`"); ServiceAccountTTL serviceAccountTTL = new ServiceAccountTTL(); serviceAccountTTL.setRole_name(serviceAccount.getName()); serviceAccountTTL.setService_account_name(serviceAccount.getName() + "@null") ; serviceAccountTTL.setTtl(serviceAccount.getTtl()); Response response = getMockResponse(HttpStatus.OK, true, "{\"keys\":[\"testacc02\"]}"); when(reqProcessor.process(Mockito.anyString(),Mockito.anyObject(),Mockito.anyString())).thenReturn(response); when(JSONUtil.getJSON((ServiceAccountTTL)Mockito.any())).thenReturn(getJSON(serviceAccountTTL)); List<ADServiceAccount> allServiceAccounts = new ArrayList<>(); allServiceAccounts.add(generateADServiceAccount("testacc02")); ReflectionTestUtils.setField(serviceAccountsService, "ldapTemplate", ldapTemplate); when(ldapTemplate.search(Mockito.anyString(), Mockito.any(), Mockito.any(AttributesMapper.class))).thenReturn(allServiceAccounts); ResponseEntity<String> responseEntityActual = serviceAccountsService.updateOnboardedServiceAccount(token, serviceAccount, userDetails); assertEquals(HttpStatus.BAD_REQUEST, responseEntityActual.getStatusCode()); assertEquals(responseEntityExpected, responseEntityActual); }
@Test public void test_updateOnboardedServiceAccount_createrole_failure() throws Exception { ResponseEntity<String> responseEntityExpected = ResponseEntity.status(HttpStatus.MULTI_STATUS).body("{\"errors\":[\"Failed to update onboarded Service Account.\"]}"); String token = "5PDrOhsy4ig8L3EpsJZSLAMg"; UserDetails userDetails = getMockUser(true); ServiceAccount serviceAccount = generateServiceAccount("testacc02", "testacc01"); Response response = getMockResponse(HttpStatus.OK, true, "{\"keys\":[\"testacc02\"]}"); when(reqProcessor.process("/ad/serviceaccount/onboardedlist","{}",token)).thenReturn(response); Response onboardResponse = getMockResponse(HttpStatus.BAD_REQUEST, true, "{}"); when(reqProcessor.process(eq("/ad/serviceaccount/onboard"), Mockito.any(), eq(token))).thenReturn(onboardResponse); List<ADServiceAccount> allServiceAccounts = new ArrayList<>(); allServiceAccounts.add(generateADServiceAccount("testacc02")); ReflectionTestUtils.setField(serviceAccountsService, "ldapTemplate", ldapTemplate); when(ldapTemplate.search(Mockito.anyString(), Mockito.any(), Mockito.any(AttributesMapper.class))).thenReturn(allServiceAccounts); ResponseEntity<String> responseEntityActual = serviceAccountsService.updateOnboardedServiceAccount(token, serviceAccount, userDetails); assertEquals(HttpStatus.MULTI_STATUS, responseEntityActual.getStatusCode()); assertEquals(responseEntityExpected, responseEntityActual); }