package com.its.vms.webapp.config;

import com.its.vms.webapp.security.SessionListener;
import com.its.vms.webapp.service.UserService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
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.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.http.HttpSessionListener;

@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    private final UserService userService;

    public WebSecurityConfig(UserService userService) {
        this.userService = userService;
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/favicon.ico");
        web.ignoring().antMatchers(new String[]{"/css/**", "/js/**", "/img/**", "/lib/**"});

        web.ignoring().antMatchers(HttpMethod.GET, "/api/**");  // GET Method 는 모두 통과
        web.ignoring().antMatchers(HttpMethod.POST, "/api/**");  // GET Method 는 모두 통과
        web.ignoring().antMatchers(HttpMethod.PUT, "/api/**");  // GET Method 는 모두 통과
        web.ignoring().antMatchers(HttpMethod.DELETE, "/api/**");  // GET Method 는 모두 통과
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests()
                // SWAGGER 권한 설정
                .antMatchers("/swagger-ui.html", "/swagger/**", "/swagger-resources/**", "/webjars/**", "/v2/api-docs").permitAll()
                // 웹소켓 권한 설정하지
                .antMatchers("/ws/**").permitAll()
                .antMatchers("/api/**").permitAll()
                .antMatchers(new String[]{"/index"})
                .hasRole("ADMIN")
                .antMatchers(new String[]{"/**"})
                .hasRole("ADMIN")
                .and()
                .formLogin()
                .loginPage("/login")
                .defaultSuccessUrl("/index")
                .failureUrl("/denied")
                .permitAll()
                .and()
                .logout()
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                .logoutSuccessUrl("/login").invalidateHttpSession(true)
                .deleteCookies()
                .and()
                .exceptionHandling()
                .accessDeniedPage("/denied");

        http
                .csrf()
                .disable();

        http
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                .invalidSessionUrl("/login")
                .sessionFixation()
                .migrateSession()
                .maximumSessions(5)
                .maxSessionsPreventsLogin(true)
                .expiredUrl("/login")
                .sessionRegistry(this.sessionRegistry());
    }

    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(this.userService);
    }

    @Bean
    public SessionRegistry sessionRegistry() {
        return new SessionRegistryImpl();
    }

    @Bean
    public HttpSessionListener httpSessionListener() {
        return new SessionListener();
    }

}

