This commit is contained in:
parent
d124da97b8
commit
cefcd14fda
20 changed files with 663 additions and 11 deletions
|
|
@ -10,6 +10,7 @@ import org.springframework.http.converter.HttpMessageConverter;
|
|||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.context.request.RequestContextListener;
|
||||
import org.springframework.web.servlet.config.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -69,4 +70,9 @@ public class WebConfig implements WebMvcConfigurer {
|
|||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/**").allowedMethods("*");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RequestContextListener requestContextListener() {
|
||||
return new RequestContextListener();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
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 UserAuthAction implements IAction<UserAuthRequest> {
|
||||
private final UserAuthRequest authRequest;
|
||||
|
||||
public UserAuthAction() {
|
||||
this.authRequest = new UserAuthRequest();
|
||||
}
|
||||
|
||||
public UserAuthRequest getAuthRequest() {
|
||||
return authRequest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<EnumMessage> 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,8 @@ import ru.spcex.platform.utils.enumeration.IEnumId;
|
|||
public enum BackEndError implements IEnumId {
|
||||
ValidationError(3000L),
|
||||
UnknownJsonProperty(3001L),
|
||||
FailedToReadHttpMessage(3002L);
|
||||
FailedToReadHttpMessage(3002L),
|
||||
KeycloakRepeatedRoles(3003L);
|
||||
private final Long id;
|
||||
|
||||
BackEndError(Long id) {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ import org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount;
|
|||
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
|
||||
import org.keycloak.common.VerificationException;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.security.authentication.AuthenticationProvider;
|
||||
|
|
@ -24,7 +26,7 @@ import org.springframework.util.LinkedMultiValueMap;
|
|||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.HttpClientErrorException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import ru.spcex.clearing.backendapi.service.UserAutoCreateService;
|
||||
import ru.spcex.clearing.backendapi.service.UserAuthProcessor;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
|
@ -36,14 +38,15 @@ import java.util.stream.Collectors;
|
|||
|
||||
@Component("keycloakRestAuthenticationProvider")
|
||||
public class KeycloakRestTemplateAuthenticationProvider implements AuthenticationProvider {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
private final KeycloakConfigResolver resolver;
|
||||
private final HttpServletRequest currentHttpRequest;
|
||||
private final HttpServletResponse currentHttpResponse;
|
||||
private final RestTemplate restTemplate;
|
||||
private final UserAutoCreateService userAutoCreation;
|
||||
private final UserAuthProcessor userAutoCreation;
|
||||
|
||||
public KeycloakRestTemplateAuthenticationProvider(KeycloakConfigResolver resolver, HttpServletRequest currentHttpRequest, HttpServletResponse currentHttpResponse,
|
||||
@Qualifier("clearing-rest") RestTemplate restTemplate, UserAutoCreateService userAutoCreation) {
|
||||
@Qualifier("clearing-rest") RestTemplate restTemplate, UserAuthProcessor userAutoCreation) {
|
||||
this.resolver = resolver;
|
||||
this.currentHttpRequest = currentHttpRequest;
|
||||
this.currentHttpResponse = currentHttpResponse;
|
||||
|
|
@ -79,8 +82,6 @@ public class KeycloakRestTemplateAuthenticationProvider implements Authenticatio
|
|||
AccessToken accessToken = AdapterTokenVerifier.verifyToken(accessTokenString, deployment);
|
||||
//todo cors settings
|
||||
accessToken.setAllowedOrigins(Collections.singleton("*"));
|
||||
|
||||
System.out.println("login successful");
|
||||
List<SimpleGrantedAuthority> realmRoles = accessToken.getRealmAccess().getRoles().stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList());
|
||||
|
||||
RefreshableKeycloakSecurityContext skSession = new RefreshableKeycloakSecurityContext(deployment, null, accessTokenString, accessToken, null, null, refreshTokenString);
|
||||
|
|
@ -90,7 +91,7 @@ public class KeycloakRestTemplateAuthenticationProvider implements Authenticatio
|
|||
final KeycloakAccount account = new SimpleKeycloakAccount(principal, roles, skSession);
|
||||
KeycloakAuthenticationToken keycloakAuthenticationToken = new KeycloakAuthenticationToken(account, false, realmRoles);
|
||||
keycloakAuthenticationToken.setAuthenticated(true);
|
||||
checkRightsAndCreate(principalName, roles);
|
||||
checkRightsAndCreate(principalName, accessToken.getId(), roles);
|
||||
return keycloakAuthenticationToken;
|
||||
|
||||
} catch (VerificationException vex) {
|
||||
|
|
@ -100,10 +101,14 @@ public class KeycloakRestTemplateAuthenticationProvider implements Authenticatio
|
|||
}
|
||||
}
|
||||
|
||||
private void checkRightsAndCreate(String username, Set<String> roles) {
|
||||
private void checkRightsAndCreate(String username, String id, Set<String> roles) {
|
||||
|
||||
log.debug("login successful: login {}, roles {}", username, String.join(";", roles));
|
||||
//todo remove hardcode
|
||||
if (roles.contains("admin") || roles.contains("default-roles-master")) {
|
||||
userAutoCreation.createUserIfNeeded(username);
|
||||
String clientIp = currentHttpRequest != null ? currentHttpRequest.getRemoteAddr() : null;
|
||||
String serverIp = currentHttpRequest != null ? currentHttpRequest.getLocalAddr() : null;
|
||||
userAutoCreation.sendUserInfo(username, id, roles, clientIp, serverIp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
package ru.spcex.clearing.backendapi.service;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
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.platform.messaging.domain.Consts;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.utilities.UserAuthRequest;
|
||||
import ru.spcex.platform.utils.log.ExceptionUtils;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
|
||||
@Service
|
||||
public class UserAuthProcessor {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
private final IOperator operator;
|
||||
private String serverAddress;
|
||||
|
||||
@Value("${server.port}")
|
||||
private String serverPort;
|
||||
|
||||
@Autowired
|
||||
public UserAuthProcessor(IOperator operator) {
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
public void sendUserInfo(String username, String identifier, Collection<String> roles, String userIp, String serverIp) {
|
||||
UserAuthAction authEvent = new UserAuthAction();
|
||||
UserAuthRequest requestData = authEvent.getAuthRequest();
|
||||
requestData.setUsername(username);
|
||||
requestData.setIdentifier(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, authEvent);
|
||||
} catch (Throwable e) { //ExecutionException | InterruptedException
|
||||
log.error(ExceptionUtils.getStackTrace(e));
|
||||
}
|
||||
}
|
||||
|
||||
private String getServerAddress() {
|
||||
if (serverAddress != null) {
|
||||
return serverAddress;
|
||||
}
|
||||
try {
|
||||
Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
|
||||
while (networkInterfaces.hasMoreElements()) {
|
||||
NetworkInterface networkInterface = networkInterfaces.nextElement();
|
||||
Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses();
|
||||
while(inetAddresses.hasMoreElements()) {
|
||||
InetAddress inetAddress = inetAddresses.nextElement();
|
||||
if (inetAddress != null) {
|
||||
serverAddress = inetAddress.getHostAddress();
|
||||
return serverAddress;
|
||||
}
|
||||
}
|
||||
}
|
||||
serverAddress = "unknown";
|
||||
return serverAddress;
|
||||
} catch (Throwable e) {
|
||||
log.error("cannot retrieve server address {}", ExceptionUtils.getStackTrace(e));
|
||||
serverAddress = "unknown";
|
||||
return serverAddress;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -20,6 +20,10 @@
|
|||
<groupId>ru.spcex.platform</groupId>
|
||||
<artifactId>platform-messaging</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ru.spcex.platform</groupId>
|
||||
<artifactId>platform-enum</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ru.spcex.platform</groupId>
|
||||
<artifactId>platform-imdg-api-hazelcast-impl</artifactId>
|
||||
|
|
@ -36,6 +40,28 @@
|
|||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- TEST -->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.springframework</groupId>-->
|
||||
<!-- <artifactId>spring-test</artifactId>-->
|
||||
<!-- <scope>test</scope>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.mockito</groupId>-->
|
||||
<!-- <artifactId>mockito-core</artifactId>-->
|
||||
<!-- <scope>test</scope>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@ package ru.spcex.clearing.utility.config;
|
|||
|
||||
import org.apache.kafka.clients.consumer.Consumer;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import ru.spcex.clearing.platform.messaging.config.KafkaConsumerFactory;
|
||||
import ru.spcex.clearing.utility.config.settings.UtilityServiceSettings;
|
||||
|
||||
|
|
@ -11,6 +13,7 @@ import ru.spcex.clearing.utility.config.settings.UtilityServiceSettings;
|
|||
public class KafkaConfig {
|
||||
@Autowired
|
||||
@Bean
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public Consumer<String, Object> createProducer(UtilityServiceSettings settings) {
|
||||
return KafkaConsumerFactory.consumer(settings.getKafka());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,176 @@
|
|||
package ru.spcex.clearing.utility.service;
|
||||
|
||||
import org.apache.kafka.clients.consumer.Consumer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ru.clearing.classes.statics.data.user.User;
|
||||
import ru.clearing.classes.statics.data.user.UserConnect;
|
||||
import ru.clearing.classes.statics.data.user.UserRoleSession;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
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.service.QueueConsumer;
|
||||
import ru.spcex.platform.enumeration.ConnectionState;
|
||||
import ru.spcex.platform.enumeration.Status;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.utils.time.TimeUtil;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Service
|
||||
public class UserService extends QueueConsumer implements InitializingBean {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
private final Imdg<User> userMap;
|
||||
private final Imdg<UserRoleSession> userRoleSessionImdg;
|
||||
private final Imdg<UserConnect> userConnectImdg;
|
||||
|
||||
@Autowired
|
||||
public UserService(Consumer<String, Object> kafkaQueue, ImdgProvider imdgProvider) {
|
||||
super(kafkaQueue);
|
||||
this.userMap = imdgProvider.getImdg(IMDGDistributedNames.Map_User, User.class);
|
||||
this.userRoleSessionImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_UserRoleSession, UserRoleSession.class);
|
||||
this.userConnectImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_UserConnect, UserConnect.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
callback(UserAuthRequest.class)
|
||||
.setConsumer(this::userAuthSuccess)
|
||||
.forDestination(Consts.USER_AUTH_SUCCESS, callbacks::put);
|
||||
init();
|
||||
}
|
||||
|
||||
private void userAuthSuccess(BaseRequest<UserAuthRequest> authEvent) {
|
||||
UserAuthRequest authInfo = authEvent.getRequestPayload();
|
||||
log.debug("user id={} authenticated", authInfo.getUsername());
|
||||
UserInfo userInfo = createUserIfNeeded(authInfo.getUsername());
|
||||
changeRoles(userInfo.userId, userInfo.isNew, authInfo.getRoles());
|
||||
connected(userInfo.userId, authInfo.getTime(), authInfo.getClientIp(), authInfo.getServerIp());
|
||||
}
|
||||
|
||||
private UserInfo createUserIfNeeded(String username) {
|
||||
User user = userMap.getSingleObjectByFieldValues(Map.of("identifier", username));
|
||||
if (user == null) {
|
||||
user = new User();
|
||||
user.setCreated(Instant.now());
|
||||
user.setIdentifier(username);
|
||||
userMap.insert(user);
|
||||
return new UserInfo(true, user.getId());
|
||||
} else {
|
||||
return new UserInfo(false, user.getId());
|
||||
}
|
||||
}
|
||||
|
||||
private void changeRoles(Long userId, boolean isNew, Collection<String> authRoles) {
|
||||
Collection<UserRoleSession> presentRoles;
|
||||
if (isNew) {
|
||||
presentRoles = Collections.emptyList();
|
||||
} else {
|
||||
presentRoles = userRoleSessionImdg.getCollectionObjectsByFieldValues(Map.of("userId", userId));
|
||||
}
|
||||
|
||||
Collection<RoleAction> roleActions = defineAllRoleChanges(presentRoles, authRoles);
|
||||
|
||||
if (roleActions.size() > 0) {
|
||||
for (RoleAction roleAction : roleActions) {
|
||||
UserRoleSession role;
|
||||
if (roleAction.create()) {
|
||||
role = new UserRoleSession();
|
||||
role.setUserRole(roleAction.roleName);
|
||||
role.setUserId(userId);
|
||||
role.setStatus(Status.Active.getKey());
|
||||
userRoleSessionImdg.insert(role);
|
||||
} else {
|
||||
role = roleAction.roleToChange;
|
||||
role.setStatus(roleAction.newStatus.getKey());
|
||||
userRoleSessionImdg.update(role);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void connected(Long userId, Instant time, String clientIp, String serverIp) {
|
||||
UserConnect userConnect = userConnectImdg.getSingleObjectByFieldValues(Map.of("userId", userId));
|
||||
boolean isNew = false;
|
||||
if (userConnect == null) {
|
||||
userConnect = new UserConnect();
|
||||
userConnect.setUserId(userId);
|
||||
isNew = true;
|
||||
}
|
||||
userConnect.setConnectionTime(time);
|
||||
userConnect.setServerIP(serverIp);
|
||||
userConnect.setClientIP(clientIp);
|
||||
userConnect.setConnectionState(ConnectionState.Connected.getKey());
|
||||
userConnect.setClearingDate(TimeUtil.today());
|
||||
if (isNew) {
|
||||
userConnectImdg.insert(userConnect);
|
||||
} else {
|
||||
userConnectImdg.update(userConnect);
|
||||
}
|
||||
}
|
||||
|
||||
static Collection<RoleAction> defineAllRoleChanges(Collection<UserRoleSession> presentRoles, Collection<String> authRoles) {
|
||||
return Stream.concat(
|
||||
presentRoles
|
||||
.stream()
|
||||
.filter(presentRole -> !(Status.Active.equalsByKey(presentRole.getStatus()) && contain(presentRole, authRoles)))
|
||||
.filter(presentRole -> !(Status.Blocked.equalsByKey(presentRole.getStatus()) && !contain(presentRole, authRoles)))
|
||||
.map(role -> {
|
||||
RoleAction roleAction = new RoleAction();
|
||||
roleAction.roleToChange = role;
|
||||
if (Status.Active.equalsByKey(role.getStatus())) {
|
||||
roleAction.newStatus = Status.Blocked;
|
||||
} else {
|
||||
roleAction.newStatus = Status.Active;
|
||||
}
|
||||
return roleAction;
|
||||
}),
|
||||
authRoles
|
||||
.stream()
|
||||
.filter(authRole -> !contain(authRole, presentRoles))
|
||||
.map(authRole -> {
|
||||
RoleAction action = new RoleAction();
|
||||
action.newStatus = Status.Active;
|
||||
action.roleName = authRole;
|
||||
return action;
|
||||
})
|
||||
).toList();
|
||||
}
|
||||
|
||||
private static boolean contain(UserRoleSession role, Collection<String> authRoles) {
|
||||
return authRoles.stream().anyMatch(authRole -> authRole.equalsIgnoreCase(role.getUserRole()));
|
||||
}
|
||||
|
||||
private static boolean contain(String authRole, Collection<UserRoleSession> presentRoles) {
|
||||
return presentRoles.stream().anyMatch(role -> role.getUserRole().equalsIgnoreCase(authRole));
|
||||
}
|
||||
|
||||
public static class RoleAction {
|
||||
String roleName;
|
||||
//------поля при обновления-----
|
||||
Status newStatus;
|
||||
UserRoleSession roleToChange;
|
||||
boolean create() {
|
||||
return roleToChange == null;
|
||||
}
|
||||
}
|
||||
|
||||
private static class UserInfo {
|
||||
boolean isNew;
|
||||
Long userId;
|
||||
|
||||
public UserInfo(boolean isNew, Long userId) {
|
||||
this.isNew = isNew;
|
||||
this.userId = userId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ utility-service.hazelcast.login=dev
|
|||
utility-service.hazelcast.password=dev-pass
|
||||
|
||||
utility-service.kafka.bootstrap-servers=localhost:9092
|
||||
utility-service.kafka.group-id=dev-group
|
||||
utility-service.kafka.group-id=dev-group-utility-service
|
||||
utility-service.kafka.enable-auto-commit=false
|
||||
utility-service.kafka.session-timeout-ms=30000
|
||||
utility-service.kafka.auto-offset-reset=latest
|
||||
|
|
|
|||
|
|
@ -0,0 +1,94 @@
|
|||
package ru.spcex.clearing.utility.service;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import ru.clearing.classes.statics.data.user.UserRoleSession;
|
||||
import ru.spcex.platform.enumeration.Status;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class UserServiceChangeRolesTest {
|
||||
private static final AtomicLong idGenerator = new AtomicLong();
|
||||
|
||||
@Test
|
||||
public void testTwoNewRoles() {
|
||||
Collection<UserRoleSession> userRoles = new ArrayList<>();
|
||||
userRoles.add(generate("admin", Status.Active));
|
||||
userRoles.add(generate("broker", Status.Active));
|
||||
userRoles.add(generate("manager", Status.Blocked));
|
||||
Collection<String> methodsFromAuth = List.of("admin", "broker", "makler", "user");
|
||||
|
||||
Collection<UserService.RoleAction> roleActions = UserService.defineAllRoleChanges(userRoles, methodsFromAuth);
|
||||
assertEquals(2, roleActions.size());
|
||||
assertTrue(roleActions.stream().anyMatch(roleAction -> roleAction.create()
|
||||
&& "makler".equals(roleAction.roleName)));
|
||||
assertTrue(roleActions.stream().anyMatch(roleAction -> roleAction.create()
|
||||
&& "user".equals(roleAction.roleName)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneMissingTwoNew() {
|
||||
Collection<UserRoleSession> userRoles = new ArrayList<>();
|
||||
userRoles.add(generate("admin", Status.Active));
|
||||
userRoles.add(generate("broker", Status.Active));
|
||||
userRoles.add(generate("manager", Status.Active));
|
||||
Collection<String> methodsFromAuth = List.of("admin", "broker", "makler", "user");
|
||||
|
||||
Collection<UserService.RoleAction> roleActions = UserService.defineAllRoleChanges(userRoles, methodsFromAuth);
|
||||
assertEquals(3, roleActions.size());
|
||||
assertTrue(roleActions.stream().anyMatch(roleAction -> !roleAction.create()
|
||||
&& roleAction.roleToChange.getUserRole().equals("manager")
|
||||
&& roleAction.newStatus.equals(Status.Blocked)));
|
||||
assertTrue(roleActions.stream().anyMatch(roleAction -> roleAction.create()
|
||||
&& "makler".equals(roleAction.roleName)));
|
||||
assertTrue(roleActions.stream().anyMatch(roleAction -> roleAction.create()
|
||||
&& "user".equals(roleAction.roleName)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllNew() {
|
||||
Collection<UserRoleSession> userRoles = new ArrayList<>();
|
||||
Collection<String> methodsFromAuth = List.of("admin", "broker", "makler", "user");
|
||||
|
||||
Collection<UserService.RoleAction> roleActions = UserService.defineAllRoleChanges(userRoles, methodsFromAuth);
|
||||
assertEquals(4, roleActions.size());
|
||||
assertTrue(roleActions.stream().anyMatch(roleAction -> roleAction.create()
|
||||
&& "admin".equals(roleAction.roleName)));
|
||||
assertTrue(roleActions.stream().anyMatch(roleAction -> roleAction.create()
|
||||
&& "broker".equals(roleAction.roleName)));
|
||||
assertTrue(roleActions.stream().anyMatch(roleAction -> roleAction.create()
|
||||
&& "makler".equals(roleAction.roleName)));
|
||||
assertTrue(roleActions.stream().anyMatch(roleAction -> roleAction.create()
|
||||
&& "user".equals(roleAction.roleName)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwoNewRolesDifferentCase() {
|
||||
Collection<UserRoleSession> userRoles = new ArrayList<>();
|
||||
userRoles.add(generate("AdMin", Status.Active));
|
||||
userRoles.add(generate("broKer", Status.Active));
|
||||
userRoles.add(generate("MANAGER", Status.Blocked));
|
||||
Collection<String> methodsFromAuth = List.of("admin", "broker", "makler", "user");
|
||||
|
||||
Collection<UserService.RoleAction> roleActions = UserService.defineAllRoleChanges(userRoles, methodsFromAuth);
|
||||
assertEquals(2, roleActions.size());
|
||||
assertTrue(roleActions.stream().anyMatch(roleAction -> roleAction.create()
|
||||
&& "makler".equalsIgnoreCase(roleAction.roleName)));
|
||||
assertTrue(roleActions.stream().anyMatch(roleAction -> roleAction.create()
|
||||
&& "user".equalsIgnoreCase(roleAction.roleName)));
|
||||
}
|
||||
|
||||
private static UserRoleSession generate(String roleName, Status roleStatus) {
|
||||
UserRoleSession userRoleSession = new UserRoleSession();
|
||||
userRoleSession.setId(idGenerator.incrementAndGet());
|
||||
userRoleSession.setUserId(1L);
|
||||
userRoleSession.setUserRole(roleName);
|
||||
userRoleSession.setStatus(roleStatus.getKey());
|
||||
return userRoleSession;
|
||||
}
|
||||
}
|
||||
29
platform-parent/platform-enum/pom.xml
Normal file
29
platform-parent/platform-enum/pom.xml
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>platform-enum</artifactId>
|
||||
<name>Platform enumerations</name>
|
||||
<packaging>jar</packaging>
|
||||
<version>1.0.0</version>
|
||||
|
||||
<parent>
|
||||
<artifactId>platform-parent</artifactId>
|
||||
<groupId>ru.spcex.platform</groupId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>ru.spcex.platform</groupId>
|
||||
<artifactId>platform-utils</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package ru.spcex.platform.enumeration;
|
||||
|
||||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
|
||||
public enum ConnectionState implements IEnumKey {
|
||||
Connected("CNCT"), Disconnected("DSBL");
|
||||
|
||||
private final String key;
|
||||
|
||||
ConnectionState(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package ru.spcex.platform.enumeration;
|
||||
|
||||
import ru.spcex.platform.utils.enumeration.IEnumKey;
|
||||
|
||||
public enum Status implements IEnumKey {
|
||||
Active("ACTV"), Blocked("BLKD");
|
||||
|
||||
private final String key;
|
||||
|
||||
Status(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package ru.spcex.clearing.platform.messaging.domain;
|
||||
|
||||
public enum ActionType {
|
||||
NEW, UPDATE, DELETE;
|
||||
NEW, UPDATE, DELETE,
|
||||
SYSTEM;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,4 +22,6 @@ public interface Consts {
|
|||
|
||||
String DESTINATION_SDF08_NEW = "s-df-08-new";
|
||||
String DESTINATION_SDF02_NEW = "s-df-02-new";
|
||||
|
||||
String USER_AUTH_SUCCESS = "user-auth-success";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
package ru.spcex.clearing.platform.messaging.domain.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.platform.messaging.domain.json.deserialize.InstantDeserializer;
|
||||
import ru.spcex.clearing.platform.messaging.domain.json.serialize.InstantSerializer;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class UserAuthRequest {
|
||||
@JsonProperty
|
||||
private String username;
|
||||
@JsonProperty
|
||||
private String identifier;
|
||||
@JsonProperty
|
||||
private List<String> roles = new ArrayList<>();
|
||||
@JsonSerialize(using = InstantSerializer.class)
|
||||
@JsonDeserialize(using = InstantDeserializer.class)
|
||||
@JsonProperty
|
||||
private Instant time;
|
||||
@JsonProperty
|
||||
private String serverIp;
|
||||
@JsonProperty
|
||||
private String clientIp;
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
public void setIdentifier(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public List<String> getRoles() {
|
||||
return roles;
|
||||
}
|
||||
|
||||
public void setRoles(List<String> 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
package ru.spcex.platform.utils.enumeration;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
public interface IEnumKey extends Serializable {
|
||||
String getKey();
|
||||
|
||||
default boolean equalsByKey(String key) {
|
||||
return key != null && getKey().equalsIgnoreCase(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяет что среди данного набора Enum, присутствует элемент с данным id
|
||||
* id может быть null
|
||||
*/
|
||||
static <T extends Enum<T> & IEnumKey> boolean contains(String id, T... enumSet) {
|
||||
for (T e : enumSet) {
|
||||
if (Objects.equals(id, e.getKey()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static <T extends Enum<T> & IEnumKey> boolean contains(T e, T... enumSet) {
|
||||
for (T enumEl : enumSet) {
|
||||
if (enumEl.equals(e))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяет что среди всех Enum данного класса, присутствует элемент с данным id
|
||||
* id может быть null
|
||||
*/
|
||||
static <T extends Enum<T> & IEnumKey> boolean contains(Class<T> enumClass, String key) {
|
||||
for (T e : enumClass.getEnumConstants()) {
|
||||
if (Objects.equals(key, e.getKey()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает Enum по id, если в заданном классе такой определен
|
||||
* id может быть null
|
||||
*
|
||||
* @return Enum если нашел, иначе <tt>null</tt>
|
||||
*/
|
||||
static <T extends Enum<T> & IEnumKey> T getEnumByKey(Class<T> enumClass, String key) {
|
||||
for (T e : enumClass.getEnumConstants()) {
|
||||
if (Objects.equals(key, e.getKey()))
|
||||
return e;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static String getKeyOrNull(IEnumKey enumVal) {
|
||||
return enumVal == null ? null : enumVal.getKey();
|
||||
}
|
||||
|
||||
String UNDEFINED_VALUE = "_Undefined";
|
||||
}
|
||||
|
|
@ -19,4 +19,12 @@ public class TimeUtil {
|
|||
if (date == null) return null;
|
||||
return formatter.format(date.atZone(zone));
|
||||
}
|
||||
|
||||
public static Instant today() {
|
||||
return localDateToInstant(LocalDate.now());
|
||||
}
|
||||
|
||||
public static Instant localDateToInstant(LocalDate date) {
|
||||
return date.atStartOfDay(zone).toInstant();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
<module>platform-classes-base</module>
|
||||
<module>platform-imdg-api-hazelcast-impl</module>
|
||||
<module>platform-utils</module>
|
||||
<module>platform-enum</module>
|
||||
<module>platform-messaging</module>
|
||||
</modules>
|
||||
</project>
|
||||
6
pom.xml
6
pom.xml
|
|
@ -103,6 +103,12 @@
|
|||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ru.spcex.platform</groupId>
|
||||
<artifactId>platform-enum</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ru.spcex.platform</groupId>
|
||||
<artifactId>platform-imdg-api</artifactId>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue