用户管理:支持在线维护系统用户
This commit is contained in:
parent
69d22f2c78
commit
0a3542dcac
|
@ -1,8 +1,7 @@
|
||||||
package com.xxl.job.admin.controller;
|
package com.xxl.job.admin.controller;
|
||||||
|
|
||||||
import com.xxl.job.admin.controller.annotation.PermessionLimit;
|
import com.xxl.job.admin.controller.annotation.PermessionLimit;
|
||||||
import com.xxl.job.admin.controller.interceptor.PermissionInterceptor;
|
import com.xxl.job.admin.service.LoginService;
|
||||||
import com.xxl.job.admin.core.util.I18nUtil;
|
|
||||||
import com.xxl.job.admin.service.XxlJobService;
|
import com.xxl.job.admin.service.XxlJobService;
|
||||||
import com.xxl.job.core.biz.model.ReturnT;
|
import com.xxl.job.core.biz.model.ReturnT;
|
||||||
import org.springframework.beans.propertyeditors.CustomDateEditor;
|
import org.springframework.beans.propertyeditors.CustomDateEditor;
|
||||||
|
@ -30,6 +29,9 @@ public class IndexController {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private XxlJobService xxlJobService;
|
private XxlJobService xxlJobService;
|
||||||
|
@Resource
|
||||||
|
private LoginService loginService;
|
||||||
|
|
||||||
|
|
||||||
@RequestMapping("/")
|
@RequestMapping("/")
|
||||||
public String index(Model model) {
|
public String index(Model model) {
|
||||||
|
@ -49,8 +51,8 @@ public class IndexController {
|
||||||
|
|
||||||
@RequestMapping("/toLogin")
|
@RequestMapping("/toLogin")
|
||||||
@PermessionLimit(limit=false)
|
@PermessionLimit(limit=false)
|
||||||
public String toLogin(Model model, HttpServletRequest request) {
|
public String toLogin(HttpServletRequest request, HttpServletResponse response) {
|
||||||
if (PermissionInterceptor.ifLogin(request)) {
|
if (loginService.ifLogin(request, response) != null) {
|
||||||
return "redirect:/";
|
return "redirect:/";
|
||||||
}
|
}
|
||||||
return "login";
|
return "login";
|
||||||
|
@ -60,33 +62,15 @@ public class IndexController {
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@PermessionLimit(limit=false)
|
@PermessionLimit(limit=false)
|
||||||
public ReturnT<String> loginDo(HttpServletRequest request, HttpServletResponse response, String userName, String password, String ifRemember){
|
public ReturnT<String> loginDo(HttpServletRequest request, HttpServletResponse response, String userName, String password, String ifRemember){
|
||||||
// valid
|
|
||||||
if (PermissionInterceptor.ifLogin(request)) {
|
|
||||||
return ReturnT.SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// param
|
|
||||||
if (userName==null || userName.trim().length()==0 || password==null || password.trim().length()==0){
|
|
||||||
return new ReturnT<String>(500, I18nUtil.getString("login_param_empty"));
|
|
||||||
}
|
|
||||||
boolean ifRem = (ifRemember!=null && ifRemember.trim().length()>0 && "on".equals(ifRemember))?true:false;
|
boolean ifRem = (ifRemember!=null && ifRemember.trim().length()>0 && "on".equals(ifRemember))?true:false;
|
||||||
|
return loginService.login(request, response, userName, password, ifRem);
|
||||||
// do login
|
|
||||||
boolean loginRet = PermissionInterceptor.login(response, userName, password, ifRem);
|
|
||||||
if (!loginRet) {
|
|
||||||
return new ReturnT<String>(500, I18nUtil.getString("login_param_unvalid"));
|
|
||||||
}
|
|
||||||
return ReturnT.SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value="logout", method=RequestMethod.POST)
|
@RequestMapping(value="logout", method=RequestMethod.POST)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
@PermessionLimit(limit=false)
|
@PermessionLimit(limit=false)
|
||||||
public ReturnT<String> logout(HttpServletRequest request, HttpServletResponse response){
|
public ReturnT<String> logout(HttpServletRequest request, HttpServletResponse response){
|
||||||
if (PermissionInterceptor.ifLogin(request)) {
|
return loginService.logout(request, response);
|
||||||
PermissionInterceptor.logout(request, response);
|
|
||||||
}
|
|
||||||
return ReturnT.SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("/help")
|
@RequestMapping("/help")
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
package com.xxl.job.admin.controller;
|
package com.xxl.job.admin.controller;
|
||||||
|
|
||||||
|
import com.xxl.job.admin.controller.annotation.PermessionLimit;
|
||||||
import com.xxl.job.admin.core.model.XxlJobGroup;
|
import com.xxl.job.admin.core.model.XxlJobGroup;
|
||||||
import com.xxl.job.admin.core.model.XxlJobUser;
|
import com.xxl.job.admin.core.model.XxlJobUser;
|
||||||
import com.xxl.job.admin.core.util.I18nUtil;
|
import com.xxl.job.admin.core.util.I18nUtil;
|
||||||
import com.xxl.job.admin.dao.XxlJobGroupDao;
|
import com.xxl.job.admin.dao.XxlJobGroupDao;
|
||||||
import com.xxl.job.admin.dao.XxlJobUserDao;
|
import com.xxl.job.admin.dao.XxlJobUserDao;
|
||||||
|
import com.xxl.job.admin.service.LoginService;
|
||||||
import com.xxl.job.core.biz.model.ReturnT;
|
import com.xxl.job.core.biz.model.ReturnT;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
|
@ -15,6 +17,7 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -32,6 +35,7 @@ public class UserController {
|
||||||
private XxlJobGroupDao xxlJobGroupDao;
|
private XxlJobGroupDao xxlJobGroupDao;
|
||||||
|
|
||||||
@RequestMapping
|
@RequestMapping
|
||||||
|
@PermessionLimit(adminuser = true)
|
||||||
public String index(Model model) {
|
public String index(Model model) {
|
||||||
|
|
||||||
// 执行器列表
|
// 执行器列表
|
||||||
|
@ -43,6 +47,7 @@ public class UserController {
|
||||||
|
|
||||||
@RequestMapping("/pageList")
|
@RequestMapping("/pageList")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
|
@PermessionLimit(adminuser = true)
|
||||||
public Map<String, Object> pageList(@RequestParam(required = false, defaultValue = "0") int start,
|
public Map<String, Object> pageList(@RequestParam(required = false, defaultValue = "0") int start,
|
||||||
@RequestParam(required = false, defaultValue = "10") int length,
|
@RequestParam(required = false, defaultValue = "10") int length,
|
||||||
String username) {
|
String username) {
|
||||||
|
@ -61,6 +66,7 @@ public class UserController {
|
||||||
|
|
||||||
@RequestMapping("/add")
|
@RequestMapping("/add")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
|
@PermessionLimit(adminuser = true)
|
||||||
public ReturnT<String> add(XxlJobUser xxlJobUser) {
|
public ReturnT<String> add(XxlJobUser xxlJobUser) {
|
||||||
|
|
||||||
// valid username
|
// valid username
|
||||||
|
@ -95,7 +101,14 @@ public class UserController {
|
||||||
|
|
||||||
@RequestMapping("/update")
|
@RequestMapping("/update")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ReturnT<String> update(XxlJobUser xxlJobUser) {
|
@PermessionLimit(adminuser = true)
|
||||||
|
public ReturnT<String> update(HttpServletRequest request, XxlJobUser xxlJobUser) {
|
||||||
|
|
||||||
|
// avoid opt login seft
|
||||||
|
XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY);
|
||||||
|
if (loginUser.getUsername().equals(xxlJobUser.getUsername())) {
|
||||||
|
return new ReturnT<String>(ReturnT.FAIL.getCode(), I18nUtil.getString("user_update_loginuser_limit"));
|
||||||
|
}
|
||||||
|
|
||||||
// valid password
|
// valid password
|
||||||
if (StringUtils.hasText(xxlJobUser.getPassword())) {
|
if (StringUtils.hasText(xxlJobUser.getPassword())) {
|
||||||
|
@ -116,9 +129,44 @@ public class UserController {
|
||||||
|
|
||||||
@RequestMapping("/remove")
|
@RequestMapping("/remove")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ReturnT<String> remove(int id) {
|
@PermessionLimit(adminuser = true)
|
||||||
|
public ReturnT<String> remove(HttpServletRequest request, int id) {
|
||||||
|
|
||||||
|
// avoid opt login seft
|
||||||
|
XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY);
|
||||||
|
if (loginUser.getId() == id) {
|
||||||
|
return new ReturnT<String>(ReturnT.FAIL.getCode(), I18nUtil.getString("user_update_loginuser_limit"));
|
||||||
|
}
|
||||||
|
|
||||||
xxlJobUserDao.delete(id);
|
xxlJobUserDao.delete(id);
|
||||||
return ReturnT.SUCCESS;
|
return ReturnT.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/updatePwd")
|
||||||
|
@ResponseBody
|
||||||
|
public ReturnT<String> updatePwd(HttpServletRequest request, String password){
|
||||||
|
|
||||||
|
// valid password
|
||||||
|
if (password==null || password.trim().length()==0){
|
||||||
|
return new ReturnT<String>(ReturnT.FAIL.getCode(), "密码不可为空");
|
||||||
|
}
|
||||||
|
password = password.trim();
|
||||||
|
if (!(password.length()>=4 && password.length()<=20)) {
|
||||||
|
return new ReturnT<String>(ReturnT.FAIL_CODE, I18nUtil.getString("system_lengh_limit")+"[4-20]" );
|
||||||
|
}
|
||||||
|
|
||||||
|
// md5 password
|
||||||
|
String md5Password = DigestUtils.md5DigestAsHex(password.getBytes());
|
||||||
|
|
||||||
|
// update pwd
|
||||||
|
XxlJobUser loginUser = (XxlJobUser) request.getAttribute(LoginService.LOGIN_IDENTITY_KEY);
|
||||||
|
|
||||||
|
// do write
|
||||||
|
XxlJobUser existUser = xxlJobUserDao.loadByUserName(loginUser.getUsername());
|
||||||
|
existUser.setPassword(md5Password);
|
||||||
|
xxlJobUserDao.update(existUser);
|
||||||
|
|
||||||
|
return ReturnT.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,4 +19,11 @@ public @interface PermessionLimit {
|
||||||
*/
|
*/
|
||||||
boolean limit() default true;
|
boolean limit() default true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 要求管理员权限
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean adminuser() default false;
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,68 +1,27 @@
|
||||||
package com.xxl.job.admin.controller.interceptor;
|
package com.xxl.job.admin.controller.interceptor;
|
||||||
|
|
||||||
import com.xxl.job.admin.controller.annotation.PermessionLimit;
|
import com.xxl.job.admin.controller.annotation.PermessionLimit;
|
||||||
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
|
import com.xxl.job.admin.core.model.XxlJobUser;
|
||||||
import com.xxl.job.admin.core.util.CookieUtil;
|
import com.xxl.job.admin.core.util.I18nUtil;
|
||||||
|
import com.xxl.job.admin.service.LoginService;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.DigestUtils;
|
|
||||||
import org.springframework.web.method.HandlerMethod;
|
import org.springframework.web.method.HandlerMethod;
|
||||||
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
|
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 权限拦截, 简易版
|
* 权限拦截
|
||||||
*
|
*
|
||||||
* @author xuxueli 2015-12-12 18:09:04
|
* @author xuxueli 2015-12-12 18:09:04
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class PermissionInterceptor extends HandlerInterceptorAdapter {
|
public class PermissionInterceptor extends HandlerInterceptorAdapter {
|
||||||
|
|
||||||
|
@Resource
|
||||||
public static final String LOGIN_IDENTITY_KEY = "XXL_JOB_LOGIN_IDENTITY";
|
private LoginService loginService;
|
||||||
private static String LOGIN_IDENTITY_TOKEN;
|
|
||||||
public static String getLoginIdentityToken() {
|
|
||||||
if (LOGIN_IDENTITY_TOKEN == null) {
|
|
||||||
String username = XxlJobAdminConfig.getAdminConfig().getLoginUsername();
|
|
||||||
String password = XxlJobAdminConfig.getAdminConfig().getLoginPassword();
|
|
||||||
|
|
||||||
// login token
|
|
||||||
String tokenTmp = DigestUtils.md5DigestAsHex(String.valueOf(username + "_" + password).getBytes()); //.getBytes("UTF-8")
|
|
||||||
tokenTmp = new BigInteger(1, tokenTmp.getBytes()).toString(16);
|
|
||||||
|
|
||||||
LOGIN_IDENTITY_TOKEN = tokenTmp;
|
|
||||||
}
|
|
||||||
return LOGIN_IDENTITY_TOKEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean login(HttpServletResponse response, String username, String password, boolean ifRemember){
|
|
||||||
|
|
||||||
// login token
|
|
||||||
String tokenTmp = DigestUtils.md5DigestAsHex(String.valueOf(username + "_" + password).getBytes());
|
|
||||||
tokenTmp = new BigInteger(1, tokenTmp.getBytes()).toString(16);
|
|
||||||
|
|
||||||
if (!getLoginIdentityToken().equals(tokenTmp)){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// do login
|
|
||||||
CookieUtil.set(response, LOGIN_IDENTITY_KEY, getLoginIdentityToken(), ifRemember);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
public static void logout(HttpServletRequest request, HttpServletResponse response){
|
|
||||||
CookieUtil.remove(request, response, LOGIN_IDENTITY_KEY);
|
|
||||||
}
|
|
||||||
public static boolean ifLogin(HttpServletRequest request){
|
|
||||||
String indentityInfo = CookieUtil.getValue(request, LOGIN_IDENTITY_KEY);
|
|
||||||
if (indentityInfo==null || !getLoginIdentityToken().equals(indentityInfo.trim())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||||
|
@ -71,14 +30,27 @@ public class PermissionInterceptor extends HandlerInterceptorAdapter {
|
||||||
return super.preHandle(request, response, handler);
|
return super.preHandle(request, response, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ifLogin(request)) {
|
// if need login
|
||||||
|
boolean needLogin = true;
|
||||||
|
boolean needAdminuser = false;
|
||||||
HandlerMethod method = (HandlerMethod)handler;
|
HandlerMethod method = (HandlerMethod)handler;
|
||||||
PermessionLimit permission = method.getMethodAnnotation(PermessionLimit.class);
|
PermessionLimit permission = method.getMethodAnnotation(PermessionLimit.class);
|
||||||
if (permission == null || permission.limit()) {
|
if (permission!=null) {
|
||||||
|
needLogin = permission.limit();
|
||||||
|
needAdminuser = permission.adminuser();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needLogin) {
|
||||||
|
XxlJobUser loginUser = loginService.ifLogin(request, response);
|
||||||
|
if (loginUser == null) {
|
||||||
response.sendRedirect(request.getContextPath() + "/toLogin");
|
response.sendRedirect(request.getContextPath() + "/toLogin");
|
||||||
//request.getRequestDispatcher("/toLogin").forward(request, response);
|
//request.getRequestDispatcher("/toLogin").forward(request, response);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (needAdminuser && loginUser.getRole()!=1) {
|
||||||
|
throw new RuntimeException(I18nUtil.getString("system_permission_limit"));
|
||||||
|
}
|
||||||
|
request.setAttribute(LoginService.LOGIN_IDENTITY_KEY, loginUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.preHandle(request, response, handler);
|
return super.preHandle(request, response, handler);
|
||||||
|
|
|
@ -30,13 +30,6 @@ public class XxlJobAdminConfig implements InitializingBean{
|
||||||
}
|
}
|
||||||
|
|
||||||
// conf
|
// conf
|
||||||
|
|
||||||
@Value("${xxl.job.login.username}")
|
|
||||||
private String loginUsername;
|
|
||||||
|
|
||||||
@Value("${xxl.job.login.password}")
|
|
||||||
private String loginPassword;
|
|
||||||
|
|
||||||
@Value("${xxl.job.i18n}")
|
@Value("${xxl.job.i18n}")
|
||||||
private String i18n;
|
private String i18n;
|
||||||
|
|
||||||
|
@ -61,13 +54,6 @@ public class XxlJobAdminConfig implements InitializingBean{
|
||||||
@Resource
|
@Resource
|
||||||
private JavaMailSender mailSender;
|
private JavaMailSender mailSender;
|
||||||
|
|
||||||
public String getLoginUsername() {
|
|
||||||
return loginUsername;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLoginPassword() {
|
|
||||||
return loginPassword;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getI18n() {
|
public String getI18n() {
|
||||||
return i18n;
|
return i18n;
|
||||||
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
package com.xxl.job.admin.service;
|
||||||
|
|
||||||
|
import com.xxl.job.admin.core.model.XxlJobUser;
|
||||||
|
import com.xxl.job.admin.core.util.CookieUtil;
|
||||||
|
import com.xxl.job.admin.core.util.I18nUtil;
|
||||||
|
import com.xxl.job.admin.core.util.JacksonUtil;
|
||||||
|
import com.xxl.job.admin.dao.XxlJobUserDao;
|
||||||
|
import com.xxl.job.core.biz.model.ReturnT;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.util.DigestUtils;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author xuxueli 2019-05-04 22:13:264
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class LoginService {
|
||||||
|
|
||||||
|
public static final String LOGIN_IDENTITY_KEY = "XXL_JOB_LOGIN_IDENTITY";
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private XxlJobUserDao xxlJobUserDao;
|
||||||
|
|
||||||
|
|
||||||
|
private String makeToken(XxlJobUser xxlJobUser){
|
||||||
|
String tokenJson = JacksonUtil.writeValueAsString(xxlJobUser);
|
||||||
|
String tokenHex = new BigInteger(tokenJson.getBytes()).toString(16);
|
||||||
|
return tokenHex;
|
||||||
|
}
|
||||||
|
private XxlJobUser parseToken(String tokenHex){
|
||||||
|
XxlJobUser xxlJobUser = null;
|
||||||
|
if (tokenHex != null) {
|
||||||
|
String tokenJson = new String(new BigInteger(tokenHex, 16).toByteArray()); // username_password(md5)
|
||||||
|
xxlJobUser = JacksonUtil.readValue(tokenJson, XxlJobUser.class);
|
||||||
|
}
|
||||||
|
return xxlJobUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ReturnT<String> login(HttpServletRequest request, HttpServletResponse response, String username, String password, boolean ifRemember){
|
||||||
|
|
||||||
|
// param
|
||||||
|
if (username==null || username.trim().length()==0 || password==null || password.trim().length()==0){
|
||||||
|
return new ReturnT<String>(500, I18nUtil.getString("login_param_empty"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// valid passowrd
|
||||||
|
XxlJobUser xxlJobUser = xxlJobUserDao.loadByUserName(username);
|
||||||
|
if (xxlJobUser == null) {
|
||||||
|
return new ReturnT<String>(500, I18nUtil.getString("login_param_unvalid"));
|
||||||
|
}
|
||||||
|
String passwordMd5 = DigestUtils.md5DigestAsHex(password.getBytes());
|
||||||
|
if (!passwordMd5.equals(xxlJobUser.getPassword())) {
|
||||||
|
return new ReturnT<String>(500, I18nUtil.getString("login_param_unvalid"));
|
||||||
|
}
|
||||||
|
|
||||||
|
String loginToken = makeToken(xxlJobUser);
|
||||||
|
|
||||||
|
// do login
|
||||||
|
CookieUtil.set(response, LOGIN_IDENTITY_KEY, loginToken, ifRemember);
|
||||||
|
return ReturnT.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* logout
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
*/
|
||||||
|
public ReturnT<String> logout(HttpServletRequest request, HttpServletResponse response){
|
||||||
|
CookieUtil.remove(request, response, LOGIN_IDENTITY_KEY);
|
||||||
|
return ReturnT.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* logout
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public XxlJobUser ifLogin(HttpServletRequest request, HttpServletResponse response){
|
||||||
|
String cookieToken = CookieUtil.getValue(request, LOGIN_IDENTITY_KEY);
|
||||||
|
if (cookieToken != null) {
|
||||||
|
XxlJobUser cookieUser = null;
|
||||||
|
try {
|
||||||
|
cookieUser = parseToken(cookieToken);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logout(request, response);
|
||||||
|
}
|
||||||
|
if (cookieUser != null) {
|
||||||
|
XxlJobUser dbUser = xxlJobUserDao.loadByUserName(cookieUser.getUsername());
|
||||||
|
if (dbUser != null) {
|
||||||
|
if (cookieUser.getPassword().equals(dbUser.getPassword())) {
|
||||||
|
return dbUser;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -32,6 +32,7 @@ system_not_found=不存在
|
||||||
system_nav=导航
|
system_nav=导航
|
||||||
system_digits=整数
|
system_digits=整数
|
||||||
system_lengh_limit=长度限制
|
system_lengh_limit=长度限制
|
||||||
|
system_permission_limit=权限拦截
|
||||||
|
|
||||||
## daterangepicker
|
## daterangepicker
|
||||||
daterangepicker_ranges_recent_hour=最近一小时
|
daterangepicker_ranges_recent_hour=最近一小时
|
||||||
|
@ -241,7 +242,9 @@ user_permission=权限
|
||||||
user_add=新增用户
|
user_add=新增用户
|
||||||
user_update=更新用户
|
user_update=更新用户
|
||||||
user_username_repeat=账号重复
|
user_username_repeat=账号重复
|
||||||
|
user_username_valid=限制以小写字母开头,由小写字母、数字组成
|
||||||
user_password_update_placeholder=请输入新密码,为空则不更新密码
|
user_password_update_placeholder=请输入新密码,为空则不更新密码
|
||||||
|
user_update_loginuser_limit=禁止操作当前登录账号
|
||||||
|
|
||||||
## help
|
## help
|
||||||
job_help=使用教程
|
job_help=使用教程
|
||||||
|
|
|
@ -32,6 +32,7 @@ system_not_found=not exist
|
||||||
system_nav=Navigation
|
system_nav=Navigation
|
||||||
system_digits=digits
|
system_digits=digits
|
||||||
system_lengh_limit=Length limit
|
system_lengh_limit=Length limit
|
||||||
|
system_permission_limit=Permission limit
|
||||||
|
|
||||||
## daterangepicker
|
## daterangepicker
|
||||||
daterangepicker_ranges_recent_hour=recent one hour
|
daterangepicker_ranges_recent_hour=recent one hour
|
||||||
|
@ -241,7 +242,9 @@ user_permission=Permission
|
||||||
user_add=Add User
|
user_add=Add User
|
||||||
user_update=Edit User
|
user_update=Edit User
|
||||||
user_username_repeat=Username Repeat
|
user_username_repeat=Username Repeat
|
||||||
|
user_username_valid=Restrictions start with a lowercase letter and consist of lowercase letters and Numbers
|
||||||
user_password_update_placeholder=Please input password, empty means not update
|
user_password_update_placeholder=Please input password, empty means not update
|
||||||
|
user_update_loginuser_limit=Operation of current login account is not allowed
|
||||||
|
|
||||||
## help
|
## help
|
||||||
job_help=Tutorial
|
job_help=Tutorial
|
||||||
|
|
|
@ -89,4 +89,68 @@ $(function(){
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// update pwd
|
||||||
|
$('#updatePwd').on('click', function(){
|
||||||
|
$('#updatePwdModal').modal({backdrop: false, keyboard: false}).modal('show');
|
||||||
|
});
|
||||||
|
var updatePwdModalValidate = $("#updatePwdModal .form").validate({
|
||||||
|
errorElement : 'span',
|
||||||
|
errorClass : 'help-block',
|
||||||
|
focusInvalid : true,
|
||||||
|
rules : {
|
||||||
|
password : {
|
||||||
|
required : true ,
|
||||||
|
rangelength:[4,50]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
messages : {
|
||||||
|
password : {
|
||||||
|
required : '请输入密码' ,
|
||||||
|
rangelength : "密码长度限制为4~50"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
highlight : function(element) {
|
||||||
|
$(element).closest('.form-group').addClass('has-error');
|
||||||
|
},
|
||||||
|
success : function(label) {
|
||||||
|
label.closest('.form-group').removeClass('has-error');
|
||||||
|
label.remove();
|
||||||
|
},
|
||||||
|
errorPlacement : function(error, element) {
|
||||||
|
element.parent('div').append(error);
|
||||||
|
},
|
||||||
|
submitHandler : function(form) {
|
||||||
|
$.post(base_url + "/user/updatePwd", $("#updatePwdModal .form").serialize(), function(data, status) {
|
||||||
|
if (data.code == 200) {
|
||||||
|
$('#updatePwdModal').modal('hide');
|
||||||
|
|
||||||
|
layer.msg( '修改密码成功,即将注销登陆' );
|
||||||
|
setTimeout(function(){
|
||||||
|
$.post(base_url + "/logout", function(data, status) {
|
||||||
|
if (data.code == 200) {
|
||||||
|
window.location.href = base_url + "/";
|
||||||
|
} else {
|
||||||
|
layer.open({
|
||||||
|
icon: '2',
|
||||||
|
content: (data.msg||'注销失败')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 500);
|
||||||
|
} else {
|
||||||
|
layer.open({
|
||||||
|
icon: '2',
|
||||||
|
content: (data.msg||'修改密码失败')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$("#updatePwdModal").on('hide.bs.modal', function () {
|
||||||
|
$("#updatePwdModal .form")[0].reset();
|
||||||
|
updatePwdModalValidate.resetForm();
|
||||||
|
$("#updatePwdModal .form .form-group").removeClass("has-error");
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -50,7 +50,7 @@ $(function() {
|
||||||
{
|
{
|
||||||
"data": 'permission',
|
"data": 'permission',
|
||||||
"width":'10%',
|
"width":'10%',
|
||||||
"visible" : true
|
"visible" : false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"data": I18n.system_opt ,
|
"data": I18n.system_opt ,
|
||||||
|
@ -144,6 +144,12 @@ $(function() {
|
||||||
$("#addModal .form input[name='permission']").prop("checked",false);
|
$("#addModal .form input[name='permission']").prop("checked",false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
jQuery.validator.addMethod("myValid01", function(value, element) {
|
||||||
|
var length = value.length;
|
||||||
|
var valid = /^[a-z][a-z0-9]*$/;
|
||||||
|
return this.optional(element) || valid.test(value);
|
||||||
|
}, I18n.user_username_valid );
|
||||||
|
|
||||||
// add
|
// add
|
||||||
$(".add").click(function(){
|
$(".add").click(function(){
|
||||||
$('#addModal').modal({backdrop: false, keyboard: false}).modal('show');
|
$('#addModal').modal({backdrop: false, keyboard: false}).modal('show');
|
||||||
|
@ -155,7 +161,8 @@ $(function() {
|
||||||
rules : {
|
rules : {
|
||||||
username : {
|
username : {
|
||||||
required : true,
|
required : true,
|
||||||
rangelength:[4, 20]
|
rangelength:[4, 20],
|
||||||
|
myValid01: true
|
||||||
},
|
},
|
||||||
password : {
|
password : {
|
||||||
required : true,
|
required : true,
|
||||||
|
|
|
@ -49,6 +49,8 @@
|
||||||
<script src="${request.contextPath}/static/adminlte/bower_components/PACE/pace.min.js"></script>
|
<script src="${request.contextPath}/static/adminlte/bower_components/PACE/pace.min.js"></script>
|
||||||
<#-- jquery cookie -->
|
<#-- jquery cookie -->
|
||||||
<script src="${request.contextPath}/static/plugins/jquery/jquery.cookie.js"></script>
|
<script src="${request.contextPath}/static/plugins/jquery/jquery.cookie.js"></script>
|
||||||
|
<#-- jquery.validate -->
|
||||||
|
<script src="${request.contextPath}/static/plugins/jquery/jquery.validate.min.js"></script>
|
||||||
|
|
||||||
<#-- layer -->
|
<#-- layer -->
|
||||||
<script src="${request.contextPath}/static/plugins/layer/layer.js"></script>
|
<script src="${request.contextPath}/static/plugins/layer/layer.js"></script>
|
||||||
|
@ -79,16 +81,49 @@
|
||||||
|
|
||||||
<div class="navbar-custom-menu">
|
<div class="navbar-custom-menu">
|
||||||
<ul class="nav navbar-nav">
|
<ul class="nav navbar-nav">
|
||||||
<li class="dropdown user user-menu">
|
<#-- login user -->
|
||||||
<a href=";" id="logoutBtn" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
|
<li class="dropdown">
|
||||||
<span class="hidden-xs">${I18n.logout_btn}</span>
|
<a href="javascript:" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
|
||||||
|
欢迎 ${Request["XXL_JOB_LOGIN_IDENTITY"].username}
|
||||||
|
<span class="caret"></span>
|
||||||
</a>
|
</a>
|
||||||
|
<ul class="dropdown-menu" role="menu">
|
||||||
|
<li id="updatePwd" ><a href="javascript:">修改密码</a></li>
|
||||||
|
<li id="logoutBtn" ><a href="javascript:">${I18n.logout_btn}</a></li>
|
||||||
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
<!-- 修改密码.模态框 -->
|
||||||
|
<div class="modal fade" id="updatePwdModal" tabindex="-1" role="dialog" aria-hidden="true">
|
||||||
|
<div class="modal-dialog ">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h4 class="modal-title" >修改密码</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form class="form-horizontal form" role="form" >
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="lastname" class="col-sm-2 control-label">新密码<font color="red">*</font></label>
|
||||||
|
<div class="col-sm-10"><input type="text" class="form-control" name="password" placeholder="请输入新密码" maxlength="100" ></div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-offset-3 col-sm-6">
|
||||||
|
<button type="submit" class="btn btn-primary" >保存</button>
|
||||||
|
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</#macro>
|
</#macro>
|
||||||
|
|
||||||
<#macro commonLeft pageName >
|
<#macro commonLeft pageName >
|
||||||
|
@ -103,7 +138,9 @@
|
||||||
<li class="nav-click <#if pageName == "jobinfo">active</#if>" ><a href="${request.contextPath}/jobinfo"><i class="fa fa-circle-o text-yellow"></i><span>${I18n.jobinfo_name}</span></a></li>
|
<li class="nav-click <#if pageName == "jobinfo">active</#if>" ><a href="${request.contextPath}/jobinfo"><i class="fa fa-circle-o text-yellow"></i><span>${I18n.jobinfo_name}</span></a></li>
|
||||||
<li class="nav-click <#if pageName == "joblog">active</#if>" ><a href="${request.contextPath}/joblog"><i class="fa fa-circle-o text-green"></i><span>${I18n.joblog_name}</span></a></li>
|
<li class="nav-click <#if pageName == "joblog">active</#if>" ><a href="${request.contextPath}/joblog"><i class="fa fa-circle-o text-green"></i><span>${I18n.joblog_name}</span></a></li>
|
||||||
<li class="nav-click <#if pageName == "jobgroup">active</#if>" ><a href="${request.contextPath}/jobgroup"><i class="fa fa-circle-o text-red"></i><span>${I18n.jobgroup_name}</span></a></li>
|
<li class="nav-click <#if pageName == "jobgroup">active</#if>" ><a href="${request.contextPath}/jobgroup"><i class="fa fa-circle-o text-red"></i><span>${I18n.jobgroup_name}</span></a></li>
|
||||||
|
<#if Request["XXL_JOB_LOGIN_IDENTITY"].role == 1>
|
||||||
<li class="nav-click <#if pageName == "user">active</#if>" ><a href="${request.contextPath}/user"><i class="fa fa-circle-o text-purple"></i><span>${I18n.user_manage}</span></a></li>
|
<li class="nav-click <#if pageName == "user">active</#if>" ><a href="${request.contextPath}/user"><i class="fa fa-circle-o text-purple"></i><span>${I18n.user_manage}</span></a></li>
|
||||||
|
</#if>
|
||||||
<li class="nav-click <#if pageName == "help">active</#if>" ><a href="${request.contextPath}/help"><i class="fa fa-circle-o text-gray"></i><span>${I18n.job_help}</span></a></li>
|
<li class="nav-click <#if pageName == "help">active</#if>" ><a href="${request.contextPath}/help"><i class="fa fa-circle-o text-gray"></i><span>${I18n.job_help}</span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -194,8 +194,6 @@
|
||||||
<!-- DataTables -->
|
<!-- DataTables -->
|
||||||
<script src="${request.contextPath}/static/adminlte/bower_components/datatables.net/js/jquery.dataTables.min.js"></script>
|
<script src="${request.contextPath}/static/adminlte/bower_components/datatables.net/js/jquery.dataTables.min.js"></script>
|
||||||
<script src="${request.contextPath}/static/adminlte/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
|
<script src="${request.contextPath}/static/adminlte/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
|
||||||
<#-- jquery.validate -->
|
|
||||||
<script src="${request.contextPath}/static/plugins/jquery/jquery.validate.min.js"></script>
|
|
||||||
<script src="${request.contextPath}/static/js/jobgroup.index.1.js"></script>
|
<script src="${request.contextPath}/static/js/jobgroup.index.1.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -413,7 +413,6 @@ exit 0
|
||||||
<!-- DataTables -->
|
<!-- DataTables -->
|
||||||
<script src="${request.contextPath}/static/adminlte/bower_components/datatables.net/js/jquery.dataTables.min.js"></script>
|
<script src="${request.contextPath}/static/adminlte/bower_components/datatables.net/js/jquery.dataTables.min.js"></script>
|
||||||
<script src="${request.contextPath}/static/adminlte/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
|
<script src="${request.contextPath}/static/adminlte/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
|
||||||
<script src="${request.contextPath}/static/plugins/jquery/jquery.validate.min.js"></script>
|
|
||||||
<!-- moment -->
|
<!-- moment -->
|
||||||
<script src="${request.contextPath}/static/adminlte/bower_components/moment/moment.min.js"></script>
|
<script src="${request.contextPath}/static/adminlte/bower_components/moment/moment.min.js"></script>
|
||||||
<script src="${request.contextPath}/static/js/jobinfo.index.1.js"></script>
|
<script src="${request.contextPath}/static/js/jobinfo.index.1.js"></script>
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<@netCommon.commonScript />
|
<@netCommon.commonScript />
|
||||||
<script src="${request.contextPath}/static/plugins/jquery/jquery.validate.min.js"></script>
|
|
||||||
<script src="${request.contextPath}/static/adminlte/plugins/iCheck/icheck.min.js"></script>
|
<script src="${request.contextPath}/static/adminlte/plugins/iCheck/icheck.min.js"></script>
|
||||||
<script src="${request.contextPath}/static/js/login.1.js"></script>
|
<script src="${request.contextPath}/static/js/login.1.js"></script>
|
||||||
|
|
||||||
|
|
|
@ -173,7 +173,6 @@
|
||||||
<!-- DataTables -->
|
<!-- DataTables -->
|
||||||
<script src="${request.contextPath}/static/adminlte/bower_components/datatables.net/js/jquery.dataTables.min.js"></script>
|
<script src="${request.contextPath}/static/adminlte/bower_components/datatables.net/js/jquery.dataTables.min.js"></script>
|
||||||
<script src="${request.contextPath}/static/adminlte/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
|
<script src="${request.contextPath}/static/adminlte/bower_components/datatables.net-bs/js/dataTables.bootstrap.min.js"></script>
|
||||||
<script src="${request.contextPath}/static/plugins/jquery/jquery.validate.min.js"></script>
|
|
||||||
<script src="${request.contextPath}/static/js/user.index.1.js"></script>
|
<script src="${request.contextPath}/static/js/user.index.1.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package com.xxl.job.admin.controller;
|
package com.xxl.job.admin.controller;
|
||||||
|
|
||||||
import com.xxl.job.admin.controller.interceptor.PermissionInterceptor;
|
import com.xxl.job.admin.service.LoginService;
|
||||||
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
@ -22,10 +21,10 @@ public class JobInfoControllerTest extends AbstractSpringMvcTest {
|
||||||
MvcResult ret = mockMvc.perform(
|
MvcResult ret = mockMvc.perform(
|
||||||
post("/login")
|
post("/login")
|
||||||
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
|
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
|
||||||
.param("userName", XxlJobAdminConfig.getAdminConfig().getLoginUsername())
|
.param("userName", "admin")
|
||||||
.param("password", XxlJobAdminConfig.getAdminConfig().getLoginPassword())
|
.param("password", "123456")
|
||||||
).andReturn();
|
).andReturn();
|
||||||
cookie = ret.getResponse().getCookie(PermissionInterceptor.LOGIN_IDENTITY_KEY);
|
cookie = ret.getResponse().getCookie(LoginService.LOGIN_IDENTITY_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in New Issue