mirror of
https://github.com/getrebuild/rebuild.git
synced 2024-09-20 15:35:55 +08:00
admin verify
This commit is contained in:
parent
42d1af2f2d
commit
39c5d11a98
|
@ -20,6 +20,9 @@ package com.rebuild.server.bizz.privileges;
|
|||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import com.rebuild.server.bizz.RoleService;
|
||||
import com.rebuild.server.bizz.UserService;
|
||||
|
||||
import cn.devezhao.persist4j.engine.ID;
|
||||
|
||||
/**
|
||||
|
@ -64,4 +67,19 @@ public class User extends cn.devezhao.bizz.security.member.User {
|
|||
}
|
||||
return getOwningRole() != null && getOwningDept() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否管理员
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isAdmin() {
|
||||
if (getIdentity().equals(UserService.ADMIN_USER)) {
|
||||
return true;
|
||||
}
|
||||
if (getOwningRole() != null && getOwningRole().getIdentity().equals(RoleService.ADMIN_ROLE)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ public class AppUtils {
|
|||
* 获取当前请求用户
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
* @return null or UserID
|
||||
*/
|
||||
public static ID getRequestUser(HttpServletRequest request) {
|
||||
Object user = request.getSession(true).getAttribute(WebUtils.CURRENT_USER);
|
||||
|
|
|
@ -34,6 +34,7 @@ import com.rebuild.server.Application;
|
|||
import com.rebuild.server.RebuildException;
|
||||
import com.rebuild.server.ServerListener;
|
||||
import com.rebuild.utils.AppUtils;
|
||||
import com.rebuild.web.admin.AdminEntryControll;
|
||||
|
||||
import cn.devezhao.commons.CodecUtils;
|
||||
import cn.devezhao.commons.ThrowableUtils;
|
||||
|
@ -128,27 +129,37 @@ public class RequestWatchHandler extends HandlerInterceptorAdapter {
|
|||
*/
|
||||
public static boolean verfiyPass(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
request.setAttribute(TIMEOUT_KEY, System.currentTimeMillis());
|
||||
final String requestURI = request.getRequestURI();
|
||||
|
||||
ID user = AppUtils.getRequestUser(request);
|
||||
if (user != null) {
|
||||
Application.getSessionStore().setCurrentCaller(user);
|
||||
|
||||
// 管理后台访问
|
||||
if (requestURI.contains("/admin/") && !AdminEntryControll.isAdminVerified(request)) {
|
||||
if (ServletUtils.isAjaxRequest(request)) {
|
||||
ServletUtils.writeJson(response, AppUtils.formatClientMsg(403, "请验证管理员访问权限"));
|
||||
} else {
|
||||
response.sendRedirect(ServerListener.getContextPath() + "/user/entry-admin?nexturl=" + CodecUtils.urlEncode(requestURI));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
String rUrl = request.getRequestURI();
|
||||
boolean isIgnore = false;
|
||||
for (String r : IGNORE_RES) {
|
||||
if (rUrl.contains(r)) {
|
||||
if (requestURI.contains(r)) {
|
||||
isIgnore = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isIgnore) {
|
||||
LOG.warn("Unauthorized access [ " + rUrl + " ] from [ " + ServletUtils.getReferer(request) + " ]");
|
||||
LOG.warn("Unauthorized access [ " + requestURI + " ] from [ " + ServletUtils.getReferer(request) + " ]");
|
||||
if (ServletUtils.isAjaxRequest(request)) {
|
||||
ServletUtils.writeJson(response, AppUtils.formatClientMsg(403, "非授权访问"));
|
||||
ServletUtils.writeJson(response, AppUtils.formatClientMsg(403, "未授权访问"));
|
||||
} else {
|
||||
String reqUrl = request.getRequestURI();
|
||||
response.sendRedirect(ServerListener.getContextPath() + "/user/login?nexturl=" + CodecUtils.urlEncode(reqUrl));
|
||||
response.sendRedirect(ServerListener.getContextPath() + "/user/login?nexturl=" + CodecUtils.urlEncode(requestURI));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
95
src/main/java/com/rebuild/web/admin/AdminEntryControll.java
Normal file
95
src/main/java/com/rebuild/web/admin/AdminEntryControll.java
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
rebuild - Building your system freely.
|
||||
Copyright (C) 2018 devezhao <zhaofang123@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.rebuild.web.admin;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import com.rebuild.server.Application;
|
||||
import com.rebuild.server.bizz.privileges.User;
|
||||
import com.rebuild.web.BaseControll;
|
||||
import com.rebuild.web.RequestWatchHandler;
|
||||
|
||||
import cn.devezhao.commons.CalendarUtils;
|
||||
import cn.devezhao.commons.EncryptUtils;
|
||||
import cn.devezhao.commons.web.ServletUtils;
|
||||
import cn.devezhao.commons.web.WebUtils;
|
||||
import cn.devezhao.persist4j.engine.ID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author devezhao
|
||||
* @since 10/13/2018
|
||||
*/
|
||||
@Controller
|
||||
public class AdminEntryControll extends BaseControll {
|
||||
|
||||
@RequestMapping("/user/entry-admin")
|
||||
public ModelAndView pageEntryAdmin(HttpServletRequest request, HttpServletResponse response)
|
||||
throws IOException {
|
||||
boolean pass = RequestWatchHandler.verfiyPass(request, response);
|
||||
if (!pass) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ID adminId = getRequestUser(request);
|
||||
User admin = Application.getUserStore().getUser(adminId);
|
||||
if (admin.isAdmin()) {
|
||||
return createModelAndView("/admin/entry-admin.jsp");
|
||||
} else {
|
||||
response.sendError(403, "非管理员用户");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping("/user/admin-verify")
|
||||
public void adminVerify(HttpServletRequest request, HttpServletResponse response)
|
||||
throws IOException {
|
||||
ID adminId = getRequestUser(request);
|
||||
String passwd = getParameterNotNull(request, "passwd");
|
||||
|
||||
Object[] foundUser = Application.createNoFilterQuery(
|
||||
"select password from User where userId = ?")
|
||||
.setParameter(1, adminId)
|
||||
.unique();
|
||||
if (foundUser[0].equals(EncryptUtils.toSHA256Hex(passwd))) {
|
||||
ServletUtils.setSessionAttribute(request, KEY_VERIFIED, CalendarUtils.now());
|
||||
writeSuccess(response);
|
||||
} else {
|
||||
ServletUtils.setSessionAttribute(request, KEY_VERIFIED, null);
|
||||
writeFailure(response, "密码不正确");
|
||||
}
|
||||
}
|
||||
|
||||
private static final String KEY_VERIFIED = WebUtils.KEY_PREFIX + "-AdminVerified";
|
||||
/**
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
public static boolean isAdminVerified(HttpServletRequest request) {
|
||||
Object verified = ServletUtils.getSessionAttribute(request, KEY_VERIFIED);
|
||||
return verified != null;
|
||||
}
|
||||
}
|
|
@ -35,6 +35,7 @@ import com.alibaba.fastjson.JSONObject;
|
|||
import com.rebuild.server.Application;
|
||||
import com.rebuild.server.bizz.RoleService;
|
||||
import com.rebuild.server.entityhub.AccessibleMeta;
|
||||
import com.rebuild.server.metadata.EntityHelper;
|
||||
import com.rebuild.server.metadata.PortalMetaSorter;
|
||||
import com.rebuild.utils.JSONUtils;
|
||||
import com.rebuild.web.BaseControll;
|
||||
|
@ -59,7 +60,7 @@ public class RolePrivilegesControll extends BaseControll {
|
|||
return mv;
|
||||
}
|
||||
|
||||
@RequestMapping("role-privileges/{id}")
|
||||
@RequestMapping("role/{id}")
|
||||
public ModelAndView pagePrivileges(@PathVariable String id, HttpServletRequest request) throws IOException {
|
||||
ModelAndView mv = createModelAndView("/admin/bizuser/role-privileges.jsp", "Role");
|
||||
setEntities(mv);
|
||||
|
@ -75,7 +76,9 @@ public class RolePrivilegesControll extends BaseControll {
|
|||
private void setEntities(ModelAndView mv) {
|
||||
List<String[]> entities = new ArrayList<>();
|
||||
for (Entity e : PortalMetaSorter.sortEntities(true)) {
|
||||
entities.add(new String[] { e.getName(), AccessibleMeta.getLabel(e) });
|
||||
if (EntityHelper.hasPrivilegesField(e)) {
|
||||
entities.add(new String[] { e.getName(), AccessibleMeta.getLabel(e) });
|
||||
}
|
||||
}
|
||||
mv.getModel().put("Entities", entities);
|
||||
}
|
||||
|
|
23
src/main/webapp/_include/NavTopOnlyHeader.jsp
Normal file
23
src/main/webapp/_include/NavTopOnlyHeader.jsp
Normal file
|
@ -0,0 +1,23 @@
|
|||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
||||
<nav class="navbar navbar-expand fixed-top rb-top-header">
|
||||
<div class="container-fluid">
|
||||
<div class="rb-navbar-header">
|
||||
<a class="navbar-brand" href="${baseUrl}/dashboard/home"></a>
|
||||
</div>
|
||||
<div class="rb-right-navbar">
|
||||
<ul class="nav navbar-nav float-right rb-user-nav">
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="${baseUrl}/me/profile" data-toggle="dropdown"><img src="${baseUrl}/assets/img/avatar.png" alt="Avatar"><span class="user-name">admin</span></a>
|
||||
<div class="dropdown-menu">
|
||||
<div class="user-info">
|
||||
<div class="user-name">admin</div>
|
||||
<div class="user-id">hello@getrebuild.com</div>
|
||||
</div>
|
||||
<a class="dropdown-item" href="${baseUrl}/me/profile"><span class="icon zmdi zmdi-face"></span>个人信息</a>
|
||||
<a class="dropdown-item" href="${baseUrl}/user/logout"><span class="icon zmdi zmdi-power"></span>退出</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
|
@ -151,7 +151,7 @@
|
|||
<script src="${baseUrl}/assets/js/rb-forms-ext.jsx" type="text/babel"></script>
|
||||
<script type="text/babel">
|
||||
RbForm.postAfter = function(data){
|
||||
location.href = rb.baseUrl + '/admin/bizuser/role-privileges/' + data.id
|
||||
location.href = rb.baseUrl + '/admin/bizuser/role/' + data.id
|
||||
}
|
||||
var currentRoleId
|
||||
$(document).ready(function(){
|
||||
|
@ -218,7 +218,7 @@ const loadRoles = function() {
|
|||
$.get(rb.baseUrl + '/admin/bizuser/role-list', function(res){
|
||||
$('.dept-tree ul').empty()
|
||||
$(res.data).each(function(){
|
||||
let item = $('<li><a class="text-truncate" href="' + rb.baseUrl + '/admin/bizuser/role-privileges/' + this.id + '">' + this.name + '</a></li>').appendTo('.dept-tree ul')
|
||||
let item = $('<li><a class="text-truncate" href="' + rb.baseUrl + '/admin/bizuser/role/' + this.id + '">' + this.name + '</a></li>').appendTo('.dept-tree ul')
|
||||
if (currentRoleId == this.id) item.addClass('active')
|
||||
})
|
||||
})
|
||||
|
@ -269,7 +269,7 @@ const updatePrivileges = function() {
|
|||
let priv = { entity: privEntity, zero: privZero }
|
||||
console.log(JSON.stringify(priv))
|
||||
$.post(rb.baseUrl + '/admin/bizuser/privileges-update?role=' + currentRoleId, JSON.stringify(priv), function(){
|
||||
location.reload()
|
||||
rb.notice('权限保存成功', 'success')
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
|
53
src/main/webapp/admin/entry-admin.jsp
Normal file
53
src/main/webapp/admin/entry-admin.jsp
Normal file
|
@ -0,0 +1,53 @@
|
|||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<%@ include file="/_include/Head.jsp"%>
|
||||
<title>验证管理员</title>
|
||||
<style type="text/css">
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="rb-wrapper rb-nosidebar-left rb-color-header">
|
||||
<jsp:include page="/_include/NavTopOnlyHeader.jsp">
|
||||
<jsp:param value="" name="pageTitle"/>
|
||||
</jsp:include>
|
||||
<div class="rb-content">
|
||||
<div class="main-content container-fluid">
|
||||
<div class="splash-container">
|
||||
<div class="card card-border-color card-border-color-primary">
|
||||
<div class="card-header">
|
||||
<h4>需要验证你的管理员身份</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="form-group">
|
||||
<input class="form-control" id="passwd" type="password" placeholder="输入登录密码" autocomplete="off">
|
||||
</div>
|
||||
<div class="form-group login-submit">
|
||||
<button class="btn btn-primary btn-xl J_verify-btn">验证</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="splash-footer">
|
||||
<span><a href="javascript:history.back()">返回</a></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<%@ include file="/_include/Foot.jsp"%>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
let nexturl = decodeURIComponent($urlp('nexturl') || '../admin/systems')
|
||||
$('.J_verify-btn').click(function(){
|
||||
let passwd = $val('#passwd')
|
||||
if (!!!passwd) return
|
||||
$.post('admin-verify?passwd=' + passwd, function(res) {
|
||||
if (res.error_code == 0) location.replace(nexturl)
|
||||
else rb.notice(res.error_msg)
|
||||
})
|
||||
})
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
BIN
src/main/webapp/assets/img/logo-1.0.psd
Normal file
BIN
src/main/webapp/assets/img/logo-1.0.psd
Normal file
Binary file not shown.
BIN
src/main/webapp/assets/img/logo-white.png
Normal file
BIN
src/main/webapp/assets/img/logo-white.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.4 KiB |
Binary file not shown.
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.4 KiB |
|
@ -144,6 +144,9 @@ class RbForm extends React.Component {
|
|||
}
|
||||
|
||||
_data.metadata = { entity: this.state.entity, id: this.state.id }
|
||||
if (RbForm.postBefore(data) == false) {
|
||||
return
|
||||
}
|
||||
|
||||
let btns = $(this.refs['rbform-action']).find('.btn').button('loading')
|
||||
let that = this
|
||||
|
@ -159,7 +162,13 @@ class RbForm extends React.Component {
|
|||
})
|
||||
}
|
||||
|
||||
static postAfter() {
|
||||
// 保存前调用
|
||||
// @return false 则不继续保存
|
||||
static postBefore(data) {
|
||||
return true
|
||||
}
|
||||
// 保存后调用
|
||||
static postAfter(data) {
|
||||
if (window.rbList) window.rbList.reload()
|
||||
else if (parent.rbList) parent.rbList.reload()
|
||||
if (window.rbFromView) location.reload()
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<div class="splash-container">
|
||||
<div class="card card-border-color card-border-color-primary">
|
||||
<div class="card-header">
|
||||
<img class="logo-img" src="../assets/img/logo.png" alt="REBUILD" width="102" height="27">
|
||||
<img class="logo-img" src="../assets/img/logo.png" alt="REBUILD">
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="form-group">
|
||||
|
|
Loading…
Reference in a new issue