diff --git a/src/main/kotlin/uk/co/neviyn/booru/Repository.kt b/src/main/kotlin/uk/co/neviyn/booru/Repository.kt index 99b1df8..37f985a 100644 --- a/src/main/kotlin/uk/co/neviyn/booru/Repository.kt +++ b/src/main/kotlin/uk/co/neviyn/booru/Repository.kt @@ -2,7 +2,9 @@ package uk.co.neviyn.booru import org.springframework.data.repository.CrudRepository -interface UserRepository : CrudRepository +interface UserRepository : CrudRepository { + fun findByName(name: String) : User? +} interface RoleRepository : CrudRepository diff --git a/src/main/kotlin/uk/co/neviyn/booru/Security.kt b/src/main/kotlin/uk/co/neviyn/booru/Security.kt new file mode 100644 index 0000000..4ca697e --- /dev/null +++ b/src/main/kotlin/uk/co/neviyn/booru/Security.kt @@ -0,0 +1,56 @@ +package uk.co.neviyn.booru + +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.WebSecurityConfigurerAdapter +import org.springframework.security.core.GrantedAuthority +import org.springframework.security.core.authority.SimpleGrantedAuthority +import org.springframework.security.core.userdetails.UserDetails +import org.springframework.security.core.userdetails.UserDetailsService +import org.springframework.security.core.userdetails.UsernameNotFoundException +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder +import org.springframework.security.crypto.password.PasswordEncoder +import org.springframework.stereotype.Service + +@Configuration +class SecurityConfig @Autowired constructor(val userDetailsService: CustomUserDetailsService): WebSecurityConfigurerAdapter() { + override fun configure(http: HttpSecurity) { + //http.authorizeRequests().antMatchers("").authenticated() TODO: Restrict certain routes needing login + http.authorizeRequests().anyRequest().permitAll().and() + .formLogin().loginPage("/login").permitAll().and() + .logout().logoutSuccessUrl("/").permitAll().and() + .httpBasic() + } + + override fun configure(auth: AuthenticationManagerBuilder) { + auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()) + } +} + +class CustomUserDetails(private val user: User) : UserDetails { + override fun getAuthorities(): MutableCollection = user.roles.map { SimpleGrantedAuthority(it.name) }.toMutableList() + + override fun getPassword(): String = user.password + + override fun getUsername(): String = user.name + + override fun isAccountNonExpired(): Boolean = true + + override fun isAccountNonLocked(): Boolean = true + + override fun isCredentialsNonExpired(): Boolean = true + + override fun isEnabled(): Boolean = true + +} + +@Service +class CustomUserDetailsService @Autowired constructor(val userRepository: UserRepository) : UserDetailsService { + override fun loadUserByUsername(p0: String): UserDetails = CustomUserDetails(userRepository.findByName(p0) ?: throw UsernameNotFoundException(p0)) +} + +@Bean +fun passwordEncoder() : PasswordEncoder = BCryptPasswordEncoder() \ No newline at end of file