日志记录提交
This commit is contained in:
@@ -136,7 +136,8 @@ public class MemberService {
|
||||
return response(tenantId, membership);
|
||||
}
|
||||
|
||||
@BusinessAudit(event = "MEMBER_PASSWORD_RESET", resourceType = "MEMBERSHIP", resourceId = "#membershipId", description = "管理员重置成员密码", captureAfter = false)
|
||||
@BusinessAudit(event = "MEMBER_PASSWORD_RESET", resourceType = "MEMBERSHIP", resourceId = "#membershipId",
|
||||
description = "管理员重置成员密码", captureBefore = false, captureAfter = false)
|
||||
public void resetPassword(long tenantId, Long membershipId, ResetMemberPasswordRequest request) {
|
||||
IamMembership membership = required(tenantId, membershipId);
|
||||
if ("OWNER".equals(membership.getMemberType())) {
|
||||
|
||||
@@ -143,7 +143,8 @@ public class PlatformInternalUserService {
|
||||
}
|
||||
|
||||
@BusinessAudit(event = "PLATFORM_INTERNAL_USER_PASSWORD_RESET", resourceType = "MEMBERSHIP",
|
||||
resourceId = "#membershipId", description = "重置平台内部用户密码", captureAfter = false)
|
||||
resourceId = "#membershipId", description = "重置平台内部用户密码",
|
||||
captureBefore = false, captureAfter = false)
|
||||
public void resetPassword(Long membershipId, ResetInternalUserPasswordRequest request) {
|
||||
IamMembership membership = required(membershipId);
|
||||
IamUser user = requiredUser(membership.getUserId());
|
||||
|
||||
@@ -189,7 +189,8 @@ public class PlatformUserManagementService {
|
||||
}
|
||||
|
||||
@BusinessAudit(event = "PLATFORM_USER_PASSWORD_RESET", resourceType = "MEMBERSHIP",
|
||||
resourceId = "#membershipId", description = "平台重置用户密码", captureAfter = false)
|
||||
resourceId = "#membershipId", description = "平台重置用户密码",
|
||||
captureBefore = false, captureAfter = false)
|
||||
public void resetPassword(Long membershipId, ResetPasswordRequest request) {
|
||||
IamUser user = requiredUser(requiredPlatformMembership(membershipId).getUserId());
|
||||
call(() -> authClient.reset(internalToken, user.getAuthUserId(),
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
USE baiyue_iam;
|
||||
|
||||
-- 可靠审计本地 Outbox;与 IAM 业务表位于同一数据库。
|
||||
CREATE TABLE IF NOT EXISTS sys_audit_outbox (
|
||||
event_id VARCHAR(64) NOT NULL, event_type VARCHAR(64) NOT NULL, resource_type VARCHAR(64) NOT NULL,
|
||||
resource_id VARCHAR(128) NULL, service_name VARCHAR(64) NULL, payload_json JSON NOT NULL,
|
||||
status VARCHAR(16) NOT NULL DEFAULT 'PENDING', attempt_count INT NOT NULL DEFAULT 0,
|
||||
compensation_count INT NOT NULL DEFAULT 0,
|
||||
next_retry_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), lease_owner VARCHAR(128) NULL,
|
||||
lease_until DATETIME(3) NULL, last_error VARCHAR(1000) NULL, dead_at DATETIME(3) NULL,
|
||||
sent_at DATETIME(3) NULL, created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
|
||||
PRIMARY KEY (event_id), KEY idx_audit_outbox_publish (status, next_retry_at, lease_until, created_at),
|
||||
KEY idx_audit_outbox_retention (status, sent_at)
|
||||
) ENGINE=InnoDB COMMENT='可靠审计事件本地发送箱';
|
||||
@@ -0,0 +1,33 @@
|
||||
USE baiyue_iam;
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
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
|
||||
(5102070, 0, 'PLATFORM', 'MENU', 5103000, 'firstleg:fee-item:view',
|
||||
'费用项目', '/master-data/fee-items', NULL, 40, 'ACTIVE', 1, 0),
|
||||
(5102071, 0, 'PLATFORM', 'BUTTON', 5102070, 'firstleg:fee-item:create',
|
||||
'新增费用项目', NULL, NULL, 10, 'ACTIVE', 1, 0),
|
||||
(5102072, 0, 'PLATFORM', 'BUTTON', 5102070, 'firstleg:fee-item:edit',
|
||||
'编辑或停用费用项目', NULL, NULL, 20, 'ACTIVE', 1, 0),
|
||||
(5102073, 0, 'PLATFORM', 'BUTTON', 5102070, 'firstleg:fee-item:delete',
|
||||
'删除费用项目', NULL, NULL, 30, 'ACTIVE', 1, 0),
|
||||
(5102081, 0, 'PLATFORM', 'BUTTON', 5102030, 'firstleg:inbound:fee-detail:view',
|
||||
'查看入库费用明细', NULL, NULL, 100, 'ACTIVE', 1, 0),
|
||||
(5102082, 0, 'PLATFORM', 'BUTTON', 5102030, 'firstleg:inbound:fee-detail:edit',
|
||||
'新增编辑入库费用明细', NULL, NULL, 110, 'ACTIVE', 1, 0),
|
||||
(5102083, 0, 'PLATFORM', 'BUTTON', 5102030, 'firstleg:inbound:fee-detail:delete',
|
||||
'删除入库费用明细', NULL, NULL, 120, 'ACTIVE', 1, 0),
|
||||
(5102084, 0, 'PLATFORM', 'BUTTON', 5102030, 'firstleg:inbound:fee-detail:review',
|
||||
'审核入库费用明细', NULL, NULL, 130, '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),
|
||||
sort_no = VALUES(sort_no), status = 'ACTIVE', built_in = 1, deleted = 0;
|
||||
|
||||
INSERT INTO iam_role_permission (role_id, permission_id, tenant_id)
|
||||
SELECT 4000001, id, 0
|
||||
FROM iam_permission
|
||||
WHERE id IN (5102070, 5102071, 5102072, 5102073, 5102081, 5102082, 5102083, 5102084)
|
||||
ON DUPLICATE KEY UPDATE tenant_id = VALUES(tenant_id);
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.baiyue.iam.service;
|
||||
|
||||
import com.baiyue.common.audit.BusinessAudit;
|
||||
import com.baiyue.iam.dto.MemberDtos.ResetMemberPasswordRequest;
|
||||
import com.baiyue.iam.dto.PlatformInternalUserDtos.ResetInternalUserPasswordRequest;
|
||||
import com.baiyue.iam.dto.PlatformUserManagementDtos.ResetPasswordRequest;
|
||||
import com.baiyue.iam.dto.RbacDtos.AssignRolesRequest;
|
||||
import com.baiyue.iam.dto.RbacDtos.CreateRoleRequest;
|
||||
import com.baiyue.iam.dto.RbacDtos.GrantPermissionsRequest;
|
||||
import com.baiyue.iam.dto.RbacDtos.UpdateRoleRequest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
|
||||
class BusinessAuditCoverageTest {
|
||||
@Test
|
||||
void shouldAuditRbacChanges() throws Exception {
|
||||
assertAudit(RbacService.class, "createRole", "ROLE_CREATE", "ROLE", "#request.roleCode",
|
||||
long.class, String.class, CreateRoleRequest.class);
|
||||
assertAudit(RbacService.class, "updateRole", "ROLE_UPDATE", "ROLE", "#roleId",
|
||||
long.class, String.class, Long.class, UpdateRoleRequest.class);
|
||||
assertAudit(RbacService.class, "changeStatus", "ROLE_STATUS_CHANGE", "ROLE", "#roleId",
|
||||
long.class, String.class, Long.class,
|
||||
com.baiyue.iam.dto.RbacDtos.ChangeRoleStatusRequest.class);
|
||||
assertAudit(RbacService.class, "deleteRole", "ROLE_DELETE", "ROLE", "#roleId",
|
||||
long.class, String.class, Long.class);
|
||||
assertAudit(RbacService.class, "assignRoles", "MEMBER_ROLE_ASSIGN", "MEMBERSHIP", "#request.membershipId",
|
||||
long.class, String.class, AssignRolesRequest.class);
|
||||
assertAudit(RbacService.class, "grantPermissions", "ROLE_PERMISSION_GRANT", "ROLE", "#request.roleId",
|
||||
long.class, String.class, GrantPermissionsRequest.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNeverCapturePasswordSnapshots() throws Exception {
|
||||
assertPasswordAudit(MemberService.class, "resetPassword", long.class, Long.class,
|
||||
ResetMemberPasswordRequest.class);
|
||||
assertPasswordAudit(PlatformUserManagementService.class, "resetPassword", Long.class,
|
||||
ResetPasswordRequest.class);
|
||||
assertPasswordAudit(PlatformInternalUserService.class, "resetPassword", Long.class,
|
||||
ResetInternalUserPasswordRequest.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldAuditCustomerReview() throws Exception {
|
||||
assertAudit(TenantService.class, "review", "TENANT_REVIEW", "TENANT_REVIEW", "#reviewId",
|
||||
long.class, long.class, boolean.class, String.class);
|
||||
}
|
||||
|
||||
private void assertAudit(Class<?> type, String methodName, String event, String resourceType,
|
||||
String resourceId, Class<?>... parameterTypes) throws Exception {
|
||||
BusinessAudit audit = annotation(type, methodName, parameterTypes);
|
||||
assertEquals(event, audit.event());
|
||||
assertEquals(resourceType, audit.resourceType());
|
||||
assertEquals(resourceId, audit.resourceId());
|
||||
}
|
||||
|
||||
private void assertPasswordAudit(Class<?> type, String methodName, Class<?>... parameterTypes) throws Exception {
|
||||
BusinessAudit audit = annotation(type, methodName, parameterTypes);
|
||||
assertFalse(audit.captureBefore());
|
||||
assertFalse(audit.captureAfter());
|
||||
}
|
||||
|
||||
private BusinessAudit annotation(Class<?> type, String methodName, Class<?>... parameterTypes) throws Exception {
|
||||
Method method = type.getDeclaredMethod(methodName, parameterTypes);
|
||||
return method.getAnnotation(BusinessAudit.class);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user