package com.cgi.eoss.ftep.api.security.dev;

import com.cgi.eoss.ftep.api.security.FtepUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
import org.springframework.security.acls.AclPermissionEvaluator;
import org.springframework.security.acls.model.AclService;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configuration.EnableGlobalAuthentication;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.access.ExceptionTranslationFilter;
import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider;
import org.springframework.security.web.authentication.preauth.RequestAttributeAuthenticationFilter;

@Configuration
@ConditionalOnProperty(value = "ftep.api.security.mode", havingValue = "DEVELOPMENT_BECOME_ANY_USER")
@EnableWebSecurity
@EnableGlobalAuthentication
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class ApiSecurityDevConfig {

    @Bean
    public WebSecurityConfigurerAdapter webSecurityConfigurerAdapter(
            @Value("${ftep.api.security.username-request-attribute:REMOTE_USER}") String usernameRequestAttribute) {
        return new WebSecurityConfigurerAdapter() {
            @Override
            protected void configure(HttpSecurity httpSecurity) throws Exception {
                // Maps a session attribute to a request attribute, allowing us to choose a user id per session
                SessionUserAttributeInjectorFilter sessionUserAttributeInjector = new SessionUserAttributeInjectorFilter(usernameRequestAttribute);

                // Retrieve the "sso" user from the request attributes (not from headers, as in SSO mode)
                RequestAttributeAuthenticationFilter filter = new RequestAttributeAuthenticationFilter();
                filter.setAuthenticationManager(authenticationManager());
                filter.setPrincipalEnvironmentVariable(usernameRequestAttribute);
                filter.setExceptionIfVariableMissing(false);

                ExceptionTranslationFilter exceptionTranslationFilter = new ExceptionTranslationFilter(new Http403ForbiddenEntryPoint());

                httpSecurity
                        .addFilterBefore(sessionUserAttributeInjector, RequestAttributeAuthenticationFilter.class)
                        .addFilterBefore(exceptionTranslationFilter, SessionUserAttributeInjectorFilter.class)
                        .addFilter(filter)
                        .authorizeRequests()
                        .antMatchers("/**/dev/user/become/*").permitAll()
                        .anyRequest().authenticated();
                httpSecurity
                        .csrf().disable();
                httpSecurity
                        .cors();
            }
        };
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth, FtepUserDetailsService ftepUserDetailsService) {
        PreAuthenticatedAuthenticationProvider authenticationProvider = new PreAuthenticatedAuthenticationProvider();
        authenticationProvider.setPreAuthenticatedUserDetailsService(ftepUserDetailsService);
        auth.authenticationProvider(authenticationProvider);
    }

    @Bean
    public AclPermissionEvaluator aclPermissionEvaluator(AclService aclService) {
        return new AclPermissionEvaluator(aclService);
    }

    @Bean
    public MethodSecurityExpressionHandler createExpressionHandler(AclPermissionEvaluator aclPermissionEvaluator) {
        DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
        expressionHandler.setPermissionEvaluator(aclPermissionEvaluator);
        return expressionHandler;
    }

}

@@ -92,32 +92,106 @@
 DetailsService;%0A
+import com.cgi.eoss.ftep.api.security.FtepWebAuthenticationDetailsSource;%0A
 import org.sprin
@@ -2234,16 +2234,120 @@
 ttribute
+,%0A            @Value(%22$%7Bftep.api.security.email-request-header:REMOTE_EMAIL%7D%22) String emailRequestHeader
 ) %7B%0A    
@@ -3124,24 +3124,139 @@
 Attribute);%0A
+                filter.setAuthenticationDetailsSource(new FtepWebAuthenticationDetailsSource(emailRequestHeader));%0A
             

Fix user details mapping in DEV security mode