package org.pac4j.springframework.security.util;

import org.pac4j.core.authorization.authorizer.Authorizer;
import org.pac4j.core.authorization.authorizer.IsFullyAuthenticatedAuthorizer;
import org.pac4j.core.authorization.authorizer.IsRememberedAuthorizer;
import org.pac4j.core.exception.TechnicalException;
import org.pac4j.core.exception.http.HttpAction;
import org.pac4j.core.profile.ProfileHelper;
import org.pac4j.core.profile.UserProfile;
import org.pac4j.springframework.security.authentication.Pac4jAuthenticationToken;
import org.pac4j.springframework.security.authentication.Pac4jRememberMeAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;

/**
 * Helper for Spring Security.
 *
 * @author Jerome Leleu
 * @since 2.0.0
 */
public final class SpringSecurityHelper {

    private final static Authorizer IS_REMEMBERED_AUTHORIZER = new IsRememberedAuthorizer();

    private final static Authorizer IS_FULLY_AUTHENTICATED_AUTHORIZER = new IsFullyAuthenticatedAuthorizer();

    /**
     * Build a list of authorities from a list of profiles.
     *
     * @param profiles a map of profiles
     * @return a list of authorities
     */
    public static List<GrantedAuthority> buildAuthorities(final List<UserProfile> profiles) {
        final List<GrantedAuthority> authorities = new ArrayList<>();
        for (final UserProfile profile : profiles) {
            final Set<String> roles = profile.getRoles();
            for (final String role : roles) {
                authorities.add(new SimpleGrantedAuthority(role));
            }
        }
        return authorities;
    }

    /**
     * Populate the authenticated user profiles in the Spring Security context.
     *
     * @param profiles the linked hashmap of profiles
     */
    public static void populateAuthentication(final LinkedHashMap<String, UserProfile> profiles) {
        if (profiles != null && profiles.size() > 0) {
            final List<UserProfile> listProfiles = ProfileHelper.flatIntoAProfileList(profiles);
            try {
                if (IS_FULLY_AUTHENTICATED_AUTHORIZER.isAuthorized(null, null, listProfiles)) {
                    SecurityContextHolder.getContext().setAuthentication(new Pac4jAuthenticationToken(listProfiles));
                } else if (IS_REMEMBERED_AUTHORIZER.isAuthorized(null, null, listProfiles)) {
                    SecurityContextHolder.getContext().setAuthentication(new Pac4jRememberMeAuthenticationToken(listProfiles));
                }
            } catch (final HttpAction e) {
                throw new TechnicalException(e);
            }
        }
    }
}

@@ -609,32 +609,89 @@
 nticationToken;%0A
+import org.springframework.security.core.Authentication;%0A
 import org.sprin
@@ -902,94 +902,9 @@
 til.
-ArrayList;%0Aimport java.util.LinkedHashMap;%0Aimport java.util.List;%0Aimport java.util.Set
+*
 ;%0A%0A/
@@ -1859,79 +1859,74 @@
   * 
-Popula
+Compu
 te the 
-authenticated user profiles in the Spring Security context
+Spring Security authentication from the pac4j profiles
 .%0A  
@@ -1994,39 +1994,117 @@
    *
-/%0A    public static void popula
+ @return the optional Spring Security authentication%0A     */%0A    public static Optional%3CAuthentication%3E compu
 teAu
@@ -2325,30 +2325,8 @@
 s);%0A
-            try %7B%0A    
     
@@ -2433,64 +2433,26 @@
     
-    SecurityContextHolder.getContext().setAuthentication
+return Optional.of
 (new
@@ -2485,36 +2485,32 @@
 listProfiles));%0A
-    
             %7D el
@@ -2603,137 +2603,642 @@
     
-    SecurityContextHolder.getContext().setAuthentication(new Pac4jRememberMeAuthenticationToken(listProfiles));%0A                %7D
+return Optional.of(new Pac4jRememberMeAuthenticationToken(listProfiles));%0A            %7D%0A        %7D%0A        return Optional.empty();%0A    %7D%0A%0A    /**%0A     * Populate the authenticated user profiles in the Spring Security context.%0A     *%0A     * @param profiles the linked hashmap of profiles%0A     */%0A    public static void populateAuthentication(final LinkedHashMap%3CString, UserProfile%3E profiles) %7B%0A        final Optional%3CAuthentication%3E authentication = computeAuthentication(profiles);%0A        if (authentication.isPresent()) %7B%0A            try %7B%0A                SecurityContextHolder.getContext().setAuthentication(authentication.get());
 %0A   

refactor SpringSecurityHelper