Преглед на файлове

chore: 升级至 1.5.1

* chore: 升级至 1.5.1; pref: 消灭大部分 `@Resource` 字段注入,改为构造器注入

* docs: 订正注释; pref: 优化乘法计算

* feat: `SysLogAspect` 切面记录系统操作日志时,支持先去除敏感字段后再入库

* pref: 优化 copyOptions 为类成员属性

* pref: 更新 SysLog 敏感字段

* chore: 升级至 1.5.1
Uncarbon преди 4 години
родител
ревизия
d28dcd8ffc

+ 2 - 2
pom.xml

@@ -7,11 +7,11 @@
     <parent>
         <groupId>cc.uncarbon.framework</groupId>
         <artifactId>helio-starters</artifactId>
-        <version>1.5.0</version>
+        <version>1.5.1</version>
     </parent>
 
     <artifactId>helio-boot</artifactId>
-    <version>1.5.0</version>
+    <version>1.5.1</version>
 
     <properties>
     </properties>

+ 6 - 6
src/main/java/cc/uncarbon/config/AsyncConfiguration.java

@@ -1,5 +1,8 @@
 package cc.uncarbon.config;
 
+import java.util.concurrent.Executor;
+import java.util.concurrent.ThreadPoolExecutor;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
 import org.springframework.boot.autoconfigure.task.TaskExecutionProperties;
@@ -9,10 +12,6 @@ import org.springframework.scheduling.annotation.AsyncConfigurer;
 import org.springframework.scheduling.annotation.EnableAsync;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 
-import javax.annotation.Resource;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ThreadPoolExecutor;
-
 
 /**
  * @author Uncarbon
@@ -20,10 +19,11 @@ import java.util.concurrent.ThreadPoolExecutor;
 @Slf4j
 @EnableAsync
 @Configuration
+@RequiredArgsConstructor
 public class AsyncConfiguration implements AsyncConfigurer {
 
-    @Resource
-    private TaskExecutionProperties taskExecutionProperties;
+    private final TaskExecutionProperties taskExecutionProperties;
+
 
     @Bean(name = "taskExecutor")
     public ThreadPoolTaskExecutor taskExecutor() {

+ 32 - 10
src/main/java/cc/uncarbon/module/sys/aspect/SysLogAspect.java

@@ -2,12 +2,13 @@ package cc.uncarbon.module.sys.aspect;
 
 import cc.uncarbon.framework.core.context.UserContextHolder;
 import cc.uncarbon.module.sys.annotation.SysLog;
+import cc.uncarbon.module.sys.constant.SysConstant;
 import cc.uncarbon.module.sys.entity.SysLogEntity;
 import cc.uncarbon.module.sys.enums.SysLogStatusEnum;
 import cc.uncarbon.module.sys.service.SysLogService;
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.bean.copier.CopyOptions;
 import cn.hutool.json.JSONUtil;
-import java.util.Arrays;
-import java.util.stream.Collectors;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.aspectj.lang.ProceedingJoinPoint;
@@ -18,8 +19,13 @@ import org.aspectj.lang.reflect.MethodSignature;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Component;
 
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.stream.Collectors;
+
 /**
- * SysLog切面实现类
+ * SysLog 切面实现类
+ *
  * @author Uncarbon
  */
 @Aspect
