fr.smallcrew.security.service.UserService Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of smallcrew-security Show documentation
Show all versions of smallcrew-security Show documentation
Foundation of all smallcrew's projects needing authenticated users and role management
The newest version!
package fr.smallcrew.security.service;
import com.google.common.base.Strings;
import fr.smallcrew.data.service.CrudService;
import fr.smallcrew.data.service.PaginableService;
import fr.smallcrew.security.data.LostPasswordData;
import fr.smallcrew.security.domain.DomainUser;
import fr.smallcrew.security.exception.InvalidPasswordException;
import fr.smallcrew.security.exception.InvalidPasswordRequestTokenException;
import fr.smallcrew.security.exception.InvalidUsernameException;
import fr.smallcrew.security.exception.UserExistsException;
import fr.smallcrew.security.repository.DomainUserRepository;
import fr.smallcrew.security.web.AuthenticatedUser;
import fr.smallcrew.utils.MailerHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.security.authentication.encoding.PasswordEncoder;
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.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Maps.newHashMap;
import static fr.smallcrew.security.domain.DomainUser.Builder.checkEMail;
import static fr.smallcrew.security.domain.DomainUser.Builder.checkPassword;
import static fr.smallcrew.security.domain.DomainUser.Builder.checkUsername;
import static org.joda.time.LocalDate.fromDateFields;
import static org.joda.time.LocalDate.now;
@Service
@Transactional(readOnly = true)
public class UserService implements UserDetailsService, CrudService, PaginableService {
@Autowired
private DomainUserRepository domainUserRepository;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private MailerHelper mailerHelper;
@Override
@Transactional
public DomainUser create(DomainUser inputUser) {
checkNullUser(inputUser);
DomainUser.Builder builder = new DomainUser.Builder()
.username(inputUser.getUsername())
.email(inputUser.getEmail())
.password(inputUser.getPassword())
.passwordEncoder(passwordEncoder)
.passwordSalt(UUID.randomUUID().toString());
return domainUserRepository.save(builder.build());
}
@Override
@Transactional
public DomainUser update(DomainUser inputUser) {
DomainUser updateUser = domainUserRepository.findOne(inputUser.getId());
if (!updateUser.getPassword().equals(inputUser.getPassword())) {
checkPassword(inputUser.getPassword());
updateUser.setPassword(passwordEncoder.encodePassword(inputUser.getPassword(), updateUser.getPasswordSalt()));
}
updateUser.setUsername(checkUsername(inputUser.getUsername()));
updateUser.setEmail(checkEMail(inputUser.getEmail()));
return domainUserRepository.save(updateUser);
}
@Override
@Transactional
public void delete(Integer userId) {
DomainUser user = findByID(userId);
domainUserRepository.delete(user.getId());
}
@Override
public DomainUser findByID(Integer id) {
DomainUser user = domainUserRepository.findOne(id);
checkNotNullUser(user);
return user;
}
@Override
public Page findAll(int page, int size, String sortField, String sortDirection) {
Sort.Direction direction = Sort.DEFAULT_DIRECTION;
if (Strings.isNullOrEmpty(sortField)) {
sortField = DomainUser.ID;
}
if (!Strings.isNullOrEmpty(sortDirection)) {
direction = Sort.Direction.fromString(sortDirection);
}
PageRequest pageRequest = new PageRequest(page, size, new Sort(new Sort.Order(direction, sortField)));
return domainUserRepository.findAll(null, pageRequest);
}
@Override
public UserDetails loadUserByUsername(String userNameOrEmail) throws UsernameNotFoundException {
List authorities = newArrayList();
DomainUser user = domainUserRepository.findByUsernameOrEmail(userNameOrEmail, userNameOrEmail);
checkNotNullUser(user);
maybeAddAdminGrants(authorities, user);
return new AuthenticatedUser(user, authorities);
}
@Transactional
public LostPasswordData requestPasswordChangeToken(String userNameOrEmail, Date date) {
DomainUser user = domainUserRepository.findByUsernameOrEmail(userNameOrEmail, userNameOrEmail);
checkNotNullUser(user);
user.setPasswordRequestToken(UUID.randomUUID().toString());
user.setPasswordRequestDate(date);
domainUserRepository.save(user);
return new LostPasswordData(user.getEmail(), user.getPasswordRequestToken());
}
@Transactional
public void changePassword(String userNameOrEmail, String token, String newPassword, String confirmedPassword) {
DomainUser user = domainUserRepository.findByUsernameOrEmail(userNameOrEmail, userNameOrEmail);
checkNotNullUser(user);
if (user.getPasswordRequestToken() == null) {
throw new InvalidPasswordRequestTokenException();
}
boolean tokenIsExpired = now().minusDays(1).isAfter(fromDateFields(user.getPasswordRequestDate()));
if (!user.getPasswordRequestToken().equals(token) || tokenIsExpired) {
throw new InvalidPasswordRequestTokenException();
}
if (newPassword.equals(confirmedPassword)) {
checkPassword(newPassword);
user.setPassword(passwordEncoder.encodePassword(newPassword, user.getPasswordSalt()));
user.setPasswordRequestDate(null);
user.setPasswordRequestToken(null);
} else {
throw new InvalidPasswordException();
}
domainUserRepository.save(user);
}
public LostPasswordData sendLostPasswordMail(String username, Locale locale) {
Map data = newHashMap();
LostPasswordData lostPasswordData = requestPasswordChangeToken(username, new Date());
data.put("passwordData", lostPasswordData);
mailerHelper.send(lostPasswordData.getEmail(), "lostPassword", locale, data);
return lostPasswordData;
}
private void maybeAddAdminGrants(List authorities, DomainUser user) {
if (user.getId() == 1) {
authorities.add(new SimpleGrantedAuthority("admin"));
}
}
private void checkNotNullUser(DomainUser user) {
if (user == null) {
throw new InvalidUsernameException();
}
}
private void checkNullUser(DomainUser user) {
if (domainUserRepository.findByUsernameOrEmail(user.getUsername(), user.getEmail()) != null) {
throw new UserExistsException();
}
}
}