package org.apereo.cas.authorization;

import org.ldaptive.ConnectionFactory;
import org.ldaptive.LdapAttribute;
import org.ldaptive.LdapEntry;
import org.ldaptive.SearchExecutor;
import org.pac4j.core.authorization.generator.AuthorizationGenerator;
import org.pac4j.core.profile.CommonProfile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Provides a simple {@link AuthorizationGenerator} implementation that obtains user roles from an LDAP search.
 * Searches are performed by this component for every user details lookup:
 * <ol>
 * <li>Search for an entry to resolve the username. In most cases the search should return exactly one result,
 * but the {@link #allowMultipleResults} property may be toggled to change that behavior.</li>
 * </ol>
 *
 * @author Jerome Leleu
 * @author Marvin S. Addison
 * @author Misagh Moayyed
 * @since 4.0.0
 */
public class LdapUserAttributesToRolesAuthorizationGenerator extends BaseUseAttributesAuthorizationGenerator {

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

    private final String roleAttribute;
    private final String rolePrefix;

    /**
     * Creates a new instance with the given required parameters.
     *
     * @param factory              Source of LDAP connections for searches.
     * @param userSearchExecutor   Executes the LDAP search for user data.
     * @param allowMultipleResults allow multiple search results in which case the first result
     *                             returned is used to construct user details, or false to indicate that
     *                             a runtime exception should be raised on multiple search results for user details.
     * @param roleAttribute        the role attribute
     * @param rolePrefix           the role prefix
     */
    public LdapUserAttributesToRolesAuthorizationGenerator(final ConnectionFactory factory,
                                                           final SearchExecutor userSearchExecutor,
                                                           final boolean allowMultipleResults,
                                                           final String roleAttribute,
                                                           final String rolePrefix) {
        super(factory, userSearchExecutor, allowMultipleResults);
        this.roleAttribute = roleAttribute;
        this.rolePrefix = rolePrefix;
    }

    @Override
    protected CommonProfile generateAuthorizationForLdapEntry(final CommonProfile profile, final LdapEntry userEntry) {
        if (userEntry.getAttributes().isEmpty()) {
            throw new IllegalStateException("No attributes are retrieved for this user.");
        }

        final LdapAttribute attribute = userEntry.getAttribute(this.roleAttribute);
        if (attribute == null) {
            throw new IllegalStateException("Configured role attribute cannot be found for this user");
        }

        addProfileRoles(userEntry, profile, attribute, this.rolePrefix);
        return profile;
    }
}

@@ -2598,16 +2598,17 @@
     if (
+!
 userEntr
@@ -2646,106 +2646,8 @@
     
-        throw new IllegalStateException(%22No attributes are retrieved for this user.%22);%0A        %7D%0A%0A
     
@@ -2730,24 +2730,28 @@
 e);%0A        
+    
 if (attribut
@@ -2752,17 +2752,17 @@
 tribute 
-=
+!
 = null) 
@@ -2779,38 +2779,124 @@
     
+ 
-throw new IllegalStateExceptio
+   addProfileRoles(userEntry, profile, attribute, this.rolePrefix);%0A            %7D else %7B%0A                LOGGER.war
 n(%22C
@@ -2957,26 +2957,29 @@
 %22);%0A        
+    
 %7D
-%0A
 %0A        add
@@ -2979,72 +2979,97 @@
     
-addProfileRoles(userEntry, profile, attribute, this.rolePrefix);
+%7D else %7B%0A            LOGGER.warn(%22No attributes are retrieved for this user.%22);%0A        %7D
 %0A   

Replace IllegalStateException with log messages. (#2776)