From 71d01af67102a4efa765bb220eb244722cad6a59 Mon Sep 17 00:00:00 2001 From: ialbert Date: Thu, 29 Dec 2022 16:33:02 +0300 Subject: [PATCH] separated user update from user auth success --- .../controller/queue/user/UserController.java | 13 +++- .../request/cud/utilities/UserAuthAction.java | 64 +++++-------------- .../cud/utilities/UserAuthSystemAction.java | 42 ++++++++++++ .../backendapi/service/UserAuthProcessor.java | 8 ++- .../clearing/utility/service/UserService.java | 14 ++++ .../platform/messaging/domain/Consts.java | 1 + .../cud/utilities/UserUpdateRequest.java | 29 +++++++++ 7 files changed, 117 insertions(+), 54 deletions(-) create mode 100644 clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/utilities/UserAuthSystemAction.java create mode 100644 platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/utilities/UserUpdateRequest.java diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/user/UserController.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/user/UserController.java index 9c676f3f0..1ab83b5c6 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/user/UserController.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/queue/user/UserController.java @@ -3,6 +3,8 @@ package ru.spcex.clearing.backendapi.controller.queue.user; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.security.core.Authentication; @@ -33,6 +35,7 @@ import java.util.concurrent.ExecutionException; @Controller @RequestMapping("/users") public class UserController extends AbstractQueueController { + private Logger log = LoggerFactory.getLogger(getClass()); private final IStateLoader stateLoader; private final Imdg userImdg; @@ -62,14 +65,18 @@ public class UserController extends AbstractQueueController { @RequestMapping(method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE) @ResponseBody public CudResponse update( - @RequestBody UserAuthAction userAuthAction) throws ExecutionException, InterruptedException { + @RequestBody UserAuthAction userUpdateAction) throws ExecutionException, InterruptedException { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); String username = KeycloakUtils.getUserNameFromAuthentication(authentication); + if (!username.equals(userUpdateAction.getUsername())) { + log.warn("user {} sended update request for user {}", username, userUpdateAction.getUsername()); + throw new IllegalStateException("cannot perform delete action for " + username); + } User user = userImdg.getSingleObjectByFieldValues(Map.of("identifier", username)); if (user == null) { - return processRequest(Consts.USER_AUTH_SUCCESS, userAuthAction); + log.info("user {} authenticated, but User object was not created", username); } - throw new IllegalStateException("cannot create user cause it is exists: " + username); + return processRequest(Consts.USER_UPDATE, userUpdateAction); } diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/utilities/UserAuthAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/utilities/UserAuthAction.java index f922f4200..df59f552e 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/utilities/UserAuthAction.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/utilities/UserAuthAction.java @@ -2,35 +2,24 @@ package ru.spcex.clearing.backendapi.controller.request.cud.utilities; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; import ru.spcex.clearing.backendapi.domain.actions.IAction; import ru.spcex.clearing.backendapi.errors.BackEndError; import ru.spcex.clearing.platform.messaging.domain.ActionType; -import ru.spcex.clearing.platform.messaging.domain.cud.utilities.UserAuthRequest; -import ru.spcex.clearing.platform.messaging.domain.json.deserialize.InstantDeserializer; -import ru.spcex.clearing.platform.messaging.domain.json.serialize.InstantSerializer; +import ru.spcex.clearing.platform.messaging.domain.cud.utilities.UserUpdateRequest; +import ru.spcex.platform.enumeration.UserRole; import ru.spcex.platform.utils.enumeration.EnumMessage; +import ru.spcex.platform.utils.enumeration.IEnumKey; -import java.time.Instant; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; -public class UserAuthAction implements IAction { +public class UserAuthAction implements IAction { @JsonProperty private String username; @JsonProperty private List roles = new ArrayList<>(); - @JsonSerialize(using = InstantSerializer.class) - @JsonDeserialize(using = InstantDeserializer.class) - @JsonProperty - private Instant time; - @JsonProperty - private String serverIp; - @JsonProperty - private String clientIp; @Override public Collection validate() { @@ -38,24 +27,27 @@ public class UserAuthAction implements IAction { if (count != roles.size()) { return List.of(new EnumMessage(BackEndError.KeycloakRepeatedRoles)); } + boolean unknownRolePresent = roles + .stream() + .anyMatch(role -> IEnumKey.getEnumByKey(UserRole.class, role) == null); + if (unknownRolePresent) { + return List.of(new EnumMessage(BackEndError.ValidationError, roles)); + } return Collections.emptyList(); } @Override - public UserAuthRequest toRequest() { - UserAuthRequest userAuthRequest = new UserAuthRequest(); - userAuthRequest.setServerIp(serverIp); - userAuthRequest.setClientIp(clientIp); - userAuthRequest.setUsername(username); - userAuthRequest.setRoles(roles); - userAuthRequest.setTime(time); - return userAuthRequest; + public UserUpdateRequest toRequest() { + UserUpdateRequest userUpdateRequest = new UserUpdateRequest(); + userUpdateRequest.setUsername(username); + userUpdateRequest.setRoles(roles); + return userUpdateRequest; } @Override public ActionType getActionType() { - return ActionType.SYSTEM; + return ActionType.UPDATE; } public String getUsername() { @@ -73,28 +65,4 @@ public class UserAuthAction implements IAction { public void setRoles(List roles) { this.roles = roles; } - - public Instant getTime() { - return time; - } - - public void setTime(Instant time) { - this.time = time; - } - - public String getServerIp() { - return serverIp; - } - - public void setServerIp(String serverIp) { - this.serverIp = serverIp; - } - - public String getClientIp() { - return clientIp; - } - - public void setClientIp(String clientIp) { - this.clientIp = clientIp; - } } diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/utilities/UserAuthSystemAction.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/utilities/UserAuthSystemAction.java new file mode 100644 index 000000000..b4bfd9d80 --- /dev/null +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/request/cud/utilities/UserAuthSystemAction.java @@ -0,0 +1,42 @@ +package ru.spcex.clearing.backendapi.controller.request.cud.utilities; + + +import ru.spcex.clearing.backendapi.domain.actions.IAction; +import ru.spcex.clearing.backendapi.errors.BackEndError; +import ru.spcex.clearing.platform.messaging.domain.ActionType; +import ru.spcex.clearing.platform.messaging.domain.cud.utilities.UserAuthRequest; +import ru.spcex.platform.utils.enumeration.EnumMessage; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +public class UserAuthSystemAction implements IAction { +private final UserAuthRequest authRequest; + + public UserAuthSystemAction() { + this.authRequest = new UserAuthRequest(); + } + + public UserAuthRequest getAuthRequest() { + return authRequest; + } + + @Override + public Collection validate() { + long count = authRequest.getRoles().stream().distinct().count(); + if (count != authRequest.getRoles().size()) { + return List.of(new EnumMessage(BackEndError.KeycloakRepeatedRoles)); + } + return Collections.emptyList(); + } + + @Override + public UserAuthRequest toRequest() { + return authRequest; + } + + @Override + public ActionType getActionType() { + return ActionType.SYSTEM; + }} diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/UserAuthProcessor.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/UserAuthProcessor.java index 97f35a7a6..e160f761a 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/UserAuthProcessor.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/UserAuthProcessor.java @@ -5,9 +5,10 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; -import ru.spcex.clearing.backendapi.controller.request.cud.utilities.UserAuthAction; +import ru.spcex.clearing.backendapi.controller.request.cud.utilities.UserAuthSystemAction; import ru.spcex.clearing.backendapi.controller.request.cud.utilities.UserLogoutAction; import ru.spcex.clearing.platform.messaging.domain.Consts; +import ru.spcex.clearing.platform.messaging.domain.cud.utilities.UserAuthRequest; import ru.spcex.clearing.platform.messaging.domain.cud.utilities.UserLogoutRequest; import ru.spcex.platform.utils.log.ExceptionUtils; @@ -33,14 +34,15 @@ public class UserAuthProcessor { } public void sendAuthSuccessEvent(String identifier, Collection roles, String userIp, String serverIp) { - UserAuthAction requestData = new UserAuthAction(); + UserAuthSystemAction authEvent = new UserAuthSystemAction(); + UserAuthRequest requestData = authEvent.toRequest(); requestData.setUsername(identifier); requestData.setTime(Instant.now()); requestData.setRoles(new ArrayList<>(roles)); requestData.setServerIp(serverIp + ":" + serverPort); //getServerAddress() + ":" + serverPort requestData.setClientIp(userIp); try { - operator.sendRequestToQueue(Consts.USER_AUTH_SUCCESS, requestData); + operator.sendRequestToQueue(Consts.USER_AUTH_SUCCESS, authEvent); } catch (Throwable e) { //ExecutionException | InterruptedException log.error(ExceptionUtils.getStackTrace(e)); } diff --git a/clearing-parent/utility-service/src/main/java/ru/spcex/clearing/utility/service/UserService.java b/clearing-parent/utility-service/src/main/java/ru/spcex/clearing/utility/service/UserService.java index 7490e5b30..5f7c95189 100644 --- a/clearing-parent/utility-service/src/main/java/ru/spcex/clearing/utility/service/UserService.java +++ b/clearing-parent/utility-service/src/main/java/ru/spcex/clearing/utility/service/UserService.java @@ -14,6 +14,7 @@ import ru.spcex.clearing.platform.messaging.domain.BaseRequest; import ru.spcex.clearing.platform.messaging.domain.Consts; import ru.spcex.clearing.platform.messaging.domain.cud.utilities.UserAuthRequest; import ru.spcex.clearing.platform.messaging.domain.cud.utilities.UserLogoutRequest; +import ru.spcex.clearing.platform.messaging.domain.cud.utilities.UserUpdateRequest; import ru.spcex.clearing.platform.messaging.service.QueueConsumer; import ru.spcex.platform.enumeration.ConnectionState; import ru.spcex.platform.enumeration.Status; @@ -97,12 +98,25 @@ public class UserService extends QueueConsumer implements InitializingBean { callback(UserAuthRequest.class) .setConsumer(this::userAuthSuccess) .forDestination(Consts.USER_AUTH_SUCCESS, callbacks::put); + callback(UserUpdateRequest.class) + .setConsumer(this::userUpdate) + .forDestination(Consts.USER_UPDATE, callbacks::put); callback(UserLogoutRequest.class) .setConsumer(this::usersLogoutSuccess) .forDestination(Consts.USER_LOGOUT_SUCCESS, callbacks::put); init(); } + private void userUpdate(BaseRequest updateEvent) { + UserUpdateRequest updateInfo = updateEvent.getRequestPayload(); + log.debug("user name={} update request", updateInfo.getUsername()); + UserInfo userInfo = createUserIfNeeded(updateInfo.getUsername()); + if (userInfo.isNew) { + log.warn("update for non-existent user"); + } + changeRoles(userInfo.userId, userInfo.isNew, updateInfo.getRoles()); + } + private void userAuthSuccess(BaseRequest authEvent) { UserAuthRequest authInfo = authEvent.getRequestPayload(); log.debug("user name={} authenticated", authInfo.getUsername()); diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java index 0ffbba428..418f49b34 100644 --- a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/Consts.java @@ -39,6 +39,7 @@ public interface Consts { String DESTINATION_SDF02_NEW = "s-df-02-new"; String USER_AUTH_SUCCESS = "user-auth-success"; + String USER_UPDATE = "user-update"; String USER_LOGOUT_SUCCESS = "user-logout-success"; String USER_SETTINGS_UPDATE = "user-settings-update"; diff --git a/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/utilities/UserUpdateRequest.java b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/utilities/UserUpdateRequest.java new file mode 100644 index 000000000..500979c8a --- /dev/null +++ b/platform-parent/platform-messaging/src/main/java/ru/spcex/clearing/platform/messaging/domain/cud/utilities/UserUpdateRequest.java @@ -0,0 +1,29 @@ +package ru.spcex.clearing.platform.messaging.domain.cud.utilities; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.ArrayList; +import java.util.List; + +public class UserUpdateRequest { + @JsonProperty + private String username; + @JsonProperty + private List roles = new ArrayList<>(); + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public List getRoles() { + return roles; + } + + public void setRoles(List roles) { + this.roles = roles; + } +}