001package com.identityworksllc.iiq.common.moveleave;
002
003import com.identityworksllc.iiq.common.IdentityLinkUtil;
004import com.identityworksllc.iiq.common.LinkRef;
005import sailpoint.api.SailPointContext;
006import sailpoint.object.*;
007import sailpoint.tools.GeneralException;
008
009import java.util.ArrayList;
010import java.util.List;
011import java.util.Set;
012
013/**
014 * A helper for Leaver triggers that can find accounts from a set of applications
015 * that are not associated with any role assignments.
016 */
017public class AccountsWithoutRoles {
018    /**
019     * The set of application names to check against.
020     */
021    private final Set<String> applicationNames;
022
023    /**
024     * The SailPointContext to use for the operations.
025     */
026    private final SailPointContext context;
027
028    /**
029     * Constructor for AccountsWithoutRoles.
030     *
031     * @param context The SailPointContext to use for the operations.
032     * @param applicationNames A set of application names to check against.
033     */
034    public AccountsWithoutRoles(SailPointContext context, Set<String> applicationNames) {
035        this.context = context;
036        this.applicationNames = applicationNames;
037    }
038
039    /**
040     * Get a list of accounts that are not associated with any role assignments for the target identity.
041     *
042     * @param target The target identity to check against.
043     * @return A list of {@link LinkRef} objects representing accounts without roles.
044     * @throws GeneralException If an error occurs while retrieving the accounts.
045     */
046    public List<LinkRef> getAccountsWithoutRoles(Identity target) throws GeneralException {
047        List<LinkRef> accountsWithoutRoles = new ArrayList<>();
048
049        IdentityLinkUtil ilu = new IdentityLinkUtil(context, target);
050
051        for(String applicationName : applicationNames) {
052            List<Link> links = ilu.getLinksByApplication(applicationName);
053
054            for(Link link : links) {
055                boolean matchExists = linkAssociatedWithRole(target, link);
056
057                if (!matchExists) {
058                    accountsWithoutRoles.add(new LinkRef(link.getApplicationName(), link.getNativeIdentity()));
059                }
060            }
061        }
062
063        return accountsWithoutRoles;
064    }
065
066    /**
067     * Check if the link is associated with any role assignments for the target identity.
068     *
069     * @param target The target identity to check against.
070     * @param link The link to check.
071     * @return true if the link is associated with a role assignment, false otherwise.
072     */
073    private static boolean linkAssociatedWithRole(Identity target, Link link) {
074        boolean matchExists = false;
075
076        for (RoleAssignment ra : target.getRoleAssignments()) {
077            for (RoleTarget rt : ra.getTargets()) {
078                if (rt.getApplicationName().equals(link.getApplicationName())) {
079                    if (rt.getNativeIdentity() == null || rt.getNativeIdentity().equals(link.getNativeIdentity())) {
080                        matchExists = true;
081                        break;
082                    }
083                }
084            }
085        }
086        return matchExists;
087    }
088}