Projekt

Obecné

Profil

Stáhnout (5.43 KB) Statistiky
| Větev: | Tag: | Revize:
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("/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
}
(3-3/7)