2 * In Samsung Ukraine R&D Center (SRK under a contract between)
3 * LLC "Samsung Electronics Co", Ltd (Seoul, Republic of Korea)
4 * Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved.
6 package com.samsung.samserver.service.impl;
9 import com.samsung.samserver.service.dto.UserDTO;
11 import com.samsung.samserver.config.Constants;
12 import com.samsung.samserver.domain.*;
13 import com.samsung.samserver.repository.AuthorityRepository;
14 import com.samsung.samserver.repository.UserRepository;
15 import com.samsung.samserver.security.AuthoritiesConstants;
16 import com.samsung.samserver.security.SecurityUtils;
17 import org.apache.commons.lang3.RandomStringUtils;
18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory;
20 import org.springframework.data.domain.Page;
21 import org.springframework.data.domain.Pageable;
22 import org.springframework.scheduling.annotation.Scheduled;
23 import org.springframework.security.crypto.password.PasswordEncoder;
24 import org.springframework.stereotype.Service;
25 import org.springframework.transaction.annotation.Transactional;
27 import java.time.Instant;
28 import java.time.temporal.ChronoUnit;
30 import java.util.stream.Collectors;
33 * Service class for managing users.
37 public class UserService {
39 private final Logger log = LoggerFactory.getLogger(UserService.class);
41 private final UserRepository userRepository;
43 private final PasswordEncoder passwordEncoder;
45 private final AuthorityRepository authorityRepository;
47 public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder, AuthorityRepository authorityRepository) {
48 this.userRepository = userRepository;
49 this.passwordEncoder = passwordEncoder;
50 this.authorityRepository = authorityRepository;
53 public Optional<User> activateRegistration(String key) {
54 log.debug("Activating user for activation key {}", key);
55 return userRepository.findOneByActivationKey(key)
57 // activate given user for the registration key.
58 user.setActivated(true);
59 user.setActivationKey(null);
60 log.debug("Activated user: {}", user);
65 public Optional<User> completePasswordReset(String newPassword, String key) {
66 log.debug("Reset user password for reset key {}", key);
68 return userRepository.findOneByResetKey(key)
69 .filter(user -> user.getResetDate().isAfter(Instant.now().minusSeconds(86400)))
71 user.setPassword(passwordEncoder.encode(newPassword));
72 user.setResetKey(null);
73 user.setResetDate(null);
78 public Optional<User> requestPasswordReset(String mail) {
79 return userRepository.findOneByEmailIgnoreCase(mail)
80 .filter(User::getActivated)
82 user.setResetKey(RandomUtil.generateResetKey());
83 user.setResetDate(Instant.now());
88 public User registerUser(UserDTO userDTO, String password) {
90 User newUser = new User();
91 Authority authority = authorityRepository.findOne(AuthoritiesConstants.USER);
92 Set<Authority> authorities = new HashSet<>();
93 String encryptedPassword = passwordEncoder.encode(password);
94 newUser.setLogin(userDTO.getLogin());
95 // new user gets initially a generated password
96 newUser.setPassword(encryptedPassword);
97 newUser.setFirstName(userDTO.getFirstName());
98 newUser.setLastName(userDTO.getLastName());
99 newUser.setEmail(userDTO.getEmail());
100 newUser.setImageUrl(userDTO.getImageUrl());
101 newUser.setLangKey(userDTO.getLangKey());
102 // new user is not active
103 newUser.setActivated(false);
104 // new user gets registration key
105 newUser.setActivationKey(RandomUtil.generateActivationKey());
106 authorities.add(authority);
107 newUser.setAuthorities(authorities);
108 userRepository.save(newUser);
109 log.debug("Created Information for User: {}", newUser);
113 public User createUser(UserDTO userDTO) {
114 User user = new User();
115 user.setLogin(userDTO.getLogin());
116 user.setFirstName(userDTO.getFirstName());
117 user.setLastName(userDTO.getLastName());
118 user.setEmail(userDTO.getEmail());
119 user.setImageUrl(userDTO.getImageUrl());
120 if (userDTO.getLangKey() == null) {
121 user.setLangKey(Constants.DEFAULT_LANGUAGE); // default language
123 user.setLangKey(userDTO.getLangKey());
125 if (userDTO.getAuthorities() != null) {
126 Set<Authority> authorities = userDTO.getAuthorities().stream()
127 .map(authorityRepository::findOne)
128 .collect(Collectors.toSet());
129 user.setAuthorities(authorities);
131 String encryptedPassword = passwordEncoder.encode(RandomUtil.generatePassword());
132 user.setPassword(encryptedPassword);
133 user.setResetKey(RandomUtil.generateResetKey());
134 user.setResetDate(Instant.now());
135 user.setActivated(true);
136 userRepository.save(user);
137 log.debug("Created Information for User: {}", user);
142 * Update basic information (first name, last name, email, language) for the current user.
144 * @param firstName first name of user
145 * @param lastName last name of user
146 * @param email email id of user
147 * @param langKey language key
148 * @param imageUrl image URL of user
150 public void updateUser(String firstName, String lastName, String email, String langKey, String imageUrl) {
151 SecurityUtils.getCurrentUserLogin()
152 .flatMap(userRepository::findOneByLogin)
154 user.setFirstName(firstName);
155 user.setLastName(lastName);
156 user.setEmail(email);
157 user.setLangKey(langKey);
158 user.setImageUrl(imageUrl);
159 log.debug("Changed Information for User: {}", user);
164 * Update all information for a specific user, and return the modified user.
166 * @param userDTO user to update
167 * @return updated user
169 public Optional<UserDTO> updateUser(UserDTO userDTO) {
170 return Optional.of(userRepository
171 .findOne(userDTO.getId()))
173 user.setLogin(userDTO.getLogin());
174 user.setFirstName(userDTO.getFirstName());
175 user.setLastName(userDTO.getLastName());
176 user.setEmail(userDTO.getEmail());
177 user.setImageUrl(userDTO.getImageUrl());
178 user.setActivated(userDTO.isActivated());
179 user.setLangKey(userDTO.getLangKey());
180 Set<Authority> managedAuthorities = user.getAuthorities();
181 managedAuthorities.clear();
182 userDTO.getAuthorities().stream()
183 .map(authorityRepository::findOne)
184 .forEach(managedAuthorities::add);
185 log.debug("Changed Information for User: {}", user);
191 public void deleteUser(String login) {
192 userRepository.findOneByLogin(login).ifPresent(user -> {
193 userRepository.delete(user);
194 log.debug("Deleted User: {}", user);
198 public void changePassword(String password) {
199 SecurityUtils.getCurrentUserLogin()
200 .flatMap(userRepository::findOneByLogin)
202 String encryptedPassword = passwordEncoder.encode(password);
203 user.setPassword(encryptedPassword);
204 log.debug("Changed password for User: {}", user);
208 @Transactional(readOnly = true)
209 public Page<UserDTO> getAllManagedUsers(Pageable pageable) {
210 return userRepository.findAllByLoginNot(pageable, Constants.ANONYMOUS_USER).map(UserDTO::new);
213 @Transactional(readOnly = true)
214 public Optional<User> getUserWithAuthoritiesByLogin(String login) {
215 return userRepository.findOneWithAuthoritiesByLogin(login);
218 @Transactional(readOnly = true)
219 public Optional<User> getUserWithAuthorities(Long id) {
220 return userRepository.findOneWithAuthoritiesById(id);
223 @Transactional(readOnly = true)
224 public Optional<User> getUserWithAuthorities() {
225 return SecurityUtils.getCurrentUserLogin().flatMap(userRepository::findOneWithAuthoritiesByLogin);
229 * Not activated users should be automatically deleted after 3 days.
231 * This is scheduled to get fired everyday, at 01:00 (am).
233 @Scheduled(cron = "0 0 1 * * ?")
234 public void removeNotActivatedUsers() {
235 List<User> users = userRepository.findAllByActivatedIsFalseAndCreatedDateBefore(Instant.now().minus(3, ChronoUnit.DAYS));
236 for (User user : users) {
237 log.debug("Deleting not activated user {}", user.getLogin());
238 userRepository.delete(user);
243 * @return a list of all the authorities
245 public List<String> getAuthorities() {
246 return authorityRepository.findAll().stream().map(Authority::getName).collect(Collectors.toList());
250 * Utility class for generating random Strings.
252 public static final class RandomUtil {
254 private static final int DEF_COUNT = 20;
256 private RandomUtil() {
260 * Generate a password.
262 * @return the generated password
264 public static String generatePassword() {
265 return RandomStringUtils.randomAlphanumeric(DEF_COUNT);
269 * Generate an activation key.
271 * @return the generated activation key
273 public static String generateActivationKey() {
274 return RandomStringUtils.randomNumeric(DEF_COUNT);
278 * Generate a reset key.
280 * @return the generated reset key
282 public static String generateResetKey() {
283 return RandomStringUtils.randomNumeric(DEF_COUNT);