diff --git a/servers/zms/pom.xml b/servers/zms/pom.xml
index 9ada4a598ec..cefa825d107 100644
--- a/servers/zms/pom.xml
+++ b/servers/zms/pom.xml
@@ -27,7 +27,7 @@
war
- 0.9745
+ 0.9760
diff --git a/servers/zms/src/main/java/com/yahoo/athenz/zms/DBService.java b/servers/zms/src/main/java/com/yahoo/athenz/zms/DBService.java
index dfcae50284e..24f37ebbd26 100644
--- a/servers/zms/src/main/java/com/yahoo/athenz/zms/DBService.java
+++ b/servers/zms/src/main/java/com/yahoo/athenz/zms/DBService.java
@@ -528,11 +528,13 @@ boolean processPolicy(ObjectStoreConnection con, Policy originalPolicy, String d
if (newAssertions != null) {
for (Assertion assertion : newAssertions) {
if (!con.insertAssertion(domainName, policyName, policy.getVersion(), assertion)) {
+ LOG.error("unable to insert assertion for policy {} in domain {}", policyName, domainName);
return false;
}
// insert the new assertion conditions if any
if (assertion.getConditions() != null) {
if (!con.insertAssertionConditions(assertion.getId(), assertion.getConditions())) {
+ LOG.error("unable to insert assertion conditions for policy {} in domain {}", policyName, domainName);
return false;
}
}
@@ -563,6 +565,7 @@ boolean processPolicy(ObjectStoreConnection con, Policy originalPolicy, String d
if (!ignoreDeletes) {
for (Assertion assertion : delAssertions) {
if (!con.deleteAssertion(domainName, policyName, policy.getVersion(), assertion.getId())) {
+ LOG.error("unable to delete assertion for policy {} in domain {}", policyName, domainName);
return false;
}
}
@@ -571,10 +574,12 @@ boolean processPolicy(ObjectStoreConnection con, Policy originalPolicy, String d
for (Assertion assertion : addAssertions) {
if (!con.insertAssertion(domainName, policyName, policy.getVersion(), assertion)) {
+ LOG.error("unable to insert assertion for policy {} in domain {}", policyName, domainName);
return false;
}
if (assertion.getConditions() != null) {
if (!con.insertAssertionConditions(assertion.getId(), assertion.getConditions())) {
+ LOG.error("unable to insert assertion condition for policy {} in domain {}", policyName, domainName);
return false;
}
}
@@ -588,6 +593,7 @@ boolean processPolicy(ObjectStoreConnection con, Policy originalPolicy, String d
for (Map.Entry> entry : delConditions.entrySet()) {
Long assertionId = entry.getKey();
if (!con.deleteAssertionConditions(assertionId)) {
+ LOG.error("unable to delete assertion condition for policy {} in domain {}", policyName, domainName);
return false;
}
}
@@ -596,6 +602,7 @@ boolean processPolicy(ObjectStoreConnection con, Policy originalPolicy, String d
Long assertionId = entry.getKey();
List conditionsList = entry.getValue();
if (!con.insertAssertionConditions(assertionId, new AssertionConditions().setConditionsList(conditionsList))) {
+ LOG.error("unable to insert assertion condition for policy {} in domain {}", policyName, domainName);
return false;
}
}
@@ -819,6 +826,8 @@ boolean processRole(ObjectStoreConnection con, Role originalRole, String domainN
}
member.setRequestPrincipal(admin);
if (!con.insertRoleMember(domainName, roleName, member, admin, auditRef)) {
+ LOG.error("unable to insert member {} to role {} in domain {}",
+ member.getMemberName(), roleName, domainName);
return false;
}
}
@@ -922,6 +931,8 @@ boolean processGroup(ObjectStoreConnection con, Group originalGroup, final Strin
member.setPendingState(null);
}
if (!con.insertGroupMember(domainName, groupName, member, admin, auditRef)) {
+ LOG.error("unable to insert member {} to group {} in domain {}",
+ member.getMemberName(), groupName, domainName);
return false;
}
}
@@ -1155,11 +1166,15 @@ boolean processUpdateRoleMembers(ObjectStoreConnection con, Role originalRole,
if (pendingState && deleteProtection == Boolean.TRUE) {
member.setApproved(false).setPendingState(ZMSConsts.PENDING_REQUEST_DELETE_STATE);
if (!con.insertRoleMember(domainName, roleName, member, admin, auditRef)) {
+ LOG.error("unable to insert member {} to role {} in domain {}",
+ member.getMemberName(), roleName, domainName);
return false;
}
addMemberToNotifySet(notifyMembers, member.getMemberName());
} else {
if (!con.deleteRoleMember(domainName, roleName, member.getMemberName(), admin, auditRef)) {
+ LOG.error("unable to delete member {} from role {} in domain {}",
+ member.getMemberName(), roleName, domainName);
return false;
}
}
@@ -1175,6 +1190,8 @@ boolean processUpdateRoleMembers(ObjectStoreConnection con, Role originalRole,
member.setPendingState(null);
}
if (!con.insertRoleMember(domainName, roleName, member, admin, auditRef)) {
+ LOG.error("unable to insert member {} to role {} in domain {}",
+ member.getMemberName(), roleName, domainName);
return false;
}
}
@@ -1209,11 +1226,15 @@ private boolean processUpdateGroupMembers(ObjectStoreConnection con, Group origi
if (pendingState && deleteProtection == Boolean.TRUE) {
member.setApproved(false).setPendingState(ZMSConsts.PENDING_REQUEST_DELETE_STATE);
if (!con.insertGroupMember(domainName, groupName, member, admin, auditRef)) {
+ LOG.error("unable to insert member {} to group {} in domain {}",
+ member.getMemberName(), groupName, domainName);
return false;
}
addMemberToNotifySet(notifyMembers, member.getMemberName());
} else {
if (!con.deleteGroupMember(domainName, groupName, member.getMemberName(), admin, auditRef)) {
+ LOG.error("unable to delete member {} from group {} in domain {}",
+ member.getMemberName(), groupName, domainName);
return false;
}
}
@@ -1229,6 +1250,8 @@ private boolean processUpdateGroupMembers(ObjectStoreConnection con, Group origi
member.setPendingState(null);
}
if (!con.insertGroupMember(domainName, groupName, member, admin, auditRef)) {
+ LOG.error("unable to insert member {} to group {} in domain {}",
+ member.getMemberName(), groupName, domainName);
return false;
}
}
@@ -1290,6 +1313,7 @@ boolean processServiceIdentity(ResourceContext ctx, ObjectStoreConnection con, S
for (PublicKeyEntry publicKey : publicKeys) {
if (!con.insertPublicKeyEntry(domainName, serviceName, publicKey)) {
+ LOG.error("unable to insert public key to service {} in domain {}", serviceName, domainName);
return false;
}
}
@@ -1331,6 +1355,7 @@ boolean processServiceIdentity(ResourceContext ctx, ObjectStoreConnection con, S
if (!ignoreDeletes) {
for (String publicKey : delPublicKeysSet) {
if (!con.deletePublicKeyEntry(domainName, serviceName, publicKey)) {
+ LOG.error("unable to delete public key from service {} in domain {}", serviceName, domainName);
return false;
}
}
@@ -1339,6 +1364,7 @@ boolean processServiceIdentity(ResourceContext ctx, ObjectStoreConnection con, S
for (String publicKey : newPublicKeysSet) {
if (!con.insertPublicKeyEntry(domainName, serviceName, publicKeysMap.get(publicKey))) {
+ LOG.error("unable to insert public key to service {} in domain {}", serviceName, domainName);
return false;
}
}
@@ -1346,6 +1372,7 @@ boolean processServiceIdentity(ResourceContext ctx, ObjectStoreConnection con, S
for (String publicKey : updatePublicKeysSet) {
if (!con.updatePublicKeyEntry(domainName, serviceName, updatePublicKeysMap.get(publicKey))) {
+ LOG.error("unable to update public key in service {} in domain {}", serviceName, domainName);
return false;
}
}
@@ -1374,6 +1401,7 @@ boolean processServiceIdentity(ResourceContext ctx, ObjectStoreConnection con, S
for (String host : delHosts) {
if (!con.deleteServiceHost(domainName, serviceName, host)) {
+ LOG.error("unable to delete host in service {} in domain {}", serviceName, domainName);
return false;
}
}
@@ -1381,6 +1409,7 @@ boolean processServiceIdentity(ResourceContext ctx, ObjectStoreConnection con, S
for (String host : newHosts) {
if (!con.insertServiceHost(domainName, serviceName, host)) {
+ LOG.error("unable to insert host to service {} in domain {}", serviceName, domainName);
return false;
}
}
@@ -1587,6 +1616,7 @@ boolean processPolicyCopyAssertions(ObjectStoreConnection con, Policy policy, fi
// insert assertion (and get new assertion id)
if (!con.insertAssertion(domainName, policyName, version, assertion)) {
+ LOG.error("unable to insert assertion to policy {} in domain {}", policyName, domainName);
return false;
}
@@ -1594,6 +1624,7 @@ boolean processPolicyCopyAssertions(ObjectStoreConnection con, Policy policy, fi
if (assertionConditions.getConditionsList() != null && !assertionConditions.getConditionsList().isEmpty()) {
if (!con.insertAssertionConditions(assertion.getId(), assertionConditions)) {
+ LOG.error("unable to insert assertion conditions to policy {} in domain {}", policyName, domainName);
return false;
}
}
@@ -3255,8 +3286,7 @@ void executeDeleteUser(ResourceContext ctx, String userName, String domainName,
// left behind will be cleaned up from this operation
if (!con.deletePrincipal(userName, true)) {
- throw ZMSUtils.notFoundError(caller + ": unable to delete user: "
- + userName, caller);
+ throw ZMSUtils.notFoundError(caller + ": unable to delete user: " + userName, caller);
}
// automatically update any domain contact record where this user is referenced
@@ -4539,6 +4569,8 @@ boolean processDomainContacts(ObjectStoreConnection con, final String domainName
for (Map.Entry entry : updatedContacts.entrySet()) {
if (!StringUtil.isEmpty(entry.getValue())) {
if (!con.insertDomainContact(domainName, entry.getKey(), entry.getValue())) {
+ LOG.error("unable to insert contact {}/{} in domain {}",
+ entry.getKey(), entry.getValue(), domainName);
return false;
}
}
@@ -4552,6 +4584,7 @@ boolean processDomainContacts(ObjectStoreConnection con, final String domainName
if (updatedContacts.isEmpty()) {
for (String contact : originalContacts.keySet()) {
if (!con.deleteDomainContact(domainName, contact)) {
+ LOG.error("unable to delete contact type {} in domain {}", contact, domainName);
return false;
}
}
@@ -4568,10 +4601,12 @@ boolean processDomainContacts(ObjectStoreConnection con, final String domainName
if (!originalContacts.get(type).equals(name)) {
if (StringUtil.isEmpty(name)) {
if (!con.deleteDomainContact(domainName, type)) {
+ LOG.error("unable to delete contact {} in domain {}", type, domainName);
return false;
}
} else {
if (!con.updateDomainContact(domainName, type, name)) {
+ LOG.error("unable to update contact {}/{} in domain {}", type, name, domainName);
return false;
}
}
@@ -4579,6 +4614,7 @@ boolean processDomainContacts(ObjectStoreConnection con, final String domainName
} else {
if (!StringUtil.isEmpty(entry.getValue())) {
if (!con.insertDomainContact(domainName, type, name)) {
+ LOG.error("unable to insert contact {}/{} in domain {}", type, name, domainName);
return false;
}
}
@@ -4591,6 +4627,7 @@ boolean processDomainContacts(ObjectStoreConnection con, final String domainName
for (String type : originalContacts.keySet()) {
if (!updatedContacts.containsKey(type)) {
if (!con.deleteDomainContact(domainName, type)) {
+ LOG.error("unable to delete contact type {} in domain {}", type, domainName);
return false;
}
}
@@ -7697,11 +7734,12 @@ private boolean insertRoleMembers(ResourceContext ctx, ObjectStoreConnection con
roleMember.setPendingState(roleMember.getApproved() == Boolean.FALSE ? ZMSConsts.PENDING_REQUEST_ADD_STATE : null);
roleMember.setRequestPrincipal(principal);
if (!con.insertRoleMember(domainName, roleName, roleMember, principal, auditRef)) {
- LOG.error("unable to update member {}", roleMember.getMemberName());
+ LOG.error("unable to update member {} in domain {}", roleMember.getMemberName(), domainName);
continue;
}
} catch (Exception ex) {
- LOG.error("unable to update member {} error: {}", roleMember.getMemberName(), ex.getMessage());
+ LOG.error("unable to update member {} in domain {}, error: {}", roleMember.getMemberName(),
+ domainName, ex.getMessage());
continue;
}
@@ -7729,11 +7767,12 @@ boolean insertGroupMembers(ResourceContext ctx, ObjectStoreConnection con, List<
for (GroupMember groupMember : groupMembers) {
try {
if (!con.insertGroupMember(domainName, groupName, groupMember, principal, auditRef)) {
- LOG.error("unable to update group member {}", groupMember.getMemberName());
+ LOG.error("unable to update group member {} in domain {}", groupMember.getMemberName(), domainName);
continue;
}
} catch (Exception ex) {
- LOG.error("unable to update member {} error: {}", groupMember.getMemberName(), ex.getMessage());
+ LOG.error("unable to update member {} in domain {}, error: {}", groupMember.getMemberName(),
+ domainName, ex.getMessage());
continue;
}
@@ -7762,11 +7801,12 @@ boolean updateRoleMemberDisabledState(ResourceContext ctx, ObjectStoreConnection
try {
if (!con.updateRoleMemberDisabledState(domainName, roleName, roleMember.getMemberName(), principal,
roleMember.getSystemDisabled(), auditRef)) {
- LOG.error("unable to update member {}", roleMember.getMemberName());
+ LOG.error("unable to update member {} in domain {}", roleMember.getMemberName(), domainName);
continue;
}
} catch (Exception ex) {
- LOG.error("unable to update member {} error: {}", roleMember.getMemberName(), ex.getMessage());
+ LOG.error("unable to update member {} in domain {}, error: {}", roleMember.getMemberName(),
+ domainName, ex.getMessage());
continue;
}
@@ -7795,11 +7835,12 @@ boolean updateGroupMemberDisabledState(ResourceContext ctx, ObjectStoreConnectio
try {
if (!con.updateGroupMemberDisabledState(domainName, groupName, groupMember.getMemberName(), principal,
groupMember.getSystemDisabled(), auditRef)) {
- LOG.error("unable to update group member {}", groupMember.getMemberName());
+ LOG.error("unable to update group member {} in domain {}", groupMember.getMemberName(), domainName);
continue;
}
} catch (Exception ex) {
- LOG.error("unable to update group member {} error: {}", groupMember.getMemberName(), ex.getMessage());
+ LOG.error("unable to update group member {} in domain {}, error: {}", groupMember.getMemberName(),
+ domainName, ex.getMessage());
continue;
}
@@ -9220,7 +9261,8 @@ void executePutAssertionConditions(ResourceContext ctx, String domainName, Strin
// process our insert assertion condition.
if (!con.insertAssertionConditions(assertionId, assertionConditions)) {
- throw ZMSUtils.requestError(String.format("%s: unable to insert assertion conditions for policy=%s assertionId=%d", caller, policyName, assertionId), caller);
+ throw ZMSUtils.requestError(String.format("%s: unable to insert assertion conditions for policy=%s assertionId=%d",
+ caller, policyName, assertionId), caller);
}
// update our policy and domain time-stamps, and invalidate local cache entry
@@ -9573,6 +9615,7 @@ private boolean processDomainDependency(ObjectStoreConnection con, String domain
// if we didn't insert a dependency then we need to return failure
if (!con.insertDomainDependency(domainName, service)) {
+ LOG.error("unable to insert dependency {} in domain {}", service, domainName);
return false;
}
@@ -9592,6 +9635,7 @@ private boolean processDeleteDomainDependency(ObjectStoreConnection con, String
// if we didn't delete the dependency then we need to return failure
if (!con.deleteDomainDependency(domainName, service)) {
+ LOG.error("unable to delete dependency {} in domain {}", service, domainName);
return false;
}
diff --git a/servers/zms/src/test/java/com/yahoo/athenz/zms/DBServiceTest.java b/servers/zms/src/test/java/com/yahoo/athenz/zms/DBServiceTest.java
index e9208236a9e..319a3eb1139 100644
--- a/servers/zms/src/test/java/com/yahoo/athenz/zms/DBServiceTest.java
+++ b/servers/zms/src/test/java/com/yahoo/athenz/zms/DBServiceTest.java
@@ -6370,6 +6370,30 @@ public void testProcessRoleUpdate() throws ServerResourceException {
assertFalse(role4.getSelfServe());
}
+ @Test
+ public void testProcessRoleInsertRoleMemberFailure() throws ServerResourceException {
+ ObjectStoreConnection conn = Mockito.mock(ObjectStoreConnection.class);
+
+ // Create a role with role members
+ List roleMembers = new ArrayList<>();
+ roleMembers.add(new RoleMember().setMemberName("user.member1"));
+ Role role = new Role().setName("newRole").setRoleMembers(roleMembers);
+
+ // Mock insertRole to return true (so we pass the first check)
+ Mockito.when(conn.insertRole(anyString(), any(Role.class))).thenReturn(true);
+
+ // Mock insertRoleMember to return false (to trigger failure)
+ Mockito.when(conn.insertRoleMember(anyString(), anyString(), any(RoleMember.class),
+ anyString(), anyString())).thenReturn(false);
+
+ StringBuilder auditDetails = new StringBuilder("testAudit");
+ boolean result = zms.dbService.processRole(conn, null, "testDomain", "newRole",
+ role, adminUser, null, auditRef, false, auditDetails);
+
+ // Assert that processRole returns false when insertRoleMember fails
+ assertFalse(result);
+ }
+
@Test
public void testUpdateRoleMetaFields() throws ServerResourceException {
final String caller = "testUpdateRoleMetaFields";
@@ -10782,6 +10806,28 @@ public void testUpdateGroupMemberDisabledStateFailure() throws ServerResourceExc
zms.dbService.store = saveStore;
}
+ @Test
+ public void testUpdateGroupMemberDisabledStateException() throws ServerResourceException {
+
+ final String domainName = "update-group-members-disabled-exception";
+ final String groupName = "group1";
+
+ Mockito.when(mockJdbcConn.updateGroupMemberDisabledState(anyString(), anyString(), anyString(), anyString(),
+ anyInt(), anyString())).thenThrow(new ServerResourceException(ServerResourceException.INTERNAL_SERVER_ERROR, "Database error"));
+
+ ObjectStore saveStore = zms.dbService.store;
+ zms.dbService.store = mockObjStore;
+
+ List groupMembers = new ArrayList<>();
+ groupMembers.add(new GroupMember().setMemberName("user.joe").setSystemDisabled(1));
+ groupMembers.add(new GroupMember().setMemberName("user.jane").setSystemDisabled(2));
+
+ assertFalse(zms.dbService.updateGroupMemberDisabledState(mockDomRsrcCtx, mockJdbcConn, groupMembers,
+ domainName, groupName, adminUser, auditRef, "unit-test"));
+
+ zms.dbService.store = saveStore;
+ }
+
@Test
public void testExecutePutGroupMembershipDecisionFailure() throws ServerResourceException {
@@ -11934,6 +11980,165 @@ public void testServiceSameTagKeyValues() throws ServerResourceException {
}
+ @Test
+ public void testProcessServiceIdentityInsertPublicKeyEntryFailure() throws ServerResourceException {
+ // Test case for insertPublicKeyEntry fails for new service
+ ObjectStoreConnection conn = Mockito.mock(ObjectStoreConnection.class);
+
+ PublicKeyEntry publicKey = new PublicKeyEntry().setId("key1").setKey("public-key-data");
+ List publicKeys = Collections.singletonList(publicKey);
+ ServiceIdentity service = new ServiceIdentity()
+ .setName("newService")
+ .setPublicKeys(publicKeys);
+
+ Mockito.when(conn.insertServiceIdentity("sys.auth", service)).thenReturn(true);
+ Mockito.when(conn.insertPublicKeyEntry("sys.auth", "newService", publicKey)).thenReturn(false);
+
+ StringBuilder auditDetails = new StringBuilder("testAudit");
+ boolean success = zms.dbService.processServiceIdentity(null, conn, null, "sys.auth", "newService",
+ service, false, auditDetails);
+
+ assertFalse(success);
+ Mockito.verify(conn, times(1)).insertServiceIdentity("sys.auth", service);
+ Mockito.verify(conn, times(1)).insertPublicKeyEntry("sys.auth", "newService", publicKey);
+ }
+
+ @Test
+ public void testProcessServiceIdentityDeletePublicKeyEntryFailure() throws ServerResourceException {
+ // Test case for deletePublicKeyEntry fails for update service
+ ObjectStoreConnection conn = Mockito.mock(ObjectStoreConnection.class);
+
+ PublicKeyEntry originalPublicKey = new PublicKeyEntry().setId("key1").setKey("original-key-data");
+ List originalPublicKeys = Collections.singletonList(originalPublicKey);
+ ServiceIdentity originalService = new ServiceIdentity()
+ .setName("existingService")
+ .setPublicKeys(originalPublicKeys);
+
+ // New service without the public key (should trigger deletion)
+ ServiceIdentity service = new ServiceIdentity()
+ .setName("existingService")
+ .setPublicKeys(null);
+
+ Mockito.when(conn.updateServiceIdentity("sys.auth", service)).thenReturn(true);
+ Mockito.when(conn.deletePublicKeyEntry("sys.auth", "existingService", "key1")).thenReturn(false);
+
+ StringBuilder auditDetails = new StringBuilder("testAudit");
+ boolean success = zms.dbService.processServiceIdentity(null, conn, originalService, "sys.auth", "existingService",
+ service, false, auditDetails);
+
+ assertFalse(success);
+ Mockito.verify(conn, times(1)).updateServiceIdentity("sys.auth", service);
+ Mockito.verify(conn, times(1)).deletePublicKeyEntry("sys.auth", "existingService", "key1");
+ }
+
+ @Test
+ public void testProcessServiceIdentityUpdatePublicKeyEntryFailure() throws ServerResourceException {
+ // Test case for updatePublicKeyEntry fails for update service
+ ObjectStoreConnection conn = Mockito.mock(ObjectStoreConnection.class);
+
+ PublicKeyEntry originalPublicKey = new PublicKeyEntry().setId("key1").setKey("original-key-data");
+ List originalPublicKeys = Collections.singletonList(originalPublicKey);
+ ServiceIdentity originalService = new ServiceIdentity()
+ .setName("existingService")
+ .setPublicKeys(originalPublicKeys);
+
+ // Update service with same key id but different key value (should trigger update)
+ PublicKeyEntry updatedPublicKey = new PublicKeyEntry().setId("key1").setKey("updated-key-data");
+ List updatedPublicKeys = Collections.singletonList(updatedPublicKey);
+ ServiceIdentity service = new ServiceIdentity()
+ .setName("existingService")
+ .setPublicKeys(updatedPublicKeys);
+
+ Mockito.when(conn.updateServiceIdentity("sys.auth", service)).thenReturn(true);
+ Mockito.when(conn.updatePublicKeyEntry("sys.auth", "existingService", updatedPublicKey)).thenReturn(false);
+
+ StringBuilder auditDetails = new StringBuilder("testAudit");
+ boolean success = zms.dbService.processServiceIdentity(null, conn, originalService, "sys.auth", "existingService",
+ service, false, auditDetails);
+
+ assertFalse(success);
+ Mockito.verify(conn, times(1)).updateServiceIdentity("sys.auth", service);
+ Mockito.verify(conn, times(1)).updatePublicKeyEntry("sys.auth", "existingService", updatedPublicKey);
+ }
+
+ @Test
+ public void testProcessServiceIdentityDeleteServiceHostFailure() throws ServerResourceException {
+ // Test case for deleteServiceHost fails
+ ObjectStoreConnection conn = Mockito.mock(ObjectStoreConnection.class);
+
+ List originalHosts = Collections.singletonList("host1.example.com");
+ ServiceIdentity originalService = new ServiceIdentity()
+ .setName("existingService")
+ .setHosts(originalHosts);
+
+ // New service without the host (should trigger deletion)
+ ServiceIdentity service = new ServiceIdentity()
+ .setName("existingService")
+ .setHosts(null);
+
+ Mockito.when(conn.updateServiceIdentity("sys.auth", service)).thenReturn(true);
+ Mockito.when(conn.deleteServiceHost("sys.auth", "existingService", "host1.example.com")).thenReturn(false);
+
+ StringBuilder auditDetails = new StringBuilder("testAudit");
+ boolean success = zms.dbService.processServiceIdentity(null, conn, originalService, "sys.auth", "existingService",
+ service, false, auditDetails);
+
+ assertFalse(success);
+ Mockito.verify(conn, times(1)).updateServiceIdentity("sys.auth", service);
+ Mockito.verify(conn, times(1)).deleteServiceHost("sys.auth", "existingService", "host1.example.com");
+ }
+
+ @Test
+ public void testProcessServiceIdentityInsertServiceHostFailure() throws ServerResourceException {
+ // Test case for insertServiceHost fails
+ ObjectStoreConnection conn = Mockito.mock(ObjectStoreConnection.class);
+
+ ServiceIdentity originalService = new ServiceIdentity()
+ .setName("existingService")
+ .setHosts(null);
+
+ // New service with a new host (should trigger insertion)
+ List newHosts = Collections.singletonList("newhost.example.com");
+ ServiceIdentity service = new ServiceIdentity()
+ .setName("existingService")
+ .setHosts(newHosts);
+
+ Mockito.when(conn.updateServiceIdentity("sys.auth", service)).thenReturn(true);
+ Mockito.when(conn.insertServiceHost("sys.auth", "existingService", "newhost.example.com")).thenReturn(false);
+
+ StringBuilder auditDetails = new StringBuilder("testAudit");
+ boolean success = zms.dbService.processServiceIdentity(null, conn, originalService, "sys.auth", "existingService",
+ service, false, auditDetails);
+
+ assertFalse(success);
+ Mockito.verify(conn, times(1)).updateServiceIdentity("sys.auth", service);
+ Mockito.verify(conn, times(1)).insertServiceHost("sys.auth", "existingService", "newhost.example.com");
+ }
+
+ @Test
+ public void testProcessServiceIdentityProcessTagsFailure() throws ServerResourceException {
+ // Test case for processServiceIdentityTags fails
+ ObjectStoreConnection conn = Mockito.mock(ObjectStoreConnection.class);
+
+ Map serviceTags = Collections.singletonMap(
+ "tagKey", new TagValueList().setList(Collections.singletonList("tagVal"))
+ );
+ ServiceIdentity service = new ServiceIdentity()
+ .setName("newService")
+ .setTags(serviceTags);
+
+ Mockito.when(conn.insertServiceIdentity("sys.auth", service)).thenReturn(true);
+ Mockito.when(conn.insertServiceTags("newService", "sys.auth", serviceTags)).thenReturn(false);
+
+ StringBuilder auditDetails = new StringBuilder("testAudit");
+ boolean success = zms.dbService.processServiceIdentity(null, conn, null, "sys.auth", "newService",
+ service, false, auditDetails);
+
+ assertFalse(success);
+ Mockito.verify(conn, times(1)).insertServiceIdentity("sys.auth", service);
+ Mockito.verify(conn, times(1)).insertServiceTags("newService", "sys.auth", serviceTags);
+ }
+
@Test
public void testRoleSameTagKeyValues() throws ServerResourceException {
ObjectStoreConnection conn = Mockito.mock(ObjectStoreConnection.class);
@@ -13434,6 +13639,122 @@ public void testProcessPolicyAssertionConditionsConReturnFalse() throws ServerRe
}
+
+ @Test
+ public void testProcessPolicyDeleteAssertionReturnsFalse() throws ServerResourceException {
+ // Test case for deleteAssertion returns false
+ ObjectStoreConnection conn = Mockito.mock(ObjectStoreConnection.class);
+
+ // Create original policy with an assertion that will be deleted
+ Policy originalPolicy = new Policy().setName("testPolicy");
+ Assertion oldAssertion = new Assertion()
+ .setId(1L)
+ .setAction("testAction")
+ .setResource("sys.auth:testResource")
+ .setRole("sys.auth:role.testRole")
+ .setEffect(AssertionEffect.ALLOW);
+ originalPolicy.setAssertions(new LinkedList<>(Collections.singletonList(oldAssertion)));
+
+ // Create new policy without the old assertion (so it will be deleted)
+ Policy newPolicy = new Policy().setName("testPolicy");
+ newPolicy.setAssertions(new LinkedList<>());
+
+ // Mock updatePolicy to return true, but deleteAssertion to return false
+ Mockito.when(conn.updatePolicy("sys.auth", newPolicy)).thenReturn(true);
+ Mockito.when(conn.deleteAssertion("sys.auth", "testPolicy", null, 1L)).thenReturn(false);
+
+ StringBuilder auditDetails = new StringBuilder("testAudit");
+ boolean success = zms.dbService.processPolicy(conn, originalPolicy, "sys.auth", "testPolicy",
+ newPolicy, false, auditDetails);
+
+ assertFalse(success);
+ Mockito.verify(conn, Mockito.times(1)).deleteAssertion("sys.auth", "testPolicy", null, 1L);
+ }
+
+ @Test
+ public void testProcessPolicyInsertAssertionReturnsFalse() throws ServerResourceException {
+ // Test case for insertAssertion returns false
+ ObjectStoreConnection conn = Mockito.mock(ObjectStoreConnection.class);
+
+ // Create original policy with an assertion
+ Policy originalPolicy = new Policy().setName("testPolicy");
+ Assertion oldAssertion = new Assertion()
+ .setId(1L)
+ .setAction("oldAction")
+ .setResource("sys.auth:oldResource")
+ .setRole("sys.auth:role.oldRole")
+ .setEffect(AssertionEffect.ALLOW);
+ originalPolicy.setAssertions(new LinkedList<>(Collections.singletonList(oldAssertion)));
+
+ // Create new policy with a different assertion (so old one stays, new one is added)
+ Policy newPolicy = new Policy().setName("testPolicy");
+ Assertion newAssertion = new Assertion()
+ .setId(2L)
+ .setAction("newAction")
+ .setResource("sys.auth:newResource")
+ .setRole("sys.auth:role.newRole")
+ .setEffect(AssertionEffect.ALLOW);
+ newPolicy.setAssertions(new LinkedList<>(Collections.singletonList(newAssertion)));
+
+ // Mock updatePolicy to return true, deleteAssertion to return true (for old assertion),
+ // but insertAssertion to return false
+ Mockito.when(conn.updatePolicy("sys.auth", newPolicy)).thenReturn(true);
+ Mockito.when(conn.deleteAssertion("sys.auth", "testPolicy", null, 1L)).thenReturn(true);
+ Mockito.when(conn.insertAssertion("sys.auth", "testPolicy", null, newAssertion)).thenReturn(false);
+
+ StringBuilder auditDetails = new StringBuilder("testAudit");
+ boolean success = zms.dbService.processPolicy(conn, originalPolicy, "sys.auth", "testPolicy",
+ newPolicy, false, auditDetails);
+
+ assertFalse(success);
+ Mockito.verify(conn, Mockito.times(1)).insertAssertion("sys.auth", "testPolicy", null, newAssertion);
+ }
+
+ @Test
+ public void testProcessPolicyInsertAssertionConditionsReturnsFalse() throws ServerResourceException {
+ // Test case for insertAssertionConditions returns false
+ ObjectStoreConnection conn = Mockito.mock(ObjectStoreConnection.class);
+
+ // Create original policy with an assertion
+ Policy originalPolicy = new Policy().setName("testPolicy");
+ Assertion oldAssertion = new Assertion()
+ .setId(1L)
+ .setAction("oldAction")
+ .setResource("sys.auth:oldResource")
+ .setRole("sys.auth:role.oldRole")
+ .setEffect(AssertionEffect.ALLOW);
+ originalPolicy.setAssertions(new LinkedList<>(Collections.singletonList(oldAssertion)));
+
+ // Create new policy with a new assertion that has conditions
+ Policy newPolicy = new Policy().setName("testPolicy");
+ Assertion newAssertion = new Assertion()
+ .setId(2L)
+ .setAction("newAction")
+ .setResource("sys.auth:newResource")
+ .setRole("sys.auth:role.newRole")
+ .setEffect(AssertionEffect.ALLOW)
+ .setConditions(
+ new AssertionConditions()
+ .setConditionsList(List.of(createAssertionConditionObject(1, "test1", "test1")))
+ );
+ newPolicy.setAssertions(new LinkedList<>(Collections.singletonList(newAssertion)));
+
+ // Mock updatePolicy to return true, deleteAssertion to return true,
+ // insertAssertion to return true, but insertAssertionConditions to return false
+ Mockito.when(conn.updatePolicy("sys.auth", newPolicy)).thenReturn(true);
+ Mockito.when(conn.deleteAssertion("sys.auth", "testPolicy", null, 1L)).thenReturn(true);
+ Mockito.when(conn.insertAssertion("sys.auth", "testPolicy", null, newAssertion)).thenReturn(true);
+ Mockito.when(conn.insertAssertionConditions(2L, newAssertion.getConditions())).thenReturn(false);
+
+ StringBuilder auditDetails = new StringBuilder("testAudit");
+ boolean success = zms.dbService.processPolicy(conn, originalPolicy, "sys.auth", "testPolicy",
+ newPolicy, false, auditDetails);
+
+ assertFalse(success);
+ Mockito.verify(conn, Mockito.times(1)).insertAssertion("sys.auth", "testPolicy", null, newAssertion);
+ Mockito.verify(conn, Mockito.times(1)).insertAssertionConditions(2L, newAssertion.getConditions());
+ }
+
@Test
public void testProcessPolicyWithTagsInsert() throws ServerResourceException {
ObjectStoreConnection conn = Mockito.mock(ObjectStoreConnection.class);
@@ -13987,6 +14308,114 @@ public void testProcessUpdateRoleMembersDeleteRoleMembers() throws ServerResourc
roleName, "user.admin", false, null, null, auditRef, auditDetails));
}
+ @Test
+ public void testProcessUpdateGroupMembersInsertGroupMemberReturnsFalse() throws Exception {
+
+ final String domainName = "process-update-group-members-insert-fails";
+ final String groupName = "group1";
+
+ // Create original group with a member that will be deleted
+ List oldMembers = new ArrayList<>();
+ oldMembers.add(new GroupMember().setMemberName("user.joe").setActive(true).setApproved(true));
+ Group originalGroup = new Group().setName(groupName).setGroupMembers(oldMembers);
+
+ // New group with no members (member will be deleted)
+ List newMembers = new ArrayList<>();
+
+ ObjectStoreConnection conn = Mockito.mock(ObjectStoreConnection.class);
+ // Mock insertGroupMember to return false
+ Mockito.when(conn.insertGroupMember(eq(domainName), eq(groupName), any(GroupMember.class),
+ eq("user.admin"), eq(auditRef))).thenReturn(false);
+
+ StringBuilder auditDetails = new StringBuilder();
+ Set notifyMembers = new HashSet<>();
+
+ // Use reflection to access the private method
+ java.lang.reflect.Method method = DBService.class.getDeclaredMethod(
+ "processUpdateGroupMembers",
+ ObjectStoreConnection.class,
+ Group.class,
+ List.class,
+ boolean.class,
+ String.class,
+ String.class,
+ String.class,
+ boolean.class,
+ Boolean.class,
+ Set.class,
+ String.class,
+ StringBuilder.class
+ );
+ method.setAccessible(true);
+
+ // Test: pendingState=true, deleteProtection=Boolean.TRUE, ignoreDeletes=false
+ // This will trigger the code path where insertGroupMember is called for deleted members
+ boolean result = (boolean) method.invoke(zms.dbService, conn, originalGroup, newMembers, false,
+ domainName, groupName, "user.admin", true, Boolean.TRUE, notifyMembers, auditRef, auditDetails);
+
+ assertFalse(result, "processUpdateGroupMembers should return false when insertGroupMember returns false");
+
+ // Verify that insertGroupMember was called for the deleted member
+ Mockito.verify(conn, times(1)).insertGroupMember(eq(domainName), eq(groupName),
+ any(GroupMember.class), eq("user.admin"), eq(auditRef));
+ }
+
+ @Test
+ public void testProcessUpdateGroupMembersInsertGroupMemberReturnsTrue() throws Exception {
+
+ final String domainName = "process-update-group-members-insert-succeeds";
+ final String groupName = "group1";
+
+ // Create original group with a member that will be deleted
+ List oldMembers = new ArrayList<>();
+ oldMembers.add(new GroupMember().setMemberName("user.joe").setActive(true).setApproved(true));
+ Group originalGroup = new Group().setName(groupName).setGroupMembers(oldMembers);
+
+ // New group with no members (member will be deleted)
+ List newMembers = new ArrayList<>();
+
+ ObjectStoreConnection conn = Mockito.mock(ObjectStoreConnection.class);
+ // Mock insertGroupMember to return true
+ Mockito.when(conn.insertGroupMember(eq(domainName), eq(groupName), any(GroupMember.class),
+ eq("user.admin"), eq(auditRef))).thenReturn(true);
+
+ StringBuilder auditDetails = new StringBuilder();
+ Set notifyMembers = new HashSet<>();
+
+ // Use reflection to access the private method
+ java.lang.reflect.Method method = DBService.class.getDeclaredMethod(
+ "processUpdateGroupMembers",
+ ObjectStoreConnection.class,
+ Group.class,
+ List.class,
+ boolean.class,
+ String.class,
+ String.class,
+ String.class,
+ boolean.class,
+ Boolean.class,
+ Set.class,
+ String.class,
+ StringBuilder.class
+ );
+ method.setAccessible(true);
+
+ // Test: pendingState=true, deleteProtection=Boolean.TRUE, ignoreDeletes=false
+ // This will trigger the code path where insertGroupMember is called for deleted members
+ boolean result = (boolean) method.invoke(zms.dbService, conn, originalGroup, newMembers, false,
+ domainName, groupName, "user.admin", true, Boolean.TRUE, notifyMembers, auditRef, auditDetails);
+
+ assertTrue(result, "processUpdateGroupMembers should return true when insertGroupMember succeeds");
+
+ // Verify that insertGroupMember was called for the deleted member
+ Mockito.verify(conn, times(1)).insertGroupMember(eq(domainName), eq(groupName),
+ any(GroupMember.class), eq("user.admin"), eq(auditRef));
+
+ // Verify that the member was added to notifyMembers
+ assertTrue(notifyMembers.contains("user.joe"),
+ "Member should be added to notifyMembers when insertGroupMember succeeds");
+ }
+
@Test
public void testGetPendingRoleMember() throws ServerResourceException {