[SECARSP-111] +Auth API [SECARSP-115 +Get Devices]
[platform/core/security/suspicious-activity-monitor.git] / server / src / main / java / com / samsung / samserver / web / rest / service / AccountService.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.web.rest.service;
7
8 import com.samsung.samserver.domain.User;
9 import com.samsung.samserver.repository.UserRepository;
10 import com.samsung.samserver.security.SecurityUtils;
11 import com.samsung.samserver.service.impl.MailService;
12 import com.samsung.samserver.service.impl.UserService;
13 import com.samsung.samserver.service.dto.UserDTO;
14
15 import com.samsung.samserver.web.rest.errors.InternalServerErrorException;
16 import com.samsung.samserver.web.rest.errors.UserServiceError;
17 import org.apache.commons.lang3.StringUtils;
18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory;
20 import org.springframework.stereotype.Service;
21 import org.springframework.web.bind.annotation.*;
22
23 import javax.servlet.http.HttpServletRequest;
24 import javax.validation.Valid;
25 import javax.validation.constraints.Size;
26 import java.util.*;
27
28 /**
29  * REST service for managing the current user's account.
30  */
31 @Service
32 public class AccountService {
33
34     private final Logger log = LoggerFactory.getLogger(AccountService.class);
35
36     private final UserRepository userRepository;
37
38     private final UserService userService;
39
40     private final MailService mailService;
41
42     public AccountService(UserRepository userRepository, UserService userService, MailService mailService) {
43
44         this.userRepository = userRepository;
45         this.userService = userService;
46         this.mailService = mailService;
47     }
48
49     /**
50      * POST  /register : register the user.
51      *
52      * @param managedUserVM the managed user View Model
53      * @throws UserServiceError.InvalidPasswordException 400 (Bad Request) if the password is incorrect
54      * @throws UserServiceError.EmailAlreadyUsedException 400 (Bad Request) if the email is already used
55      * @throws UserServiceError.LoginAlreadyUsedException 400 (Bad Request) if the login is already used
56      */
57     public void registerAccount(@Valid @RequestBody ManagedUserVM managedUserVM) {
58         if (!checkPasswordLength(managedUserVM.getPassword())) {
59             throw new UserServiceError.InvalidPasswordException();
60         }
61         userRepository.findOneByLogin(managedUserVM.getLogin().toLowerCase()).ifPresent(u -> {throw new UserServiceError.LoginAlreadyUsedException();});
62         userRepository.findOneByEmailIgnoreCase(managedUserVM.getEmail()).ifPresent(u -> {throw new UserServiceError.EmailAlreadyUsedException();});
63         User user = userService.registerUser(managedUserVM, managedUserVM.getPassword());
64         mailService.sendActivationEmail(user);
65     }
66
67     /**
68      * GET  /activate : activate the registered user.
69      *
70      * @param key the activation key
71      * @throws RuntimeException 500 (Internal Server Error) if the user couldn't be activated
72      */
73     public void activateAccount(@RequestParam(value = "key") String key) {
74         Optional<User> user = userService.activateRegistration(key);
75         if (!user.isPresent()) {
76             throw new InternalServerErrorException("No user was found for this reset key");
77         }
78     }
79
80     /**
81      * GET  /authenticate : check if the user is authenticated, and return its login.
82      *
83      * @param request the HTTP request
84      * @return the login if the user is authenticated
85      */
86     public String isAuthenticated(HttpServletRequest request) {
87         log.debug("REST request to check if the current user is authenticated");
88         return request.getRemoteUser();
89     }
90
91     /**
92      * GET  /account : get the current user.
93      *
94      * @return the current user
95      * @throws RuntimeException 500 (Internal Server Error) if the user couldn't be returned
96      */
97     public UserDTO getAccount() {
98         return userService.getUserWithAuthorities()
99             .map(UserDTO::new)
100             .orElseThrow(() -> new InternalServerErrorException("User could not be found"));
101     }
102
103     /**
104      * POST  /account : update the current user information.
105      *
106      * @param userDTO the current user information
107      * @throws UserServiceError.EmailAlreadyUsedException 400 (Bad Request) if the email is already used
108      * @throws RuntimeException 500 (Internal Server Error) if the user login wasn't found
109      */
110     public void saveAccount(@Valid @RequestBody UserDTO userDTO) {
111         final String userLogin = SecurityUtils.getCurrentUserLogin().orElseThrow(() -> new InternalServerErrorException("Current user login not found"));
112         Optional<User> existingUser = userRepository.findOneByEmailIgnoreCase(userDTO.getEmail());
113         if (existingUser.isPresent() && (!existingUser.get().getLogin().equalsIgnoreCase(userLogin))) {
114             throw new UserServiceError.EmailAlreadyUsedException();
115         }
116         Optional<User> user = userRepository.findOneByLogin(userLogin);
117         if (!user.isPresent()) {
118             throw new InternalServerErrorException("User could not be found");
119         }
120         userService.updateUser(userDTO.getFirstName(), userDTO.getLastName(), userDTO.getEmail(),
121             userDTO.getLangKey(), userDTO.getImageUrl());
122    }
123
124     /**
125      * POST  /account/change-password : changes the current user's password
126      *
127      * @param password the new password
128      * @throws UserServiceError.InvalidPasswordException 400 (Bad Request) if the new password is incorrect
129      */
130     public void changePassword(@RequestBody String password) {
131         if (!checkPasswordLength(password)) {
132             throw new UserServiceError.InvalidPasswordException();
133         }
134         userService.changePassword(password);
135    }
136
137     /**
138      * POST   /account/reset-password/init : Send an email to reset the password of the user
139      *
140      * @param mail the mail of the user
141      * @throws UserServiceError.EmailNotFoundException 400 (Bad Request) if the email address is not registered
142      */
143     public void requestPasswordReset(@RequestBody String mail) {
144        mailService.sendPasswordResetMail(
145            userService.requestPasswordReset(mail)
146                .orElseThrow(UserServiceError.EmailNotFoundException::new)
147        );
148     }
149
150     /**
151      * POST   /account/reset-password/finish : Finish to reset the password of the user
152      *
153      * @param keyAndPassword the generated key and the new password
154      * @throws UserServiceError.InvalidPasswordException 400 (Bad Request) if the password is incorrect
155      * @throws RuntimeException 500 (Internal Server Error) if the password could not be reset
156      */
157     public void finishPasswordReset(@RequestBody KeyAndPasswordVM keyAndPassword) {
158         if (!checkPasswordLength(keyAndPassword.getNewPassword())) {
159             throw new UserServiceError.InvalidPasswordException();
160         }
161         Optional<User> user =
162             userService.completePasswordReset(keyAndPassword.getNewPassword(), keyAndPassword.getKey());
163
164         if (!user.isPresent()) {
165             throw new InternalServerErrorException("No user was found for this reset key");
166         }
167     }
168
169     private static boolean checkPasswordLength(String password) {
170         return !StringUtils.isEmpty(password) &&
171             password.length() >= ManagedUserVM.PASSWORD_MIN_LENGTH &&
172             password.length() <= ManagedUserVM.PASSWORD_MAX_LENGTH;
173     }
174
175
176     /**
177      * View Model object for storing the user's key and password.
178      */
179     public static class KeyAndPasswordVM {
180
181         private String key;
182
183         private String newPassword;
184
185         public String getKey() {
186             return key;
187         }
188
189         public void setKey(String key) {
190             this.key = key;
191         }
192
193         public String getNewPassword() {
194             return newPassword;
195         }
196
197         public void setNewPassword(String newPassword) {
198             this.newPassword = newPassword;
199         }
200     }
201
202
203     /**
204      * View Model extending the UserDTO, which is meant to be used in the user management UI.
205      */
206     public static class ManagedUserVM extends UserDTO {
207
208         public static final int PASSWORD_MIN_LENGTH = 4;
209
210         public static final int PASSWORD_MAX_LENGTH = 100;
211
212         @Size(min = PASSWORD_MIN_LENGTH, max = PASSWORD_MAX_LENGTH)
213         private String password;
214
215         public ManagedUserVM() {
216             // Empty constructor needed for Jackson.
217         }
218
219         public String getPassword() {
220             return password;
221         }
222
223         public void setPassword(String password) {
224             this.password = password;
225         }
226
227         @Override
228         public String toString() {
229             return "ManagedUserVM{" +
230                 "} " + super.toString();
231         }
232     }
233
234
235 }