安装时填写白名单,页面输入框提示,token 变为WebHooks ,Controller 获取用户对象线程安全

This commit is contained in:
jiangzeyin 2019-03-01 17:19:21 +08:00
parent a78aeedb8b
commit c4fe9ed9ba
21 changed files with 127 additions and 50 deletions

View File

@ -1,4 +1,4 @@
package cn.keepbx.jpom.controller;
package cn.keepbx.jpom.common;
import cn.jiangzeyin.controller.base.AbstractController;
import cn.keepbx.jpom.common.interceptor.LoginInterceptor;
@ -12,11 +12,23 @@ import org.springframework.web.context.request.RequestAttributes;
* @date 2018/9/28
*/
public abstract class BaseController extends AbstractController {
protected UserModel userName;
private static final ThreadLocal<UserModel> USER_MODEL_THREAD_LOCAL = new ThreadLocal<>();
@Override
public void resetInfo() {
userName = (UserModel) getSessionAttributeObj(LoginInterceptor.SESSION_NAME);
USER_MODEL_THREAD_LOCAL.set(getUserModel());
}
protected UserModel getUser() {
return USER_MODEL_THREAD_LOCAL.get();
}
public static void remove() {
USER_MODEL_THREAD_LOCAL.remove();
}
private static UserModel getUserModel() {
return (UserModel) getRequestAttributes().getAttribute(LoginInterceptor.SESSION_NAME, RequestAttributes.SCOPE_SESSION);
}
/**
@ -25,14 +37,10 @@ public abstract class BaseController extends AbstractController {
* @return 用户名
*/
public static String getUserName() {
UserModel userModel = (UserModel) getRequestAttributes().getAttribute(LoginInterceptor.SESSION_NAME, RequestAttributes.SCOPE_SESSION);
UserModel userModel = getUserModel();
if (userModel == null) {
return null;
}
return userModel.getId();
}
// protected String getSocketPwd() {
// return userName.getUserMd5Key();
// }
}

View File

@ -2,6 +2,7 @@ package cn.keepbx.jpom.common.interceptor;
import cn.jiangzeyin.common.interceptor.BaseInterceptor;
import cn.jiangzeyin.common.interceptor.InterceptorPattens;
import cn.keepbx.jpom.common.BaseController;
import cn.keepbx.jpom.model.UserModel;
import org.springframework.web.method.HandlerMethod;
@ -17,10 +18,11 @@ import javax.servlet.http.HttpSession;
*/
@InterceptorPattens
public class LoginInterceptor extends BaseInterceptor {
/**
* session
*/
public static final String SESSION_NAME = "user";
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
super.preHandle(request, response, handler);
@ -39,4 +41,10 @@ public class LoginInterceptor extends BaseInterceptor {
reload();
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
super.afterCompletion(request, response, handler, ex);
BaseController.remove();
}
}

View File

@ -1,5 +1,6 @@
package cn.keepbx.jpom.controller;
import cn.keepbx.jpom.common.BaseController;
import cn.keepbx.jpom.common.interceptor.NotLogin;
import cn.keepbx.jpom.system.ConfigBean;
import org.springframework.http.MediaType;

View File

