add Session Settings
This commit is contained in:
4
pom.xml
4
pom.xml
@@ -18,8 +18,8 @@
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>25</maven.compiler.source>
|
||||
<maven.compiler.target>25</maven.compiler.target>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<!-- основные версии -->
|
||||
<springdoc.version>2.8.14</springdoc.version>
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
package ru.copperside.controller;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import ru.copperside.model.authinfo.AuthInfo;
|
||||
import ru.copperside.service.AuthInfoService;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/authinfo")
|
||||
@RequiredArgsConstructor
|
||||
public class AuthInfoController {
|
||||
private final AuthInfoService service;
|
||||
|
||||
// Пример: GET /api/authinfo/user123?type=Secret
|
||||
@GetMapping("/{dataId}")
|
||||
public ResponseEntity<AuthInfo> getByDataIdAndType(
|
||||
@PathVariable String dataId
|
||||
) {
|
||||
return ResponseEntity.ok(service.getByDataIdAndType(dataId));
|
||||
}
|
||||
}
|
||||
*/
|
||||
@@ -7,6 +7,7 @@ import ru.copperside.model.authinfo.SecretData;
|
||||
import ru.copperside.model.dto.RolePermissionDto;
|
||||
import ru.copperside.model.enums.AuthenticationType;
|
||||
import ru.copperside.model.permission.Permission;
|
||||
import ru.copperside.model.session.SessionSettings;
|
||||
import ru.copperside.service.DebugAuthService;
|
||||
|
||||
import java.util.List;
|
||||
@@ -55,4 +56,9 @@ public class DebugAuthController {
|
||||
) {
|
||||
return ResponseEntity.ok(service.getPermissions(hierarchyId));
|
||||
}
|
||||
|
||||
@GetMapping("/merged")
|
||||
public ResponseEntity<SessionSettings> merged(@RequestParam Long authId) {
|
||||
return ResponseEntity.ok(service.getMerged(authId));
|
||||
}
|
||||
}
|
||||
@@ -3,18 +3,38 @@ package ru.copperside.model.session;
|
||||
import lombok.Builder;
|
||||
import lombok.extern.jackson.Jacksonized;
|
||||
import ru.copperside.model.enums.AuthType;
|
||||
import com.fasterxml.jackson.annotation.JsonAlias;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import ru.copperside.util.DurationFlexibleDeserializer;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Jacksonized
|
||||
@Builder
|
||||
@Builder(toBuilder = true)
|
||||
public record SessionSettings(
|
||||
Duration ttl,
|
||||
@JsonAlias({"Ttl", "TTL", "ttl"})
|
||||
@JsonDeserialize(
|
||||
using = DurationFlexibleDeserializer.class
|
||||
)
|
||||
java.time.Duration ttl,
|
||||
|
||||
@JsonAlias({"AutoProlongation", "autoProlongation"})
|
||||
Boolean autoProlongation,
|
||||
|
||||
@JsonAlias({"AuthType", "authType"})
|
||||
AuthType authType,
|
||||
List<String> authStepTypes,
|
||||
|
||||
@JsonAlias({"AuthStepTypes", "authStepTypes"})
|
||||
java.util.List<String> authStepTypes,
|
||||
|
||||
@JsonAlias({"IgnoreConfirmation", "ignoreConfirmation"})
|
||||
Boolean ignoreConfirmation,
|
||||
|
||||
@JsonAlias({"OneActiveSession", "oneActiveSession"})
|
||||
Boolean oneActiveSession,
|
||||
|
||||
@JsonAlias({"InMemory", "inMemory"})
|
||||
Boolean inMemory
|
||||
) {}
|
||||
@@ -1,250 +0,0 @@
|
||||
/*
|
||||
package ru.copperside.repository;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
|
||||
import ru.copperside.model.authinfo.*;
|
||||
import ru.copperside.model.enums.AuthType;
|
||||
import ru.copperside.model.enums.KeyUsage;
|
||||
import ru.copperside.model.enums.SecretType;
|
||||
import ru.copperside.model.session.SessionSettings;
|
||||
import ru.copperside.sql.SqlRegistry;
|
||||
import ru.copperside.util.SessionSettingsHelper;
|
||||
|
||||
import static ru.copperside.util.RepoMappingHelper.*;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
@Repository
|
||||
@RequiredArgsConstructor
|
||||
public class AuthInfoRepositoryJdbc implements AuthInfoRepository {
|
||||
private final NamedParameterJdbcTemplate jdbc;
|
||||
private final ObjectMapper om;
|
||||
private final SqlRegistry sqlRegistry;
|
||||
|
||||
private static final String SQL_INIT = "auth/find_authinfo_init_by_dataid_and_type";
|
||||
private static final String SQL_PRIV = "auth/find_privatedata_by_authid";
|
||||
private static final String SQL_ROLESET = "auth/find_rolesettings_by_authid";
|
||||
|
||||
@Override
|
||||
public Optional<AuthInfo> findByDataIdAndType(String dataId, String type) {
|
||||
var params = new MapSqlParameterSource()
|
||||
.addValue("dataId", dataId)
|
||||
.addValue("type", type);
|
||||
|
||||
RowMapper<AuthInfo> rm = (rs, rn) -> mapAuthInfo(rs);
|
||||
|
||||
List<AuthInfo> list = jdbc.query(sqlRegistry.get(SQL_INIT), params, rm);
|
||||
|
||||
if (!list.isEmpty()) {
|
||||
AuthInfo base = list.get(0);
|
||||
if (base.authId() != null) {
|
||||
JsonNode privateData = loadPrivateData(base.authId());
|
||||
return Optional.of(base.toBuilder().privateData(privateData).build());
|
||||
}
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private JsonNode loadPrivateData(Long authId) {
|
||||
if (authId == null) return null;
|
||||
var params = new MapSqlParameterSource().addValue("authId", authId);
|
||||
ObjectNode pd = om.createObjectNode();
|
||||
|
||||
jdbc.query(sqlRegistry.get(SQL_PRIV), params, rs -> {
|
||||
String key = rs.getString("KEY");
|
||||
String value = rs.getString("VALUE");
|
||||
try {
|
||||
JsonNode node = om.readTree(value);
|
||||
pd.set(key, node);
|
||||
} catch (Exception e) {
|
||||
pd.put(key, value);
|
||||
}
|
||||
});
|
||||
return pd;
|
||||
}
|
||||
|
||||
private AuthInfo mapAuthInfo(ResultSet rs) {
|
||||
try {
|
||||
Long authId = getLong(rs, "AD_AUTHID"); // AD_AUTHID -> AuthInfo.authId
|
||||
String dataId = rs.getString("AD_DATAID"); // AD_DATAID -> AuthInfo.dataId
|
||||
Long hierarchyId = getLong(rs, "AH_HIERARCHYID"); // AH_HIERARCHYID -> AuthInfo.hierarchyId
|
||||
String displayName = rs.getString("AH_DISPLAYNAME"); // AH_DISPLAYNAME -> AuthInfo.displayName
|
||||
String secretType = rs.getString("AD_TYPE");
|
||||
|
||||
Boolean isEnabled = null;
|
||||
Boolean needActivation = null;
|
||||
|
||||
JsonNode paramsJson = readJsonFlexible(rs, "AI_PARAMETERS", om);
|
||||
if (paramsJson != null && !paramsJson.isNull()) {
|
||||
isEnabled = getBooleanCaseInsensitive(paramsJson, "IsEnabled", "isEnabled");
|
||||
needActivation = getBooleanCaseInsensitive(paramsJson, "NeedActivation", "needActivation");
|
||||
}
|
||||
|
||||
SecretData secretData = null;
|
||||
JsonNode secretJson = readJsonFlexible(rs, "AD_DATA", om);
|
||||
|
||||
if (secretJson != null && !secretJson.isNull()) {
|
||||
Boolean sdIsEnabled = getBooleanCaseInsensitive(secretJson, "IsEnable", "isEnabled");
|
||||
String keyUsageStr = getStringCaseInsensitive(secretJson, "KeyUsage", "keyUsage");
|
||||
String secretTypeStr = getStringCaseInsensitive(secretJson, "SecretType", "secretType");
|
||||
String secretValue = getStringCaseInsensitive(secretJson, "Secret", "secret");
|
||||
|
||||
EnumSet<KeyUsage> keyUsages = parseKeyUsageSet(secretJson, keyUsageStr);
|
||||
SecretType sType = parseSecretType(secretTypeStr);
|
||||
|
||||
secretData = SecretData.builder()
|
||||
.type(secretType) // тип секрета из AD_TYPE (внешний)
|
||||
.isEnabled(sdIsEnabled)
|
||||
.keyUsage(keyUsages)
|
||||
.secretType(sType)
|
||||
.secret(secretValue)
|
||||
.build();
|
||||
}else {
|
||||
secretData = SecretData.builder()
|
||||
.type(secretType)
|
||||
.build();
|
||||
}
|
||||
|
||||
JsonNode aiSettingsJson = readJsonFlexible(rs, "AI_SETTINGS", om);
|
||||
SessionSettings sessionSettings = computeSessionSettings(authId, aiSettingsJson); // ⬅️ главный расчёт
|
||||
|
||||
return AuthInfo.builder()
|
||||
.authId(authId)
|
||||
.dataId(dataId)
|
||||
.hierarchyId(hierarchyId)
|
||||
.displayName(displayName)
|
||||
.isEnabled(isEnabled)
|
||||
.needActivation(needActivation)
|
||||
.permissions(List.of())
|
||||
.sessionSettings(sessionSettings)
|
||||
.sessionData(null)
|
||||
.privateData(null)
|
||||
.secretData(secretData)
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Failed to map AuthInfo", e);
|
||||
}
|
||||
}
|
||||
|
||||
private SessionSettings computeSessionSettings(Long authId, JsonNode aiSettingsJson) {
|
||||
// userSettings = {}; merge(AI_SETTINGS, false)
|
||||
SessionSettings userSettings = SessionSettingsHelper.merge(
|
||||
SessionSettings.builder().build(),
|
||||
mapSessionSettings(aiSettingsJson),
|
||||
false
|
||||
);
|
||||
|
||||
// Ролевые настройки с ORDER BY LEVEL (накатываем последовательно isRole=true)
|
||||
var resultRef = new AtomicReference<>(SessionSettings.builder().build());
|
||||
var params = new MapSqlParameterSource().addValue("authId", authId);
|
||||
jdbc.query(sqlRegistry.get(SQL_ROLESET), params, rs -> {
|
||||
JsonNode roleJson = readJsonFlexible(rs, "SETTINGS", om);
|
||||
SessionSettings roleSet = mapSessionSettings(roleJson);
|
||||
resultRef.set(SessionSettingsHelper.merge(resultRef.get(), roleSet, true));
|
||||
});
|
||||
|
||||
// финально поверх — userSettings (isRole=false)
|
||||
return SessionSettingsHelper.merge(resultRef.get(), userSettings, false);
|
||||
}
|
||||
|
||||
private SessionSettings mapSessionSettings(JsonNode node) {
|
||||
if (node == null || node.isNull()) return null;
|
||||
|
||||
Duration ttl = null;
|
||||
if (node.hasNonNull("ttlSec")) {
|
||||
ttl = Duration.ofSeconds(node.path("ttlSec").asLong(0));
|
||||
} else if (node.hasNonNull("ttl")) {
|
||||
try { ttl = Duration.parse(node.path("ttl").asText()); } catch (Exception ignore) {}
|
||||
}
|
||||
|
||||
AuthType authType = null;
|
||||
if (node.hasNonNull("authType")) {
|
||||
var at = node.get("authType");
|
||||
if (at.isInt()) {
|
||||
authType = AuthType.fromCode(at.asInt(0));
|
||||
} else {
|
||||
try { authType = AuthType.valueOf(at.asText()); } catch (Exception ignore) {}
|
||||
}
|
||||
}
|
||||
|
||||
List<String> steps = new ArrayList<>();
|
||||
if (node.hasNonNull("authStepTypes") && node.get("authStepTypes").isArray()) {
|
||||
for (JsonNode n : node.get("authStepTypes")) {
|
||||
steps.add(n.asText());
|
||||
}
|
||||
}
|
||||
|
||||
return new SessionSettingsBuilder()
|
||||
.ttl(ttl)
|
||||
.autoProlongation(asNullableBool(node, "autoProlongation"))
|
||||
.authType(authType)
|
||||
.authStepTypes(steps)
|
||||
.ignoreConfirmation(asNullableBool(node, "ignoreConfirmation"))
|
||||
.oneActiveSession(asNullableBool(node, "oneActiveSession"))
|
||||
.inMemory(asNullableBool(node, "inMemory"))
|
||||
.build();
|
||||
}
|
||||
|
||||
private Boolean asNullableBool(JsonNode node, String field) {
|
||||
return node.has(field) && !node.get(field).isNull() ? node.get(field).asBoolean() : null;
|
||||
}
|
||||
|
||||
private static final class SessionSettingsBuilder {
|
||||
private Duration ttl;
|
||||
private Boolean autoProlongation;
|
||||
private AuthType authType;
|
||||
private List<String> authStepTypes;
|
||||
private Boolean ignoreConfirmation;
|
||||
private Boolean oneActiveSession;
|
||||
private Boolean inMemory;
|
||||
|
||||
SessionSettingsBuilder() {}
|
||||
SessionSettingsBuilder(SessionSettings base) {
|
||||
if (base == null) return;
|
||||
this.ttl = base.ttl();
|
||||
this.autoProlongation = base.autoProlongation();
|
||||
this.authType = base.authType();
|
||||
this.authStepTypes = base.authStepTypes();
|
||||
this.ignoreConfirmation = base.ignoreConfirmation();
|
||||
this.oneActiveSession = base.oneActiveSession();
|
||||
this.inMemory = base.inMemory();
|
||||
}
|
||||
|
||||
SessionSettingsBuilder ttl(Duration v) { this.ttl = v; return this; }
|
||||
SessionSettingsBuilder autoProlongation(Boolean v) { this.autoProlongation = v; return this; }
|
||||
SessionSettingsBuilder authType(AuthType v) { this.authType = v; return this; }
|
||||
SessionSettingsBuilder authStepTypes(List<String> v) { this.authStepTypes = v; return this; }
|
||||
SessionSettingsBuilder ignoreConfirmation(Boolean v) { this.ignoreConfirmation = v; return this; }
|
||||
SessionSettingsBuilder oneActiveSession(Boolean v) { this.oneActiveSession = v; return this; }
|
||||
SessionSettingsBuilder inMemory(Boolean v) { this.inMemory = v; return this; }
|
||||
|
||||
SessionSettings build() {
|
||||
return SessionSettings.builder()
|
||||
.ttl(ttl)
|
||||
.autoProlongation(autoProlongation)
|
||||
.authType(authType)
|
||||
.authStepTypes(authStepTypes == null ? null : List.copyOf(authStepTypes))
|
||||
.ignoreConfirmation(ignoreConfirmation)
|
||||
.oneActiveSession(oneActiveSession)
|
||||
.inMemory(inMemory)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1,49 @@
|
||||
package ru.copperside.repository;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.ObjectReader;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import ru.copperside.model.session.SessionSettings;
|
||||
import ru.copperside.sql.SqlRegistry;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static ru.copperside.util.RepoMappingHelper.readJson;
|
||||
import static ru.copperside.util.SessionSettingsHelper.merge;
|
||||
|
||||
@Repository
|
||||
@RequiredArgsConstructor
|
||||
public class SettingsRepositoryJdbc implements SettingsRepository {
|
||||
|
||||
private final NamedParameterJdbcTemplate jdbc;
|
||||
private final ObjectMapper om;
|
||||
private final SqlRegistry sql;
|
||||
|
||||
private ObjectReader settingsReader() {
|
||||
return om.readerFor(SessionSettings.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionSettings loadMerged(Long authId) {
|
||||
var p = new MapSqlParameterSource().addValue("authId", authId);
|
||||
|
||||
// user
|
||||
SessionSettings user = jdbc.query(sql.get("auth/find_settings_by_authid"), p, rs ->
|
||||
rs.next() ? readJson(rs, "AI_SETTINGS", settingsReader()) : null);
|
||||
|
||||
// roles (по уровням, порядке дерева)
|
||||
List<SessionSettings> roles = jdbc.query(sql.get("auth/find_rolesettings_by_authid"), p,
|
||||
(rs, rn) -> readJson(rs, "SETTINGS", settingsReader()));
|
||||
|
||||
// merge: роли последовательно (isRole=true), затем поверх пользовательские (isRole=false)
|
||||
SessionSettings acc = roles.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.reduce(SessionSettings.builder().build(), (a, r) -> merge(a, r, true), (a, b) -> b);
|
||||
|
||||
return merge(acc, user, false);
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,10 @@ import ru.copperside.model.authinfo.SecretData;
|
||||
import ru.copperside.model.dto.RolePermissionDto;
|
||||
import ru.copperside.model.enums.AuthenticationType;
|
||||
import ru.copperside.model.permission.Permission;
|
||||
import ru.copperside.model.session.SessionSettings;
|
||||
import ru.copperside.repository.PermissionsRepository;
|
||||
import ru.copperside.repository.SecretRepository;
|
||||
import ru.copperside.repository.SettingsRepository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -17,6 +19,7 @@ public class DebugAuthService {
|
||||
|
||||
private final SecretRepository secretRepository;
|
||||
private final PermissionsRepository permissionsRepository;
|
||||
private final SettingsRepository settingsRepository;
|
||||
|
||||
public SecretData getSecretData(String dataId, String type) {
|
||||
// если не указали type — считаем Secret
|
||||
@@ -40,6 +43,8 @@ public class DebugAuthService {
|
||||
public List<Permission> getPermissions(Long hierarchyId) {
|
||||
return permissionsRepository.findCompiledByHierarchyId(hierarchyId);
|
||||
}
|
||||
|
||||
public SessionSettings getMerged(Long authId) {
|
||||
return settingsRepository.loadMerged(authId);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package ru.copperside.util;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
|
||||
public class DurationFlexibleDeserializer extends JsonDeserializer<Duration> {
|
||||
|
||||
@Override
|
||||
public Duration deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
|
||||
JsonNode node = p.getCodec().readTree(p);
|
||||
if (node == null || node.isNull()) return null;
|
||||
|
||||
// число → секунды
|
||||
if (node.isNumber()) {
|
||||
return Duration.ofSeconds(node.longValue());
|
||||
}
|
||||
|
||||
String s = node.asText(null);
|
||||
if (s == null || s.isBlank()) return null;
|
||||
|
||||
// Формат "hh:mm:ss" как в C# TimeSpan ("00:10:00")
|
||||
if (s.matches("\\d{1,2}:\\d{2}:\\d{2}")) {
|
||||
String[] parts = s.split(":");
|
||||
long h = Long.parseLong(parts[0]);
|
||||
long m = Long.parseLong(parts[1]);
|
||||
long sec = Long.parseLong(parts[2]);
|
||||
return Duration.ofHours(h).plusMinutes(m).plusSeconds(sec);
|
||||
}
|
||||
|
||||
// ISO-8601 (P1D, PT10M, ...)
|
||||
if (s.startsWith("P") || s.startsWith("p")) {
|
||||
try { return Duration.parse(s); } catch (Exception ignore) {}
|
||||
}
|
||||
|
||||
// короткие формы: "1h", "30m", "15s", "600" (сек)
|
||||
try {
|
||||
String v = s.trim().toLowerCase();
|
||||
if (v.endsWith("h")) return Duration.ofHours(Long.parseLong(v.substring(0, v.length()-1)));
|
||||
if (v.endsWith("m")) return Duration.ofMinutes(Long.parseLong(v.substring(0, v.length()-1)));
|
||||
if (v.endsWith("s")) return Duration.ofSeconds(Long.parseLong(v.substring(0, v.length()-1)));
|
||||
return Duration.ofSeconds(Long.parseLong(v));
|
||||
} catch (Exception ignore) {}
|
||||
|
||||
// последняя попытка — ISO
|
||||
try { return Duration.parse(s); } catch (Exception ignore) {}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,64 +1,63 @@
|
||||
package ru.copperside.util;
|
||||
|
||||
import ru.copperside.model.enums.AuthType;
|
||||
import ru.copperside.model.session.SessionSettings;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public final class SessionSettingsHelper {
|
||||
private SessionSettingsHelper() {}
|
||||
|
||||
public static SessionSettings merge(SessionSettings target, SessionSettings merge, boolean isRole) {
|
||||
if (target == null && merge == null) return null;
|
||||
if (target == null) target = SessionSettings.builder().build();
|
||||
if (merge == null) return target;
|
||||
/** Merge session settings. isRole=true — логика «ролевого» слияния из C#. */
|
||||
public static SessionSettings merge(SessionSettings base, SessionSettings merge, boolean isRole) {
|
||||
if (base == null) base = SessionSettings.builder().build();
|
||||
if (merge == null) return base;
|
||||
|
||||
Duration ttl = target.ttl();
|
||||
Boolean auto = target.autoProlongation();
|
||||
AuthType at = target.authType();
|
||||
List<String> steps = target.authStepTypes();
|
||||
Boolean ign = target.ignoreConfirmation();
|
||||
Boolean one = target.oneActiveSession();
|
||||
Boolean mem = target.inMemory();
|
||||
var b = base.toBuilder();
|
||||
|
||||
// TTL, AutoProlongation
|
||||
if (merge.ttl() != null) b.ttl(merge.ttl());
|
||||
if (merge.autoProlongation() != null) b.autoProlongation(merge.autoProlongation());
|
||||
|
||||
// AuthType: для ролей — берём максимальный (по ordinal), иначе — прямое присваивание
|
||||
if (merge.authType() != null) {
|
||||
if (isRole) {
|
||||
if (merge.ttl() != null) ttl = merge.ttl();
|
||||
if (merge.autoProlongation() != null) auto = merge.autoProlongation();
|
||||
if (merge.authType() != null) at = (at == null) ? merge.authType() : max(at, merge.authType());
|
||||
if (merge.authStepTypes() != null && !merge.authStepTypes().isEmpty()) {
|
||||
Set<String> s = new LinkedHashSet<>();
|
||||
if (steps != null) s.addAll(steps);
|
||||
s.addAll(merge.authStepTypes());
|
||||
steps = List.copyOf(s);
|
||||
}
|
||||
if (merge.ignoreConfirmation() != null) {
|
||||
if (ign == null) ign = merge.ignoreConfirmation();
|
||||
else if (!merge.ignoreConfirmation()) ign = false;
|
||||
var current = b.build().authType();
|
||||
if (current == null || current.ordinal() < merge.authType().ordinal()) {
|
||||
b.authType(merge.authType());
|
||||
}
|
||||
} else {
|
||||
if (merge.ttl() != null) ttl = merge.ttl();
|
||||
if (merge.autoProlongation() != null) auto = merge.autoProlongation();
|
||||
if (merge.authType() != null) at = merge.authType();
|
||||
if (merge.authStepTypes() != null) steps = merge.authStepTypes();
|
||||
if (merge.ignoreConfirmation() != null) ign = merge.ignoreConfirmation();
|
||||
if (merge.oneActiveSession() != null) one = merge.oneActiveSession();
|
||||
b.authType(merge.authType());
|
||||
}
|
||||
}
|
||||
|
||||
mem = Boolean.TRUE.equals(mem) || Boolean.TRUE.equals(merge.inMemory());
|
||||
|
||||
return SessionSettings.builder()
|
||||
.ttl(ttl).autoProlongation(auto).authType(at)
|
||||
.authStepTypes(steps)
|
||||
.ignoreConfirmation(ign).oneActiveSession(one).inMemory(mem)
|
||||
.build();
|
||||
// AuthStepTypes: роли — объединение множеств; пользователь — overwrite
|
||||
if (merge.authStepTypes() != null) {
|
||||
if (isRole && base.authStepTypes() != null) {
|
||||
var set = new LinkedHashSet<>(base.authStepTypes());
|
||||
set.addAll(merge.authStepTypes());
|
||||
b.authStepTypes(set.stream().toList());
|
||||
} else {
|
||||
b.authStepTypes(merge.authStepTypes());
|
||||
}
|
||||
}
|
||||
|
||||
private static AuthType max(AuthType a, AuthType b) {
|
||||
int ca = a == null ? 0 : a.ordinal();
|
||||
int cb = b == null ? 0 : b.ordinal();
|
||||
return (ca >= cb) ? a : b; // Unknown < Simple < TwoStep
|
||||
// IgnoreConfirmation: роли — если хоть одна роль false → false; пользователь — overwrite
|
||||
if (merge.ignoreConfirmation() != null) {
|
||||
if (isRole) {
|
||||
var cur = base.ignoreConfirmation();
|
||||
if (cur == null) b.ignoreConfirmation(merge.ignoreConfirmation());
|
||||
else if (!merge.ignoreConfirmation()) b.ignoreConfirmation(false);
|
||||
} else {
|
||||
b.ignoreConfirmation(merge.ignoreConfirmation());
|
||||
}
|
||||
}
|
||||
|
||||
// OneActiveSession — простое присваивание (если задано)
|
||||
if (merge.oneActiveSession() != null) b.oneActiveSession(merge.oneActiveSession());
|
||||
|
||||
// InMemory: ИЛИ
|
||||
b.inMemory(Boolean.TRUE.equals(base.inMemory()) || Boolean.TRUE.equals(merge.inMemory()));
|
||||
|
||||
return b.build();
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ server:
|
||||
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:oracle:thin:@127.0.0.1:1521/TKBPAYPDB
|
||||
username: WFMPROP
|
||||
password: WFMPROP
|
||||
url: jdbc:oracle:thin:@cdm-oradb-02.ad.transcapital.com:1523/wfm
|
||||
username: AUTH
|
||||
password: .,z;pws-2shds
|
||||
driver-class-name: oracle.jdbc.OracleDriver
|
||||
|
||||
@@ -5,7 +5,7 @@ FROM (
|
||||
WHERE ah.LEFTKEY <= ah2.LEFTKEY
|
||||
AND ah.RIGHTKEY >= ah2.RIGHTKEY
|
||||
AND ah2.AUTHID = :authId
|
||||
) h
|
||||
JOIN HIERARCHYROLE hr ON h.HIERARCHYID = hr.HIERARCHYID
|
||||
JOIN ROLES r ON r.ROLEID = hr.ROLEID
|
||||
) h
|
||||
JOIN HIERARCHYROLE hr ON hr.HIERARCHYID = h.HIERARCHYID
|
||||
JOIN ROLES r ON r.ROLEID = hr.ROLEID
|
||||
ORDER BY h."LEVEL"
|
||||
3
src/main/resources/sql/auth/find_settings_by_authid.sql
Normal file
3
src/main/resources/sql/auth/find_settings_by_authid.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
SELECT ai.SETTINGS AS AI_SETTINGS
|
||||
FROM AUTHIDS ai
|
||||
WHERE ai.AUTHID = :authId
|
||||
Reference in New Issue
Block a user