diff --git a/common/pom.xml b/common/pom.xml
index 5679795..06bb8e7 100644
--- a/common/pom.xml
+++ b/common/pom.xml
@@ -19,6 +19,24 @@
spring-boot-starter-web
provided
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+ provided
+
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+ provided
+
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+ provided
+
io.springfox
diff --git a/common/src/main/java/com/usthe/common/support/SpringContextHolder.java b/common/src/main/java/com/usthe/common/support/SpringContextHolder.java
new file mode 100644
index 0000000..484215d
--- /dev/null
+++ b/common/src/main/java/com/usthe/common/support/SpringContextHolder.java
@@ -0,0 +1,48 @@
+package com.usthe.common.support;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+/**
+ * Spring的ApplicationContext的持有者,可以用静态方法的方式获取spring容器中的bean
+ * @author tomsun28
+ * @date 21:07 2018/4/18
+ */
+@Component
+public class SpringContextHolder implements ApplicationContextAware {
+
+ private static ApplicationContext applicationContext;
+
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ set(applicationContext);
+ }
+
+ private static void set(ApplicationContext applicationContext) {
+ SpringContextHolder.applicationContext = applicationContext;
+ }
+
+ public static ApplicationContext getApplicationContext() {
+ assertApplicationContext();
+ return applicationContext;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static T getBean(String beanName) {
+ assertApplicationContext();
+ return (T) applicationContext.getBean(beanName);
+ }
+
+ public static T getBean(Class tClass) {
+ assertApplicationContext();
+ return (T) applicationContext.getBean(tClass);
+ }
+
+ private static void assertApplicationContext() {
+ if (null == SpringContextHolder.applicationContext) {
+ throw new RuntimeException("applicationContext为空,请检查是否注入springContextHolder");
+ }
+ }
+}
diff --git a/common/src/main/java/com/usthe/common/support/valid/EmailParamValidator.java b/common/src/main/java/com/usthe/common/support/valid/EmailParamValidator.java
new file mode 100644
index 0000000..748130f
--- /dev/null
+++ b/common/src/main/java/com/usthe/common/support/valid/EmailParamValidator.java
@@ -0,0 +1,20 @@
+package com.usthe.common.support.valid;
+
+import com.usthe.common.util.CommonUtil;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+/**
+ * email注解数据自定义校验器
+ * @author tomsun28
+ * @date 2021/11/17 19:44
+ */
+public class EmailParamValidator implements ConstraintValidator {
+
+ @Override
+ public boolean isValid(String value, ConstraintValidatorContext context) {
+ // 判断value是否满足ipv4 ipv5 域名 格式
+ return CommonUtil.validateEmail(value);
+ }
+}
diff --git a/common/src/main/java/com/usthe/common/support/valid/EmailValid.java b/common/src/main/java/com/usthe/common/support/valid/EmailValid.java
new file mode 100644
index 0000000..ee36489
--- /dev/null
+++ b/common/src/main/java/com/usthe/common/support/valid/EmailValid.java
@@ -0,0 +1,29 @@
+package com.usthe.common.support.valid;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * email注解数据自定义校验器注解
+ * @author tomsun28
+ * @date 2021/11/17 19:42
+ */
+@Target({ FIELD, PARAMETER })
+@Retention(RUNTIME)
+@Documented
+@Constraint(validatedBy = EmailParamValidator.class)
+public @interface EmailValid {
+
+ String message() default "Email value is invalid";
+
+ Class>[] groups() default {};
+
+ Class extends Payload>[] payload() default {};
+}
diff --git a/common/src/main/java/com/usthe/common/support/valid/HostParamValidator.java b/common/src/main/java/com/usthe/common/support/valid/HostParamValidator.java
new file mode 100644
index 0000000..70119c2
--- /dev/null
+++ b/common/src/main/java/com/usthe/common/support/valid/HostParamValidator.java
@@ -0,0 +1,20 @@
+package com.usthe.common.support.valid;
+
+import com.usthe.common.util.IpDomainUtil;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+/**
+ * host注解数据自定义校验器
+ * @author tomsun28
+ * @date 2021/11/17 19:44
+ */
+public class HostParamValidator implements ConstraintValidator {
+
+ @Override
+ public boolean isValid(String value, ConstraintValidatorContext context) {
+ // 判断value是否满足ipv4 ipv5 域名 格式
+ return IpDomainUtil.validateIpDomain(value);
+ }
+}
diff --git a/common/src/main/java/com/usthe/common/support/valid/HostValid.java b/common/src/main/java/com/usthe/common/support/valid/HostValid.java
new file mode 100644
index 0000000..68a8b95
--- /dev/null
+++ b/common/src/main/java/com/usthe/common/support/valid/HostValid.java
@@ -0,0 +1,29 @@
+package com.usthe.common.support.valid;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * host注解数据自定义校验器注解
+ * @author tomsun28
+ * @date 2021/11/17 19:42
+ */
+@Target({ FIELD, PARAMETER })
+@Retention(RUNTIME)
+@Documented
+@Constraint(validatedBy = HostParamValidator.class)
+public @interface HostValid {
+
+ String message() default "Host value is invalid,must ipv4, ipv6 or domain";
+
+ Class>[] groups() default {};
+
+ Class extends Payload>[] payload() default {};
+}
diff --git a/common/src/main/java/com/usthe/common/support/valid/PhoneNumParamValidator.java b/common/src/main/java/com/usthe/common/support/valid/PhoneNumParamValidator.java
new file mode 100644
index 0000000..28f1adb
--- /dev/null
+++ b/common/src/main/java/com/usthe/common/support/valid/PhoneNumParamValidator.java
@@ -0,0 +1,20 @@
+package com.usthe.common.support.valid;
+
+import com.usthe.common.util.CommonUtil;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+
+/**
+ * PhoneNum注解数据自定义校验器
+ * @author tomsun28
+ * @date 2021/11/17 19:44
+ */
+public class PhoneNumParamValidator implements ConstraintValidator {
+
+ @Override
+ public boolean isValid(String value, ConstraintValidatorContext context) {
+ // 判断value是否满足ipv4 ipv5 域名 格式
+ return CommonUtil.validatePhoneNum(value);
+ }
+}
diff --git a/common/src/main/java/com/usthe/common/support/valid/PhoneNumValid.java b/common/src/main/java/com/usthe/common/support/valid/PhoneNumValid.java
new file mode 100644
index 0000000..f8f374b
--- /dev/null
+++ b/common/src/main/java/com/usthe/common/support/valid/PhoneNumValid.java
@@ -0,0 +1,29 @@
+package com.usthe.common.support.valid;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * phoneNum注解数据自定义校验器注解
+ * @author tomsun28
+ * @date 2021/11/17 19:42
+ */
+@Target({ FIELD, PARAMETER })
+@Retention(RUNTIME)
+@Documented
+@Constraint(validatedBy = PhoneNumParamValidator.class)
+public @interface PhoneNumValid {
+
+ String message() default "Phone num value is invalid";
+
+ Class>[] groups() default {};
+
+ Class extends Payload>[] payload() default {};
+}
diff --git a/common/src/main/java/com/usthe/common/util/AesUtil.java b/common/src/main/java/com/usthe/common/util/AesUtil.java
index 5df5507..d6220bd 100644
--- a/common/src/main/java/com/usthe/common/util/AesUtil.java
+++ b/common/src/main/java/com/usthe/common/util/AesUtil.java
@@ -1,7 +1,6 @@
package com.usthe.common.util;
import lombok.extern.slf4j.Slf4j;
-import org.apache.tomcat.util.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
@@ -9,6 +8,7 @@ import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
+import java.util.Base64;
/**
* AES 对称加密解密工具
@@ -58,7 +58,7 @@ public class AesUtil {
//根据密码器的初始化方式--加密:将数据加密
byte[] byteAes = cipher.doFinal(byteEncode);
//将加密后的byte[]数据转换为Base64字符串
- return new String(Base64.encodeBase64(byteAes),StandardCharsets.UTF_8);
+ return new String(Base64.getEncoder().encode(byteAes),StandardCharsets.UTF_8);
//将字符串返回
} catch (Exception e) {
log.error("密文加密失败"+e.getMessage(),e);
@@ -85,27 +85,22 @@ public class AesUtil {
//初始化密码器,第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作,第二个参数为使用的KEY
cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(decryptKey.getBytes(StandardCharsets.UTF_8)));
//8.将加密并编码base64后的字符串内容base64解码成字节数组
- byte[] bytesContent = Base64.decodeBase64(content);
+ byte[] bytesContent = Base64.getDecoder().decode(content);
/*
* 解密
*/
byte[] byteDecode = cipher.doFinal(bytesContent);
return new String(byteDecode, StandardCharsets.UTF_8);
} catch (NoSuchAlgorithmException e) {
- log.error("没有指定的加密算法::"+e.getMessage(),e);
+ log.error("没有指定的加密算法::{}", e.getMessage(),e);
} catch (IllegalBlockSizeException e) {
- log.error("非法的块大小"+"::"+e.getMessage(),e);
- throw new RuntimeException("密文解密失败");
+ log.error("非法的块大小::{}", e.getMessage(),e);
} catch (NullPointerException e) {
- log.error("秘钥解析空指针异常"+"::"+e.getMessage(),e);
- throw new RuntimeException("秘钥解析空指针异常");
+ log.error("秘钥解析空指针异常::{}", e.getMessage(),e);
} catch (Exception e) {
- log.error("秘钥AES解析出现未知错误"+"::"+e.getMessage(),e);
- throw new RuntimeException("密文解密失败");
+ log.error("秘钥AES解析出现未知错误::{}", e.getMessage(),e);
}
- //如果有错就返null
- return null;
-
+ return content;
}
/**
@@ -115,6 +110,6 @@ public class AesUtil {
*/
public static boolean isCiphertext(String text) {
// 根据是否被base64来判断是否已经被加密
- return Base64.isBase64(text);
+ return Base64Util.isBase64(text);
}
}
diff --git a/common/src/main/java/com/usthe/common/util/Base64Util.java b/common/src/main/java/com/usthe/common/util/Base64Util.java
new file mode 100644
index 0000000..bf19514
--- /dev/null
+++ b/common/src/main/java/com/usthe/common/util/Base64Util.java
@@ -0,0 +1,19 @@
+package com.usthe.common.util;
+
+import java.util.Base64;
+
+/**
+ * base64工具类
+ * @author tom
+ * @date 2022/1/12 12:12
+ */
+public class Base64Util {
+
+ public static boolean isBase64(String base64) {
+ try {
+ return Base64.getDecoder().decode(base64) != null;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+}
diff --git a/common/src/main/java/com/usthe/common/util/CommonConstants.java b/common/src/main/java/com/usthe/common/util/CommonConstants.java
index 58a340e..6e6fc35 100644
--- a/common/src/main/java/com/usthe/common/util/CommonConstants.java
+++ b/common/src/main/java/com/usthe/common/util/CommonConstants.java
@@ -8,10 +8,15 @@ package com.usthe.common.util;
public interface CommonConstants {
/**
- * 响应状态码: 成功
+ * 响应状态码: 通用成功
*/
byte SUCCESS_CODE = 0x00;
+ /**
+ * 响应状态码: 通用失败
+ */
+ byte FAIL_CODE = 0x0F;
+
/**
* 响应状态码: 参数校验失败
*/
@@ -37,6 +42,13 @@ public interface CommonConstants {
*/
byte MONITOR_LOGIN_FAILED_CODE = 0x05;
+ /**
+ * 响应状态码: 注册失败异常
+ */
+ byte MONITOR_REGISTER_FAILED_CODE = 0x06;
+
+
+
/**
* 监控状态码: 未管理
*/
@@ -126,4 +138,39 @@ public interface CommonConstants {
* 可达性对象
*/
String REACHABLE = "reachable";
+
+ /**
+ * 参数类型 数字
+ */
+ byte PARAM_TYPE_NUMBER = 0;
+
+ /**
+ * 参数类型 字符串
+ */
+ byte PARAM_TYPE_STRING = 1;
+
+ /**
+ * 参数类型 密码
+ */
+ byte PARAM_TYPE_PASSWORD = 2;
+
+ /**
+ * 认证类型 账户密码
+ */
+ byte AUTH_TYPE_PASSWORD = 1;
+
+ /**
+ * 认证类型 GITHUB三方登陆
+ */
+ byte AUTH_TYPE_GITHUB = 2;
+
+ /**
+ * 认证类型 微信三方登陆
+ */
+ byte AUTH_TYPE_WEIXIN = 3;
+
+ /**
+ * 认证类型 GITEE三方登陆
+ */
+ byte AUTH_TYPE_GITEE = 5;
}
diff --git a/common/src/main/java/com/usthe/common/util/CommonUtil.java b/common/src/main/java/com/usthe/common/util/CommonUtil.java
index ad3bbcb..7b25c28 100644
--- a/common/src/main/java/com/usthe/common/util/CommonUtil.java
+++ b/common/src/main/java/com/usthe/common/util/CommonUtil.java
@@ -2,6 +2,9 @@ package com.usthe.common.util;
import lombok.extern.slf4j.Slf4j;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
/**
* 公共工具类
* @author tomsun28
@@ -10,6 +13,12 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
public class CommonUtil {
+ private static final Pattern EMAIL_PATTERN = Pattern.compile("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*");
+
+ private static final Pattern PHONE_PATTERN = Pattern.compile("^(((13[0-9])|(15[0-9])|(18[0-9])|(17[0-9]))+\\d{8})?$");
+
+ private static final int PHONE_LENGTH = 11;
+
/**
* 将字符串str转换为double数字类型
* @param str string
@@ -27,4 +36,30 @@ public class CommonUtil {
}
}
+ /**
+ * 邮箱格式校验
+ * @param email 邮箱
+ * @return 是否校验成功
+ */
+ public static boolean validateEmail(String email) {
+ if (email == null || "".equals(email)) {
+ return false;
+ }
+ Matcher m = EMAIL_PATTERN.matcher(email);
+ return m.find();
+ }
+
+ /**
+ * 手机号格式校验
+ * @param phoneNum 手机号
+ * @return 是否校验成功
+ */
+ public static boolean validatePhoneNum(String phoneNum) {
+ if (phoneNum == null || "".equals(phoneNum) || phoneNum.length() != PHONE_LENGTH) {
+ return false;
+ }
+ Matcher m = PHONE_PATTERN.matcher(phoneNum);
+ return m.find();
+ }
+
}
diff --git a/common/src/main/java/com/usthe/common/util/LruHashMap.java b/common/src/main/java/com/usthe/common/util/LruHashMap.java
new file mode 100644
index 0000000..360d59f
--- /dev/null
+++ b/common/src/main/java/com/usthe/common/util/LruHashMap.java
@@ -0,0 +1,25 @@
+package com.usthe.common.util;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * 最近最少使用淘汰算法map
+ * @author tom
+ * @date 2021/12/27 14:13
+ */
+public class LruHashMap extends LinkedHashMap {
+
+ private int threshold;
+
+ public LruHashMap(int threshold) {
+ super(16, 0.75f, true);
+ this.threshold = threshold;
+ }
+
+ @Override
+ protected boolean removeEldestEntry(Map.Entry eldest) {
+ return size() > threshold;
+ }
+
+}
diff --git a/manager/src/main/resources/sureness.yml b/manager/src/main/resources/sureness.yml
index 81fb504..18b395d 100644
--- a/manager/src/main/resources/sureness.yml
+++ b/manager/src/main/resources/sureness.yml
@@ -10,7 +10,7 @@ resourceRole:
# load api resource which do not need protected, means them need be excluded.
# these api resource can be access by everyone
excludedResource:
- - /account/auth/form===post
+ - /account/auth/**===*
- /i18n/**===get
# web ui 静态资源
- /console/**===get