浏览代码

fix: 5.2.8待发布更新

msgroup 3 年之前
父节点
当前提交
1f526b0cb8

+ 2 - 0
src/main/java/net/mingsoft/cms/action/CategoryAction.java

@@ -86,6 +86,7 @@ public class CategoryAction extends BaseAction {
     })
 	@RequestMapping(value="/list",method = {RequestMethod.GET, RequestMethod.POST})
 	@ResponseBody
+	@RequiresPermissions("cms:category:view")
 	public ResultData list(@ModelAttribute @ApiIgnore CategoryEntity category) {
 		BasicUtil.startPage();
 		List categoryList = categoryBiz.query(category);
@@ -110,6 +111,7 @@ public class CategoryAction extends BaseAction {
 	@ApiOperation(value = "获取分类列表接口")
     @ApiImplicitParam(name = "id", value = "编号", required =true,paramType="query")
 	@GetMapping("/get")
+	@RequiresPermissions("cms:category:view")
 	@ResponseBody
 	public ResultData get(@ModelAttribute @ApiIgnore CategoryEntity category){
 		if(category.getId()==null) {

+ 5 - 0
src/main/java/net/mingsoft/cms/action/ContentAction.java

@@ -31,6 +31,7 @@ import net.mingsoft.basic.annotation.LogAnn;
 import net.mingsoft.basic.bean.EUListBean;
 import net.mingsoft.basic.constant.e.BusinessTypeEnum;
 import net.mingsoft.basic.util.BasicUtil;
+import net.mingsoft.basic.util.SqlInjectionUtil;
 import net.mingsoft.basic.util.StringUtil;
 import net.mingsoft.cms.bean.ContentBean;
 import net.mingsoft.cms.biz.ICategoryBiz;
@@ -113,7 +114,10 @@ public class ContentAction extends BaseAction {
     })
 	@PostMapping("/list")
 	@ResponseBody
+	@RequiresPermissions("cms:content:view")
 	public ResultData list(@ModelAttribute @ApiIgnore ContentBean content) {
+		// 检查SQL注入
+		SqlInjectionUtil.filterContent(content.getCategoryId());
 		BasicUtil.startPage();
 		List contentList = contentBiz.query(content);
 		return ResultData.build().success(new EUListBean(contentList,(int) BasicUtil.endPage(contentList).getTotal()));
@@ -136,6 +140,7 @@ public class ContentAction extends BaseAction {
     @ApiImplicitParam(name = "id", value = "编号", required =true,paramType="query")
 	@GetMapping("/get")
 	@ResponseBody
+	@RequiresPermissions("cms:content:view")
 	public ResultData get(@ModelAttribute @ApiIgnore ContentEntity content){
 		if(content.getId()==null) {
 			return ResultData.build().error();

+ 9 - 3
src/main/java/net/mingsoft/cms/action/web/MCmsAction.java

@@ -26,6 +26,7 @@ package net.mingsoft.cms.action.web;
 
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.PageUtil;
+import com.alibaba.fastjson.JSON;
 import freemarker.core.ParseException;
 import freemarker.template.MalformedTemplateNameException;
 import freemarker.template.TemplateNotFoundException;
@@ -541,12 +542,12 @@ public class MCmsAction extends net.mingsoft.cms.action.BaseAction {
     /**
      * 存储自定义模型字段和接口参数
      *
-     * @author 铭开源团队
+     * @author 铭开源团队
      * @date 2019年3月5日
      */
     class DiyModelMap {
-        String key;
-        Object value;
+        private String key;
+        private Object value;
 
         public String getKey() {
             return key;
@@ -563,6 +564,11 @@ public class MCmsAction extends net.mingsoft.cms.action.BaseAction {
         public void setValue(Object value) {
             this.value = value;
         }
+
+        @Override
+        public String toString() {
+            return JSON.toJSONString(this);
+        }
     }
 
 }

+ 83 - 0
src/main/java/net/mingsoft/cms/aop/CategoryAop.java

@@ -0,0 +1,83 @@
+/**
+ * Copyright (c) 2012-2022 铭软科技(mingsoft.net)
+ * 本软件及相关文档文件(以下简称“软件”)的版权归 铭软科技 所有
+ * 遵循铭软科技《保密协议》
+ */
+
+package net.mingsoft.cms.aop;
+
+import cn.hutool.core.io.FileUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import net.mingsoft.basic.util.BasicUtil;
+import net.mingsoft.cms.entity.CategoryEntity;
+import net.mingsoft.mdiy.biz.IDictBiz;
+import net.mingsoft.mdiy.entity.DictEntity;
+import org.apache.commons.lang3.StringUtils;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.After;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.io.File;
+import java.util.List;
+import java.util.stream.Collectors;
+
+
+/**
+ * 增加移动审批权限
+ */
+
+@Aspect
+@Component("CategoryAop")
+public class CategoryAop extends net.mingsoft.basic.aop.BaseAop {
+
+
+    @Value("${ms.diy.html-dir:html}")
+    private String htmlDir;
+
+
+    @Pointcut("execution(* net.mingsoft.cms.action.CategoryAction.delete(..)) ")
+    public void delete() {
+    }
+
+    /**
+     * 删除栏目后并删除文章对应的静态化文件
+     *
+     * @param jp
+     */
+    @After("delete()")
+    public void delete(JoinPoint jp) {
+        List<CategoryEntity> categoryEntities = (List<CategoryEntity>) getJsonParam(jp);
+        for (CategoryEntity categoryEntity : categoryEntities) {
+            // 删除静态文件
+            deleteCategoryHtml(categoryEntity.getCategoryPath());
+        }
+    }
+
+
+    /**
+     * @param categoryPath 栏目目录
+     *                     删除栏目静态文件
+     */
+    public void deleteCategoryHtml(String categoryPath) {
+        // html真实路径
+        String htmlPath = BasicUtil.getRealPath(htmlDir);
+        // appDir
+        String appDir = BasicUtil.getApp().getAppDir();
+        // 删除静态文件
+        // 文件夹路径组成 html真实路径 + appdir + 栏目路径
+        boolean flag = FileUtil.del(htmlPath
+                + File.separator + appDir
+                + categoryPath
+        );
+        if (flag) {
+            LOG.info("删除静态文件夹成功!");
+        } else {
+            LOG.info("删除失败!");
+        }
+    }
+
+}

+ 87 - 10
src/main/java/net/mingsoft/cms/aop/ContentAop.java

@@ -7,10 +7,10 @@
  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  * the Software, and to permit persons to whom the Software is furnished to do so,
  * subject to the following conditions:
-
+ * <p>
  * The above copyright notice and this permission notice shall be included in all
  * copies or substantial portions of the Software.
-
+ * <p>
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
@@ -22,20 +22,33 @@
 
 package net.mingsoft.cms.aop;
 
+import cn.hutool.core.io.FileUtil;
 import net.mingsoft.basic.aop.BaseAop;
 import net.mingsoft.basic.util.BasicUtil;
+import net.mingsoft.cms.biz.ICategoryBiz;
 import net.mingsoft.cms.biz.IContentBiz;
 import net.mingsoft.cms.biz.IHistoryLogBiz;
+import net.mingsoft.cms.entity.CategoryEntity;
 import net.mingsoft.cms.entity.ContentEntity;
 import net.mingsoft.cms.entity.HistoryLogEntity;
+import net.mingsoft.mdiy.util.ParserUtil;
 import org.apache.commons.lang3.StringUtils;
+import org.aspectj.lang.JoinPoint;
 import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.After;
 import org.aspectj.lang.annotation.Around;
 import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
+import java.io.File;
+import java.util.ArrayList;
 import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * @author 铭飞开源团队
@@ -45,18 +58,25 @@ import java.util.Date;
 @Aspect
 public class ContentAop extends BaseAop {
 
+
     /**
      * 注入文章业务
      */
     @Autowired
     private IContentBiz contentBiz;
 
+    @Autowired
+    private ICategoryBiz categoryBiz;
+
     /**
      * 注入浏览记录业务
      */
     @Autowired
     private IHistoryLogBiz historyLogBiz;
 
+    @Value("${ms.diy.html-dir:html}")
+    private String htmlDir;
+
     /**
      * 文章浏览记录,
      * 如果该文章该ip已经记录过,则不在重复记录
@@ -65,17 +85,17 @@ public class ContentAop extends BaseAop {
      * @throws Throwable
      */
     @Around("execution(* net.mingsoft.cms.action.web.ContentAction.get(..))")
-    public Object get(ProceedingJoinPoint pjp) throws Throwable{
+    public Object get(ProceedingJoinPoint pjp) throws Throwable {
 
 //        获取方法参数
         ContentEntity content = getType(pjp, ContentEntity.class);
 //        如果id为空则直接发行
-        if(content.getId()==null) {
+        if (content.getId() == null) {
             return pjp.proceed();
         }
         content = contentBiz.getById(content.getId());
         //如果文章不存在则直接发行
-        if(content == null){
+        if (content == null) {
             return pjp.proceed();
         }
 
@@ -84,23 +104,80 @@ public class ContentAop extends BaseAop {
         historyLog.setContentId(content.getId());
         historyLog.setHlIp(BasicUtil.getIp());
         historyLog.setHlIsMobile(BasicUtil.isMobileDevice());
-        HistoryLogEntity _historyLog = (HistoryLogEntity)historyLogBiz.getEntity(historyLog);
+        HistoryLogEntity _historyLog = (HistoryLogEntity) historyLogBiz.getEntity(historyLog);
         //如果该ip该文章没有浏览记录则保存浏览记录
         //并且更新点击数
-        if(_historyLog == null || StringUtils.isBlank(_historyLog.getId())){
+        if (_historyLog == null || StringUtils.isBlank(_historyLog.getId())) {
             historyLog.setCreateDate(new Date());
             historyLogBiz.saveEntity(historyLog);
             //更新点击数
             ContentEntity updateContent = new ContentEntity();
             updateContent.setId(content.getId());
-            if(content.getContentHit() == null){
+            if (content.getContentHit() == null) {
                 updateContent.setContentHit(1);
-            }else{
-                updateContent.setContentHit(content.getContentHit()+1);
+            } else {
+                updateContent.setContentHit(content.getContentHit() + 1);
             }
             contentBiz.updateEntity(updateContent);
         }
 
         return pjp.proceed();
     }
+
+
+    @Pointcut("execution(* net.mingsoft.cms.action.ContentAction.delete(..))")
+    public void delete() {
+    }
+
+    /**
+     * 删除文章后并删除文章对应的静态化文件
+     * @param jp
+     */
+    @After("delete()")
+    public void delete(JoinPoint jp) {
+        List<ContentEntity> contents = (List<ContentEntity>) getJsonParam(jp);
+
+        // 获取栏目ID对应文章ID数组 map
+        Map<String, List<String>> categoryIdByContentIds = contents.stream()
+                .collect(Collectors.groupingBy(ContentEntity::getCategoryId, Collectors.mapping(ContentEntity::getId, Collectors.toList())));
+        List<String> categoryIds = new ArrayList<>(categoryIdByContentIds.keySet());
+        // 考虑到在全部中删除文章 栏目不同
+        for (String categoryId : categoryIds) {
+            // 获取栏目
+            CategoryEntity category = categoryBiz.getById(categoryId);
+            // 获取栏目路径
+            String categoryPath = category.getCategoryPath();
+            for (String contentId : categoryIdByContentIds.get(categoryId)) {
+                // 删除静态文件
+                deleteHtml(categoryPath, contentId);
+            }
+        }
+    }
+
+
+    /**
+     * @param categoryPath 栏目目录
+     * @param contentId 文章ID
+     * 根据文章实体删除静态文件
+     */
+    private void deleteHtml(String categoryPath, String contentId) {
+        // html真实路径
+        String htmlPath = BasicUtil.getRealPath(htmlDir);
+        // appDir
+        String appDir = BasicUtil.getApp().getAppDir();
+
+        // 删除静态文件
+        // 文件路径组成 html真实路径 + appdir + 栏目路径 + 文章ID + .html
+        boolean flag = FileUtil.del(htmlPath
+                + File.separator + appDir
+                + categoryPath
+                + File.separator + contentId
+                + ParserUtil.HTML_SUFFIX);
+        if (flag) {
+            LOG.info("删除静态文件成功!");
+        } else {
+            LOG.info("删除失败!");
+        }
+
+    }
 }

+ 5 - 1
src/main/resources/application.yml

@@ -12,6 +12,7 @@ logging:
   config: classpath:log4j-spring.xml
 
 ms:
+
   shiro-key: 4AvVhmFLUs0KTA3Kprsdag== #生产必须修改此值否则会存在安全风险,可以通过 https://base64.us/随机生产一个Base64值
   html-dir: html
   rand-code:
@@ -23,7 +24,10 @@ ms:
   manager:
     path: /ms #后台访问的路径,如:http://项目/ms/login.do,生产的时候建议修改
     check-code: true #默认开启验证码验证,false验证码不验证
-
+  xss:
+    xssEnable: true #xss过滤器的开关
+    filterUrl: /**   #过滤的url,多个用逗号分开
+    excludeUrl: /ms**,/static**,/template**,/file/upload.do  #排除的url,多个用逗号分开
   upload:
     enable-web: true  #启用web层的上传
     template: template #模板文件夹支持重命名,不支持路径