优化
This commit is contained in:
@@ -13760,10 +13760,91 @@ VALUES
|
||||
(5205011, 10001, 'MERCHANT', 'BUTTON', 5205000, 'merchant:finance:statement:view', '查看账单详情及收款', NULL, 'GET', 20, 'ACTIVE', 0)
|
||||
ON DUPLICATE KEY UPDATE permission_name=VALUES(permission_name), parent_id=VALUES(parent_id), route_path=VALUES(route_path), http_method=VALUES(http_method), status='ACTIVE', deleted=0;
|
||||
|
||||
-- Finance G1/G2 新权限只进入可分配权限目录,不默认授予平台管理员。
|
||||
DROP PROCEDURE IF EXISTS migrate_finance_g1_g2_permissions;
|
||||
DELIMITER $$
|
||||
CREATE PROCEDURE migrate_finance_g1_g2_permissions()
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM baiyue_iam.iam_permission
|
||||
WHERE (id = 5105022 AND permission_code <> 'platform:finance:account:view')
|
||||
OR (id = 5105023 AND permission_code <> 'platform:finance:fee-source:view')
|
||||
OR (id = 5105024 AND permission_code <> 'platform:finance:fee-source:review')
|
||||
OR (id = 5105025 AND permission_code <> 'platform:finance:fee-source:settlement')
|
||||
OR (permission_code = 'platform:finance:account:view' AND id <> 5105022)
|
||||
OR (permission_code = 'platform:finance:fee-source:view' AND id <> 5105023)
|
||||
OR (permission_code = 'platform:finance:fee-source:review' AND id <> 5105024)
|
||||
OR (permission_code = 'platform:finance:fee-source:settlement' AND id <> 5105025)
|
||||
OR (id IN (5105022, 5105023, 5105024, 5105025)
|
||||
AND (tenant_id <> 0 OR app_code <> 'PLATFORM'))
|
||||
) THEN
|
||||
SIGNAL SQLSTATE '45000'
|
||||
SET MESSAGE_TEXT = 'finance G1/G2 permission id/code conflict';
|
||||
END IF;
|
||||
|
||||
INSERT INTO baiyue_iam.iam_permission
|
||||
(id, tenant_id, app_code, permission_type, parent_id, permission_code,
|
||||
permission_name, route_path, http_method, sort_no, status, built_in, deleted)
|
||||
VALUES
|
||||
(5105022, 0, 'PLATFORM', 'BUTTON', 5105000, 'platform:finance:account:view',
|
||||
'查看客户财务账户及流水', NULL, 'GET', 130, 'ACTIVE', 1, 0),
|
||||
(5105023, 0, 'PLATFORM', 'BUTTON', 5105000, 'platform:finance:fee-source:view',
|
||||
'查看财务费用来源', NULL, 'GET', 140, 'ACTIVE', 1, 0),
|
||||
(5105024, 0, 'PLATFORM', 'BUTTON', 5105000, 'platform:finance:fee-source:review',
|
||||
'审核财务费用来源', NULL, 'POST', 150, 'ACTIVE', 1, 0),
|
||||
(5105025, 0, 'PLATFORM', 'BUTTON', 5105000, 'platform:finance:fee-source:settlement',
|
||||
'设置费用来源参与结算', NULL, 'PUT', 160, 'ACTIVE', 1, 0)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
permission_type = VALUES(permission_type), parent_id = VALUES(parent_id),
|
||||
permission_name = VALUES(permission_name), route_path = VALUES(route_path),
|
||||
http_method = VALUES(http_method), sort_no = VALUES(sort_no),
|
||||
status = 'ACTIVE', built_in = 1, deleted = 0;
|
||||
|
||||
IF (SELECT COUNT(*)
|
||||
FROM baiyue_iam.iam_permission
|
||||
WHERE tenant_id = 0
|
||||
AND app_code = 'PLATFORM'
|
||||
AND permission_type = 'BUTTON'
|
||||
AND parent_id = 5105000
|
||||
AND status = 'ACTIVE'
|
||||
AND built_in = 1
|
||||
AND deleted = 0
|
||||
AND permission_code IN (
|
||||
'platform:finance:account:view',
|
||||
'platform:finance:fee-source:view',
|
||||
'platform:finance:fee-source:review',
|
||||
'platform:finance:fee-source:settlement')) <> 4 THEN
|
||||
SIGNAL SQLSTATE '45000'
|
||||
SET MESSAGE_TEXT = 'finance G1/G2 permission catalog is incomplete';
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
CALL migrate_finance_g1_g2_permissions();
|
||||
DROP PROCEDURE IF EXISTS migrate_finance_g1_g2_permissions;
|
||||
|
||||
INSERT INTO baiyue_iam.iam_role_permission (role_id, permission_id, tenant_id)
|
||||
SELECT 4000001, id, 0 FROM baiyue_iam.iam_permission
|
||||
WHERE tenant_id=0 AND app_code='PLATFORM' AND (permission_code='platform:finance' OR permission_code LIKE 'platform:finance:%')
|
||||
WHERE tenant_id=0 AND app_code='PLATFORM' AND permission_code IN (
|
||||
'platform:finance',
|
||||
'platform:finance:bill:view', 'platform:finance:bill:create',
|
||||
'platform:finance:bill:update', 'platform:finance:bill:issue',
|
||||
'platform:finance:bill:adjust', 'platform:finance:bill:void',
|
||||
'platform:finance:receipt:view', 'platform:finance:receipt:create',
|
||||
'platform:finance:cost:view', 'platform:finance:cost:create',
|
||||
'platform:finance:customer-terms:view', 'platform:finance:customer-terms:update')
|
||||
ON DUPLICATE KEY UPDATE tenant_id=VALUES(tenant_id);
|
||||
DELETE rp
|
||||
FROM baiyue_iam.iam_role_permission rp
|
||||
JOIN baiyue_iam.iam_permission p
|
||||
ON p.id = rp.permission_id AND p.tenant_id = rp.tenant_id
|
||||
WHERE rp.role_id = 4000001
|
||||
AND rp.tenant_id = 0
|
||||
AND p.permission_code IN (
|
||||
'platform:finance:account:view',
|
||||
'platform:finance:fee-source:view',
|
||||
'platform:finance:fee-source:review',
|
||||
'platform:finance:fee-source:settlement');
|
||||
INSERT INTO baiyue_iam.iam_role_permission (role_id, permission_id, tenant_id)
|
||||
SELECT 4000101, id, 10001 FROM baiyue_iam.iam_permission
|
||||
WHERE tenant_id=10001 AND app_code='MERCHANT' AND (permission_code='merchant:finance:statement' OR permission_code LIKE 'merchant:finance:%')
|
||||
@@ -13773,7 +13854,7 @@ ON DUPLICATE KEY UPDATE tenant_id=VALUES(tenant_id);
|
||||
DELIMITER $$
|
||||
CREATE PROCEDURE assert_finance_permissions()
|
||||
BEGIN
|
||||
IF (SELECT COUNT(*) FROM baiyue_iam.iam_permission WHERE tenant_id=0 AND app_code='PLATFORM' AND permission_code LIKE 'platform:finance:%' AND status='ACTIVE' AND deleted=0) <> 12 THEN
|
||||
IF (SELECT COUNT(*) FROM baiyue_iam.iam_permission WHERE tenant_id=0 AND app_code='PLATFORM' AND permission_code LIKE 'platform:finance:%' AND status='ACTIVE' AND deleted=0) <> 16 THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='统一迁移失败:平台 Finance 权限不完整';
|
||||
END IF;
|
||||
IF (SELECT COUNT(*) FROM baiyue_iam.iam_permission WHERE tenant_id=10001 AND app_code='MERCHANT' AND permission_code IN ('merchant:finance:statement:list','merchant:finance:statement:view') AND status='ACTIVE' AND deleted=0) <> 2 THEN
|
||||
@@ -13782,6 +13863,9 @@ BEGIN
|
||||
IF (SELECT COUNT(*) FROM baiyue_iam.iam_role_permission rp JOIN baiyue_iam.iam_permission p ON p.id=rp.permission_id AND p.tenant_id=rp.tenant_id WHERE rp.role_id=4000001 AND rp.tenant_id=0 AND (p.permission_code='platform:finance' OR p.permission_code LIKE 'platform:finance:%')) <> 13 THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='统一迁移失败:平台管理员 Finance 授权不完整';
|
||||
END IF;
|
||||
IF (SELECT COUNT(*) FROM baiyue_iam.iam_role_permission rp JOIN baiyue_iam.iam_permission p ON p.id=rp.permission_id AND p.tenant_id=rp.tenant_id WHERE rp.role_id=4000001 AND rp.tenant_id=0 AND p.permission_code IN ('platform:finance:account:view','platform:finance:fee-source:view','platform:finance:fee-source:review','platform:finance:fee-source:settlement')) <> 0 THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='统一迁移失败:Finance G1/G2 新权限不得默认授予平台管理员';
|
||||
END IF;
|
||||
IF (SELECT COUNT(*) FROM baiyue_iam.iam_role_permission rp JOIN baiyue_iam.iam_permission p ON p.id=rp.permission_id AND p.tenant_id=rp.tenant_id WHERE rp.role_id=4000101 AND rp.tenant_id=10001 AND (p.permission_code='merchant:finance:statement' OR p.permission_code LIKE 'merchant:finance:%')) <> 3 THEN
|
||||
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='统一迁移失败:客户管理员 Finance 只读授权不完整';
|
||||
END IF;
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.baiyue.finance;
|
||||
|
||||
import com.baiyue.finance.controller.FinancePhase1OperationController;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class FinancePhase1PermissionContractTest {
|
||||
@Test
|
||||
void freezesG1AndG2ControllerPermissionsAndHttpActions() throws Exception {
|
||||
assertEndpoint("listDerivedCustomerAccounts", GetMapping.class,
|
||||
"hasAuthority('platform:finance:account:view')", int.class, int.class, String.class, String.class);
|
||||
assertEndpoint("listDerivedCustomerAccountLedger", GetMapping.class,
|
||||
"hasAuthority('platform:finance:account:view')", long.class, int.class, int.class,
|
||||
String.class, java.time.LocalDate.class, java.time.LocalDate.class);
|
||||
assertEndpoint("getFinanceFeeSource", GetMapping.class,
|
||||
"hasAuthority('platform:finance:fee-source:view')", long.class);
|
||||
assertEndpoint("reviewFinanceFeeSource", PostMapping.class,
|
||||
"hasAuthority('platform:finance:fee-source:review')",
|
||||
com.baiyue.common.security.AuthenticatedUser.class, long.class, String.class,
|
||||
com.baiyue.finance.dto.FinancePhase1Dtos.ReviewRequest.class);
|
||||
assertEndpoint("updateFeeSourceSettlementInclusion", PutMapping.class,
|
||||
"hasAuthority('platform:finance:fee-source:settlement')",
|
||||
com.baiyue.common.security.AuthenticatedUser.class, long.class, String.class,
|
||||
com.baiyue.finance.dto.FinancePhase1Dtos.SettlementInclusionRequest.class);
|
||||
}
|
||||
|
||||
private static void assertEndpoint(String methodName,
|
||||
Class<? extends java.lang.annotation.Annotation> mapping,
|
||||
String authority,
|
||||
Class<?>... parameterTypes) throws Exception {
|
||||
Method method = FinancePhase1OperationController.class.getMethod(methodName, parameterTypes);
|
||||
assertThat(method.isAnnotationPresent(mapping)).isTrue();
|
||||
assertThat(method.getAnnotation(PreAuthorize.class).value()).isEqualTo(authority);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
-- Finance G1/G2 permissions exposed by FinancePhase1OperationController.
|
||||
-- These resources are assignable to custom platform roles; this migration does not grant them by default.
|
||||
USE baiyue_iam;
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
DROP PROCEDURE IF EXISTS migrate_finance_g1_g2_permissions;
|
||||
DELIMITER $$
|
||||
CREATE PROCEDURE migrate_finance_g1_g2_permissions()
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM iam_permission
|
||||
WHERE (id = 5105000 AND permission_code <> 'platform:finance')
|
||||
OR (id = 5105022 AND permission_code <> 'platform:finance:account:view')
|
||||
OR (id = 5105023 AND permission_code <> 'platform:finance:fee-source:view')
|
||||
OR (id = 5105024 AND permission_code <> 'platform:finance:fee-source:review')
|
||||
OR (id = 5105025 AND permission_code <> 'platform:finance:fee-source:settlement')
|
||||
OR (permission_code = 'platform:finance' AND id <> 5105000)
|
||||
OR (permission_code = 'platform:finance:account:view' AND id <> 5105022)
|
||||
OR (permission_code = 'platform:finance:fee-source:view' AND id <> 5105023)
|
||||
OR (permission_code = 'platform:finance:fee-source:review' AND id <> 5105024)
|
||||
OR (permission_code = 'platform:finance:fee-source:settlement' AND id <> 5105025)
|
||||
OR (id IN (5105000, 5105022, 5105023, 5105024, 5105025)
|
||||
AND (tenant_id <> 0 OR app_code <> 'PLATFORM'))
|
||||
) THEN
|
||||
SIGNAL SQLSTATE '45000'
|
||||
SET MESSAGE_TEXT = 'finance G1/G2 permission id/code conflict';
|
||||
END IF;
|
||||
|
||||
INSERT INTO iam_permission
|
||||
(id, tenant_id, app_code, permission_type, parent_id, permission_code,
|
||||
permission_name, route_path, http_method, sort_no, status, built_in, deleted)
|
||||
VALUES
|
||||
(5105000, 0, 'PLATFORM', 'MENU', 0, 'platform:finance',
|
||||
'财务管理', '/finance', NULL, 60, 'ACTIVE', 1, 0),
|
||||
(5105022, 0, 'PLATFORM', 'BUTTON', 5105000, 'platform:finance:account:view',
|
||||
'查看客户财务账户及流水', NULL, 'GET', 130, 'ACTIVE', 1, 0),
|
||||
(5105023, 0, 'PLATFORM', 'BUTTON', 5105000, 'platform:finance:fee-source:view',
|
||||
'查看财务费用来源', NULL, 'GET', 140, 'ACTIVE', 1, 0),
|
||||
(5105024, 0, 'PLATFORM', 'BUTTON', 5105000, 'platform:finance:fee-source:review',
|
||||
'审核财务费用来源', NULL, 'POST', 150, 'ACTIVE', 1, 0),
|
||||
(5105025, 0, 'PLATFORM', 'BUTTON', 5105000, 'platform:finance:fee-source:settlement',
|
||||
'设置费用来源参与结算', NULL, 'PUT', 160, 'ACTIVE', 1, 0)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
permission_type = VALUES(permission_type), parent_id = VALUES(parent_id),
|
||||
permission_name = VALUES(permission_name), route_path = VALUES(route_path),
|
||||
http_method = VALUES(http_method), sort_no = VALUES(sort_no),
|
||||
status = 'ACTIVE', built_in = 1, deleted = 0;
|
||||
|
||||
IF (SELECT COUNT(*)
|
||||
FROM iam_permission
|
||||
WHERE tenant_id = 0
|
||||
AND app_code = 'PLATFORM'
|
||||
AND permission_type = 'BUTTON'
|
||||
AND parent_id = 5105000
|
||||
AND status = 'ACTIVE'
|
||||
AND built_in = 1
|
||||
AND deleted = 0
|
||||
AND permission_code IN (
|
||||
'platform:finance:account:view',
|
||||
'platform:finance:fee-source:view',
|
||||
'platform:finance:fee-source:review',
|
||||
'platform:finance:fee-source:settlement')) <> 4 THEN
|
||||
SIGNAL SQLSTATE '45000'
|
||||
SET MESSAGE_TEXT = 'finance G1/G2 permission catalog is incomplete';
|
||||
END IF;
|
||||
|
||||
IF (SELECT COUNT(*)
|
||||
FROM iam_permission
|
||||
WHERE id = 5105000
|
||||
AND tenant_id = 0
|
||||
AND app_code = 'PLATFORM'
|
||||
AND permission_type = 'MENU'
|
||||
AND parent_id = 0
|
||||
AND permission_code = 'platform:finance'
|
||||
AND status = 'ACTIVE'
|
||||
AND built_in = 1
|
||||
AND deleted = 0) <> 1 THEN
|
||||
SIGNAL SQLSTATE '45000'
|
||||
SET MESSAGE_TEXT = 'finance permission parent is invalid';
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
CALL migrate_finance_g1_g2_permissions();
|
||||
DROP PROCEDURE IF EXISTS migrate_finance_g1_g2_permissions;
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.baiyue.iam.repository;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class FinanceG1G2PermissionSqlContractTest {
|
||||
@Test
|
||||
void declaresTheFourControllerPermissionsUnderFinanceWithoutDefaultRoleGrants() throws Exception {
|
||||
String sql = new ClassPathResource("db/finance-g1-g2-permissions.sql")
|
||||
.getContentAsString(StandardCharsets.UTF_8);
|
||||
|
||||
assertThat(sql)
|
||||
.contains("(5105022, 0, 'PLATFORM', 'BUTTON', 5105000, 'platform:finance:account:view'")
|
||||
.contains("(5105023, 0, 'PLATFORM', 'BUTTON', 5105000, 'platform:finance:fee-source:view'")
|
||||
.contains("(5105024, 0, 'PLATFORM', 'BUTTON', 5105000, 'platform:finance:fee-source:review'")
|
||||
.contains("(5105025, 0, 'PLATFORM', 'BUTTON', 5105000, 'platform:finance:fee-source:settlement'")
|
||||
.contains("NULL, 'GET', 130, 'ACTIVE', 1, 0")
|
||||
.contains("NULL, 'GET', 140, 'ACTIVE', 1, 0")
|
||||
.contains("NULL, 'POST', 150, 'ACTIVE', 1, 0")
|
||||
.contains("NULL, 'PUT', 160, 'ACTIVE', 1, 0")
|
||||
.contains("ON DUPLICATE KEY UPDATE")
|
||||
.contains("CALL migrate_finance_g1_g2_permissions()")
|
||||
.contains("DROP PROCEDURE IF EXISTS migrate_finance_g1_g2_permissions")
|
||||
.doesNotContain("INSERT INTO iam_role_permission");
|
||||
}
|
||||
|
||||
@Test
|
||||
void failsClosedOnPermissionIdentityConflictsAndAssertsCatalogCompleteness() throws Exception {
|
||||
String sql = new ClassPathResource("db/finance-g1-g2-permissions.sql")
|
||||
.getContentAsString(StandardCharsets.UTF_8);
|
||||
|
||||
assertThat(sql)
|
||||
.contains("SIGNAL SQLSTATE '45000'")
|
||||
.contains("id = 5105022 AND permission_code <> 'platform:finance:account:view'")
|
||||
.contains("permission_code = 'platform:finance:fee-source:settlement' AND id <> 5105025")
|
||||
.contains("tenant_id <> 0 OR app_code <> 'PLATFORM'")
|
||||
.contains("parent_id = 5105000")
|
||||
.contains("permission_type = 'MENU'")
|
||||
.contains("built_in = 1")
|
||||
.contains("finance permission parent is invalid")
|
||||
.contains("permission catalog is incomplete");
|
||||
}
|
||||
|
||||
@Test
|
||||
void unifiedSqlMirrorsCatalogButDoesNotAutoGrantTheNewPermissions() throws Exception {
|
||||
String sql = Files.readString(resolveUnifiedSql(), StandardCharsets.UTF_8);
|
||||
String financeSection = sql.substring(sql.indexOf("-- Finance F1 人工财务权限"),
|
||||
sql.indexOf("CALL assert_unified_final_schema()"));
|
||||
String platformAdminGrant = financeSection.substring(
|
||||
financeSection.indexOf("SELECT 4000001, id, 0 FROM baiyue_iam.iam_permission"),
|
||||
financeSection.indexOf("ON DUPLICATE KEY UPDATE tenant_id=VALUES(tenant_id);"));
|
||||
|
||||
assertThat(financeSection)
|
||||
.contains("(5105022, 0, 'PLATFORM', 'BUTTON', 5105000, 'platform:finance:account:view'")
|
||||
.contains("(5105023, 0, 'PLATFORM', 'BUTTON', 5105000, 'platform:finance:fee-source:view'")
|
||||
.contains("(5105024, 0, 'PLATFORM', 'BUTTON', 5105000, 'platform:finance:fee-source:review'")
|
||||
.contains("(5105025, 0, 'PLATFORM', 'BUTTON', 5105000, 'platform:finance:fee-source:settlement'")
|
||||
.contains("NULL, 'GET', 130, 'ACTIVE', 1, 0")
|
||||
.contains("NULL, 'GET', 140, 'ACTIVE', 1, 0")
|
||||
.contains("NULL, 'POST', 150, 'ACTIVE', 1, 0")
|
||||
.contains("NULL, 'PUT', 160, 'ACTIVE', 1, 0")
|
||||
.contains("permission_code IN (\n 'platform:finance',")
|
||||
.contains("permission_code LIKE 'platform:finance:%' AND status='ACTIVE' AND deleted=0) <> 16")
|
||||
.contains("p.permission_code IN ('platform:finance:account:view','platform:finance:fee-source:view','platform:finance:fee-source:review','platform:finance:fee-source:settlement')) <> 0")
|
||||
.contains("平台管理员 Finance 授权不完整")
|
||||
.contains("Finance G1/G2 新权限不得默认授予平台管理员");
|
||||
assertThat(platformAdminGrant)
|
||||
.contains("'platform:finance'")
|
||||
.contains("'platform:finance:customer-terms:update'")
|
||||
.doesNotContain("LIKE 'platform:finance:%'")
|
||||
.doesNotContain("platform:finance:account:view")
|
||||
.doesNotContain("platform:finance:fee-source:view")
|
||||
.doesNotContain("platform:finance:fee-source:review")
|
||||
.doesNotContain("platform:finance:fee-source:settlement");
|
||||
}
|
||||
|
||||
private static Path resolveUnifiedSql() {
|
||||
Path direct = Path.of("deploy", "sql", "头程数据库统一增量-MySQL8.sql");
|
||||
return Files.exists(direct) ? direct : Path.of("..", "deploy", "sql", "头程数据库统一增量-MySQL8.sql");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user