From 48499e906961c71a081a5b61ee087c1f02ba12f0 Mon Sep 17 00:00:00 2001 From: Matej Hrica <492778@mail.muni.cz> Date: Sun, 7 May 2023 19:46:31 +0200 Subject: [PATCH] Send user activitry to user service --- .../client/UserServiceRequestInterceptor.java | 19 +- user/openapi.yaml | 168 ++---------------- user/pom.xml | 5 +- .../user/server/rest/UserController.java | 36 ++-- .../user/server/service/UserService.java | 31 ---- .../cz/muni/fi/pa165/user/server/UsersIT.java | 100 ----------- 6 files changed, 47 insertions(+), 312 deletions(-) diff --git a/user-client/src/main/java/cz/muni/fi/pa165/user/client/UserServiceRequestInterceptor.java b/user-client/src/main/java/cz/muni/fi/pa165/user/client/UserServiceRequestInterceptor.java index 00b84c0..1704da2 100644 --- a/user-client/src/main/java/cz/muni/fi/pa165/user/client/UserServiceRequestInterceptor.java +++ b/user-client/src/main/java/cz/muni/fi/pa165/user/client/UserServiceRequestInterceptor.java @@ -3,10 +3,12 @@ package cz.muni.fi.pa165.user.client; import cz.muni.chat.fi.pa165.user.client.invoker.ApiClient; import cz.muni.chat.fi.pa165.user.client.invoker.ApiException; +import cz.muni.fi.pa165.user.client.model.NewActivityDto; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.core.OAuth2AccessToken; import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthentication; import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionAuthenticatedPrincipal; import org.springframework.stereotype.Component; @@ -16,7 +18,7 @@ import org.springframework.web.servlet.HandlerInterceptor; @Component public class UserServiceRequestInterceptor implements HandlerInterceptor { - public void sendRequest() { + public void sendRequest(HttpServletRequest request) { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication == null) { System.out.println("auth disabled"); @@ -27,15 +29,20 @@ public class UserServiceRequestInterceptor implements HandlerInterceptor { for (var atrib : authPrincipal.getAttributes().entrySet()) { System.out.println("\t" + atrib.getKey() + " = " + atrib.getValue()); } - String token = ((BearerTokenAuthentication) authentication).getToken().getTokenValue(); - System.out.println("using token: '" + token + "'"); + var token = (OAuth2AccessToken) (((BearerTokenAuthentication) authentication).getToken()); + + System.out.println("using token: '" + token.getTokenValue() + "'"); try { var client = new ApiClient(); client.setRequestInterceptor((builder -> { - builder.header("Authorization", "Bearer " + token); + builder.header("Authorization", "Bearer " + token.getTokenValue()); })); var api = new UserApi(client); - System.out.println("proof that we can call: " + api.getUserById(1L)); + api.registerUserActivity(new NewActivityDto() + .url(request.getRequestURI()) + .httpMethod(request.getMethod()) + ); + request.getRequestURI(); } catch (ApiException e) { e.printStackTrace(); } @@ -44,7 +51,7 @@ public class UserServiceRequestInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("pre handle"); - sendRequest(); + sendRequest(request); return true; } } \ No newline at end of file diff --git a/user/openapi.yaml b/user/openapi.yaml index bcaedac..5cf9d8d 100644 --- a/user/openapi.yaml +++ b/user/openapi.yaml @@ -35,33 +35,6 @@ paths: type: array items: $ref: '#/components/schemas/UserDto' - put: - tags: - - User - summary: Create user - description: Create a new user and return it. - operationId: createUser - requestBody: - description: Data to create a new user - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/CreationUserDto' - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/UserDto' - "400": - description: Invalid input - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorMessage' - /api/users/{id}: get: tags: @@ -89,33 +62,23 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - put: + /api/users/activity: + post: tags: - User - summary: Update user by id. - description: Update a user - operationId: updateUserById + summary: Register activity for a user. + description: Register activity for a user. + operationId: registerUserActivity requestBody: - description: Data to create a new user + description: Data of the activity required: true content: application/json: schema: - $ref: '#/components/schemas/CreationUserDto' - parameters: - - name: id - in: path - required: true - schema: - type: integer - format: int64 + $ref: '#/components/schemas/NewActivityDto' responses: "200": description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/UserDto' "404": description: Not Found content: @@ -128,55 +91,6 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorMessage' - delete: - tags: - - User - summary: Delete user by id. - description: delete a user - operationId: deleteUserById - parameters: - - name: id - in: path - required: true - schema: - type: integer - format: int64 - responses: - "200": - description: OK - "404": - description: Not Found - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorMessage' - /api/login: - put: - tags: - - User - summary: Login to application - description: Login to application and return an authentication token - operationId: login - requestBody: - description: Login name and password - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/LoginDto' - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/LoginResponse' - "400": - description: Invalid input - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorMessage' components: securitySchemes: BearerAuth: @@ -241,68 +155,20 @@ components: role: description: the role of the user type: string - # FIXME: is this an openapi bug or just wrong syntax ? https://github.com/OpenAPITools/openapi-generator/issues/11323 - #enum: - # - manager - # - admin - CreationUserDto: + + NewActivityDto: type: object title: User description: Represents a user. required: - - login - - firstName - - lastName - - password - - email - - role + - url + - httpMethod properties: - login: - type: string - description: name used for logging in - example: john.doe - firstName: + url: type: string - description: first name of a the user - example: John - lastName: - type: string - description: last name of a user - example: Doe - password: - type: string - description: password of the user - example: secretPassword - email: - type: string - description: email address of the user - example: john@example.com - role: - type: string - # TODO: enum - LoginDto: - type: object - title: User - description: Represents login information for a user. - required: - - login - - password - properties: - login: - type: string - description: name used for logging in - example: john.doe - password: - type: string - description: password of the user - example: secretPassword - LoginResponse: - type: object - title: User - description: Represents a login response - required: - - token - properties: - token: + description: the url of the method + example: /api/weatherForecast + httpMethod: type: string - description: token used for authentication \ No newline at end of file + description: the method the user called + example: GET \ No newline at end of file diff --git a/user/pom.xml b/user/pom.xml index 4046e6b..e60c48d 100644 --- a/user/pom.xml +++ b/user/pom.xml @@ -77,7 +77,10 @@ <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-resource-server</artifactId> </dependency> - + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-oauth2-client</artifactId> + </dependency> <!-- for pagination from JPA without actually using JPA --> <dependency> <groupId>org.springframework.data</groupId> diff --git a/user/src/main/java/cz/muni/fi/pa165/user/server/rest/UserController.java b/user/src/main/java/cz/muni/fi/pa165/user/server/rest/UserController.java index 8760b2c..42e7df1 100644 --- a/user/src/main/java/cz/muni/fi/pa165/user/server/rest/UserController.java +++ b/user/src/main/java/cz/muni/fi/pa165/user/server/rest/UserController.java @@ -1,13 +1,13 @@ package cz.muni.fi.pa165.user.server.rest; import cz.muni.fi.pa165.user.server.api.UserApiDelegate; -import cz.muni.fi.pa165.user.server.model.CreationUserDto; -import cz.muni.fi.pa165.user.server.model.LoginDto; -import cz.muni.fi.pa165.user.server.model.LoginResponse; +import cz.muni.fi.pa165.user.server.model.NewActivityDto; import cz.muni.fi.pa165.user.server.model.UserDto; import cz.muni.fi.pa165.user.server.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionAuthenticatedPrincipal; import org.springframework.web.bind.annotation.RestController; import java.util.List; @@ -28,28 +28,18 @@ public class UserController implements UserApiDelegate { } @Override - public ResponseEntity<UserDto> createUser(CreationUserDto creationUserDto) { - return ResponseEntity.ok(userService.createUser(creationUserDto)); - } - - @Override - public ResponseEntity<UserDto> updateUserById(Long id, CreationUserDto creationUserDto) { - return ResponseEntity.ok(userService.updateUserById(id, creationUserDto)); - } - - @Override - public ResponseEntity<Void> deleteUserById(Long id) { - userService.deleteUserById(id); - return ResponseEntity.ok(null); - } - - @Override - public ResponseEntity<LoginResponse> login(LoginDto loginDto) { - return ResponseEntity.ok(userService.login(loginDto)); + public ResponseEntity<List<UserDto>> getAllUsers() { + return ResponseEntity.ok(userService.getAllUsers()); } @Override - public ResponseEntity<List<UserDto>> getAllUsers() { - return ResponseEntity.ok(userService.getAllUsers()); + public ResponseEntity<Void> registerUserActivity(NewActivityDto newActivityDto) { + var principal = (OAuth2IntrospectionAuthenticatedPrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + for (var entry : principal.getAttributes().entrySet()) { + System.out.println(entry.getKey() + "=" + entry.getValue()); + } + System.out.println("called " + newActivityDto.getHttpMethod() + " on " + newActivityDto.getUrl()); + + return ResponseEntity.ok().build(); } } diff --git a/user/src/main/java/cz/muni/fi/pa165/user/server/service/UserService.java b/user/src/main/java/cz/muni/fi/pa165/user/server/service/UserService.java index 0562646..e7210ed 100644 --- a/user/src/main/java/cz/muni/fi/pa165/user/server/service/UserService.java +++ b/user/src/main/java/cz/muni/fi/pa165/user/server/service/UserService.java @@ -1,8 +1,5 @@ package cz.muni.fi.pa165.user.server.service; -import cz.muni.fi.pa165.user.server.model.CreationUserDto; -import cz.muni.fi.pa165.user.server.model.LoginDto; -import cz.muni.fi.pa165.user.server.model.LoginResponse; import cz.muni.fi.pa165.user.server.model.UserDto; import org.springframework.stereotype.Service; @@ -21,34 +18,6 @@ public class UserService { .role("manager"); } - public UserDto createUser(CreationUserDto creationUserDto) { - return new UserDto() - .id(1L) - .login(creationUserDto.getLogin()) - .firstName(creationUserDto.getFirstName()) - .lastName(creationUserDto.getLastName()) - .email(creationUserDto.getEmail()) - .role(creationUserDto.getRole()); - } - - public UserDto updateUserById(Long id, CreationUserDto creationUserDto) { - return new UserDto() - .id(id) - .login(creationUserDto.getLogin()) - .firstName(creationUserDto.getFirstName()) - .lastName(creationUserDto.getLastName()) - .email(creationUserDto.getEmail()) - .role(creationUserDto.getRole()); - } - - public void deleteUserById(Long id) { - - } - - public LoginResponse login(LoginDto loginDto) { - return new LoginResponse().token("token-for-" + loginDto.getLogin()); - } - public List<UserDto> getAllUsers() { return List.of(getUserById(1L)); } diff --git a/user/src/test/java/cz/muni/fi/pa165/user/server/UsersIT.java b/user/src/test/java/cz/muni/fi/pa165/user/server/UsersIT.java index 2bffec1..c515b00 100644 --- a/user/src/test/java/cz/muni/fi/pa165/user/server/UsersIT.java +++ b/user/src/test/java/cz/muni/fi/pa165/user/server/UsersIT.java @@ -1,7 +1,6 @@ package cz.muni.fi.pa165.user.server; import com.fasterxml.jackson.databind.ObjectMapper; -import cz.muni.fi.pa165.user.server.model.LoginResponse; import cz.muni.fi.pa165.user.server.model.UserDto; import org.junit.jupiter.api.Test; import org.slf4j.Logger; @@ -9,7 +8,6 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import static org.assertj.core.api.Assertions.assertThat; @@ -67,102 +65,4 @@ class UsersIT { assertThat(responseDtos[0].getEmail()).isEqualTo("john@example.com"); } - @Test - void createUser() throws Exception { - log.debug("createUser() running"); - String requestBody = """ - { - "login": "john.doe", - "firstName": "John", - "lastName": "Doe", - "password": "secretPassword", - "email": "john@example.com", - "role": "manager" - }"""; - - String response = mockMvc.perform( - put("/api/users/") - .contentType(MediaType.APPLICATION_JSON) - .content(requestBody)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.id").value(1L)) - .andExpect(jsonPath("$.firstName").value("John")) - .andExpect(jsonPath("$.lastName").value("Doe")) - .andExpect(jsonPath("$.login").value("john.doe")) - .andExpect(jsonPath("$.email").value("john@example.com")) - .andExpect(jsonPath("$.role").value("manager")) - .andReturn().getResponse().getContentAsString(); - log.debug("response: {}", response); - UserDto responseDto = objectMapper.readValue(response, UserDto.class); - assertThat(responseDto.getId()).isEqualTo(1L); - assertThat(responseDto.getFirstName()).isEqualTo("John"); - assertThat(responseDto.getLastName()).isEqualTo("Doe"); - assertThat(responseDto.getLogin()).isEqualTo("john.doe"); - assertThat(responseDto.getEmail()).isEqualTo("john@example.com"); - } - - @Test - void updateUserById() throws Exception { - log.debug("updateUserByIdTest() running"); - String requestBody = """ - { - "login": "john.doe", - "firstName": "John", - "lastName": "Doe", - "password": "secretPassword", - "email": "john@example.com", - "role": "manager" - }"""; - - String response = mockMvc.perform( - put("/api/users/1") - .contentType(MediaType.APPLICATION_JSON) - .content(requestBody)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.firstName").value("John")) - .andExpect(jsonPath("$.lastName").value("Doe")) - .andExpect(jsonPath("$.login").value("john.doe")) - .andExpect(jsonPath("$.email").value("john@example.com")) - .andExpect(jsonPath("$.role").value("manager")) - .andReturn().getResponse().getContentAsString(); - log.debug("response: {}", response); - UserDto responseDto = objectMapper.readValue(response, UserDto.class); - assertThat(responseDto.getFirstName()).isEqualTo("John"); - assertThat(responseDto.getLastName()).isEqualTo("Doe"); - assertThat(responseDto.getLogin()).isEqualTo("john.doe"); - assertThat(responseDto.getEmail()).isEqualTo("john@example.com"); - } - - @Test - void deleteUser() throws Exception { - log.debug("deleteUserBy() running"); - - String response = mockMvc.perform( - delete("/api/users/1")) - .andExpect(status().isOk()) - .andReturn().getResponse().getContentAsString(); - log.debug("response: {}", response); - } - - @Test - void login() throws Exception { - log.debug("login() running"); - String requestBody = """ - { - "login": "john.doe", - "password": "password" - }"""; - - String response = mockMvc.perform( - put("/api/login") - .contentType(MediaType.APPLICATION_JSON) - .content(requestBody)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.token").value("token-for-john.doe")) - .andReturn().getResponse().getContentAsString(); - log.debug("response: {}", response); - LoginResponse responseDto = objectMapper.readValue(response, LoginResponse.class); - assertThat(responseDto.getToken()).isEqualTo("token-for-john.doe"); - } - } -- GitLab