package com.pcalouche.spat.restservices.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.pcalouche.spat.restservices.api.repository.UserRepository;
import com.pcalouche.spat.restservices.security.filter.AjaxLoginProcessingFilter;
import com.pcalouche.spat.restservices.security.filter.JwtAuthenticationProcessingFilter;
import com.pcalouche.spat.restservices.security.provider.AjaxLoginAuthenticationProvider;
import com.pcalouche.spat.restservices.security.provider.JwtAuthenticationProvider;
import com.pcalouche.spat.restservices.security.util.SecurityUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
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.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import java.util.Arrays;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    private final UserRepository userRepository;
    private final ObjectMapper objectMapper;

    public SecurityConfig(UserRepository userRepository,
                          ObjectMapper objectMapper) {
        this.userRepository = userRepository;
        this.objectMapper = objectMapper;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        AjaxLoginAuthenticationProvider ajaxLoginAuthenticationProvider = new AjaxLoginAuthenticationProvider(userRepository);
        JwtAuthenticationProvider jwtAuthenticationProvider = new JwtAuthenticationProvider(userRepository);
        AuthenticationManager authenticationManager = new ProviderManager(Arrays.asList(ajaxLoginAuthenticationProvider, jwtAuthenticationProvider));
        AjaxLoginProcessingFilter ajaxLoginProcessingFilter = new AjaxLoginProcessingFilter(authenticationManager, objectMapper);
        JwtAuthenticationProcessingFilter jwtAuthenticationProcessingFilter = new JwtAuthenticationProcessingFilter(authenticationManager, objectMapper);

        http
                // Disable basic security since we won't be using that
                .httpBasic().disable()
                // We don't need CSRF for JWT based authentication.  The nature of JWT authentication prevents CSRF.
                .csrf().disable()
                // Handle CORS (Cross-origin resource sharing)
                .cors()
                .and()
                // Need for H2 console to work properly
                .headers().frameOptions().sameOrigin()
                .and()
                // Sessions are stateless with JWT based authentication
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                // Setup which endpoints are authorized and which are not
                .and()
                .authorizeRequests()
                .antMatchers(SecurityUtils.WHITELISTED_ENDPOINTS).permitAll()
                .antMatchers(SecurityUtils.AUTHENTICATED_PATH).authenticated()
                // Setup filters for the endpoints
                .and()
                .addFilterBefore(ajaxLoginProcessingFilter, UsernamePasswordAuthenticationFilter.class)
                .addFilterBefore(jwtAuthenticationProcessingFilter, UsernamePasswordAuthenticationFilter.class);
    }
}

@@ -578,16 +578,68 @@
 yUtils;%0A
+import org.springframework.context.annotation.Bean;%0A
 import o
@@ -1575,80 +1575,248 @@
 nal 
-UserRepository userRepository;%0A    private final ObjectMapper objectMapp
+ObjectMapper objectMapper;%0A    private final AjaxLoginAuthenticationProvider ajaxLoginAuthenticationProvider;%0A    private final JwtAuthenticationProvider jwtAuthenticationProvider;%0A    private final AuthenticationManager authenticationManag
 er;%0A
@@ -1932,54 +1932,8 @@
 ) %7B%0A
-        this.userRepository = userRepository;%0A
     
@@ -1978,99 +1978,49 @@
     
-%7D%0A%0A
     
-@Override%0A    protected void configure(HttpSecurity http) throws Exception %7B%0A       
+ajaxLoginAuthenticationProvider = new
  Aja
@@ -2043,34 +2043,53 @@
 tionProvider
- ajaxLogin
+(userRepository);%0A        jwt
 Authenticati
@@ -2101,33 +2101,27 @@
 vider = new 
-AjaxLogin
+Jwt
 Authenticati
@@ -2148,36 +2148,33 @@
 itory);%0A        
-JwtA
+a
 uthenticationPro
@@ -2166,36 +2166,77 @@
 thentication
-Provider jwt
+Manager = new ProviderManager(Arrays.asList(ajaxLogin
 Authenticati
@@ -2241,32 +2241,27 @@
 tionProvider
- = new J
+, j
 wtAuthentica
@@ -2276,34 +2276,44 @@
 ider
-(userRepository
+)
 );%0A    
+%7D%0A%0A
     
+@Override%0A    public 
 Auth
@@ -2355,106 +2355,299 @@
 ager
- = new ProviderManager(Arrays.asList(ajaxLoginAuthenticationProvider, jwtAuthenticationProvider));
+() %7B%0A        return authenticationManager;%0A    %7D%0A%0A    @Bean%0A    @Override%0A    public AuthenticationManager authenticationManagerBean() throws Exception %7B%0A        return super.authenticationManagerBean();%0A    %7D%0A%0A    @Override%0A    protected void configure(HttpSecurity http) throws Exception %7B
 %0A   
@@ -3967,32 +3967,172 @@
          .and()%0A
+                .authenticationProvider(ajaxLoginAuthenticationProvider)%0A                .authenticationProvider(jwtAuthenticationProvider)%0A
                 

tweak security config more