[SECARSP-111] +Auth API [SECARSP-115 +Get Devices]
[platform/core/security/suspicious-activity-monitor.git] / server / src / main / java / com / samsung / samserver / service / impl / UserService.java
1 /*
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.
5  */
6 package com.samsung.samserver.service.impl;
7
8
9 import com.samsung.samserver.service.dto.UserDTO;
10
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;
26
27 import java.time.Instant;
28 import java.time.temporal.ChronoUnit;
29 import java.util.*;
30 import java.util.stream.Collectors;
31
32 /**
33  * Service class for managing users.
34  */
35 @Service
36 @Transactional
37 public class UserService {
38
39     private final Logger log = LoggerFactory.getLogger(UserService.class);
40
41     private final UserRepository userRepository;
42
43     private final PasswordEncoder passwordEncoder;
44
45     private final AuthorityRepository authorityRepository;
46
47     public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder, AuthorityRepository authorityRepository) {
48         this.userRepository = userRepository;
49         this.passwordEncoder = passwordEncoder;
50         this.authorityRepository = authorityRepository;
51     }
52
53     public Optional<User> activateRegistration(String key) {
54         log.debug("Activating user for activation key {}", key);
55         return userRepository.findOneByActivationKey(key)
56             .map(user -> {
57                 // activate given user for the registration key.
58                 user.setActivated(true);
59                 user.setActivationKey(null);
60                 log.debug("Activated user: {}", user);
61                 return user;
62             });
63     }
64
65     public Optional<User> completePasswordReset(String newPassword, String key) {
66        log.debug("Reset user password for reset key {}", key);
67
68        return userRepository.findOneByResetKey(key)
69            .filter(user -> user.getResetDate().isAfter(Instant.now().minusSeconds(86400)))
70            .map(user -> {
71                 user.setPassword(passwordEncoder.encode(newPassword));
72                 user.setResetKey(null);
73                 user.setResetDate(null);
74                 return user;
75            });
76     }
77
78     public Optional<User> requestPasswordReset(String mail) {
79         return userRepository.findOneByEmailIgnoreCase(mail)
80             .filter(User::getActivated)
81             .map(user -> {
82                 user.setResetKey(RandomUtil.generateResetKey());
83                 user.setResetDate(Instant.now());
84                 return user;
85             });
86     }
87
88     public User registerUser(UserDTO userDTO, String password) {
89
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);
110         return newUser;
111     }
112
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
122         } else {
123             user.setLangKey(userDTO.getLangKey());
124         }
125         if (userDTO.getAuthorities() != null) {
126             Set<Authority> authorities = userDTO.getAuthorities().stream()
127                 .map(authorityRepository::findOne)
128                 .collect(Collectors.toSet());
129             user.setAuthorities(authorities);
130         }
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);
138         return user;
139     }
140
141     /**
142      * Update basic information (first name, last name, email, language) for the current user.
143      *
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
149      */
150     public void updateUser(String firstName, String lastName, String email, String langKey, String imageUrl) {
151         SecurityUtils.getCurrentUserLogin()
152             .flatMap(userRepository::findOneByLogin)
153             .ifPresent(user -> {
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);
160             });
161     }
162
163     /**
164      * Update all information for a specific user, and return the modified user.
165      *
166      * @param userDTO user to update
167      * @return updated user
168      */
169     public Optional<UserDTO> updateUser(UserDTO userDTO) {
170         return Optional.of(userRepository
171             .findOne(userDTO.getId()))
172             .map(user -> {
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);
186                 return user;
187             })
188             .map(UserDTO::new);
189     }
190
191     public void deleteUser(String login) {
192         userRepository.findOneByLogin(login).ifPresent(user -> {
193             userRepository.delete(user);
194             log.debug("Deleted User: {}", user);
195         });
196     }
197
198     public void changePassword(String password) {
199         SecurityUtils.getCurrentUserLogin()
200             .flatMap(userRepository::findOneByLogin)
201             .ifPresent(user -> {
202                 String encryptedPassword = passwordEncoder.encode(password);
203                 user.setPassword(encryptedPassword);
204                 log.debug("Changed password for User: {}", user);
205             });
206     }
207
208     @Transactional(readOnly = true)
209     public Page<UserDTO> getAllManagedUsers(Pageable pageable) {
210         return userRepository.findAllByLoginNot(pageable, Constants.ANONYMOUS_USER).map(UserDTO::new);
211     }
212
213     @Transactional(readOnly = true)
214     public Optional<User> getUserWithAuthoritiesByLogin(String login) {
215         return userRepository.findOneWithAuthoritiesByLogin(login);
216     }
217
218     @Transactional(readOnly = true)
219     public Optional<User> getUserWithAuthorities(Long id) {
220         return userRepository.findOneWithAuthoritiesById(id);
221     }
222
223     @Transactional(readOnly = true)
224     public Optional<User> getUserWithAuthorities() {
225         return SecurityUtils.getCurrentUserLogin().flatMap(userRepository::findOneWithAuthoritiesByLogin);
226     }
227
228     /**
229      * Not activated users should be automatically deleted after 3 days.
230      * <p>
231      * This is scheduled to get fired everyday, at 01:00 (am).
232      */
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);
239         }
240     }
241
242     /**
243      * @return a list of all the authorities
244      */
245     public List<String> getAuthorities() {
246         return authorityRepository.findAll().stream().map(Authority::getName).collect(Collectors.toList());
247     }
248
249     /**
250      * Utility class for generating random Strings.
251      */
252     public static final class RandomUtil {
253
254         private static final int DEF_COUNT = 20;
255
256         private RandomUtil() {
257         }
258
259         /**
260          * Generate a password.
261          *
262          * @return the generated password
263          */
264         public static String generatePassword() {
265             return RandomStringUtils.randomAlphanumeric(DEF_COUNT);
266         }
267
268         /**
269          * Generate an activation key.
270          *
271          * @return the generated activation key
272          */
273         public static String generateActivationKey() {
274             return RandomStringUtils.randomNumeric(DEF_COUNT);
275         }
276
277         /**
278          * Generate a reset key.
279          *
280          * @return the generated reset key
281          */
282         public static String generateResetKey() {
283             return RandomStringUtils.randomNumeric(DEF_COUNT);
284         }
285     }
286 }