fix: project overseas authorization outside jwt

This commit is contained in:
2026-09-07 11:37:06 +08:00
parent 6b479d1a68
commit 4963889024
33 changed files with 382 additions and 92 deletions
@@ -21,10 +21,10 @@ class LastlegSecurityContractTest {
"PRIMARY KEY (event_id)", "payload_hash CHAR(64)",
"CREATE TABLE IF NOT EXISTS ll_security_projection",
"PRIMARY KEY (aggregate_type,aggregate_id)", "aggregate_version BIGINT",
"permission_version BIGINT");
"permission_version BIGINT", "roles_json JSON", "authorities_json JSON");
for (String sql : new String[]{baseline, migration}) {
assertThat(sql).contains("('USER','1000001',0,'ACTIVE',0,0",
"('AUTHORIZATION','1000001',0,NULL,0,0",
assertThat(sql).contains("('USER','1000001',0,'ACTIVE',0,JSON_ARRAY(),JSON_ARRAY(),0",
"('AUTHORIZATION','1000001',0,NULL,0,JSON_ARRAY(),JSON_ARRAY(),0",
"baseline-platform-admin-user-v0",
"baseline-platform-admin-authorization-v0")
.doesNotContain("baseline-merchant-admin");
@@ -39,7 +39,7 @@ class LastlegSecurityContractTest {
assertThat(service).contains("EventPayloadHash.matches", "validatedStorageHash")
.doesNotContain("LoadingCompletedConsumer");
assertThat(mirror).contains("TransactionPhase.AFTER_COMMIT", "Redis 镜像写入失败");
assertThat(validation).contains("SELECT MAX(permission_version)", "tenant_id=?",
assertThat(validation).contains("SELECT permission_version", "authorities_json", "tenant_id=?",
"SECURITY_PROJECTION_MISSING", "SECURITY_PROJECTION_NOT_READY", "USER_DISABLED",
"TENANT_DISABLED", "PERMISSION_VERSION_STALE");
assertThat(validationDto).contains("Long userId", "Long tenantId", "Long permissionVersion")
@@ -43,7 +43,9 @@ class LastlegSecurityProjectionTransportTest {
private EventEnvelope envelope() {
var value = new IamSecurityEventsV1.PermissionVersionChanged(
101L, 0L, "PLATFORM", 3L, "contract", Instant.parse("2026-08-25T07:00:00Z"));
101L, 0L, "PLATFORM", 3L, "contract", Instant.parse("2026-08-25T07:00:00Z"),
java.util.Set.of("PLATFORM_ADMIN"),
java.util.Set.of("platform:overseas-warehouse:last-mile-order:list"));
var payload = objectMapper.valueToTree(value);
return new EventEnvelope("00000000-0000-4000-8000-000000000091",
EventTypes.IAM_PERMISSION_VERSION_CHANGED, IamSecurityEventsV1.VERSION,
@@ -5,6 +5,7 @@ import com.baiyue.lastleg.security.dto.LastlegSecurityDtos.ValidationRequest;
import org.junit.jupiter.api.Test;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
@@ -16,7 +17,7 @@ import static org.mockito.Mockito.mock;
class LastlegSecurityValidationServiceTest {
private final JdbcTemplate jdbc = mock(JdbcTemplate.class);
private final LastlegSecurityValidationService service = new LastlegSecurityValidationService(jdbc);
private final LastlegSecurityValidationService service = new LastlegSecurityValidationService(jdbc, new ObjectMapper());
@Test void disabledUserFailsClosed() {
doReturn(List.of("DISABLED")).when(jdbc)
@@ -40,7 +41,8 @@ class LastlegSecurityValidationServiceTest {
}
@Test void customerProjectionIsMandatoryButPlatformTenantDoesNotNeedOne() {
doReturn(List.of("ACTIVE"), List.of(), List.of("ACTIVE"), List.of(8L)).when(jdbc)
doReturn(List.of("ACTIVE"), List.of(), List.of("ACTIVE"), List.of(8L),
List.of("[]\n[\"platform:overseas-warehouse:last-mile-order:list\"]")).when(jdbc)
.query(anyString(), any(RowMapper.class), any(Object[].class));
assertThat(service.validate(new ValidationRequest(42L, 100L, 8L)).failureReason())
.isEqualTo(FailureReason.SECURITY_PROJECTION_MISSING);
@@ -49,7 +51,7 @@ class LastlegSecurityValidationServiceTest {
@Test void permissionVersionMustExactlyMatchReliableProjection() {
doReturn(List.of("ACTIVE"), List.of(9L), List.of("ACTIVE"), List.of(9L),
List.of("ACTIVE"), List.of(9L)).when(jdbc)
List.of("ACTIVE"), List.of(9L), List.of("[]\n[]")).when(jdbc)
.query(anyString(), any(RowMapper.class), any(Object[].class));
assertThat(service.validate(new ValidationRequest(42L, 0L, 8L)).failureReason())
.isEqualTo(FailureReason.PERMISSION_VERSION_STALE);