feat(iam): split domestic and overseas container permissions
This commit is contained in:
@@ -35,6 +35,14 @@ class IamOpenApiContractTest {
|
||||
.contains("platform:overseas-warehouse:customer-visit:list")
|
||||
.contains("platform:overseas-warehouse:customer-visit:edit")
|
||||
.contains("platform:overseas-warehouse:outbound:cancel")
|
||||
.contains("platform:firstleg:container:list/create/edit")
|
||||
.contains("platform:firstleg:terminal-drayage:list")
|
||||
.contains("platform:firstleg:terminal-drayage:document:edit")
|
||||
.contains("platform:firstleg:terminal-drayage:fleet:edit")
|
||||
.contains("platform:firstleg:terminal-drayage:pickup-appointment:edit")
|
||||
.contains("platform:firstleg:terminal-drayage:pickup:confirm")
|
||||
.contains("platform:firstleg:terminal-drayage:empty-return:confirm")
|
||||
.contains("不以 `container:list/edit` 兼容放行国外操作")
|
||||
.contains("merchant:warehouse:delivery:list")
|
||||
.contains("merchant:warehouse:delivery:create")
|
||||
.contains("merchant:cross-border:procurement")
|
||||
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
package com.baiyue.iam.repository;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class ContainerWorkspacePermissionSqlContractTest {
|
||||
private static final Pattern CODE = Pattern.compile("platform:firstleg:(?:container|terminal-drayage):[a-z0-9:-]+");
|
||||
private static final Set<String> REQUIRED = Set.of(
|
||||
"platform:firstleg:container:list",
|
||||
"platform:firstleg:container:create",
|
||||
"platform:firstleg:container:edit",
|
||||
"platform:firstleg:terminal-drayage:list",
|
||||
"platform:firstleg:terminal-drayage:document:edit",
|
||||
"platform:firstleg:terminal-drayage:fleet:edit",
|
||||
"platform:firstleg:terminal-drayage:pickup-appointment:edit",
|
||||
"platform:firstleg:terminal-drayage:pickup:confirm",
|
||||
"platform:firstleg:terminal-drayage:empty-return:confirm");
|
||||
|
||||
@Test
|
||||
void definesSeparateDomesticAndOverseasMenusWithoutAliases() throws Exception {
|
||||
String sql = sql();
|
||||
|
||||
assertThat(codes(catalog(sql))).containsExactlyInAnyOrderElementsOf(REQUIRED);
|
||||
assertThat(sql).contains(
|
||||
"'platform:firstleg:container:list',\n '国内送柜报关','/container-loading/domestic','GET'",
|
||||
"'platform:firstleg:terminal-drayage:list',\n '国外清关提柜','/container-loading/overseas','GET'",
|
||||
"permission.permission_code='platform:firstleg:container:view'",
|
||||
"SET status='INACTIVE', deleted=1");
|
||||
assertThat(codes(catalog(sql))).noneMatch(code -> code.endsWith(":view"));
|
||||
assertThat(sql).doesNotContain(
|
||||
"platform:firstleg:domestic-container:",
|
||||
"platform:firstleg:overseas-container:",
|
||||
"platform:firstleg:terminal-drayage:edit");
|
||||
}
|
||||
|
||||
@Test
|
||||
void keepsDomesticWritesAndDefinesFineGrainedOverseasWrites() throws Exception {
|
||||
assertThat(sql()).contains(
|
||||
"'platform:firstleg:container:create',\n '建立国内货柜',NULL,'POST'",
|
||||
"'platform:firstleg:container:edit',\n '维护国内货柜资料',NULL,'PUT'",
|
||||
"'platform:firstleg:terminal-drayage:document:edit',\n '维护目的港清关与DO/PU',NULL,'POST'",
|
||||
"'platform:firstleg:terminal-drayage:fleet:edit',\n '维护目的港码头车队',NULL,'POST'",
|
||||
"'platform:firstleg:terminal-drayage:pickup-appointment:edit',\n '预约目的港提柜',NULL,'POST'",
|
||||
"'platform:firstleg:terminal-drayage:pickup:confirm',\n '确认目的港实际提柜',NULL,'POST'",
|
||||
"'platform:firstleg:terminal-drayage:empty-return:confirm',\n '确认目的港实际还柜',NULL,'POST'");
|
||||
}
|
||||
|
||||
@Test
|
||||
void grantsTheCompleteMatrixOnlyToTheExistingDefaultPlatformRoles() throws Exception {
|
||||
String sql = sql();
|
||||
int grantStart = sql.indexOf("-- 平台超级管理员和现有订单运营保持货柜全链路能力");
|
||||
int assertionStart = sql.indexOf("IF (SELECT COUNT(*) FROM iam_permission", grantStart);
|
||||
String grant = sql.substring(grantStart, assertionStart);
|
||||
|
||||
assertThat(grant).contains(
|
||||
"role.role_code IN ('PLATFORM_ADMIN','ORDER_OPERATOR')",
|
||||
"platform:firstleg:container:list",
|
||||
"platform:firstleg:terminal-drayage:list",
|
||||
"platform:firstleg:terminal-drayage:empty-return:confirm");
|
||||
assertThat(grant).doesNotContain(
|
||||
"PLATFORM_CUSTOM_ADMIN",
|
||||
"WAREHOUSE_OPERATOR",
|
||||
"WAREHOUSE_TALLY",
|
||||
"OVERSEAS_WAREHOUSE_PDA_OPERATOR",
|
||||
"CN_FIRSTLEG_PDA_OPERATOR",
|
||||
"MERCHANT_OWNER");
|
||||
assertThat(sql).contains(
|
||||
"permission_code IN (",
|
||||
")) <> 9 THEN",
|
||||
")) <> 18 THEN");
|
||||
}
|
||||
|
||||
@Test
|
||||
void failsClosedForFixedIdentityConflictsAndRemainsReplaySafe() throws Exception {
|
||||
assertThat(sql()).contains(
|
||||
"migrate_container_workspace_permissions",
|
||||
"id = 5102090 AND permission_code <> 'platform:firstleg:container:list'",
|
||||
"id = 5102205 AND permission_code <> 'platform:firstleg:terminal-drayage:empty-return:confirm'",
|
||||
"permission_code = 'platform:firstleg:terminal-drayage:list' AND id <> 5102200",
|
||||
"SIGNAL SQLSTATE '45000'",
|
||||
"ON DUPLICATE KEY UPDATE",
|
||||
"INSERT IGNORE INTO iam_role_permission");
|
||||
}
|
||||
|
||||
private static String sql() throws Exception {
|
||||
return new ClassPathResource("db/container-workspace-permissions.sql")
|
||||
.getContentAsString(StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
private static Set<String> codes(String source) {
|
||||
Set<String> values = new LinkedHashSet<>();
|
||||
CODE.matcher(source).results().map(result -> result.group()).forEach(values::add);
|
||||
return values;
|
||||
}
|
||||
|
||||
private static String catalog(String sql) {
|
||||
int start = sql.indexOf("INSERT INTO iam_permission");
|
||||
int end = sql.indexOf("ON DUPLICATE KEY UPDATE", start);
|
||||
assertThat(start).isGreaterThanOrEqualTo(0);
|
||||
assertThat(end).isGreaterThan(start);
|
||||
return sql.substring(start, end);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user