@@ -29,7 +35,13 @@ import org.springframework.stereotype.Component;
 public class SysLogAspect {
 
     private final SysLogService sysLogService;
+    // Bean 属性复制配置项
+    private static final CopyOptions copyOptions4MaskingArgs = new CopyOptions();
 
+    static {
+        copyOptions4MaskingArgs.setIgnoreNullValue(false);
+        copyOptions4MaskingArgs.setIgnoreProperties(SysConstant.SENSITIVE_FIELDS);
+    }
 
     @Pointcut("@annotation(cc.uncarbon.module.sys.annotation.SysLog)")
     public void sysLogPointcut() {
@@ -48,21 +60,31 @@ public class SysLogAspect {
                 .setUsername(UserContextHolder.getUserName())
                 ;
 
-        // 请求方法
+        // 记录请求方法
         MethodSignature methodSignature = (MethodSignature) point.getSignature();
         sysLogEntity.setMethod(methodSignature.toString());
 
-        // 操作内容
+        // 记录操作内容
         SysLog sysLogAnnotation = methodSignature.getMethod().getAnnotation(SysLog.class);
         sysLogEntity.setOperation(sysLogAnnotation.value());
 
-        // 请求参数
-        sysLogEntity.setParams(Arrays.stream(point.getArgs()).map(JSONUtil::toJsonStr).collect(Collectors.joining(",")));
-
-        // IP地址
+        /*
+        记录请求参数
+         */
+        HashMap<Object, Object> afterMasked = new HashMap<>();
+        sysLogEntity.setParams(Arrays.stream(point.getArgs()).map(
+                each -> {
+                    // 先去除敏感字段后再入库
+                    afterMasked.clear();
+                    BeanUtil.copyProperties(each, afterMasked, copyOptions4MaskingArgs);
+                    return JSONUtil.toJsonStr(afterMasked);
+                }
+        ).collect(Collectors.joining(",")));
+
+        // 记录IP地址
         sysLogEntity.setIp(UserContextHolder.getClientIP());
 
-        // 状态
+        // 记录状态
         sysLogEntity.setStatus(SysLogStatusEnum.SUCCESS);
 
         this.callSysLogServiceSave(sysLogEntity);

+ 2 - 37
src/main/java/cc/uncarbon/module/sys/constant/SysConstant.java

@@ -24,43 +24,8 @@ public interface SysConstant {
     Long SUPER_ADMIN_ROLE_ID = 1L;
 
     /**
-     * 缓存键名-侧边菜单-前缀
+     * 敏感字段,`SysLogAspect` 切面记录系统操作日志时,会先去除敏感字段后再入库
      */
-    String REDIS_KEY_SIDE_MENU = "sys-service:sideMenu:";
-
-    /**
-     * 缓存键名-侧边菜单-区分用户ID
-     */
-    String REDIS_KEY_SIDE_MENU_BY_USERID = REDIS_KEY_SIDE_MENU + "userId_%s";
-
-    /**
-     * 缓存键名-所有可见菜单-前缀
-     */
-    String REDIS_KEY_VISIBLE_MENU = "sys-service:visibleMenu:";
-
-    /**
-     * 缓存键名-所有可见菜单-区分用户ID
-     */
-    String REDIS_KEY_VISIBLE_MENU_BY_USERID = REDIS_KEY_VISIBLE_MENU + "userId_%s";
-
-    /**
-     * 参数键名-缓存菜单时长
-     */
-    String PARAM_KEY_CACHE_MENU_DURATION = "sys:cache-menu-duration";
-
-    /**
-     * 缓存键名前缀-用户业务缓存
-     */
-    String CACHE_KEY_USER_BIZ_CACHE = "sys-service:userBizCache:%s";
-
-    /**
-     * 缓存键名-用户拥有角色ID
-     */
-    String REDIS_KEY_USER_OWNED_ROLE_IDS = CACHE_KEY_USER_BIZ_CACHE + ":ownedRoleIds";
-
-    /**
-     * 一整天有多少秒
-     */
-    long ONE_DAY_SECONDS = 86400;
+    String[] SENSITIVE_FIELDS = {"password", "oldPassword", "newPassword", "confirmNewPassword", "passwordOfNewUser", "randomPassword", "tenantAdminPassword"};
 
 }

+ 2 - 1
src/main/java/cc/uncarbon/module/sys/service/SysRoleMenuRelationService.java

@@ -42,7 +42,8 @@ public class SysRoleMenuRelationService extends HelioBaseServiceImpl<SysRoleMenu
             throw new IllegalArgumentException("roleIds不能为空");
         }
 
-        Set<Long> ret = new HashSet<>(roleIds.size() * 16);
+        // aka * 16
+        Set<Long> ret = new HashSet<>(roleIds.size() << 4);
         roleIds.forEach(
                 roleId -> ret.addAll(this.list(
                             new QueryWrapper<SysRoleMenuRelationEntity>()

+ 2 - 7
src/main/java/cc/uncarbon/module/sys/service/SysUserService.java

@@ -172,15 +172,10 @@ public class SysUserService extends HelioBaseServiceImpl<SysUserMapper, SysUserE
     @SysLog(value = "登录后台用户")
     public SysUserLoginBO adminLogin(SysUserLoginDTO dto) {
         /*
-        这里是实际启用了多租户功能,并主动指定租户ID
-        实际生产应用时,推荐前端传值加密,后端在此解密
+        如果启用了多租户功能,并且前端指定了租户ID,则先查库确认租户是否有效
 
-        表级、数据源级多租户,登录前【必须】主动指定租户ID
-        e.g. dto.setTenantId(101L)
+        注意:数据源级多租户,登录前【必须】主动指定租户ID,如: dto.setTenantId(101L);
          */
-
-        dto.setTenantId(101L);
-
         // ConcurrentHashMap 的 value 不能为 null,还是 new 一个吧
         TenantContext tenantContext = new TenantContext();
         if (isTenantEnabled && ObjectUtil.isNotNull(dto.getTenantId())) {