fix:登录流程改造1
This commit is contained in:
parent
0f1c24caf9
commit
02328d1760
@ -0,0 +1,40 @@
|
||||
package com.cisd.tms.modules.auth.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Schema(description = "修改口令准备响应")
|
||||
public class PasswordChangePrepareResponse {
|
||||
|
||||
@Schema(description = "改密确认令牌")
|
||||
private String changeToken;
|
||||
|
||||
@Schema(description = "旧口令动态摘要挑战随机数")
|
||||
private String oldServerRandom;
|
||||
|
||||
@Schema(description = "新口令盐值,前端写入 UKey")
|
||||
private String newPasswordSalt;
|
||||
|
||||
public String getChangeToken() {
|
||||
return changeToken;
|
||||
}
|
||||
|
||||
public void setChangeToken(String changeToken) {
|
||||
this.changeToken = changeToken;
|
||||
}
|
||||
|
||||
public String getOldServerRandom() {
|
||||
return oldServerRandom;
|
||||
}
|
||||
|
||||
public void setOldServerRandom(String oldServerRandom) {
|
||||
this.oldServerRandom = oldServerRandom;
|
||||
}
|
||||
|
||||
public String getNewPasswordSalt() {
|
||||
return newPasswordSalt;
|
||||
}
|
||||
|
||||
public void setNewPasswordSalt(String newPasswordSalt) {
|
||||
this.newPasswordSalt = newPasswordSalt;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,152 @@
|
||||
package com.cisd.tms.modules.log.controller;
|
||||
|
||||
import com.cisd.tms.modules.auth.controller.AuthAdminController;
|
||||
import com.cisd.tms.modules.auth.controller.AuthController;
|
||||
import com.cisd.tms.modules.device.controller.DeviceController;
|
||||
import com.cisd.tms.modules.device.controller.IpWhitelistController;
|
||||
import com.cisd.tms.modules.device.controller.NetworkConfigController;
|
||||
import com.cisd.tms.modules.device.controller.TimeConfigController;
|
||||
import com.cisd.tms.modules.log.annotation.AuditedOperation;
|
||||
import com.cisd.tms.modules.log.enums.ActionType;
|
||||
import com.cisd.tms.modules.log.enums.ModuleCode;
|
||||
import com.cisd.tms.modules.mk.controller.LmkController;
|
||||
import com.cisd.tms.modules.openapi.service.controller.OpenApiController;
|
||||
import com.cisd.tms.modules.upgrade.controller.UpgradeController;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
class AuditedOperationEndpointsTest {
|
||||
|
||||
@Test
|
||||
void shouldAuditAuthStateChanges() throws Exception {
|
||||
assertAudit(AuthController.class, "passwordLogin", ModuleCode.AUTH, ActionType.LOGIN,
|
||||
com.cisd.tms.modules.auth.dto.PasswordLoginRequest.class);
|
||||
assertAudit(AuthController.class, "ukeyLogin", ModuleCode.AUTH, ActionType.LOGIN,
|
||||
com.cisd.tms.modules.auth.dto.UkeyLoginRequest.class);
|
||||
assertAudit(AuthController.class, "logout", ModuleCode.AUTH, ActionType.LOGOUT,
|
||||
jakarta.servlet.http.HttpServletRequest.class);
|
||||
assertAudit(AuthController.class, "changeAccountPassword", ModuleCode.AUTH, ActionType.UPDATE,
|
||||
Integer.class, com.cisd.tms.modules.auth.dto.ChangePasswordRequest.class, jakarta.servlet.http.HttpServletRequest.class);
|
||||
|
||||
assertAudit(AuthAdminController.class, "resetPassword", ModuleCode.AUTH, ActionType.RESET,
|
||||
String.class, jakarta.servlet.http.HttpServletRequest.class);
|
||||
assertAudit(AuthAdminController.class, "changeAccountPassword", ModuleCode.AUTH, ActionType.UPDATE,
|
||||
String.class, Integer.class, com.cisd.tms.modules.auth.dto.AdminChangePasswordRequest.class,
|
||||
jakarta.servlet.http.HttpServletRequest.class);
|
||||
assertAudit(AuthAdminController.class, "issueSuperAdminUkeyBindingSign", ModuleCode.AUTH, ActionType.BIND,
|
||||
com.cisd.tms.modules.mk.dto.UKeySignDTO.class);
|
||||
assertAudit(AuthAdminController.class, "issueUkeyBindingSign", ModuleCode.AUTH, ActionType.BIND,
|
||||
String.class, com.cisd.tms.modules.mk.dto.UKeySignDTO.class, jakarta.servlet.http.HttpServletRequest.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldAuditDeviceNetworkAndMasterKeyMutations() throws Exception {
|
||||
assertAudit(DeviceController.class, "restart", ModuleCode.DEVICE, ActionType.RESTART,
|
||||
jakarta.servlet.http.HttpServletRequest.class);
|
||||
assertAudit(TimeConfigController.class, "configureTime", ModuleCode.DEVICE, ActionType.UPDATE,
|
||||
com.cisd.tms.modules.device.dto.TimeConfigRequest.class);
|
||||
|
||||
assertAudit(NetworkConfigController.class, "configureNetworkCard", ModuleCode.NETWORK, ActionType.UPDATE,
|
||||
com.cisd.tms.modules.device.dto.network.NetworkConfigureRequest.class);
|
||||
assertAudit(NetworkConfigController.class, "addNetworkCard", ModuleCode.NETWORK, ActionType.CREATE,
|
||||
com.cisd.tms.modules.device.dto.network.NetworkConfigureRequest.class);
|
||||
assertAudit(NetworkConfigController.class, "deleteNetworkCardRecord", ModuleCode.NETWORK, ActionType.DELETE,
|
||||
com.cisd.tms.modules.device.dto.network.NetworkDeleteRequest.class);
|
||||
assertAudit(NetworkConfigController.class, "deleteBond", ModuleCode.NETWORK, ActionType.DELETE, String.class);
|
||||
assertAudit(NetworkConfigController.class, "createBond", ModuleCode.NETWORK, ActionType.CREATE,
|
||||
com.cisd.tms.modules.device.dto.network.BondCreateRequest.class);
|
||||
assertAudit(NetworkConfigController.class, "configBond", ModuleCode.NETWORK, ActionType.UPDATE,
|
||||
com.cisd.tms.modules.device.dto.network.BondConfigRequest.class);
|
||||
assertAudit(NetworkConfigController.class, "routeAdd", ModuleCode.NETWORK, ActionType.CREATE,
|
||||
com.cisd.tms.modules.device.dto.network.RouteCreateRequest.class);
|
||||
assertAudit(NetworkConfigController.class, "routeUpdate", ModuleCode.NETWORK, ActionType.UPDATE,
|
||||
com.cisd.tms.modules.device.dto.network.RouteUpdateRequest.class);
|
||||
assertAudit(NetworkConfigController.class, "routeDelete", ModuleCode.NETWORK, ActionType.DELETE,
|
||||
com.cisd.tms.modules.device.dto.network.RouteDeleteRequest.class);
|
||||
|
||||
assertAudit(IpWhitelistController.class, "addWhitelist", ModuleCode.DEVICE, ActionType.CREATE,
|
||||
com.cisd.tms.modules.device.dto.network.IpWhitelistRequest.class);
|
||||
assertAudit(IpWhitelistController.class, "updateWhitelist", ModuleCode.DEVICE, ActionType.UPDATE,
|
||||
com.cisd.tms.modules.device.dto.network.IpWhitelistRequest.class);
|
||||
assertAudit(IpWhitelistController.class, "deleteWhitelist", ModuleCode.DEVICE, ActionType.DELETE, Long.class);
|
||||
|
||||
assertAudit(LmkController.class, "initMasterKey", ModuleCode.KEY, ActionType.CREATE);
|
||||
assertAudit(LmkController.class, "destroyMasterKey", ModuleCode.KEY, ActionType.DELETE);
|
||||
assertAudit(LmkController.class, "recoverLmkEx", ModuleCode.KEY, ActionType.RECOVER,
|
||||
com.cisd.tms.modules.mk.dto.MasterKeyRecoverPacketsRequest.class);
|
||||
assertAudit(LmkController.class, "Activate", ModuleCode.DEVICE, ActionType.ENABLE,
|
||||
com.cisd.tms.modules.mk.dto.MasterKeyActivateRequest.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldAuditFileUpgradeBackupLogAndOpenApiMutations() throws Exception {
|
||||
assertAudit(com.cisd.tms.modules.file.controller.FileController.class, "upload", ModuleCode.SYSTEM, ActionType.IMPORT,
|
||||
org.springframework.web.multipart.MultipartFile.class);
|
||||
|
||||
assertAudit(UpgradeController.class, "uploadPackage", ModuleCode.UPGRADE, ActionType.IMPORT,
|
||||
org.springframework.web.multipart.MultipartFile.class);
|
||||
assertAudit(UpgradeController.class, "create", ModuleCode.UPGRADE, ActionType.CREATE,
|
||||
com.cisd.tms.modules.upgrade.dto.UpgradeCreateTaskRequest.class);
|
||||
assertAudit(UpgradeController.class, "execute", ModuleCode.UPGRADE, ActionType.EXECUTE, String.class);
|
||||
assertAudit(UpgradeController.class, "rollback", ModuleCode.UPGRADE, ActionType.ROLLBACK, String.class);
|
||||
|
||||
assertAudit(BackupController.class, "backup", ModuleCode.LOG, ActionType.BACKUP);
|
||||
assertAudit(BackupController.class, "downloadBackupFile", ModuleCode.LOG, ActionType.EXPORT, String.class);
|
||||
assertAudit(BackupConfigController.class, "saveOrUpdateConfig", ModuleCode.LOG, ActionType.UPDATE,
|
||||
com.cisd.tms.modules.log.dto.BackupConfigRequest.class);
|
||||
assertAudit(OperationAuditController.class, "reviewLog", ModuleCode.LOG, ActionType.UPDATE,
|
||||
String.class, com.cisd.tms.modules.log.dto.AuditLogReviewRequest.class);
|
||||
assertAudit(AuditLogRestoreController.class, "restoreFromZip", ModuleCode.LOG, ActionType.RECOVER,
|
||||
org.springframework.web.multipart.MultipartFile.class);
|
||||
|
||||
assertAudit(OpenApiController.class, "rawSign", ModuleCode.KEY, ActionType.EXECUTE,
|
||||
com.cisd.tms.modules.openapi.service.dto.RawSignRequest.class);
|
||||
assertAudit(OpenApiController.class, "dettachedSign", ModuleCode.KEY, ActionType.EXECUTE,
|
||||
com.cisd.tms.modules.openapi.service.dto.DettachedSignRequest.class);
|
||||
assertAudit(OpenApiController.class, "uploadCert", ModuleCode.KEY, ActionType.IMPORT,
|
||||
com.cisd.tms.modules.openapi.service.dto.UploadCertRequest.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotAuditReadOnlyPreviewAndVerifyEndpoints() throws Exception {
|
||||
assertNoAudit(UpgradeController.class, "preview", com.cisd.tms.modules.upgrade.dto.UpgradePreviewRequest.class);
|
||||
assertNoAudit(OperationAuditController.class, "queryPage",
|
||||
com.cisd.tms.modules.log.dto.OperationAuditLogPageRequest.class);
|
||||
assertNoAudit(OpenApiController.class, "rawVerify", com.cisd.tms.modules.openapi.service.dto.RawVerifyRequest.class);
|
||||
assertNoAudit(OpenApiController.class, "dettachedVerify",
|
||||
com.cisd.tms.modules.openapi.service.dto.DettachedVerifyRequest.class);
|
||||
assertNoAudit(OpenApiController.class, "dettachedVerifySimple",
|
||||
com.cisd.tms.modules.openapi.service.dto.DettachedVerifyRequest.class);
|
||||
}
|
||||
|
||||
private static void assertAudit(
|
||||
Class<?> controller,
|
||||
String methodName,
|
||||
ModuleCode moduleCode,
|
||||
ActionType actionType,
|
||||
Class<?>... parameterTypes
|
||||
) throws Exception {
|
||||
AuditedOperation annotation = auditedOperation(controller, methodName, parameterTypes);
|
||||
Assertions.assertNotNull(annotation, controller.getSimpleName() + "#" + methodName);
|
||||
Assertions.assertEquals(moduleCode, annotation.module(), controller.getSimpleName() + "#" + methodName);
|
||||
Assertions.assertEquals(actionType, annotation.action(), controller.getSimpleName() + "#" + methodName);
|
||||
}
|
||||
|
||||
private static void assertNoAudit(Class<?> controller, String methodName, Class<?>... parameterTypes) throws Exception {
|
||||
Assertions.assertNull(auditedOperation(controller, methodName, parameterTypes),
|
||||
controller.getSimpleName() + "#" + methodName);
|
||||
}
|
||||
|
||||
private static AuditedOperation auditedOperation(Class<?> controller, String methodName, Class<?>... parameterTypes)
|
||||
throws Exception {
|
||||
Method method = controller.getMethod(methodName, parameterTypes);
|
||||
AuditedOperation methodAnnotation = AnnotatedElementUtils.findMergedAnnotation(method, AuditedOperation.class);
|
||||
if (methodAnnotation != null) {
|
||||
return methodAnnotation;
|
||||
}
|
||||
return AnnotatedElementUtils.findMergedAnnotation(controller, AuditedOperation.class);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.cisd.tms.modules.log.repository;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
class OperationAuditSchemaContractTest {
|
||||
|
||||
@Test
|
||||
void shouldAllowAnonymousBootstrapAuditLogRole() throws Exception {
|
||||
String fullSql = readClasspathResource("db/migration/V2__tms_schema_full.sql");
|
||||
|
||||
Assertions.assertTrue(fullSql.contains("operator_role_code VARCHAR(64) NULL"));
|
||||
Assertions.assertFalse(fullSql.contains("operator_role_code VARCHAR(64) NOT NULL"));
|
||||
}
|
||||
|
||||
private static String readClasspathResource(String path) throws Exception {
|
||||
ClassPathResource resource = new ClassPathResource(path);
|
||||
Assertions.assertTrue(resource.exists(), "Missing classpath resource: " + path);
|
||||
return new String(resource.getInputStream().readAllBytes(), StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
package com.cisd.tms.schema;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
class FullSchemaVersionContractTest {
|
||||
|
||||
@Test
|
||||
void shouldRetainV1MigrationAndExposeCurrentV2FullSchema() throws Exception {
|
||||
String v1Sql = readClasspathResource("db/migration/V1__tms_schema_full.sql");
|
||||
String v2Sql = readClasspathResource("db/migration/V2__tms_schema_full.sql");
|
||||
|
||||
Assertions.assertTrue(v1Sql.contains("ALTER TABLE tms_auth_full_account"));
|
||||
Assertions.assertTrue(v1Sql.contains("AFTER password_hash"));
|
||||
Assertions.assertFalse(v1Sql.contains("CREATE TABLE IF NOT EXISTS tms_auth_full_account"));
|
||||
Assertions.assertTrue(v2Sql.contains("CREATE TABLE IF NOT EXISTS tms_operation_audit_log"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void currentV2FullSchemaShouldNotDependOnPatchStatements() throws Exception {
|
||||
String v2Sql = readClasspathResource("db/migration/V2__tms_schema_full.sql");
|
||||
|
||||
Assertions.assertFalse(v2Sql.contains("ALTER TABLE"));
|
||||
Assertions.assertFalse(v2Sql.lines().anyMatch(line -> line.stripLeading().startsWith("UPDATE ")));
|
||||
}
|
||||
|
||||
private static String readClasspathResource(String path) throws Exception {
|
||||
ClassPathResource resource = new ClassPathResource(path);
|
||||
Assertions.assertTrue(resource.exists(), "Missing classpath resource: " + path);
|
||||
return new String(resource.getInputStream().readAllBytes(), StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
package com.cisd.tms.security.internal;
|
||||
|
||||
import com.cisd.tms.modules.auth.enums.AuthLevel;
|
||||
import com.cisd.tms.modules.auth.enums.RoleCode;
|
||||
import com.cisd.tms.modules.auth.security.RequireInternalAuth;
|
||||
import com.cisd.tms.modules.device.controller.NetworkConfigController;
|
||||
import com.cisd.tms.modules.device.controller.TimeConfigController;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
|
||||
class InternalBootstrapAuthContractTest {
|
||||
|
||||
@Test
|
||||
void shouldRequireOpsFullAfterBootstrapForNetworkAndTimeConfig() throws Exception {
|
||||
RequireInternalAuth networkAuth =
|
||||
AnnotatedElementUtils.findMergedAnnotation(NetworkConfigController.class, RequireInternalAuth.class);
|
||||
RequireInternalAuth timeAuth = AnnotatedElementUtils.findMergedAnnotation(
|
||||
TimeConfigController.class.getMethod("configureTime",
|
||||
com.cisd.tms.modules.device.dto.TimeConfigRequest.class),
|
||||
RequireInternalAuth.class
|
||||
);
|
||||
|
||||
assertBootstrapOpsFull(networkAuth);
|
||||
assertBootstrapOpsFull(timeAuth);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotStaticallyExcludeBootstrapConfigEndpointsFromInternalAuth() throws Exception {
|
||||
String source = Files.readString(
|
||||
Path.of("src/main/java/com/cisd/tms/common/config/WebMvcConfig.java"),
|
||||
StandardCharsets.UTF_8
|
||||
);
|
||||
|
||||
Assertions.assertFalse(source.contains("\"/api/v1/device/time-config\""));
|
||||
Assertions.assertFalse(source.contains("\"/api/v1/device/network/**\""));
|
||||
}
|
||||
|
||||
private static void assertBootstrapOpsFull(RequireInternalAuth auth) {
|
||||
Assertions.assertNotNull(auth);
|
||||
Assertions.assertEquals(RoleCode.OPS_ADMIN, auth.role());
|
||||
Assertions.assertEquals(AuthLevel.FULL, auth.authLevel());
|
||||
Assertions.assertTrue(auth.allowBeforeMasterKeyInitialized());
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user