DBService implements RolesProvider { void executePutRoleReview(ResourceContext ctx, String domainName, String roleName, Role role, String auditRef, String caller) { for (int retryCount = defaultRetryCount; ; retryCount--) { try (ObjectStoreConnection con = store.getConnection(false, true)) { final String principal = getPrincipalName(ctx); checkDomainAuditEnabled(con, domainName, auditRef, caller, principal, AUDIT_TYPE_ROLE); Role originalRole = getRole(con, domainName, roleName, false, false, false); if (originalRole.getTrust() != null && !originalRole.getTrust().isEmpty()) { throw ZMSUtils.requestError(caller + ": role " + roleName + " is delegated. Review should happen on the trusted role. ", caller); } Role updatedRole = new Role() .setName(originalRole.getName()); List<RoleMember> noactionMembers = applyMembershipChanges(updatedRole, originalRole, role, auditRef); StringBuilder auditDetails = new StringBuilder(ZMSConsts.STRING_BLDR_SIZE_DEFAULT); List<RoleMember> deletedMembers = new ArrayList<>(); List<RoleMember> extendedMembers = new ArrayList<>(); auditDetails.append("{\"name\": \"").append(roleName).append('\"') .append(", \"selfServe\": ").append(auditLogBooleanDefault(originalRole.getSelfServe(), Boolean.TRUE)) .append(", \"auditEnabled\": ").append(auditLogBooleanDefault(originalRole.getAuditEnabled(), Boolean.TRUE)); for (RoleMember member : updatedRole.getRoleMembers()) { if (member.getActive() == Boolean.FALSE) { if (!con.deleteRoleMember(domainName, roleName, member.getMemberName(), principal, auditRef)) { con.rollbackChanges(); throw ZMSUtils.notFoundError(caller + ": unable to delete role member: " + member.getMemberName() + " from role: " + roleName, caller); } deletedMembers.add(member); } else { if (!con.insertRoleMember(domainName, roleName, member, principal, auditRef)) { con.rollbackChanges(); throw ZMSUtils.notFoundError(caller + ": unable to extend role member: " + member.getMemberName() + " for the role: " + roleName, caller); } extendedMembers.add(member); } } auditLogRoleMembers(auditDetails, "deleted-members", deletedMembers); auditLogRoleMembers(auditDetails, "extended-members", extendedMembers); auditLogRoleMembers(auditDetails, "no-action-members", noactionMembers); auditDetails.append("}"); if (!deletedMembers.isEmpty() || !extendedMembers.isEmpty()) { con.updateRoleModTimestamp(domainName, roleName); } con.updateRoleReviewTimestamp(domainName, roleName); saveChanges(con, domainName); auditLogRequest(ctx, domainName, auditRef, caller, "REVIEW", roleName, auditDetails.toString()); return; } catch (ResourceException ex) { if (!shouldRetryOperation(ex, retryCount)) { throw ex; } } } } DBService(ObjectStore store, AuditLogger auditLogger, ZMSConfig zmsConfig, AuditReferenceValidator auditReferenceValidator); DomainRoleMembers listOverdueReviewRoleMembers(String domainName); @Override List<Role> getRolesByDomain(String domain); ResourceAccessList getResourceAccessList(String principal, String action); AthenzDomain getAthenzDomain(final String domainName, boolean masterCopy); Quota getQuota(String domainName); void executePutRoleSystemMeta(ResourceContext ctx, final String domainName, final String roleName,
           RoleSystemMeta meta, final String attribute, final String auditRef, final String caller); void executePutGroupSystemMeta(ResourceContext ctx, final String domainName, final String groupName,
                                          GroupSystemMeta meta, final String attribute, final String auditRef); void executePutServiceIdentitySystemMeta(ResourceContext ctx, String domainName, String serviceName,
            ServiceIdentitySystemMeta meta, String attribute, String auditRef, String caller); void executePutRoleMeta(ResourceContext ctx, String domainName, String roleName, Role originalRole,
                                   RoleMeta meta, String auditRef, String caller); void executePutGroupMeta(ResourceContext ctx, final String domainName, final String groupName,
                                    GroupMeta meta, final String auditRef); Set<String> getPendingMembershipApproverRoles(int delayDays); Set<String> getPendingGroupMembershipApproverRoles(int delayDays); Map<String, DomainRoleMember> getRoleExpiryMembers(int delayDays); Map<String, DomainRoleMember> getRoleReviewMembers(int delayDays); Map<String, DomainGroupMember> getGroupExpiryMembers(int delayDays); void processExpiredPendingMembers(int pendingRoleMemberLifespan, final String monitorIdentity); void processExpiredPendingGroupMembers(int pendingGroupMemberLifespan, final String monitorIdentity); static int AUDIT_TYPE_ROLE; static int AUDIT_TYPE_POLICY; static int AUDIT_TYPE_SERVICE; static int AUDIT_TYPE_DOMAIN; static int AUDIT_TYPE_ENTITY; static int AUDIT_TYPE_TENANCY; static int AUDIT_TYPE_TEMPLATE; static int AUDIT_TYPE_GROUP; }
@Test public void testExecutePutRoleReview() { final String domainName = "role-review"; List<String> admins = new ArrayList<>(); admins.add(adminUser); Timestamp thirtyDayExpiry = Timestamp.fromMillis(System.currentTimeMillis() + TimeUnit.MILLISECONDS.convert(30, TimeUnit.DAYS) + TimeUnit.MILLISECONDS.convert(1, TimeUnit.HOURS)); zms.dbService.makeDomain(mockDomRsrcCtx, ZMSTestUtils.makeDomainObject(domainName, "test desc", "org", false, "", 1234, "", 0), admins, null, auditRef); Role role1 = createRoleObject(domainName, "role1", null, "user.john", "user.jane"); Timestamp timExpiry = Timestamp.fromMillis(System.currentTimeMillis() + TimeUnit.MILLISECONDS.convert(10, TimeUnit.DAYS)); role1.getRoleMembers().add(new RoleMember().setMemberName("user.tim").setExpiration(timExpiry).setApproved(true).setActive(true)); zms.dbService.executePutRole(mockDomRsrcCtx, domainName, "role1", role1, "test", "putrole"); Role incomingRole = new Role().setName("role1"); List<RoleMember> incomingMembers = new ArrayList<>(); incomingMembers.add(new RoleMember().setMemberName("user.john").setActive(false).setExpiration(thirtyDayExpiry)); incomingMembers.add(new RoleMember().setMemberName("user.jane").setActive(true).setExpiration(thirtyDayExpiry)); incomingRole.setRoleMembers(incomingMembers); zms.dbService.executePutRoleReview(mockDomRsrcCtx, domainName, "role1", incomingRole, "review test", "putRoleReview"); Role resRole = zms.dbService.getRole(domainName, "role1", false, false, false); assertEquals(resRole.getRoleMembers().size(), 2); int membersChecked = 0; for (RoleMember roleMember : resRole.getRoleMembers()) { switch (roleMember.getMemberName()) { case "user.jane": assertEquals(roleMember.getExpiration(), thirtyDayExpiry); assertTrue(roleMember.getApproved()); membersChecked += 1; break; case "user.tim": assertEquals(roleMember.getExpiration(), timExpiry); membersChecked += 1; break; } } assertEquals(membersChecked, 2); zms.dbService.executeDeleteDomain(mockDomRsrcCtx, domainName, auditRef, "deletedomain"); }