package org.apereo.cas.aup;

import org.apache.commons.lang3.tuple.Pair;
import org.apereo.cas.authentication.Credential;
import org.apereo.cas.authentication.principal.Principal;
import org.apereo.cas.ticket.registry.TicketRegistrySupport;
import org.apereo.cas.web.support.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.webflow.execution.RequestContext;

import java.util.Map;

/**
 * This is {@link AbstractPrincipalAttributeAcceptableUsagePolicyRepository}.
 *
 * @author Misagh Moayyed
 * @since 4.2.0
 */
public abstract class AbstractPrincipalAttributeAcceptableUsagePolicyRepository implements AcceptableUsagePolicyRepository {
    private static final long serialVersionUID = 1883808902502739L;

    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractPrincipalAttributeAcceptableUsagePolicyRepository.class);

    /**
     * Single-valued attribute in LDAP that describes whether the policy
     * has been accepted. Its value must match either TRUE/FALSE.
     */
    protected final String aupAttributeName;

    /**
     * Ticket registry support.
     */
    protected final TicketRegistrySupport ticketRegistrySupport;

    public AbstractPrincipalAttributeAcceptableUsagePolicyRepository(final TicketRegistrySupport ticketRegistrySupport,
                                                                     final String aupAttributeName) {
        this.ticketRegistrySupport = ticketRegistrySupport;
        this.aupAttributeName = aupAttributeName;
    }

    @Override
    public Pair<Boolean, Principal> verify(final RequestContext requestContext, final Credential credential) {
        final Principal principal = WebUtils.getPrincipalFromRequestContext(requestContext, this.ticketRegistrySupport);
        final Map<String, Object> attributes = principal.getAttributes();
        LOGGER.debug("Principal attributes found for [{}] are [{}]", principal.getId(), attributes);

        if (attributes != null && attributes.containsKey(this.aupAttributeName)) {
            final Object value = attributes.get(this.aupAttributeName);
            LOGGER.debug("Evaluating attribute value [{}] found for [{}]", value, this.aupAttributeName);
            if (value.toString().equalsIgnoreCase(Boolean.TRUE.toString())) {
                return Pair.of(Boolean.TRUE, principal);
            }
        }

        LOGGER.warn("Usage policy has not been accepted by [{}]", principal.getId());
        return Pair.of(Boolean.FALSE, principal);
    }
}

@@ -234,16 +234,60 @@
 upport;%0A
+import org.apereo.cas.util.CollectionUtils;%0A
 import o
@@ -462,16 +462,38 @@
 til.Map;
+%0Aimport java.util.Set;
 %0A%0A/**%0A *
@@ -1842,16 +1842,766 @@
 upport);
+%0A%0A        if (isUsagePolicyAcceptedBy(principal)) %7B%0A            LOGGER.debug(%22Usage policy has been accepted by %5B%7B%7D%5D%22, principal.getId());%0A            return Pair.of(Boolean.TRUE, principal);%0A        %7D%0A%0A        LOGGER.warn(%22Usage policy has not been accepted by %5B%7B%7D%5D%22, principal.getId());%0A        return Pair.of(Boolean.FALSE, principal);%0A    %7D%0A%0A    /**%0A     * Is usage policy accepted by user?%0A     * Looks into the attributes collected by the principal to find %7B@link #aupAttributeName%7D.%0A     * If the attribute contains %7B@code true%7D, then the policy is determined as accepted.%0A     * @param principal the principal%0A     * @return true if accepted, false otherwise.%0A     */%0A    protected boolean isUsagePolicyAcceptedBy(final Principal principal) %7B
 %0A       
@@ -2870,21 +2870,18 @@
   final 
-Objec
+Se
 t value 
@@ -2882,16 +2882,45 @@
 value = 
+CollectionUtils.toCollection(
 attribut
@@ -2940,32 +2940,33 @@
 upAttributeName)
+)
 ;%0A            LO
@@ -3073,17 +3073,45 @@
     
-if (value
+return value.stream().anyMatch(v -%3E v
 .toS
@@ -3164,227 +3164,40 @@
 ()))
- %7B%0A                return Pair.of(Boolean.TRUE, principal);%0A            %7D%0A        %7D%0A%0A        LOGGER.warn(%22Usage policy has not been accepted by %5B%7B%7D%5D%22, principal.getId());%0A        return Pair.of(Boolean.FALSE, principal)
+;%0A        %7D%0A        return false
 ;%0A  

update javadocs