org.dromara.jpom.controller.system.SystemConfigController Maven / Gradle / Ivy
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Code Technology Studio
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* 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:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* 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
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package org.dromara.jpom.controller.system;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.net.Ipv4Util;
import cn.hutool.core.net.MaskBit;
import cn.hutool.core.text.CharPool;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.keepbx.jpom.IJsonMessage;
import cn.keepbx.jpom.model.JsonMessage;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import lombok.Lombok;
import lombok.extern.slf4j.Slf4j;
import org.dromara.jpom.JpomApplication;
import org.dromara.jpom.common.BaseServerController;
import org.dromara.jpom.common.Const;
import org.dromara.jpom.common.forward.NodeUrl;
import org.dromara.jpom.db.DbExtConfig;
import org.dromara.jpom.db.StorageServiceFactory;
import org.dromara.jpom.model.data.SystemIpConfigModel;
import org.dromara.jpom.permission.ClassFeature;
import org.dromara.jpom.permission.Feature;
import org.dromara.jpom.permission.MethodFeature;
import org.dromara.jpom.permission.SystemPermission;
import org.dromara.jpom.service.system.SystemParametersServer;
import org.dromara.jpom.system.ExtConfigBean;
import org.dromara.jpom.system.init.ProxySelectorConfig;
import org.springframework.beans.factory.config.YamlMapFactoryBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.sql.SQLException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
/**
* 系统配置
*
* @author bwcx_jzy
* @since 2019/08/08
*/
@RestController
@RequestMapping(value = "system")
@Feature(cls = ClassFeature.SYSTEM_CONFIG)
@SystemPermission
@Slf4j
public class SystemConfigController extends BaseServerController {
private final SystemParametersServer systemParametersServer;
private final ProxySelectorConfig proxySelectorConfig;
private final DbExtConfig dbExtConfig;
public SystemConfigController(SystemParametersServer systemParametersServer,
ProxySelectorConfig proxySelectorConfig,
DbExtConfig dbExtConfig) {
this.systemParametersServer = systemParametersServer;
this.proxySelectorConfig = proxySelectorConfig;
this.dbExtConfig = dbExtConfig;
}
/**
* get server's config or node's config
* 加载服务端或者节点端配置
*
* @param machineId 机器ID
* @return json
* @author Hotstrip
*/
@RequestMapping(value = "config-data", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
@Feature(method = MethodFeature.LIST)
public IJsonMessage configData(String machineId, HttpServletRequest request) {
IJsonMessage message = this.tryRequestNode(machineId, request, NodeUrl.SystemGetConfig);
return Optional.ofNullable(message).orElseGet(() -> {
JSONObject jsonObject = new JSONObject();
Resource resource = ExtConfigBean.getResource();
try {
String content = IoUtil.read(resource.getInputStream(), CharsetUtil.CHARSET_UTF_8);
jsonObject.put("content", content);
jsonObject.put("file", FileUtil.getAbsolutePath(resource.getFile()));
return JsonMessage.success("", jsonObject);
} catch (IOException e) {
throw Lombok.sneakyThrow(e);
}
});
}
@PostMapping(value = "save_config.json", produces = MediaType.APPLICATION_JSON_VALUE)
@Feature(method = MethodFeature.EDIT)
@SystemPermission(superUser = true)
public IJsonMessage saveConfig(String machineId, String content, String restart, HttpServletRequest request) throws SQLException, IOException {
JsonMessage jsonMessage = this.tryRequestNode(machineId, request, NodeUrl.SystemSaveConfig);
if (jsonMessage != null) {
return jsonMessage;
}
Assert.hasText(content, "内容不能为空");
ByteArrayResource byteArrayResource;
try {
YamlPropertySourceLoader yamlPropertySourceLoader = new YamlPropertySourceLoader();
// @author hjk 前端编辑器允许使用tab键,并设定为2个空格,再转换为yml时要把tab键换成2个空格
byteArrayResource = new ByteArrayResource(content.replace("\t", " ").getBytes(StandardCharsets.UTF_8));
yamlPropertySourceLoader.load("test", byteArrayResource);
} catch (Exception e) {
log.warn("内容格式错误,请检查修正", e);
return new JsonMessage<>(500, "内容格式错误,请检查修正:" + e.getMessage());
}
boolean restartBool = Convert.toBool(restart, false);
// 修改数据库密码
YamlMapFactoryBean yamlMapFactoryBean = new YamlMapFactoryBean();
yamlMapFactoryBean.setResources(byteArrayResource);
Map yamlMap = yamlMapFactoryBean.getObject();
ConfigurationProperties configurationProperties = DbExtConfig.class.getAnnotation(ConfigurationProperties.class);
Assert.notNull(configurationProperties, "没有找到数据库配置标识头");
Map dbYamlMap = BeanUtil.getProperty(yamlMap, configurationProperties.prefix());
Assert.notNull(dbYamlMap, "未解析出配置文件中的数据库配置信息");
// 解析字段密码
DbExtConfig dbExtConfig2 = BeanUtil.toBean(dbYamlMap, DbExtConfig.class, CopyOptions.create()
.setIgnoreError(true)
.setFieldNameEditor(s -> {
String camelCase = StrUtil.toCamelCase(s);
return StrUtil.toCamelCase(camelCase, CharPool.DASHED);
}));
Assert.hasText(dbExtConfig2.getUserName(), "未配置(未解析到)数据库用户名");
if (dbExtConfig2.getMode() == DbExtConfig.Mode.H2) {
String newDbExtConfigUserName = dbExtConfig2.userName();
String newDbExtConfigUserPwd = dbExtConfig2.userPwd();
String oldDbExtConfigUserName = dbExtConfig.userName();
String oldDbExtConfigUserPwd = dbExtConfig.userPwd();
if (!StrUtil.equals(oldDbExtConfigUserName, newDbExtConfigUserName) || !StrUtil.equals(oldDbExtConfigUserPwd, newDbExtConfigUserPwd)) {
// 执行修改数据库账号密码
Assert.state(restartBool, "修改数据库密码必须重启");
StorageServiceFactory.get().alterUser(oldDbExtConfigUserName, newDbExtConfigUserName, newDbExtConfigUserPwd);
}
}
Resource resource = ExtConfigBean.getResource();
Assert.state(resource.isFile(), "当前环境下不支持在线修改配置文件");
FileUtil.writeString(content, resource.getFile(), CharsetUtil.CHARSET_UTF_8);
if (restartBool) {
// 重启
JpomApplication.restart();
return JsonMessage.success(Const.UPGRADE_MSG);
}
return JsonMessage.success("修改成功");
}
/**
* 加载服务端的 ip 白名单配置
*
* @return json
*/
@RequestMapping(value = "ip-config-data", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
@Feature(cls = ClassFeature.SYSTEM_CONFIG_IP, method = MethodFeature.LIST)
public IJsonMessage ipConfigData() {
SystemIpConfigModel config = systemParametersServer.getConfig(SystemIpConfigModel.ID, SystemIpConfigModel.class);
JSONObject jsonObject = new JSONObject();
if (config != null) {
jsonObject.put("allowed", config.getAllowed());
jsonObject.put("prohibited", config.getProhibited());
}
//jsonObject.put("path", FileUtil.getAbsolutePath(systemIpConfigService.filePath()));
jsonObject.put("ip", getIp());
return JsonMessage.success("加载成功", jsonObject);
}
@RequestMapping(value = "save_ip_config.json", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
@Feature(cls = ClassFeature.SYSTEM_CONFIG_IP, method = MethodFeature.EDIT)
public IJsonMessage
© 2015 - 2024 Weber Informatics LLC | Privacy Policy