package org.uned.agonzalo16.bitacora.service.security;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.uned.agonzalo16.bitacora.dao.UserDao;
import org.uned.agonzalo16.bitacora.domain.User;
import org.uned.agonzalo16.bitacora.domain.UserType;
@Service("AuthenticationProvider")
public class AuthenticationProvider extends AbstractUserDetailsAuthenticationProvider implements UserDetailsService {
@Autowired
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
// Overridden null method to comply with provider
}
@Override
protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
String password = (String) authentication.getCredentials();
if (!StringUtils.hasText(password)) {
throw new BadCredentialsException("Please enter password");
}
return checkUserDetails(username, password, true);
}
private void insertAdmin() {
User user = new User();
user.setActive(true);
user.setCreationDate(new Date());
user.setEmail("admin@test.com");
user.setLocalization("Spain");
user.setPassword("password");
user.setType(UserType.ADMIN.getType());
user.setUsername("admin");
user.setWebSite("www.site.com");
userDao.merge(user);
}
private UserDetails checkUserDetails(String username, String password, boolean authenticate) {
if (userDao.findAll().isEmpty()) {
insertAdmin();
}
User user = userDao.findByUsername(username);
if (user == null) {
throw new BadCredentialsException("Invalid user: " + username);
}
if (!user.isActive()) {
throw new BadCredentialsException("User desactivated: " + username);
}
if (authenticate) {
String expectedPassword = user.getPassword();
if (!StringUtils.hasText(expectedPassword)) {
throw new BadCredentialsException("No password for " + username + " set in database, contact administrator");
}
String encryptedPassword = DigestUtils.md5DigestAsHex(password.getBytes());
if (!expectedPassword.equalsIgnoreCase(encryptedPassword)) {
throw new BadCredentialsException("Invalid Password");
}
}
return new AuthenticatedUser(user);
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
return checkUserDetails(username, "", false);
}
public AuthenticatedUser getCurrentUserDetails() {
AuthenticatedUser details = null;
SecurityContext securityContext = SecurityContextHolder.getContext();
Authentication authentication = securityContext.getAuthentication();
if (authentication != null && authentication.getPrincipal() instanceof AuthenticatedUser) {
details = (AuthenticatedUser) authentication.getPrincipal();
}
return details;
}
}