diff --git a/clearing-parent/backend-api/pom.xml b/clearing-parent/backend-api/pom.xml
index 1875a33b2..18b29f7d1 100644
--- a/clearing-parent/backend-api/pom.xml
+++ b/clearing-parent/backend-api/pom.xml
@@ -49,6 +49,10 @@
io.springfox
springfox-swagger-ui
+
+ ru.spcex.clearing
+ classes
+
diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/security/KeycloakRestTemplateAuthenticationProvider.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/security/KeycloakRestTemplateAuthenticationProvider.java
index 5999a8cbf..67e5c07f1 100644
--- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/security/KeycloakRestTemplateAuthenticationProvider.java
+++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/security/KeycloakRestTemplateAuthenticationProvider.java
@@ -24,6 +24,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 javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -39,13 +40,15 @@ public class KeycloakRestTemplateAuthenticationProvider implements Authenticatio
private final HttpServletRequest currentHttpRequest;
private final HttpServletResponse currentHttpResponse;
private final RestTemplate restTemplate;
+ private final UserAutoCreateService userAutoCreation;
public KeycloakRestTemplateAuthenticationProvider(KeycloakConfigResolver resolver, HttpServletRequest currentHttpRequest, HttpServletResponse currentHttpResponse,
- @Qualifier("clearing-rest") RestTemplate restTemplate) {
+ @Qualifier("clearing-rest") RestTemplate restTemplate, UserAutoCreateService userAutoCreation) {
this.resolver = resolver;
this.currentHttpRequest = currentHttpRequest;
this.currentHttpResponse = currentHttpResponse;
this.restTemplate = restTemplate;
+ this.userAutoCreation = userAutoCreation;
}
@Override
@@ -83,11 +86,11 @@ public class KeycloakRestTemplateAuthenticationProvider implements Authenticatio
RefreshableKeycloakSecurityContext skSession = new RefreshableKeycloakSecurityContext(deployment, null, accessTokenString, accessToken, null, null, refreshTokenString);
String principalName = AdapterUtils.getPrincipalName(deployment, accessToken);
final KeycloakPrincipal principal = new KeycloakPrincipal<>(principalName, skSession);
-
final Set roles = AdapterUtils.getRolesFromSecurityContext(skSession);
final KeycloakAccount account = new SimpleKeycloakAccount(principal, roles, skSession);
KeycloakAuthenticationToken keycloakAuthenticationToken = new KeycloakAuthenticationToken(account, false, realmRoles);
keycloakAuthenticationToken.setAuthenticated(true);
+ checkRightsAndCreate(principalName, roles);
return keycloakAuthenticationToken;
} catch (VerificationException vex) {
@@ -97,6 +100,13 @@ public class KeycloakRestTemplateAuthenticationProvider implements Authenticatio
}
}
+ private void checkRightsAndCreate(String username, Set roles) {
+ //todo remove hardcode
+ if (roles.contains("admin") || roles.contains("default-roles-master")) {
+ userAutoCreation.createUserIfNeeded(username);
+ }
+ }
+
@Override
public boolean supports(Class> type) {
return UsernamePasswordAuthenticationToken.class.equals(type);
diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/UserAutoCreateService.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/UserAutoCreateService.java
new file mode 100644
index 000000000..19e9e6ffb
--- /dev/null
+++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/service/UserAutoCreateService.java
@@ -0,0 +1,36 @@
+package ru.spcex.clearing.backendapi.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import ru.clearing.classes.statics.data.user.ClearingUser;
+import ru.spcex.clearing.imdg.IMDGDistributedNames;
+import ru.spcex.platform.imdg.api.Imdg;
+import ru.spcex.platform.imdg.api.ImdgProvider;
+
+import java.time.Instant;
+import java.util.Map;
+
+@Service
+public class UserAutoCreateService {
+
+ private final Imdg userMap;
+
+ @Autowired
+ public UserAutoCreateService(ImdgProvider imdgProvider) {
+ this.userMap = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingUser, ClearingUser.class);
+ }
+
+ /**
+ * при необходимости переделать на отдельный поток
+ * todo transactional?
+ */
+ public void createUserIfNeeded(String userName) {
+ ClearingUser username = userMap.getSingleObjectByFieldValues(Map.of("username", userName));
+ if (username == null) {
+ username = new ClearingUser();
+ username.setUsername(userName);
+ username.setCreated(Instant.now());
+ userMap.insert(username);
+ }
+ }
+}
diff --git a/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/user/ClearingUser.java b/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/user/ClearingUser.java
index 50fbff743..2f751c07b 100644
--- a/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/user/ClearingUser.java
+++ b/clearing-parent/classes/src/main/java/ru/clearing/classes/statics/data/user/ClearingUser.java
@@ -9,6 +9,15 @@ import ru.clearing.classes.objects.BusinessObject;
*/
public class ClearingUser extends BusinessObject {
private static final long serialVersionUID = ConstSerializable.serialVersionUID;
+ private String username;
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
// private String idpUuid;
//
diff --git a/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/object/ClearingUserMapStore.java b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/object/ClearingUserMapStore.java
new file mode 100644
index 000000000..6b00310c5
--- /dev/null
+++ b/clearing-parent/imdg/src/main/java/ru/spcex/clearing/imdg/object/ClearingUserMapStore.java
@@ -0,0 +1,61 @@
+package ru.spcex.clearing.imdg.object;
+
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Component;
+import ru.clearing.classes.statics.data.user.ClearingUser;
+import ru.spcex.clearing.imdg.IMDGDistributedNames;
+import ru.spcex.clearing.imdg.base.AutoconfiguredMap;
+import ru.spcex.clearing.imdg.base.SimpleObjectMapStore;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+//todo rewrite
+@Component
+public class ClearingUserMapStore extends SimpleObjectMapStore implements AutoconfiguredMap {
+
+ public ClearingUserMapStore(JdbcTemplate jdbcTemplate) {
+ super(jdbcTemplate);
+ //super(jdbcTemplate);
+ }
+
+ @Override
+ public String getTableName() {
+
+ return "COMPANY";
+ }
+
+ @Override
+ public String[] getFields() {
+ return new String[0];
+ }
+
+ @Override
+ public void store(Map map) {}
+
+ @Override
+ public String getMapName() {
+ return IMDGDistributedNames.Map_ClearingUser;
+ }
+
+ @Override
+ public String[] getIndexingField() {
+ return new String[] {"username"};
+ }
+
+ @Override
+ public ClearingUser load(Long key) {
+ return null;
+ }
+
+ @Override
+ public Map loadAll(Collection keys) {
+ return null;
+ }
+
+ @Override
+ public Iterable loadAllKeys() {
+ return Collections.emptyList();
+ }
+}
diff --git a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgHazelcast.java b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgHazelcast.java
index 9bdfaf9a7..ab51b6132 100644
--- a/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgHazelcast.java
+++ b/platform-parent/platform-imdg-api-hazelcast-impl/src/main/java/ru/spcex/platform/imdg/iml/hazelcast/adapter/ImdgHazelcast.java
@@ -2,9 +2,12 @@ package ru.spcex.platform.imdg.iml.hazelcast.adapter;
import com.hazelcast.core.IMap;
import com.hazelcast.core.IdGenerator;
+import com.hazelcast.query.Predicate;
+import com.hazelcast.query.Predicates;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import ru.spcex.platform.imdg.api.Imdg;
+import java.util.*;
public class ImdgHazelcast implements Imdg {
private IdGenerator idGenerator;
@@ -46,4 +49,52 @@ public class ImdgHazelcast implements Imdg {
public T getSingleObjectByID(Long paramLong) {
return map.get(paramLong);
}
+
+ /**
+ * возвращает объект удовлетворяющий условиям
+ * не проверяет, если удовлетворяющих условиям > 1
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public T getSingleObjectByFieldValues(Map> conditions) {
+ Predicate[] predicates = new Predicate[conditions.size()];
+ final int[] i = {0};
+ conditions.forEach((key, value) -> {
+ predicates[i[0]] = Predicates.equal(key, value);
+ i[0]++;
+ });
+ Predicate or = Predicates.or(predicates);
+ Set> found = map.entrySet(or);
+ Iterator> allFoundByCondition = found.iterator();
+ if (allFoundByCondition.hasNext()) {
+ return allFoundByCondition.next().getValue();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * возвращает коллекцию объектов, удовлетворяющий условиям на поля
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public Collection getCollectionObjectsByFieldValues(Map> conditions) {
+ Predicate[] predicates = new Predicate[conditions.size()];
+ final int[] i = {0};
+ conditions.forEach((key, value) -> {
+ predicates[i[0]] = Predicates.equal(key, value);
+ i[0]++;
+ });
+ Predicate or = Predicates.or(predicates);
+ Set ids = map.keySet(or);
+ Iterator idIterator = ids.iterator();
+ Collection searchResult = new ArrayList<>();
+ while(idIterator.hasNext()) {
+ T element = map.get(idIterator.next());
+ if (element != null) {
+ searchResult.add(element);
+ }
+ }
+ return searchResult;
+ }
}
diff --git a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/clearing/imdg/IMDGDistributedNames.java b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/clearing/imdg/IMDGDistributedNames.java
index 86597f7e4..908a3cdfd 100644
--- a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/clearing/imdg/IMDGDistributedNames.java
+++ b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/clearing/imdg/IMDGDistributedNames.java
@@ -38,6 +38,7 @@ public final class IMDGDistributedNames {
public static final String Map_SDf08 = "Map_SDf08";
public static final String Map_SDf02 = "Map_SDf02";
public static final String Map_SDf01 = "Map_SDf01";
+ public static final String Map_ClearingUser = "Map_ClearingUser";
// public static final String Map_InterestStatusDictionary = "Map_InterestStatusDictionary"; future
public static final String Map_AllowedDictionary = "Map_AllowedDictionary";
diff --git a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/Imdg.java b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/Imdg.java
index 259d607b6..49b9ddf94 100644
--- a/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/Imdg.java
+++ b/platform-parent/platform-imdg-api/src/main/java/ru/spcex/platform/imdg/api/Imdg.java
@@ -3,6 +3,7 @@ package ru.spcex.platform.imdg.api;
import ru.spcex.platform.classes.base.SpcexObjectBase;
import java.util.Collection;
+import java.util.Map;
public interface Imdg {
default void insert(T paramT) {
@@ -29,6 +30,14 @@ public interface Imdg {
throw new UnsupportedOperationException("not implemented getSingleObjectBySQL");
}
+ default T getSingleObjectByFieldValues(Map> conditions) {
+ throw new UnsupportedOperationException("not implemented getSingleObjectByFieldValues");
+ }
+
+ default Collection getCollectionObjectsByFieldValues(Map> conditions) {
+ throw new UnsupportedOperationException("not implemented getCollectionObjectsByFieldValues");
+ }
+
default T getSingleObjectByID(Long paramLong) {
throw new UnsupportedOperationException("not implemented getSingleObjectByID");
}