package sample.ui.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.provisioning.UserDetailsManager;
import lombok.extern.slf4j.Slf4j;
import sample.ui.model.User;
import sample.ui.repository.UserRepository;
@Slf4j
public class DBDrivenUserDetailsManager implements UserDetailsManager {
private AuthenticationManager authenticationManager;
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("User " + username + " not found.");
}
return user;
}
@Override
public void createUser(UserDetails user) {
userRepository.save((User) user);
}
@Override
public void updateUser(UserDetails user) {
userRepository.save((User) user);
}
/**
* Users are not deleted, just disabled.
*/
@Override
public void deleteUser(String username) {
User user = userRepository.findByUsername(username);
user.setEnabled(false);
userRepository.save(user);
}
@Override
public void changePassword(String oldPassword, String newPassword) {
Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
if (currentUser == null) {
// This would indicate bad coding somewhere
throw new AccessDeniedException(
"Can't change password as no Authentication object found in context for current user.");
}
String username = currentUser.getName();
log.debug("Changing password for user '" + username + "'");
// If an authentication manager has been set, re-authenticate the user
// with the supplied password.
if (authenticationManager != null) {
log.debug("Reauthenticating user '" + username + "' for password change request.");
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, oldPassword));
} else {
log.debug("No authentication manager set. Password won't be re-checked.");
}
User changedUser = userRepository.findByUsername(username);
if (changedUser == null) {
throw new IllegalStateException("Current user doesn't exist in database.");
}
changedUser.setPassword(new BCryptPasswordEncoder().encode(newPassword));
userRepository.save(changedUser);
}
@Override
public boolean userExists(String username) {
return userRepository.findByUsername(username) != null;
}
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
}