package org.apereo.cas.grouper.services;
import edu.internet2.middleware.grouperClient.ws.beans.WsGetGroupsResult;
import org.apereo.cas.grouper.GrouperFacade;
import org.apereo.cas.grouper.GrouperGroupField;
import org.apereo.cas.services.TimeBasedRegisteredServiceAccessStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* The {@link GrouperRegisteredServiceAccessStrategy} is an access strategy
* that consults a grouper instance to figure out affiliations associated
* with a user.
*
* @author Misagh Moayyed
* @since 4.2
*/
public class GrouperRegisteredServiceAccessStrategy extends TimeBasedRegisteredServiceAccessStrategy {
private static final long serialVersionUID = -3557247044344135788L;
private static final String GROUPER_GROUPS_ATTRIBUTE_NAME = "grouperAttributes";
private static final Logger LOGGER = LoggerFactory.getLogger(GrouperRegisteredServiceAccessStrategy.class);
private GrouperGroupField groupField = GrouperGroupField.NAME;
@Override
public boolean doPrincipalAttributesAllowServiceAccess(final String principal, final Map<String, Object> principalAttributes) {
final Map<String, Object> allAttributes = new HashMap<>(principalAttributes);
final List<String> grouperGroups = new ArrayList<>();
final List<WsGetGroupsResult> results = GrouperFacade.getGroupsForSubjectId(principal);
if (results.isEmpty()) {
LOGGER.warn("Subject id [{}] could not be located. Access denied", principal);
return false;
}
final boolean denied = results.stream().anyMatch(groupsResult -> {
if (groupsResult.getWsGroups() == null || groupsResult.getWsGroups().length == 0) {
LOGGER.warn("No groups could be found for subject [{}]. Access denied", groupsResult.getWsSubject().getName());
return true;
}
Arrays.stream(groupsResult.getWsGroups()).forEach(group -> grouperGroups.add(GrouperFacade.getGrouperGroupAttribute(this.groupField, group)));
return false;
});
if (denied) {
return false;
}
LOGGER.debug("Adding [{}] under attribute name [{}] to collection of CAS attributes", grouperGroups, GROUPER_GROUPS_ATTRIBUTE_NAME);
allAttributes.put(GROUPER_GROUPS_ATTRIBUTE_NAME, grouperGroups);
return super.doPrincipalAttributesAllowServiceAccess(principal, allAttributes);
}
public void setGroupField(final GrouperGroupField groupField) {
this.groupField = groupField;
}
public GrouperGroupField getGroupField() {
return this.groupField;
}
}