1
|
package cz.zcu.kiv.backendapi.user;
|
2
|
|
3
|
import com.auth0.jwt.JWT;
|
4
|
import com.auth0.jwt.JWTVerifier;
|
5
|
import com.auth0.jwt.algorithms.Algorithm;
|
6
|
import com.auth0.jwt.interfaces.DecodedJWT;
|
7
|
import com.google.common.base.Strings;
|
8
|
import cz.zcu.kiv.backendapi.exception.ApiRequestException;
|
9
|
import cz.zcu.kiv.backendapi.security.jwt.JwtUtils;
|
10
|
import cz.zcu.kiv.backendapi.user.password.PasswordDto;
|
11
|
import cz.zcu.kiv.backendapi.user.permission.PermissionDto;
|
12
|
import io.swagger.v3.oas.annotations.Operation;
|
13
|
import lombok.RequiredArgsConstructor;
|
14
|
import lombok.extern.slf4j.Slf4j;
|
15
|
import org.springframework.http.HttpHeaders;
|
16
|
import org.springframework.http.HttpStatus;
|
17
|
import org.springframework.http.ResponseEntity;
|
18
|
import org.springframework.security.core.GrantedAuthority;
|
19
|
import org.springframework.web.bind.annotation.*;
|
20
|
|
21
|
import javax.servlet.http.HttpServletRequest;
|
22
|
import javax.servlet.http.HttpServletResponse;
|
23
|
import javax.validation.Valid;
|
24
|
import javax.validation.constraints.NotNull;
|
25
|
import java.io.IOException;
|
26
|
import java.time.LocalDateTime;
|
27
|
import java.time.ZoneId;
|
28
|
import java.util.Date;
|
29
|
import java.util.List;
|
30
|
import java.util.stream.Collectors;
|
31
|
|
32
|
/**
|
33
|
* Controller for users
|
34
|
*/
|
35
|
@RestController
|
36
|
@RequiredArgsConstructor
|
37
|
@RequestMapping("/api//users")
|
38
|
@Slf4j
|
39
|
public class UserController {
|
40
|
|
41
|
/**
|
42
|
* User service
|
43
|
*/
|
44
|
private final IUserService userService;
|
45
|
|
46
|
/**
|
47
|
* JWT utils
|
48
|
*/
|
49
|
private final JwtUtils jwtUtils;
|
50
|
|
51
|
|
52
|
/**
|
53
|
* Registers new user
|
54
|
*
|
55
|
* @param userDto user DTO
|
56
|
*/
|
57
|
@PostMapping("")
|
58
|
@Operation(summary = "registers new user")
|
59
|
public void registerNewUser(@RequestBody @Valid UserDto userDto) {
|
60
|
userService.registerNewUser(userDto);
|
61
|
}
|
62
|
|
63
|
|
64
|
/**
|
65
|
* Changes password to logged-in user
|
66
|
*
|
67
|
* @param oldPassword old password
|
68
|
* @param passwordDto password DTO
|
69
|
*/
|
70
|
@PatchMapping("/password")
|
71
|
@Operation(summary = "changes password to logged-in user")
|
72
|
public void changePassword(@Valid @NotNull(message = "Old password must not be null") @RequestParam String oldPassword, @RequestBody @Valid PasswordDto passwordDto) {
|
73
|
userService.changePassword(oldPassword, passwordDto.getPassword());
|
74
|
}
|
75
|
|
76
|
/**
|
77
|
* Returns list of all users
|
78
|
*
|
79
|
* @return list of all users
|
80
|
*/
|
81
|
@GetMapping("")
|
82
|
@Operation(summary = "returns all users")
|
83
|
public ResponseEntity<List<UserDto>> getAllUsers() {
|
84
|
return new ResponseEntity<>(userService.getAllUsers(), HttpStatus.OK);
|
85
|
}
|
86
|
|
87
|
/**
|
88
|
* Updates permissions to given user
|
89
|
*
|
90
|
* @param username username
|
91
|
* @param permissionDto permissions
|
92
|
*/
|
93
|
@PatchMapping("/{username}/permissions")
|
94
|
@Operation(summary = "changes permissions to given user")
|
95
|
public void updatePermissions(@PathVariable String username, @RequestBody PermissionDto permissionDto) {
|
96
|
userService.updatePermissions(username, permissionDto);
|
97
|
}
|
98
|
|
99
|
/**
|
100
|
* Resets password to given user
|
101
|
*
|
102
|
* @param username username
|
103
|
* @param passwordDto password
|
104
|
*/
|
105
|
@PatchMapping(value = "/{username}/password")
|
106
|
@Operation(summary = "changes password to given user")
|
107
|
public void resetPassword(@PathVariable String username, @RequestBody @Valid PasswordDto passwordDto) {
|
108
|
userService.resetPassword(username, passwordDto.getPassword());
|
109
|
}
|
110
|
|
111
|
//TODO check if needed, comment otherwise
|
112
|
@DeleteMapping("/{username}")
|
113
|
@Operation(summary = "deletes user with given username")
|
114
|
public void deleteUser(@PathVariable String username) {
|
115
|
userService.deleteUser(username);
|
116
|
}
|
117
|
|
118
|
|
119
|
/**
|
120
|
* Refreshes access token if refresh token is valid
|
121
|
*
|
122
|
* @param request request
|
123
|
* @param response response
|
124
|
* @throws IOException I/O Exception
|
125
|
*/
|
126
|
@GetMapping("/token")
|
127
|
@Operation(summary = "returns a new access token and a refresh token to user")
|
128
|
public void refreshToken(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
129
|
String authorizationHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
|
130
|
if (Strings.isNullOrEmpty(authorizationHeader) || !authorizationHeader.startsWith(jwtUtils.getTokenPrefix())) {
|
131
|
throw new ApiRequestException("Refresh token is missing", HttpStatus.FORBIDDEN);
|
132
|
}
|
133
|
try {
|
134
|
String refresh_token = authorizationHeader.substring(jwtUtils.getTokenPrefix().length());
|
135
|
Algorithm algorithm = jwtUtils.getAlgorithm(); //TODO secure
|
136
|
JWTVerifier verifier = JWT.require(algorithm).build();
|
137
|
DecodedJWT decodedJWT = verifier.verify(refresh_token);
|
138
|
String username = decodedJWT.getSubject();
|
139
|
UserEntity user = userService.getUserByName(username);
|
140
|
String access_token = JWT.create()
|
141
|
.withSubject(user.getUsername())
|
142
|
.withExpiresAt(Date.from((LocalDateTime.now().plusMinutes(jwtUtils.getTokenExpirationAfterMinutes())).atZone(ZoneId.systemDefault()).toInstant()))
|
143
|
.withIssuer(request.getRequestURL().toString())
|
144
|
.withClaim(jwtUtils.getClaimAuthoritiesName(), user.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()))
|
145
|
.sign(algorithm);
|
146
|
jwtUtils.writeTokensToResponse(response, access_token, refresh_token);
|
147
|
} catch (Exception e) {
|
148
|
log.error("Error refreshing token in: " + e.getMessage());
|
149
|
jwtUtils.writeErrorToResponse(response, e);
|
150
|
}
|
151
|
}
|
152
|
}
|