diff --git a/src/main/java/cn/lihongjie/coal/annotation/RateLimit.java b/src/main/java/cn/lihongjie/coal/annotation/RateLimit.java new file mode 100644 index 00000000..9ddaa1b6 --- /dev/null +++ b/src/main/java/cn/lihongjie/coal/annotation/RateLimit.java @@ -0,0 +1,13 @@ +package cn.lihongjie.coal.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD}) +public @interface RateLimit { + + boolean value() default true; +} diff --git a/src/main/java/cn/lihongjie/coal/annotation/SignCheck.java b/src/main/java/cn/lihongjie/coal/annotation/SignCheck.java new file mode 100644 index 00000000..7fd7fc85 --- /dev/null +++ b/src/main/java/cn/lihongjie/coal/annotation/SignCheck.java @@ -0,0 +1,13 @@ +package cn.lihongjie.coal.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD}) +public @interface SignCheck { + + boolean value() default true; +} diff --git a/src/main/java/cn/lihongjie/coal/filter/RateLimitFilter.java b/src/main/java/cn/lihongjie/coal/filter/RateLimitFilter.java index 40532f82..56178a3b 100644 --- a/src/main/java/cn/lihongjie/coal/filter/RateLimitFilter.java +++ b/src/main/java/cn/lihongjie/coal/filter/RateLimitFilter.java @@ -8,6 +8,7 @@ import cn.lihongjie.coal.exception.BizException; import cn.lihongjie.coal.ip.IpQueryService; import cn.lihongjie.coal.loginUser.service.LoginUserService; import cn.lihongjie.coal.ratelimit.RateLimiterService; +import cn.lihongjie.coal.resource.dto.ResourceDto; import cn.lihongjie.coal.sysconfig.service.SysConfigService; import cn.lihongjie.coal.syslog.service.SysLogService; @@ -21,6 +22,7 @@ import jakarta.servlet.http.HttpServletResponse; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.apache.http.entity.ContentType; import org.redisson.api.RedissonClient; @@ -61,6 +63,19 @@ public class RateLimitFilter extends OncePerRequestFilter { return; } + + if (request.getAttribute(Constants.HTTP_ATTR_RESOURCE) != null) { + if (BooleanUtils.isFalse( + ((ResourceDto) request.getAttribute(Constants.HTTP_ATTR_RESOURCE)) + .getRateLimit())) { + doFilter(request, response, filterChain); + return; + + + } + } + + if (StringUtils.isNotEmpty(sessionId)) { diff --git a/src/main/java/cn/lihongjie/coal/filter/SignFilter.java b/src/main/java/cn/lihongjie/coal/filter/SignFilter.java index bc3fc62b..bebc83b9 100644 --- a/src/main/java/cn/lihongjie/coal/filter/SignFilter.java +++ b/src/main/java/cn/lihongjie/coal/filter/SignFilter.java @@ -5,6 +5,7 @@ import cn.lihongjie.coal.common.RequestUtils; import cn.lihongjie.coal.exception.BizException; import cn.lihongjie.coal.ip.IpQueryService; import cn.lihongjie.coal.loginUser.service.LoginUserService; +import cn.lihongjie.coal.resource.dto.ResourceDto; import cn.lihongjie.coal.sysconfig.service.SysConfigService; import cn.lihongjie.coal.syslog.service.SysLogService; @@ -21,6 +22,7 @@ import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.digest.HmacAlgorithms; import org.apache.commons.codec.digest.HmacUtils; +import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -68,6 +70,19 @@ public class SignFilter extends OncePerRequestFilter { return; } + + if (request.getAttribute(Constants.HTTP_ATTR_RESOURCE) != null) { + if (BooleanUtils.isFalse( + ((ResourceDto) request.getAttribute(Constants.HTTP_ATTR_RESOURCE)) + .getSignCheck())) { + doFilter(request, response, filterChain); + return; + + + } + } + + String configVal = sysConfigService.getConfigVal(Constants.SYSCONFIG_REQUEST_SIGN_IGNORE_URLS); diff --git a/src/main/java/cn/lihongjie/coal/netDisk/controller/NetDiskController.java b/src/main/java/cn/lihongjie/coal/netDisk/controller/NetDiskController.java index 14e7ec6c..c68cef66 100644 --- a/src/main/java/cn/lihongjie/coal/netDisk/controller/NetDiskController.java +++ b/src/main/java/cn/lihongjie/coal/netDisk/controller/NetDiskController.java @@ -1,6 +1,8 @@ package cn.lihongjie.coal.netDisk.controller; import cn.lihongjie.coal.annotation.OrgScope; +import cn.lihongjie.coal.annotation.RateLimit; +import cn.lihongjie.coal.annotation.SignCheck; import cn.lihongjie.coal.annotation.SysLog; import cn.lihongjie.coal.base.dto.CommonQuery; import cn.lihongjie.coal.base.dto.IdRequest; @@ -300,11 +302,11 @@ public class NetDiskController { /** * 批量下载文件/文件夹 * - * @param request * @param response */ @GetMapping("/downloadBatch") @SysLog(action = "downloadBatch", message = "ids") + @SignCheck(false) public void downloadDir(@RequestParam("ids") String ids, HttpServletResponse response) { this.service.downloadBatch( @@ -320,6 +322,8 @@ public class NetDiskController { * @return */ @GetMapping("/downloadFile") + @SignCheck(false) + @RateLimit(false) public ResponseEntity downloadFile( @RequestParam("id") String id, @RequestParam(value = "attachment", defaultValue = "false") Boolean attachment) { @@ -336,6 +340,8 @@ public class NetDiskController { * @param attachment * @param response */ + @SignCheck(false) + @RateLimit(false) @GetMapping("/downloadFileLocal") public void downloadFile( @RequestParam("id") String id, diff --git a/src/main/java/cn/lihongjie/coal/resource/dto/ResourceDto.java b/src/main/java/cn/lihongjie/coal/resource/dto/ResourceDto.java index d3d08f62..07724cc1 100644 --- a/src/main/java/cn/lihongjie/coal/resource/dto/ResourceDto.java +++ b/src/main/java/cn/lihongjie/coal/resource/dto/ResourceDto.java @@ -37,10 +37,15 @@ public class ResourceDto extends CommonDto { private String parent; + + private Boolean signCheck; + + private Boolean rateLimit; + public ResourceDto() { } - public ResourceDto(String id, String code, String name, String type, Boolean anonymous, Boolean orgAdmin, Boolean sysAdmin) { + public ResourceDto(String id, String code, String name, String type, Boolean anonymous, Boolean orgAdmin, Boolean sysAdmin, Boolean signCheck, Boolean rateLimit) { this.setId(id); this.setCode(code); @@ -50,6 +55,9 @@ public class ResourceDto extends CommonDto { this.orgAdmin = orgAdmin; this.sysAdmin = sysAdmin; this.anonymous = anonymous; + + this.signCheck = signCheck; + this.rateLimit = rateLimit; } } diff --git a/src/main/java/cn/lihongjie/coal/resource/entity/ResourceEntity.java b/src/main/java/cn/lihongjie/coal/resource/entity/ResourceEntity.java index e4226c4d..d041aaf6 100644 --- a/src/main/java/cn/lihongjie/coal/resource/entity/ResourceEntity.java +++ b/src/main/java/cn/lihongjie/coal/resource/entity/ResourceEntity.java @@ -72,6 +72,16 @@ public class ResourceEntity extends CommonEntity { @Comment("其他数据") private String metadata; + + @Comment("检查签名") + private Boolean signCheck; + + + @Comment("是否限流") + private Boolean rateLimit; + + + private static String getParent(String path) { log.debug("getParent {}", path); diff --git a/src/main/java/cn/lihongjie/coal/resource/repository/ResourceRepository.java b/src/main/java/cn/lihongjie/coal/resource/repository/ResourceRepository.java index 59802575..1ad24566 100644 --- a/src/main/java/cn/lihongjie/coal/resource/repository/ResourceRepository.java +++ b/src/main/java/cn/lihongjie/coal/resource/repository/ResourceRepository.java @@ -17,6 +17,6 @@ public interface ResourceRepository extends BaseRepository { ResourceEntity findByUrlAndType(String url, String type); - @Query("select new cn.lihongjie.coal.resource.dto.ResourceDto(r.id, r.code, r.name, r.type, r.anonymous, r.orgAdmin, r.sysAdmin) from ResourceEntity r where r.code = ?1 and r.type = ?2 ") + @Query("select new cn.lihongjie.coal.resource.dto.ResourceDto(r.id, r.code, r.name, r.type, r.anonymous, r.orgAdmin, r.sysAdmin, r.signCheck, r.rateLimit) from ResourceEntity r where r.code = ?1 and r.type = ?2 ") ResourceDto findByCodeAndType(String code, String type); } diff --git a/src/main/java/cn/lihongjie/coal/resource/service/ResourceService.java b/src/main/java/cn/lihongjie/coal/resource/service/ResourceService.java index be531590..cdafd5ef 100644 --- a/src/main/java/cn/lihongjie/coal/resource/service/ResourceService.java +++ b/src/main/java/cn/lihongjie/coal/resource/service/ResourceService.java @@ -1,5 +1,7 @@ package cn.lihongjie.coal.resource.service; +import cn.lihongjie.coal.annotation.RateLimit; +import cn.lihongjie.coal.annotation.SignCheck; import cn.lihongjie.coal.base.dto.CommonQuery; import cn.lihongjie.coal.base.dto.IdRequest; import cn.lihongjie.coal.base.service.BaseService; @@ -11,6 +13,8 @@ import cn.lihongjie.coal.resource.mapper.ResourceMapper; import cn.lihongjie.coal.resource.repository.ResourceRepository; import cn.lihongjie.coal.user.service.UserService; +import io.vavr.Tuple2; + import jakarta.annotation.PostConstruct; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; @@ -112,10 +116,10 @@ public class ResourceService extends BaseService getAllUrls() { + private List> getAllUrls() { Map handlerMethods = requestMappingHandlerMapping.getHandlerMethods(); - List urls = new ArrayList<>(); + List> urls = new ArrayList<>(); for (Map.Entry entry : handlerMethods.entrySet()) { RequestMappingInfo info = entry.getKey(); @@ -129,7 +133,7 @@ public class ResourceService extends BaseService allUrls = getAllUrls(); + List> allUrls = getAllUrls(); - for (String allUrl : allUrls) { + for (Tuple2 allUrl : allUrls) { ResourceEntity entity = new ResourceEntity(); - entity.setCode(allUrl); + entity.setCode(allUrl._1); entity.setType("3"); entity.setName(""); - entity.setUrl(allUrl); - entity.setAnonymous(StringUtils.equalsAny(allUrl, "/login", "/logout", "/genCaptcha")); + entity.setUrl(allUrl._1); + entity.setAnonymous(StringUtils.equalsAny(allUrl._1, "/login", "/logout", "/genCaptcha")); + RateLimit rateLimit = allUrl._2.getMethodAnnotation(RateLimit.class); + entity.setRateLimit(rateLimit == null || rateLimit.value()); + + SignCheck signCheck = allUrl._2.getMethodAnnotation(SignCheck.class); + entity.setSignCheck(signCheck == null || signCheck.value()); root.addChildren(entity); }