@ -3,8 +3,11 @@ package cn.keepbx.jpom.controller;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import cn.jiangzeyin.common.JsonMessage;
import cn.jiangzeyin.common.spring.SpringUtil;
import cn.keepbx.jpom.common.BaseController;
import cn.keepbx.jpom.common.interceptor.LoginInterceptor;
import cn.keepbx.jpom.common.interceptor.NotLogin;
import cn.keepbx.jpom.controller.system.WhitelistDirectoryController;
import cn.keepbx.jpom.model.UserModel;
import cn.keepbx.jpom.service.user.UserService;
import org.springframework.http.MediaType;
@ -44,7 +47,7 @@ public class InstallController extends BaseController {
@RequestMapping(value = "install_submit.json", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@NotLogin
@ResponseBody
public String installSubmit(String userName, String userPwd) {
public String installSubmit(String userName, String userPwd, String whitelistDirectory) {
if (StrUtil.isEmpty(userName)) {
return JsonMessage.getString(400, "登录名不能为空");
}
@ -62,6 +65,12 @@ public class InstallController extends BaseController {
userModel.setManage(true);
boolean b = userService.addUser(userModel);
if (b) {
// 白名单
WhitelistDirectoryController whitelistDirectoryController = SpringUtil.getBean(WhitelistDirectoryController.class);
JsonMessage jsonMessage = whitelistDirectoryController.save(whitelistDirectory);
if (jsonMessage.getCode() != 200) {
return jsonMessage.toString();
}
// 自动登录
setSessionAttribute(LoginInterceptor.SESSION_NAME, userModel);
return JsonMessage.getString(200, "初始化成功");

View File

@ -2,6 +2,7 @@ package cn.keepbx.jpom.controller;
import cn.jiangzeyin.common.DefaultSystemLog;
import cn.jiangzeyin.common.JsonMessage;
import cn.keepbx.jpom.common.BaseController;
import cn.keepbx.jpom.common.interceptor.LoginInterceptor;
import cn.keepbx.jpom.common.interceptor.NotLogin;
import cn.keepbx.jpom.model.UserModel;

View File

@ -1,5 +1,7 @@
package cn.keepbx.jpom.controller;
import cn.keepbx.jpom.common.BaseController;
import cn.keepbx.jpom.model.UserModel;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@ -16,6 +18,7 @@ public class WelcomeController extends BaseController {
@RequestMapping(value = "welcome", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
public String welcome() {
UserModel userName = getUser();
setAttribute("userInfo", userName.getUserMd5Key());
return "welcome";
}

View File

@ -5,7 +5,7 @@ import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import cn.jiangzeyin.common.DefaultSystemLog;
import cn.jiangzeyin.common.JsonMessage;
import cn.keepbx.jpom.controller.BaseController;
import cn.keepbx.jpom.common.BaseController;
import cn.keepbx.jpom.model.ProjectInfoModel;
import cn.keepbx.jpom.service.manage.CommandService;
import cn.keepbx.jpom.service.manage.ManageService;
@ -51,7 +51,7 @@ public class BuildController extends BaseController {
@RequestMapping(value = "build_download", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
public String buildDownload(String id, String key) {
if (!userName.isProject(id)) {
if (!getUser().isProject(id)) {
return "redirect:error";
}
try {
@ -69,7 +69,7 @@ public class BuildController extends BaseController {
@RequestMapping(value = "build_install", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public String buildInstall(String id, String key) throws Exception {
if (!userName.isProject(id)) {
if (!getUser().isProject(id)) {
return JsonMessage.getString(400, "你没有对应操作权限操作!");
}
ProjectInfoModel projectInfoModel = manageService.getProjectInfo(id);

View File

@ -4,8 +4,9 @@ import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.jiangzeyin.common.DefaultSystemLog;
import cn.jiangzeyin.common.JsonMessage;
import cn.keepbx.jpom.controller.BaseController;
import cn.keepbx.jpom.common.BaseController;
import cn.keepbx.jpom.model.ProjectInfoModel;
import cn.keepbx.jpom.model.UserModel;
import cn.keepbx.jpom.service.manage.ManageService;
import com.alibaba.fastjson.JSONObject;
import org.springframework.http.MediaType;
@ -47,6 +48,7 @@ public class ConsoleController extends BaseController {
} catch (IOException e) {
DefaultSystemLog.ERROR().error(e.getMessage(), e);
}
UserModel userName = getUser();
if (pim != null) {
setAttribute("projectInfo", JSONObject.toJSONString(pim));
setAttribute("userInfo", userName.getUserMd5Key());

View File

@ -2,12 +2,15 @@ package cn.keepbx.jpom.controller.manage;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.PatternPool;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.jiangzeyin.common.DefaultSystemLog;
import cn.jiangzeyin.common.JsonMessage;
import cn.keepbx.jpom.controller.BaseController;
import cn.keepbx.jpom.common.BaseController;
import cn.keepbx.jpom.model.ProjectInfoModel;
import cn.keepbx.jpom.model.UserModel;
import cn.keepbx.jpom.service.manage.ManageService;
import cn.keepbx.jpom.service.system.SystemService;
import cn.keepbx.jpom.socket.LogWebSocketHandle;
@ -110,8 +113,17 @@ public class EditProjectController extends BaseController {
log = String.format("%s/%s.log", log, id);
projectInfo.setLog(FileUtil.normalize(log));
//
String token = projectInfo.getToken();
if (!ProjectInfoModel.NO_TOKEN.equals(token)) {
if (!ReUtil.isMatch(PatternPool.URL_HTTP, token)) {
return JsonMessage.getString(401, "WebHooks 地址不合法");
}
}
ProjectInfoModel exits = manageService.getProjectInfo(id);
try {
UserModel userName = getUser();
JsonMessage jsonMessage = checkPath(projectInfo);
if (jsonMessage != null) {
return jsonMessage.toString();

View File

@ -6,9 +6,10 @@ import cn.hutool.extra.servlet.ServletUtil;
import cn.jiangzeyin.common.DefaultSystemLog;
import cn.jiangzeyin.common.JsonMessage;
import cn.jiangzeyin.controller.multipart.MultipartFileBuilder;
import cn.keepbx.jpom.common.BaseController;
import cn.keepbx.jpom.common.PageUtil;
import cn.keepbx.jpom.controller.BaseController;
import cn.keepbx.jpom.model.ProjectInfoModel;
import cn.keepbx.jpom.model.UserModel;
import cn.keepbx.jpom.service.manage.ManageService;
import cn.keepbx.jpom.system.ConfigBean;
import com.alibaba.fastjson.JSONArray;
@ -69,6 +70,7 @@ public class FileControl extends BaseController {
@RequestMapping(value = "getFileList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public String getFileList(String id) {
UserModel userName = getUser();
if (!userName.isProject(id)) {
return JsonMessage.getString(400, "你没有该操作权限操作!");
}
@ -120,6 +122,7 @@ public class FileControl extends BaseController {
public String upload(String id) throws Exception {
// String id = getParameter("id");
// boolean manager = userService.isManager(id, getUserName());
UserModel userName = getUser();
if (!userName.isProject(id)) {
return JsonMessage.getString(400, "你没有该操作权限操作!");
}
@ -166,6 +169,7 @@ public class FileControl extends BaseController {
if (ConfigBean.getInstance().safeMode) {
return JsonMessage.getString(400, "安全模式不能清除文件");
}
UserModel userName = getUser();
if (!userName.isProject(id)) {
return JsonMessage.getString(400, "你没有对应操作权限操作!");
}
@ -190,6 +194,7 @@ public class FileControl extends BaseController {
@RequestMapping(value = "deleteFile", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public String deleteFile(String id, String filename) {
UserModel userName = getUser();
if (!userName.isProject(id)) {
return JsonMessage.getString(400, "你没有对应操作权限操作!");
}

View File

@ -3,7 +3,7 @@ package cn.keepbx.jpom.controller.manage;
import cn.hutool.core.io.FileUtil;
import cn.jiangzeyin.common.DefaultSystemLog;
import cn.jiangzeyin.common.JsonMessage;
import cn.keepbx.jpom.controller.BaseController;
import cn.keepbx.jpom.common.BaseController;
import cn.keepbx.jpom.model.ProjectInfoModel;
import cn.keepbx.jpom.service.manage.CommandService;
import cn.keepbx.jpom.system.ConfigBean;

View File

@ -3,9 +3,10 @@ package cn.keepbx.jpom.controller.manage;
import cn.hutool.core.util.StrUtil;
import cn.jiangzeyin.common.DefaultSystemLog;
import cn.jiangzeyin.common.JsonMessage;
import cn.keepbx.jpom.common.BaseController;
import cn.keepbx.jpom.common.PageUtil;
import cn.keepbx.jpom.controller.BaseController;
import cn.keepbx.jpom.model.ProjectInfoModel;
import cn.keepbx.jpom.model.UserModel;
import cn.keepbx.jpom.service.manage.CommandService;
import cn.keepbx.jpom.service.manage.ManageService;
import com.alibaba.fastjson.JSONArray;
@ -55,6 +56,7 @@ public class ManageControl extends BaseController {
@ResponseBody
public String getProjectInfo() {
try {
UserModel userName = getUser();
// 查询数据
JSONObject json = manageService.getAllProjectInfo();
// 转换为数据
@ -115,7 +117,7 @@ public class ManageControl extends BaseController {
@RequestMapping(value = "deleteProject", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public String deleteProject(String id) {
// boolean manager = userService.isManager(id, getUserName());
UserModel userName = getUser();
if (!userName.isProject(id)) {
return JsonMessage.getString(500, "你没有对应权限");
}

View File

@ -4,7 +4,8 @@ import cn.hutool.core.io.FileUtil;
import cn.hutool.core.text.StrSpliter;
import cn.hutool.core.util.StrUtil;
import cn.jiangzeyin.common.JsonMessage;
import cn.keepbx.jpom.controller.BaseController;
import cn.keepbx.jpom.common.BaseController;
import cn.keepbx.jpom.model.UserModel;
import cn.keepbx.jpom.service.system.SystemService;
import cn.keepbx.jpom.system.ConfigBean;
import com.alibaba.fastjson.JSONArray;
@ -47,33 +48,42 @@ public class WhitelistDirectoryController extends BaseController {
@RequestMapping(value = "whitelistDirectory_submit", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public String whitelistDirectorySubmit(String value) {
if (StrUtil.isEmpty(value)) {
return JsonMessage.getString(401, "白名单不能为空");
}
List<String> list = StrSpliter.splitTrim(value, "\n", true);
if (list == null || list.size() <= 0) {
return JsonMessage.getString(401, "白名单不能为空");
}
if (ConfigBean.getInstance().safeMode) {
return JsonMessage.getString(401, "安全模式下不能修改白名单目录");
}
UserModel userName = getUser();
if (!userName.isManage()) {
return JsonMessage.getString(401, "你没有权限修改白名单目录");
}
JsonMessage jsonMessage = save(value);
return jsonMessage.toString();
}
public JsonMessage save(String value) {
if (StrUtil.isEmpty(value)) {
return new JsonMessage(401, "白名单不能为空");
}
List<String> list = StrSpliter.splitTrim(value, "\n", true);
if (list == null || list.size() <= 0) {
return new JsonMessage(401, "白名单不能为空");
}
JSONArray jsonArray = new JSONArray();
for (String s : list) {
String val = String.format("/%s/", s);
val = val.replace("../", "");
val = FileUtil.normalize(val);
jsonArray.add(val);
}
String error = findStartsWith(jsonArray, 0);
if (error != null) {
return JsonMessage.getString(401, "白名单目录中不能存在包含关系:" + error);
return new JsonMessage(401, "白名单目录中不能存在包含关系:" + error);
}
systemService.saveWhitelistDirectory(jsonArray);
return JsonMessage.getString(200, "保存成功");
return new JsonMessage(200, "保存成功");
}
private String findStartsWith(JSONArray jsonArray, int start) {
String str = jsonArray.getString(start);
int len = jsonArray.size();

View File

@ -3,7 +3,7 @@ package cn.keepbx.jpom.controller.user;
import cn.hutool.core.util.StrUtil;
import cn.jiangzeyin.common.DefaultSystemLog;
import cn.jiangzeyin.common.JsonMessage;
import cn.keepbx.jpom.controller.BaseController;
import cn.keepbx.jpom.common.BaseController;
import cn.keepbx.jpom.model.UserModel;
import cn.keepbx.jpom.service.user.UserService;
import cn.keepbx.jpom.system.ConfigBean;
@ -36,6 +36,7 @@ public class UserInfoController extends BaseController {
*/
@RequestMapping(value = "updatePwd", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public String updatePwd(String oldPwd, String newPwd) {
UserModel userName = getUser();
if (ConfigBean.getInstance().safeMode) {
String parent = userName.getParent();
if (UserModel.SYSTEM_ADMIN.equals(parent)) {
@ -75,6 +76,7 @@ public class UserInfoController extends BaseController {
*/
@RequestMapping(value = "deleteUser", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public String deleteUser(String id) {
UserModel userName = getUser();
if (userName == null) {
return JsonMessage.getString(401, "系统异常:不能删除");
}
@ -99,6 +101,7 @@ public class UserInfoController extends BaseController {
*/
@RequestMapping(value = "addUser", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public String addUser(String id, String name, String manage, String password) {
UserModel userName = getUser();
if (!userName.isManage()) {
return JsonMessage.getString(400, "你还没有权限");
}
@ -150,6 +153,7 @@ public class UserInfoController extends BaseController {
*/
@RequestMapping(value = "updateUser", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public String updateUser(String id, String name, String manage, String password) {
UserModel userName = getUser();
if (!userName.isManage()) {
return JsonMessage.getString(400, "你还没有权限");
}

View File

@ -1,8 +1,9 @@
package cn.keepbx.jpom.controller.user;
import cn.jiangzeyin.common.JsonMessage;
import cn.keepbx.jpom.controller.BaseController;
import cn.keepbx.jpom.common.BaseController;
import cn.keepbx.jpom.model.ProjectInfoModel;
import cn.keepbx.jpom.model.UserModel;
import cn.keepbx.jpom.service.manage.ManageService;
import cn.keepbx.jpom.service.user.UserService;
import com.alibaba.fastjson.JSONArray;
@ -45,7 +46,7 @@ public class UserListController extends BaseController {
@RequestMapping(value = "getUserList", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public String getUserList() {
// boolean manager = userService.isManager("", getUserName());
UserModel userName = getUser();
if (!userName.isManage()) {
return JsonMessage.getString(400, "你没有对应权限!");
}

View File

@ -9,6 +9,8 @@ import com.alibaba.fastjson.JSONObject;
* @author jiangzeyin
*/
public class ProjectInfoModel {
public static final String NO_TOKEN = "no";
private String id;
private String name;
private String group;
@ -134,7 +136,7 @@ public class ProjectInfoModel {
*/
public String getToken() {
if (StrUtil.isEmpty(token)) {
token = "no";
token = NO_TOKEN;
}
return token;
}

View File

@ -3,7 +3,7 @@ package cn.keepbx.jpom.system;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.jiangzeyin.common.spring.SpringUtil;
import cn.keepbx.jpom.controller.BaseController;
import cn.keepbx.jpom.common.BaseController;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

View File

@ -31,6 +31,12 @@
name="userPwd">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block" style="margin-left: 0px;">
<textarea name="whitelistDirectory" placeholder="请输入项目存放路径白名单,回车支持输入多个路径"
class="layui-textarea"></textarea>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block" style="margin-left: 0px;">
<button class="layui-btn layui-btn-danger" lay-submit lay-filter="from_login"

View File

@ -83,30 +83,30 @@
<div class="layui-inline">
<label class="layui-form-label">Jvm参数</label>
<div class="layui-input-block">
<input type="text" name="jvm" placeholder="jvm参数" class="layui-input"
<input type="text" name="jvm" placeholder="jvm参数,非必填" class="layui-input"
value="#if($item)$!item.jvm#end">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">args</label>
<div class="layui-input-block">
<input type="text" name="args" placeholder="arg参数" class="layui-input"
<input type="text" name="args" placeholder="Main函数 args参数,非必填" class="layui-input"
value="#if($item)$!item.args#end">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">Token</label>
<label class="layui-form-label">WebHooks</label>
<div class="layui-input-block">
<input type="text" name="token" placeholder="对应接口的token没有请填写no" class="layui-input"
<input type="text" name="token" placeholder="关闭程序时自动请求没有请填写no" class="layui-input"
value="#if($item)$!item.token#end">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">Build标识</label>
<div class="layui-input-block">
<input type="text" name="buildTag" placeholder="Build标识" class="layui-input"
<input type="text" name="buildTag" placeholder="CodePipeline发布后oss中的文件标识,非必填" class="layui-input"
value="#if($item)$!item.buildTag#end">
</div>
</div>

View File

@ -23,7 +23,7 @@
<div class="layui-inline" style="width: 80%;height:30vh;">
<label class="layui-form-label">白名单列表</label>
<div class="layui-input-block auto">
<textarea name="value" placeholder="请输入内容"
<textarea name="value" placeholder="请输入项目存放路径白名单,回车支持输入多个路径,系统会自动过滤 ../ 路径"
class="layui-textarea auto">$!value</textarea>
</div>
</div>

View File

@ -72,17 +72,20 @@
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">管理项目</label>
<div class="layui-input-block">
#foreach($pItem in $projects)
<input type="checkbox" name="project" project="$pItem.id" value="$pItem.id"
title="$pItem.name">
#end
#if($projects && $projects.size()>0)
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">管理项目</label>
<div class="layui-input-block">
#foreach($pItem in $projects)
<input type="checkbox" name="project" project="$pItem.id" value="$pItem.id"
title="$pItem.name">
#end
</div>
</div>
</div>
</div>
#end
<input type="hidden" lay-submit lay-filter="submitUser" id="user_submit">
</form>
</div>