· 6 years ago · Nov 25, 2019, 01:28 PM
1package com.look4app.web.rest;
2
3
4import com.look4app.domain.user.User;
5import com.look4app.repository.UserRepository;
6import com.look4app.security.SecurityUtils;
7import com.look4app.service.MailService;
8import com.look4app.service.UserService;
9import com.look4app.service.dto.PasswordChangeDTO;
10import com.look4app.service.dto.UserDTO;
11import com.look4app.web.rest.errors.EmailAlreadyUsedException;
12import com.look4app.web.rest.errors.EmailNotFoundException;
13import com.look4app.web.rest.errors.InvalidPasswordException;
14import com.look4app.web.rest.vm.KeyAndPasswordVM;
15import com.look4app.web.rest.vm.ManagedUserVM;
16
17import io.swagger.annotations.Api;
18import io.swagger.annotations.ApiOperation;
19import io.swagger.annotations.ApiParam;
20import io.swagger.annotations.ApiResponse;
21import io.swagger.annotations.ApiResponses;
22import org.apache.commons.lang3.StringUtils;
23import org.springframework.http.HttpStatus;
24import org.springframework.web.bind.annotation.GetMapping;
25import org.springframework.web.bind.annotation.PostMapping;
26import org.springframework.web.bind.annotation.RequestBody;
27import org.springframework.web.bind.annotation.RequestMapping;
28import org.springframework.web.bind.annotation.RequestParam;
29import org.springframework.web.bind.annotation.ResponseStatus;
30import org.springframework.web.bind.annotation.RestController;
31
32import javax.validation.Valid;
33import java.util.Optional;
34
35/**
36 * REST controller for managing the current user's account.
37 */
38@RestController
39@RequestMapping("/api")
40@Api(value = "/api", tags = "accountResource")
41public class AccountResource {
42
43 private static class AccountResourceException extends RuntimeException {
44
45 private static final long serialVersionUID = 1049388996908368042L;
46
47 private AccountResourceException(String message) {
48 super(message);
49 }
50 }
51
52 private final UserRepository userRepository;
53
54 private final UserService userService;
55
56 private final MailService mailService;
57
58 public AccountResource(UserRepository userRepository, UserService userService, MailService mailService) {
59
60 this.userRepository = userRepository;
61 this.userService = userService;
62 this.mailService = mailService;
63 }
64
65 /**
66 * {@code POST /register} : register the user.
67 *
68 * @param managedUserVM the managed user View Model.
69 * @throws InvalidPasswordException {@code 400 (Bad Request)} if the password is incorrect.
70 * @throws EmailAlreadyUsedException {@code 400 (Bad Request)} if the email is already used.
71 */
72 @PostMapping("/register")
73 @ResponseStatus(HttpStatus.CREATED)
74 @ApiOperation("Register user in application.")
75 @ApiResponses(value = {
76 @ApiResponse(code = 201, message = "Created"),
77 @ApiResponse(code = 400, message = "Incorrect password or email is already used")
78 })
79 public void registerAccount(@ApiParam(value = "User to register", required = true) @Valid @RequestBody ManagedUserVM managedUserVM) {
80 if (!checkPasswordLength(managedUserVM.getPassword())) {
81 throw new InvalidPasswordException();
82 }
83 User user = userService.registerUser(managedUserVM, managedUserVM.getPassword());
84 mailService.sendActivationEmail(user);
85 }
86
87 /**
88 * {@code GET /activate} : activate the registered user.
89 *
90 * @param key the activation key.
91 * @throws RuntimeException {@code 500 (Internal Server Error)} if the user couldn't be activated.
92 */
93 @GetMapping("/activate")
94 @ApiOperation(value = "Activate user account in application.")
95 @ApiResponses(value = {
96 @ApiResponse(code = 200, message = "OK"),
97 @ApiResponse(code = 500, message = "User could not be activated")
98 })
99 public void activateAccount(@ApiParam(value = "Key needed for activation", required = true) @RequestParam(value = "key") String key) {
100 Optional<User> user = userService.activateRegistration(key);
101 if (!user.isPresent()) {
102 throw new AccountResourceException("No user was found for this activation key");
103 }
104 }
105
106 /**
107 * {@code GET /account} : get the current user.
108 *
109 * @return the current user.
110 * @throws RuntimeException {@code 500 (Internal Server Error)} if the user couldn't be returned.
111 */
112 @GetMapping("/account")
113 @ApiOperation(value = "Get user account.", response = UserDTO.class)
114 @ApiResponses(value = {
115 @ApiResponse(code = 200, message = "OK", response = UserDTO.class),
116 @ApiResponse(code = 401, message = "Unauthorized"),
117 @ApiResponse(code = 403, message = "Forbidden"),
118 @ApiResponse(code = 500, message = "User could not be found")
119 })
120 public UserDTO getAccount() {
121 return userService.getUserWithAuthorities()
122 .map(UserDTO::of)
123 .orElseThrow(() -> new AccountResourceException("User could not be found"));
124 }
125
126 /**
127 * {@code POST /account} : update the current user information.
128 *
129 * @param userDTO the current user information.
130 * @throws RuntimeException {@code 500 (Internal Server Error)} if the user email wasn't found.
131 */
132 @PostMapping("/account")
133 @ApiOperation(value = "Update user account.")
134 @ApiResponses(value = {
135 @ApiResponse(code = 200, message = "OK"),
136 @ApiResponse(code = 201, message = "Created"),
137 @ApiResponse(code = 401, message = "Unauthorized"),
138 @ApiResponse(code = 403, message = "Forbidden"),
139 @ApiResponse(code = 500, message = "User could not be found")
140 })
141 public void saveAccount(@ApiParam(value = "User model", required = true) @Valid @RequestBody UserDTO userDTO) {
142 String userEmail = SecurityUtils.getCurrentUserEmail().orElseThrow(() -> new AccountResourceException("Current user email not found"));
143 Optional<User> user = userRepository.findOneByEmail(userEmail);
144 if (!user.isPresent()) {
145 throw new AccountResourceException("User could not be found");
146 }
147 userService.updateUser(userDTO.getFirstName(), userDTO.getLastName(), userDTO.getEmail(),
148 userDTO.getLangKey(), userDTO.getImageUrl());
149 }
150
151 /**
152 * {@code POST /account/change-password} : changes the current user's password.
153 *
154 * @param passwordChangeDto current and new password.
155 * @throws InvalidPasswordException {@code 400 (Bad Request)} if the new password is incorrect.
156 */
157 @PostMapping(path = "/account/change-password")
158 @ApiOperation(value = "Change user password.")
159 @ApiResponses(value = {
160 @ApiResponse(code = 200, message = "OK"),
161 @ApiResponse(code = 201, message = "Created"),
162 @ApiResponse(code = 400, message = "New password is incorrect"),
163 @ApiResponse(code = 401, message = "Unauthorized"),
164 @ApiResponse(code = 403, message = "Forbidden")
165 })
166 public void changePassword(@ApiParam(value = "Model which contains old and new password", required = true) @RequestBody PasswordChangeDTO passwordChangeDto) {
167 if (!checkPasswordLength(passwordChangeDto.getNewPassword())) {
168 throw new InvalidPasswordException();
169 }
170 userService.changePassword(passwordChangeDto.getCurrentPassword(), passwordChangeDto.getNewPassword());
171 }
172
173 /**
174 * {@code POST /account/reset-password/init} : Send an email to reset the password of the user.
175 *
176 * @param mail the mail of the user.
177 * @throws EmailNotFoundException {@code 400 (Bad Request)} if the email address is not registered.
178 */
179 @PostMapping(path = "/account/reset-password/init")
180 @ApiOperation(value = "Init request for reset password.")
181 @ApiResponses(value = {
182 @ApiResponse(code = 200, message = "OK"),
183 @ApiResponse(code = 201, message = "Created"),
184 @ApiResponse(code = 400, message = "Email address is not registered"),
185 @ApiResponse(code = 401, message = "Unauthorized"),
186 @ApiResponse(code = 403, message = "Forbidden")
187 })
188 public void requestPasswordReset(@ApiParam(value = "Mail address needed for change password operation", required = true) @RequestBody String mail) {
189 mailService.sendPasswordResetMail(
190 userService.requestPasswordReset(mail)
191 .orElseThrow(EmailNotFoundException::new)
192 );
193 }
194
195 /**
196 * {@code POST /account/reset-password/finish} : Finish to reset the password of the user.
197 *
198 * @param keyAndPassword the generated key and the new password.
199 * @throws InvalidPasswordException {@code 400 (Bad Request)} if the password is incorrect.
200 * @throws RuntimeException {@code 500 (Internal Server Error)} if the password could not be reset.
201 */
202 @PostMapping(path = "/account/reset-password/finish")
203 @ApiOperation(value = "Finish request for reset password.")
204 @ApiResponses(value = {
205 @ApiResponse(code = 200, message = "OK"),
206 @ApiResponse(code = 201, message = "Created"),
207 @ApiResponse(code = 400, message = "Password is incorrect"),
208 @ApiResponse(code = 401, message = "Unauthorized"),
209 @ApiResponse(code = 403, message = "Forbidden"),
210 @ApiResponse(code = 500, message = "Password could not be reset")
211 })
212 public void finishPasswordReset(@ApiParam(value = "Model which contains old and new password", required = true) @RequestBody KeyAndPasswordVM keyAndPassword) {
213 if (!checkPasswordLength(keyAndPassword.getNewPassword())) {
214 throw new InvalidPasswordException();
215 }
216 Optional<User> user =
217 userService.completePasswordReset(keyAndPassword.getNewPassword(), keyAndPassword.getKey());
218
219 if (!user.isPresent()) {
220 throw new AccountResourceException("No user was found for this reset key");
221 }
222 }
223
224 private static boolean checkPasswordLength(String password) {
225 return !StringUtils.isEmpty(password) &&
226 password.length() >= ManagedUserVM.PASSWORD_MIN_LENGTH &&
227 password.length() <= ManagedUserVM.PASSWORD_MAX_LENGTH;
228 }
229}