节点分发新增 http 下载白名单配置

This commit is contained in:
bwcx_jzy 2021-08-11 16:15:30 +08:00
parent a5bf9526dd
commit 3be2d7207c
7 changed files with 141 additions and 124 deletions

View File

@ -37,27 +37,18 @@ public class WhitelistDirectoryController extends BaseJpomController {
return JsonMessage.getString(200, "", agentWhitelist);
}
private List<String> parseToList(String value, String errorMsg) {
if (StrUtil.isEmpty(value)) {
return null;
}
List<String> list = StrSplitter.splitTrim(value, StrUtil.LF, true);
Assert.notEmpty(list, errorMsg);
return list;
}
@RequestMapping(value = "whitelistDirectory_submit", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public String whitelistDirectorySubmit(String project, String certificate, String nginx, String allowEditSuffix, String allowRemoteDownloadHost) {
if (StrUtil.isEmpty(project)) {
return JsonMessage.getString(401, "项目路径白名单不能为空");
}
List<String> list = this.parseToList(project, "项目路径白名单不能为空");
List<String> list = AgentWhitelist.parseToList(project, true, "项目路径白名单不能为空");
//
List<String> certificateList = this.parseToList(certificate, "证书路径白名单不能为空");
List<String> nList = this.parseToList(nginx, "nginx路径白名单不能为空");
List<String> allowEditSuffixList = this.parseToList(allowEditSuffix, "运行编辑的文件后缀不能为空");
List<String> allowRemoteDownloadHostList = this.parseToList(allowRemoteDownloadHost, "运行远程下载的 host 不能配置为空");
List<String> certificateList = AgentWhitelist.parseToList(certificate, "证书路径白名单不能为空");
List<String> nList = AgentWhitelist.parseToList(nginx, "nginx路径白名单不能为空");
List<String> allowEditSuffixList = AgentWhitelist.parseToList(allowEditSuffix, "运行编辑的文件后缀不能为空");
List<String> allowRemoteDownloadHostList = AgentWhitelist.parseToList(allowRemoteDownloadHost, "运行远程下载的 host 不能配置为空");
return save(list, certificateList, nList, allowEditSuffixList, allowRemoteDownloadHostList).toString();
}
//
@ -74,13 +65,8 @@ public class WhitelistDirectoryController extends BaseJpomController {
List<String> allowRemoteDownloadHostList) {
List<String> projectArray;
{
projectArray = AgentWhitelist.covertToArray(projects);
if (projectArray == null) {
return new JsonMessage<>(401, "项目路径白名单不能位于Jpom目录下");
}
if (projectArray.isEmpty()) {
return new JsonMessage<>(401, "项目路径白名单不能为空");
}
projectArray = AgentWhitelist.covertToArray(projects, "项目路径白名单不能位于Jpom目录下");
String error = findStartsWith(projectArray, 0);
if (error != null) {
return new JsonMessage<>(401, "白名单目录中不能存在包含关系:" + error);
@ -88,13 +74,8 @@ public class WhitelistDirectoryController extends BaseJpomController {
}
List<String> certificateArray = null;
if (certificate != null && !certificate.isEmpty()) {
certificateArray = AgentWhitelist.covertToArray(certificate);
if (certificateArray == null) {
return new JsonMessage<>(401, "证书路径白名单不能位于Jpom目录下");
}
if (certificateArray.isEmpty()) {
return new JsonMessage<>(401, "证书路径白名单不能为空");
}
certificateArray = AgentWhitelist.covertToArray(certificate, "证书路径白名单不能位于Jpom目录下");
String error = findStartsWith(certificateArray, 0);
if (error != null) {
return new JsonMessage<>(401, "证书目录中不能存在包含关系:" + error);
@ -102,13 +83,8 @@ public class WhitelistDirectoryController extends BaseJpomController {
}
List<String> nginxArray = null;
if (nginx != null && !nginx.isEmpty()) {
nginxArray = AgentWhitelist.covertToArray(nginx);
if (nginxArray == null) {
return new JsonMessage<>(401, "nginx路径白名单不能位于Jpom目录下");
}
if (nginxArray.isEmpty()) {
return new JsonMessage<>(401, "nginx路径白名单不能为空");
}
nginxArray = AgentWhitelist.covertToArray(nginx, "nginx路径白名单不能位于Jpom目录下");
String error = findStartsWith(nginxArray, 0);
if (error != null) {
return new JsonMessage<>(401, "nginx目录中不能存在包含关系" + error);
@ -153,7 +129,7 @@ public class WhitelistDirectoryController extends BaseJpomController {
* @return null 正常
*/
private String findStartsWith(List<String> jsonArray, int start) {
if (!AgentExtConfigBean.getInstance().whitelistDirectoryCheckStartsWith) {
if (jsonArray == null || !AgentExtConfigBean.getInstance().whitelistDirectoryCheckStartsWith) {
return null;
}
String str = jsonArray.get(start);

View File

@ -2,12 +2,14 @@ package io.jpom.model.data;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.text.StrSplitter;
import cn.hutool.core.util.StrUtil;
import cn.jiangzeyin.common.DefaultSystemLog;
import com.alibaba.fastjson.JSONObject;
import io.jpom.common.BaseJpomController;
import io.jpom.model.BaseJsonModel;
import io.jpom.system.ExtConfigBean;
import org.springframework.util.Assert;
import java.io.File;
import java.util.ArrayList;
@ -91,7 +93,10 @@ public class AgentWhitelist extends BaseJsonModel {
* @param list list
* @return null 是有冲突的
*/
public static List<String> covertToArray(List<String> list) {
public static List<String> covertToArray(List<String> list, String errorMsg) {
if (list == null) {
return null;
}
List<String> array = new ArrayList<>();
for (String s : list) {
String val = String.format("/%s/", s);
@ -104,7 +109,7 @@ public class AgentWhitelist extends BaseJsonModel {
}
// 判断是否保护jpom 路径
if (val == null || val.startsWith(ExtConfigBean.getInstance().getPath())) {
return null;
throw new IllegalArgumentException(errorMsg);
}
array.add(val);
}
@ -168,4 +173,36 @@ public class AgentWhitelist extends BaseJsonModel {
}
return null;
}
/**
* 将字符串转为 list
*
* @param value 字符串
* @param errorMsg 错误消息
* @return list
*/
public static List<String> parseToList(String value, String errorMsg) {
return parseToList(value, false, errorMsg);
}
/**
* 将字符串转为 list
*
* @param value 字符串
* @param required 是否为必填
* @param errorMsg 错误消息
* @return list
*/
public static List<String> parseToList(String value, boolean required, String errorMsg) {
if (required) {
Assert.hasLength(value, errorMsg);
} else {
if (StrUtil.isEmpty(value)) {
return null;
}
}
List<String> list = StrSplitter.splitTrim(value, StrUtil.LF, true);
Assert.notEmpty(list, errorMsg);
return list;
}
}

View File

@ -59,9 +59,6 @@ public class WhitelistDirectoryController extends BaseServerController {
Collection<String> fieldValue = (Collection<String>) ReflectUtil.getFieldValue(agentWhitelist, field);
map.put(field.getName(), AgentWhitelist.convertToLine(fieldValue));
}
// map.put("project", AgentWhitelist.convertToLine(agentWhitelist.getProject()));
// map.put("certificate", AgentWhitelist.convertToLine(agentWhitelist.getCertificate()));
// map.put("nginx", AgentWhitelist.convertToLine(agentWhitelist.getNginx()));
}
return JsonMessage.getString(200, "ok", map);
}

View File

@ -1,13 +1,14 @@
package io.jpom.controller.outgiving;
import cn.hutool.core.text.StrSplitter;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.RegexPool;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.jiangzeyin.common.JsonMessage;
import io.jpom.common.BaseServerController;
import io.jpom.common.interceptor.OptLog;
import io.jpom.model.data.AgentWhitelist;
import io.jpom.model.data.ServerWhitelist;
import io.jpom.model.data.UserModel;
import io.jpom.model.log.UserOperateLogV1;
import io.jpom.permission.SystemPermission;
import io.jpom.plugin.ClassFeature;
@ -15,11 +16,14 @@ import io.jpom.plugin.Feature;
import io.jpom.service.system.ServerWhitelistServer;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -34,75 +38,59 @@ import java.util.Map;
@RequestMapping(value = "/outgiving")
@Feature(cls = ClassFeature.OUTGIVING)
public class OutGivingWhitelistController extends BaseServerController {
@Resource
private ServerWhitelistServer serverWhitelistServer;
@Resource
private ServerWhitelistServer serverWhitelistServer;
// @RequestMapping(value = "whitelistDirectory.html", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
// @SystemPermission
// public String whitelistDirectory() {
// //
// UserModel userModel = getUser();
// ServerWhitelist serverWhitelist = serverWhitelistServer.getWhitelist();
// if (serverWhitelist != null && userModel.isSystemUser()) {
// List<String> whiteList = serverWhitelist.getOutGiving();
// String strWhiteList = AgentWhitelist.convertToLine(whiteList);
// setAttribute("whiteList", strWhiteList);
// }
// return "outgiving/whitelistDirectory";
// }
/**
* get whiteList data
* 白名单数据接口
*
* @return json
* @author Hotstrip
*/
@RequestMapping(value = "white-list", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
@SystemPermission
@ResponseBody
public String whiteList() {
ServerWhitelist serverWhitelist = serverWhitelistServer.getWhitelist();
Field[] fields = ReflectUtil.getFields(ServerWhitelist.class);
Map<String, String> map = new HashMap<>(8);
for (Field field : fields) {
Collection<String> fieldValue = (Collection<String>) ReflectUtil.getFieldValue(serverWhitelist, field);
map.put(field.getName(), AgentWhitelist.convertToLine(fieldValue));
}
return JsonMessage.getString(200, "ok", map);
}
/**
* @return
* @author Hotstrip
* get whiteList data
* 白名单数据接口
*/
@RequestMapping(value = "white-list", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
@SystemPermission
@ResponseBody
public String whiteList() {
Map<String, String> map = new HashMap<>();
UserModel userModel = getUser();
ServerWhitelist serverWhitelist = serverWhitelistServer.getWhitelist();
if (serverWhitelist != null && userModel.isSystemUser()) {
List<String> whiteList = serverWhitelist.getOutGiving();
String strWhiteList = AgentWhitelist.convertToLine(whiteList);
map.put("whiteList", strWhiteList);
}
return JsonMessage.getString(200, "ok", map);
}
/**
* 保存节点白名单
*
* @param outGiving 数据
* @return json
*/
@RequestMapping(value = "whitelistDirectory_submit", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
@OptLog(UserOperateLogV1.OptType.SaveOutgivingWhitelist)
@SystemPermission
public String whitelistDirectorySubmit(String outGiving, String allowRemoteDownloadHost) {
List<String> list = AgentWhitelist.parseToList(outGiving, true, "项目路径白名单不能为空");
list = AgentWhitelist.covertToArray(list, "项目路径白名单不能位于Jpom目录下");
/**
* 保存节点白名单
*
* @param data 数据
* @return json
*/
@RequestMapping(value = "whitelistDirectory_submit", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
@OptLog(UserOperateLogV1.OptType.SaveOutgivingWhitelist)
@SystemPermission
public String whitelistDirectorySubmit(String data) {
List<String> list = StrSplitter.splitTrim(data, StrUtil.LF, true);
if (list == null || list.size() <= 0) {
return JsonMessage.getString(401, "白名单不能为空");
}
list = AgentWhitelist.covertToArray(list);
if (list == null) {
return JsonMessage.getString(401, "项目路径白名单不能位于Jpom目录下");
}
if (list.isEmpty()) {
return JsonMessage.getString(401, "项目路径白名单不能为空");
}
ServerWhitelist serverWhitelist = serverWhitelistServer.getWhitelist();
if (serverWhitelist == null) {
serverWhitelist = new ServerWhitelist();
}
serverWhitelist.setOutGiving(list);
serverWhitelistServer.saveWhitelistDirectory(serverWhitelist);
ServerWhitelist serverWhitelist = serverWhitelistServer.getWhitelist();
serverWhitelist.setOutGiving(list);
//
List<String> allowRemoteDownloadHostList = AgentWhitelist.parseToList(allowRemoteDownloadHost, "运行远程下载的 host 不能配置为空");
//
if (CollUtil.isNotEmpty(allowRemoteDownloadHostList)) {
for (String s : allowRemoteDownloadHostList) {
Assert.state(ReUtil.isMatch(RegexPool.URL_HTTP, s), "配置的远程地址不规范,请重新填写:" + s);
}
}
serverWhitelist.setAllowRemoteDownloadHost(allowRemoteDownloadHostList == null ? null : CollUtil.newHashSet(allowRemoteDownloadHostList));
serverWhitelistServer.saveWhitelistDirectory(serverWhitelist);
String resultData = AgentWhitelist.convertToLine(list);
return JsonMessage.getString(200, "保存成功", resultData);
}
String resultData = AgentWhitelist.convertToLine(list);
return JsonMessage.getString(200, "保存成功", resultData);
}
}

View File

@ -3,6 +3,7 @@ package io.jpom.model.data;
import io.jpom.model.BaseJsonModel;
import java.util.List;
import java.util.Set;
/**
* 节点分发白名单
@ -11,13 +12,30 @@ import java.util.List;
* @date 2019/4/22
*/
public class ServerWhitelist extends BaseJsonModel {
private List<String> outGiving;
public List<String> getOutGiving() {
return outGiving;
}
/**
* 项目的白名单
*/
private List<String> outGiving;
public void setOutGiving(List<String> outGiving) {
this.outGiving = outGiving;
}
/**
* 运行远程下载的 host
*/
private Set<String> allowRemoteDownloadHost;
public List<String> getOutGiving() {
return outGiving;
}
public void setOutGiving(List<String> outGiving) {
this.outGiving = outGiving;
}
public Set<String> getAllowRemoteDownloadHost() {
return allowRemoteDownloadHost;
}
public void setAllowRemoteDownloadHost(Set<String> allowRemoteDownloadHost) {
this.allowRemoteDownloadHost = allowRemoteDownloadHost;
}
}

View File

@ -21,13 +21,13 @@ public class ServerWhitelistServer extends BaseDataService {
try {
JSONObject jsonObject = getJSONObject(ServerConfigBean.OUTGIVING_WHITELIST);
if (jsonObject == null) {
return null;
return new ServerWhitelist();
}
return jsonObject.toJavaObject(ServerWhitelist.class);
} catch (Exception e) {
DefaultSystemLog.getLog().error(e.getMessage(), e);
}
return null;
return new ServerWhitelist();
}
public void saveWhitelistDirectory(ServerWhitelist serverWhitelist) {

View File

@ -2,7 +2,10 @@
<div>
<a-form-model ref="editForm" :model="temp" :label-col="{ span: 6 }" :wrapper-col="{ span: 14 }">
<a-form-model-item label="白名单路径" prop="id">
<a-input v-model="temp.whiteList" type="textarea" :rows="5" style="resize: none" placeholder="请输入白名单路径,回车支持输入多个路径,系统会自动过滤 ../ 路径、不允许输入根路径"/>
<a-input v-model="temp.outGiving" type="textarea" :rows="5" style="resize: none" placeholder="请输入白名单路径,回车支持输入多个路径,系统会自动过滤 ../ 路径、不允许输入根路径"/>
</a-form-model-item>
<a-form-model-item label="远程下载安全HOST" prop="name">
<a-input v-model="temp.allowRemoteDownloadHost" type="textarea" :rows="5" style="resize: none" placeholder="请输入远程下载安全HOST回车支持输入多个路径示例 https://www.test.com 等"/>
</a-form-model-item>
<a-form-model-item :wrapper-col="{ span: 14, offset: 6 }">
<a-button type="primary" :disabled="submitAble" @click="onSubmit">提交</a-button>
@ -35,10 +38,8 @@ export default {
onSubmit() {
// disabled submit button
this.submitAble = true;
const params = {
data: this.temp.whiteList
}
editDispatchWhiteList(params).then(res => {
editDispatchWhiteList(this.temp).then(res => {
if (res.code === 200) {
//
this.$notification.success({