Browse Source

用户管理:支持在线维护系统用户

xuxueli 5 years ago
parent
commit
0a3542dcac

+ 8 - 24
xxl-job-admin/src/main/java/com/xxl/job/admin/controller/IndexController.java

@@ -1,8 +1,7 @@
 package com.xxl.job.admin.controller;
 
 import com.xxl.job.admin.controller.annotation.PermessionLimit;
-import com.xxl.job.admin.controller.interceptor.PermissionInterceptor;
-import com.xxl.job.admin.core.util.I18nUtil;
+import com.xxl.job.admin.service.LoginService;
 import com.xxl.job.admin.service.XxlJobService;
 import com.xxl.job.core.biz.model.ReturnT;
 import org.springframework.beans.propertyeditors.CustomDateEditor;
@@ -30,6 +29,9 @@ public class IndexController {
 
 	@Resource
 	private XxlJobService xxlJobService;
+	@Resource
+	private LoginService loginService;
+
 
 	@RequestMapping("/")
 	public String index(Model model) {
@@ -49,8 +51,8 @@ public class IndexController {
 	
 	@RequestMapping("/toLogin")
 	@PermessionLimit(limit=false)
-	public String toLogin(Model model, HttpServletRequest request) {
-		if (PermissionInterceptor.ifLogin(request)) {
+	public String toLogin(HttpServletRequest request, HttpServletResponse response) {
+		if (loginService.ifLogin(request, response) != null) {
 			return "redirect:/";
 		}
 		return "login";
@@ -60,33 +62,15 @@ public class IndexController {
 	@ResponseBody
 	@PermessionLimit(limit=false)
 	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;
-
-		// 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;
+		return loginService.login(request, response, userName, password, ifRem);
 	}
 	
 	@RequestMapping(value="logout", method=RequestMethod.POST)
 	@ResponseBody
 	@PermessionLimit(limit=false)
 	public ReturnT<String> logout(HttpServletRequest request, HttpServletResponse response){
-		if (PermissionInterceptor.ifLogin(request)) {
-			PermissionInterceptor.logout(request, response);
-		}
-		return ReturnT.SUCCESS;
+		return loginService.logout(request, response);
 	}
 	
 	@RequestMapping("/help")

+ 50 - 2
xxl-job-admin/src/main/java/com/xxl/job/admin/controller/UserController.java

@@ -1,10 +1,12 @@
 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.XxlJobUser;
 import com.xxl.job.admin.core.util.I18nUtil;
 import com.xxl.job.admin.dao.XxlJobGroupDao;
 import com.xxl.job.admin.dao.XxlJobUserDao;
+import com.xxl.job.admin.service.LoginService;
 import com.xxl.job.core.biz.model.ReturnT;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
@@ -15,6 +17,7 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.ResponseBody;
 
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -32,6 +35,7 @@ public class UserController {
     private XxlJobGroupDao xxlJobGroupDao;
 
     @RequestMapping
+    @PermessionLimit(adminuser = true)
     public String index(Model model) {
 
         // 执行器列表
@@ -43,6 +47,7 @@ public class UserController {
 
     @RequestMapping("/pageList")
     @ResponseBody
+    @PermessionLimit(adminuser = true)
     public Map<String, Object> pageList(@RequestParam(required = false, defaultValue = "0") int start,
                                         @RequestParam(required = false, defaultValue = "10") int length,
                                         String username) {
@@ -61,6 +66,7 @@ public class UserController {
 
     @RequestMapping("/add")
     @ResponseBody
+    @PermessionLimit(adminuser = true)
     public ReturnT<String> add(XxlJobUser xxlJobUser) {
 
         // valid username
@@ -95,7 +101,14 @@ public class UserController {
 
     @RequestMapping("/update")
     @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
         if (StringUtils.hasText(xxlJobUser.getPassword())) {
@@ -116,9 +129,44 @@ public class UserController {
 
     @RequestMapping("/remove")
     @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);
         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;
+    }
+
 }

+ 7 - 0
xxl-job-admin/src/main/java/com/xxl/job/admin/controller/annotation/PermessionLimit.java

@@ -19,4 +19,11 @@ public @interface PermessionLimit {
 	 */
 	boolean limit() default true;
 
+	/**
+	 * 要求管理员权限
+	 *
+	 * @return
+	 */
+	boolean adminuser() default false;
+
 }

+ 26 - 54
xxl-job-admin/src/main/java/com/xxl/job/admin/controller/interceptor/PermissionInterceptor.java

@@ -1,68 +1,27 @@
 package com.xxl.job.admin.controller.interceptor;
 
 import com.xxl.job.admin.controller.annotation.PermessionLimit;
-import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
-import com.xxl.job.admin.core.util.CookieUtil;
+import com.xxl.job.admin.core.model.XxlJobUser;
+import com.xxl.job.admin.core.util.I18nUtil;
+import com.xxl.job.admin.service.LoginService;
 import org.springframework.stereotype.Component;
-import org.springframework.util.DigestUtils;
 import org.springframework.web.method.HandlerMethod;
 import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
 
+import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import java.math.BigInteger;
 
 /**
- * 权限拦截, 简易版
+ * 权限拦截
  *
  * @author xuxueli 2015-12-12 18:09:04
  */
 @Component
 public class PermissionInterceptor extends HandlerInterceptorAdapter {
 
-
-	public static final String LOGIN_IDENTITY_KEY = "XXL_JOB_LOGIN_IDENTITY";
-	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;
-	}
-
-
+	@Resource
+	private LoginService loginService;
 
 	@Override
 	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
@@ -70,17 +29,30 @@ public class PermissionInterceptor extends HandlerInterceptorAdapter {
 		if (!(handler instanceof HandlerMethod)) {
 			return super.preHandle(request, response, handler);
 		}
-		
-		if (!ifLogin(request)) {
-			HandlerMethod method = (HandlerMethod)handler;
-			PermessionLimit permission = method.getMethodAnnotation(PermessionLimit.class);
-			if (permission == null || permission.limit()) {
+
+		// if need login
+		boolean needLogin = true;
+		boolean needAdminuser = false;
+		HandlerMethod method = (HandlerMethod)handler;
+		PermessionLimit permission = method.getMethodAnnotation(PermessionLimit.class);
+		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");
 				//request.getRequestDispatcher("/toLogin").forward(request, response);
 				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);
 	}
 	

+ 0 - 14
xxl-job-admin/src/main/java/com/xxl/job/admin/core/conf/XxlJobAdminConfig.java

@@ -30,13 +30,6 @@ public class XxlJobAdminConfig implements InitializingBean{
     }
 
     // conf
-
-    @Value("${xxl.job.login.username}")
-    private String loginUsername;
-
-    @Value("${xxl.job.login.password}")
-    private String loginPassword;
-
     @Value("${xxl.job.i18n}")
     private String i18n;
 
@@ -61,13 +54,6 @@ public class XxlJobAdminConfig implements InitializingBean{
     @Resource
     private JavaMailSender mailSender;
 
-    public String getLoginUsername() {
-        return loginUsername;
-    }
-
-    public String getLoginPassword() {
-        return loginPassword;
-    }
 
     public String getI18n() {
         return i18n;

+ 107 - 0
xxl-job-admin/src/main/java/com/xxl/job/admin/service/LoginService.java

@@ -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;
+    }
+
+
+}

+ 3 - 0
xxl-job-admin/src/main/resources/i18n/message.properties

@@ -32,6 +32,7 @@ system_not_found=不存在
 system_nav=导航
 system_digits=整数
 system_lengh_limit=长度限制
+system_permission_limit=权限拦截
 
 ## daterangepicker
 daterangepicker_ranges_recent_hour=最近一小时
@@ -241,7 +242,9 @@ user_permission=权限
 user_add=新增用户
 user_update=更新用户
 user_username_repeat=账号重复
+user_username_valid=限制以小写字母开头,由小写字母、数字组成
 user_password_update_placeholder=请输入新密码,为空则不更新密码
+user_update_loginuser_limit=禁止操作当前登录账号
 
 ## help
 job_help=使用教程

+ 3 - 0
xxl-job-admin/src/main/resources/i18n/message_en.properties

@@ -32,6 +32,7 @@ system_not_found=not exist
 system_nav=Navigation
 system_digits=digits
 system_lengh_limit=Length limit
+system_permission_limit=Permission limit
 
 ## daterangepicker
 daterangepicker_ranges_recent_hour=recent one hour
@@ -241,7 +242,9 @@ user_permission=Permission
 user_add=Add User
 user_update=Edit User
 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_update_loginuser_limit=Operation of current login account is not allowed
 
 ## help
 job_help=Tutorial

+ 64 - 0
xxl-job-admin/src/main/resources/static/js/common.1.js

@@ -88,5 +88,69 @@ $(function(){
 	 	$('body').addClass('sidebar-collapse');
 	 }
 	 */
+
+
+    // 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");
+    });
 	
 });

+ 9 - 2
xxl-job-admin/src/main/resources/static/js/user.index.1.js

@@ -50,7 +50,7 @@ $(function() {
 	                {
 	                	"data": 'permission',
 						"width":'10%',
-	                	"visible" : true
+	                	"visible" : false
 	                },
 	                {
 						"data": I18n.system_opt ,
@@ -144,6 +144,12 @@ $(function() {
         $("#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").click(function(){
 		$('#addModal').modal({backdrop: false, keyboard: false}).modal('show');
@@ -155,7 +161,8 @@ $(function() {
         rules : {
             username : {
 				required : true,
-                rangelength:[4, 20]
+                rangelength:[4, 20],
+                myValid01: true
 			},
             password : {
                 required : true,

+ 43 - 6
xxl-job-admin/src/main/resources/templates/common/common.macro.ftl

@@ -49,6 +49,8 @@
     <script src="${request.contextPath}/static/adminlte/bower_components/PACE/pace.min.js"></script>
     <#-- jquery cookie -->
 	<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 -->
 	<script src="${request.contextPath}/static/plugins/layer/layer.js"></script>
@@ -79,16 +81,49 @@
 
           	<div class="navbar-custom-menu">
 				<ul class="nav navbar-nav">
-					<li class="dropdown user user-menu">
-	                    <a href=";" id="logoutBtn" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
-                      		<span class="hidden-xs">${I18n.logout_btn}</span>
-	                    </a>
-					</li>
+					<#-- login user -->
+                    <li class="dropdown">
+                        <a href="javascript:" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
+                            欢迎 ${Request["XXL_JOB_LOGIN_IDENTITY"].username}
+                            <span class="caret"></span>
+                        </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>
 				</ul>
 			</div>
 
 		</nav>
 	</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 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 == "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 == "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 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>
+				</#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>
 			</ul>
 		</section>

+ 0 - 2
xxl-job-admin/src/main/resources/templates/jobgroup/jobgroup.index.ftl

@@ -194,8 +194,6 @@
 <!-- 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-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>
 </body>
 </html>

+ 0 - 1
xxl-job-admin/src/main/resources/templates/jobinfo/jobinfo.index.ftl

@@ -413,7 +413,6 @@ exit 0
 <!-- 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-bs/js/dataTables.bootstrap.min.js"></script>
-<script src="${request.contextPath}/static/plugins/jquery/jquery.validate.min.js"></script>
 <!-- moment -->
 <script src="${request.contextPath}/static/adminlte/bower_components/moment/moment.min.js"></script>
 <script src="${request.contextPath}/static/js/jobinfo.index.1.js"></script>

+ 0 - 1
xxl-job-admin/src/main/resources/templates/login.ftl

@@ -38,7 +38,6 @@
 		</form>
 	</div>
 <@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/js/login.1.js"></script>
 

+ 0 - 1
xxl-job-admin/src/main/resources/templates/user/user.index.ftl

@@ -173,7 +173,6 @@
 <!-- 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-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>
 </body>
 </html>

+ 4 - 5
xxl-job-admin/src/test/java/com/xxl/job/admin/controller/JobInfoControllerTest.java

@@ -1,7 +1,6 @@
 package com.xxl.job.admin.controller;
 
-import com.xxl.job.admin.controller.interceptor.PermissionInterceptor;
-import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
+import com.xxl.job.admin.service.LoginService;
 import org.junit.Before;
 import org.junit.Test;
 import org.springframework.http.MediaType;
@@ -22,10 +21,10 @@ public class JobInfoControllerTest extends AbstractSpringMvcTest {
     MvcResult ret = mockMvc.perform(
         post("/login")
             .contentType(MediaType.APPLICATION_FORM_URLENCODED)
-            .param("userName", XxlJobAdminConfig.getAdminConfig().getLoginUsername())
-            .param("password", XxlJobAdminConfig.getAdminConfig().getLoginPassword())
+            .param("userName", "admin")
+            .param("password", "123456")
     ).andReturn();
-    cookie = ret.getResponse().getCookie(PermissionInterceptor.LOGIN_IDENTITY_KEY);
+    cookie = ret.getResponse().getCookie(LoginService.LOGIN_IDENTITY_KEY);
   }
 
   @Test