package eu.dnetlib.organizations;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.AccessDeniedHandler;

import eu.dnetlib.organizations.controller.UserRole;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

	@Autowired
	private DataSource dataSource;

	@Autowired
	private AccessDeniedHandler accessDeniedHandler;

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

		http.csrf()
				.disable()
				.authorizeRequests()
				.antMatchers("/", "/api/**")
				.hasAnyRole(UserRole.ADMIN.name(), UserRole.NATIONAL_ADMIN.name(), UserRole.USER.name())
				.antMatchers("/registration_api/**")
				.hasRole(UserRole.NOT_AUTHORIZED.name())
				.antMatchers("/resources/**", "/webjars/**")
				.permitAll()
				.anyRequest()
				.authenticated()
				.and()
				.formLogin()
				.loginPage("/login")
				.permitAll()
				.and()
				.logout()
				.permitAll()
				.and()
				.exceptionHandling()
				.accessDeniedHandler(accessDeniedHandler);
	}

	@Autowired
	public void configureGlobal(final AuthenticationManagerBuilder auth) throws Exception {
		auth.jdbcAuthentication()
				.dataSource(dataSource)
				.usersByUsernameQuery("select ?, '{MD5}60c4a0eb167dd41e915a885f582414df', true")  // TODO: this is a MOCK, the user should
																								  // be authenticated using the openaire
																								  // credentials
				.authoritiesByUsernameQuery("with const as (SELECT ? as email) "
						+ "select c.email, 'ROLE_'||coalesce(u.role, '"
						+ UserRole.NOT_AUTHORIZED
						+ "') from const c left outer join users u on (u.email = c.email)");
	}

	@Bean
	public PasswordEncoder passwordEncoder() {
		return PasswordEncoderFactories.createDelegatingPasswordEncoder();
	}

}
