Merge remote-tracking branch 'base-version/main' into dev

# Conflicts:
#	zt-module-system/zt-module-system-server/src/main/java/com/zt/plat/module/system/controller/admin/tenant/vo/tenant/TenantSaveReqVO.java
This commit is contained in:
chenbowen
2025-10-24 17:05:16 +08:00
56 changed files with 1263 additions and 239 deletions

View File

@@ -9,11 +9,7 @@ import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.*;
/**
* 通用的签名、加解密工具类
@@ -26,7 +22,7 @@ public final class CryptoSignatureUtils {
public static final String SIGNATURE_TYPE_SHA256 = "SHA256";
private static final String AES_TRANSFORMATION = "AES/ECB/PKCS5Padding";
private static final String SIGNATURE_FIELD = "signature";
public static final String SIGNATURE_FIELD = "signature";
private CryptoSignatureUtils() {
}

View File

@@ -0,0 +1,31 @@
package com.zt.plat.framework.common.validation;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.*;
/**
* 密码复杂度校验注解,要求至少包含大小写字母、数字、特殊字符中的三种。
* @author chenbowen
*/
@Target({
ElementType.METHOD,
ElementType.FIELD,
ElementType.ANNOTATION_TYPE,
ElementType.CONSTRUCTOR,
ElementType.PARAMETER,
ElementType.TYPE_USE
})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = PasswordValidator.class)
public @interface Password {
String message() default "密码必须包含大写字母、小写字母、数字、特殊字符中的至少三种";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}

View File

@@ -0,0 +1,38 @@
package com.zt.plat.framework.common.validation;
import cn.hutool.core.util.StrUtil;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
/**
* 密码复杂度校验:至少命中以下类别中的三类:大写字母、小写字母、数字、特殊字符。
*/
public class PasswordValidator implements ConstraintValidator<Password, String> {
@Override
public void initialize(Password constraintAnnotation) {
// no-op
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (StrUtil.isBlank(value)) {
// 空值交由 @NotEmpty 等注解处理;在无需修改密码时视为空密码通过
return true;
}
int categories = 0;
if (value.matches(".*[A-Z].*")) {
categories++;
}
if (value.matches(".*[a-z].*")) {
categories++;
}
if (value.matches(".*[0-9].*")) {
categories++;
}
if (value.matches(".*[^A-Za-z0-9].*")) {
categories++;
}
return categories >= 3;
}
}

View File

@@ -0,0 +1,31 @@
package com.zt.plat.framework.common.validation;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
class PasswordValidatorTest {
private final PasswordValidator validator = new PasswordValidator();
@Test
void shouldAcceptBlankPassword() {
assertTrue(validator.isValid(null, null));
assertTrue(validator.isValid("", null));
assertTrue(validator.isValid(" ", null));
}
@Test
void shouldRejectInsufficientComplexity() {
assertFalse(validator.isValid("abcdef", null));
assertFalse(validator.isValid("ABCDEF", null));
assertFalse(validator.isValid("ABC123", null));
}
@Test
void shouldAcceptComplexPassword() {
assertTrue(validator.isValid("Abc123!", null));
assertTrue(validator.isValid("1a#BCdef", null));
}
}