NutzBook - 权限管理页面及入口方法

NutzBook - 权限管理页面及入口方法

Tags: Nutz

摘要

NutzBook - 权限管理页面及入口方法

新增AuthorityService及其实现类

package net.javablog.service;

import net.javablog.bean.Role;
import net.javablog.bean.User;

public interface AuthorityService {

    /**
     * 扫描RequiresPermissions和RequiresRoles注解
     * @param pkg 需要扫描的package
     */
    void initFormPackage(String pkg);

    /**
     * 检查最基础的权限,确保admin用户-admin角色-(用户增删改查-权限增删改查)这一基础权限设置
     * @param admin
     */
    void checkBasicRoles(User admin);

    /**
     * 添加一个权限
     */
    public void addPermission(String permission);

    /**
     * 添加一个角色
     */
    public Role addRole(String role);
}
package net.javablog.service;

import net.javablog.bean.Permission;
import net.javablog.bean.Role;
import net.javablog.bean.User;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.entity.Record;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.ContinueLoop;
import org.nutz.lang.Each;
import org.nutz.lang.ExitLoop;
import org.nutz.lang.LoopException;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.resource.Scans;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


@IocBean(name = "authorityService")
public class AuthorityServiceImpl implements AuthorityService {

    private static final Log log = Logs.get();

    @Inject
    Dao dao;

    public void initFormPackage(String pkg) {
        // 搜索@RequiresPermissions注解, 初始化权限表
        // 搜索@RequiresRoles注解, 初始化角色表
        final Set<String> permissions = new HashSet<String>();
        final Set<String> roles = new HashSet<String>();
        for (Class<?> klass : Scans.me().scanPackage(pkg)) {
            for (Method method : klass.getMethods()) {
                RequiresPermissions rp = method.getAnnotation(RequiresPermissions.class);
                if (rp != null && rp.value() != null) {
                    for (String permission : rp.value()) {
                        if (permission != null && !permission.endsWith("*"))
                            permissions.add(permission);
                    }
                }
                RequiresRoles rr = method.getAnnotation(RequiresRoles.class);
                if (rr != null && rr.value() != null) {
                    for (String role : rr.value()) {
                        roles.add(role);
                    }
                }
            }
        }
        log.debugf("found %d permission", permissions.size());
        log.debugf("found %d role", roles.size());

        // 把全部权限查出来一一检查
        dao.each(Permission.class, null, new Each<Permission>() {
            public void invoke(int index, Permission ele, int length) throws ExitLoop, ContinueLoop, LoopException {
                permissions.remove(ele.getName());
            }
        });
        dao.each(Role.class, null, new Each<Role>() {
            public void invoke(int index, Role ele, int length) throws ExitLoop, ContinueLoop, LoopException {
                roles.remove(ele.getName());
            }
        });
        for (String permission : permissions) {
            addPermission(permission);
        }
        for (String role : roles) {
            addRole(role);
        }
    }

    public void checkBasicRoles(User admin) {
        // 检查一下admin的权限
        Role adminRole = dao.fetch(Role.class, "admin");
        if (adminRole == null) {
            adminRole = addRole("admin");
        }
        // admin账号必须存在与admin组
        if (0 == dao.count("t_user_role", Cnd.where("u_id", "=", admin.getId()).and("role_id", "=", adminRole.getId()))) {
            dao.insert("t_user_role", Chain.make("u_id", admin.getId()).add("role_id", adminRole.getId()));
        }
        // admin组必须有authority:* 也就是权限管理相关的权限
        List<Record> res = dao.query("t_role_permission", Cnd.where("role_id", "=", adminRole.getId()));
        OUT:
        for (Permission permission : dao.query(Permission.class, Cnd.where("name", "like", "authority:%").or("name", "like", "user:%").or("name", "like", "topic:%"), null)) {
            for (Record re : res) {
                if (re.getInt("permission_id") == permission.getId())
                    continue OUT;
            }
            dao.insert("t_role_permission", Chain.make("role_id", adminRole.getId()).add("permission_id", permission.getId()));
        }
    }

    public void addPermission(String permission) {
        Permission p = new Permission();
        p.setName(permission);
        p.setUpdateTime(new Date());
        p.setCreateTime(new Date());
        dao.insert(p);
    }

    public Role addRole(String role) {
        Role r = new Role();
        r.setName(role);
        r.setUpdateTime(new Date());
        r.setCreateTime(new Date());
        return dao.insert(r);
    }

}

新增AuthorityModule

package net.javablog.module;

import net.javablog.bean.Permission;
import net.javablog.bean.Role;
import net.javablog.bean.User;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.FieldFilter;
import org.nutz.dao.pager.Pager;
import org.nutz.dao.util.Daos;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.adaptor.JsonAdaptor;
import org.nutz.mvc.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 角色/权限管理. 基本假设: 一个用户属于多种角色,拥有多种特许权限. 每种角色拥有多种权限
 *
 * @author wendal
 */
@At("/admin/authority")
@IocBean
@Ok("void")//避免误写导致敏感信息泄露到服务器外
public class AuthorityModule extends BaseModule {

    //---------------------------------------------
    // 查询类

    /**
     * 用户列表
     */
    @RequiresPermissions("authority:user:query")
    @At
    @Ok("json:{locked:'password|salt',ignoreNull:true}") //禁止把password和salt字段进行传输
    public Object users(@Param("query") String query, @Param("..") Pager pager) {
        return ajaxOk(query(User.class, Cnd.NEW().asc("id"), pager, null));
    }

    /**
     * 角色列表
     */
    @Ok("json")
    @RequiresPermissions("authority:role:query")
    @At
    public Object roles(@Param("query") String query, @Param("..") Pager pager) {
        return ajaxOk(query(Role.class, Cnd.NEW().asc("id"), pager, null));
    }

    /**
     * 权限列表
     */
    @Ok("json")
    @RequiresPermissions("authority:permission:query")
    @At
    public Object permissions(@Param("query") String query, @Param("..") Pager pager) {
        return ajaxOk(query(Permission.class, Cnd.NEW().asc("id"), pager, null));
    }


    //---------------------------------------------
    // 用户操作

    /**
     * 更新用户所属角色/特许权限
     */
    @POST
    @AdaptBy(type = JsonAdaptor.class)
    @RequiresPermissions("authority:user:update")
    @At("/user/update")
    @Aop(TransAop.READ_COMMITTED)
    public void updateUser(@Param("user") User user,
                           @Param("roles") List<Long> roles,
                           @Param("permissions") List<Long> permissions) {
        // 防御一下
        if (user == null)
            return;
        user = dao.fetch(User.class, user.getId());
        // 就在那么一瞬间,那个用户已经被其他用户删掉了呢
        if (user == null)
            return;
        if (roles != null) {
            List<Role> rs = new ArrayList<Role>(roles.size());
            for (long roleId : roles) {
                Role r = dao.fetch(Role.class, roleId);
                if (r != null) {
                    rs.add(r);
                }
            }
            dao.fetchLinks(user, "roles");
            if (user.getRoles().size() > 0) {
                dao.clearLinks(user, "roles");
            }
            user.setRoles(rs);
            dao.insertRelation(user, "roles");
        }
        if (permissions != null) {
            List<Permission> ps = new ArrayList<Permission>();
            for (long permissionId : permissions) {
                Permission p = dao.fetch(Permission.class, permissionId);
                if (p != null)
                    ps.add(p);
            }
            dao.fetchLinks(user, "permissions");
            if (user.getPermissions().size() > 0) {
                dao.clearLinks(user, "permissions");
            }
            user.setPermissions(ps);
            dao.insertRelation(user, "permissions");
        }
    }

    /**
     * 用于显示用户-权限修改对话框的信息
     */
    @Ok("json")
    @RequiresPermissions("authority:user:update")
    @At("/user/fetch/permission")
    public Object fetchUserPermissions(@Param("id") long id) {
        User user = dao.fetch(User.class, id);
        if (user == null)
            return ajaxFail("not such user");
        user = dao.fetchLinks(user, "permissions");
        // TODO 优化为逐步加载
        List<Permission> permissions = dao.query(Permission.class, Cnd.orderBy().asc("name"));
        NutMap data = new NutMap();
        data.put("user", user);
        data.put("permissions", permissions);
        return ajaxOk(data);
    }

    /**
     * 用于显示用户-权限修改对话框的信息
     */
    @Ok("json")
    @RequiresPermissions("authority:user:update")
    @At("/user/fetch/role")
    public Object fetchUserRoles(@Param("id") long id) {
        User user = dao.fetch(User.class, id);
        if (user == null)
            return ajaxFail("not such user");
        user = dao.fetchLinks(user, "roles");
        // TODO 优化为逐步加载
        List<Role> roles = dao.query(Role.class, Cnd.orderBy().asc("name"));
        NutMap data = new NutMap();
        data.put("user", user);
        data.put("roles", roles);
        return ajaxOk(data);
    }

    //---------------------------------------------
    // Role操作

    /**
     * 新增一个角色
     */
    @POST
    @AdaptBy(type = JsonAdaptor.class)
    @RequiresPermissions("authority:role:add")
    @At("/role/add")
    public void addRole(@Param("..") Role role) {
        if (role == null)
            return;
        dao.insert(role); // 注意,这里并没有用insertWith, 即总是插入一个无权限的角色
    }

    /**
     * 删除一个角色,其中admin角色禁止删除
     */
    @POST
    @AdaptBy(type = JsonAdaptor.class)
    @RequiresPermissions("authority:role:delete")
    @At("/role/delete")
    public void delRole(@Param("..") Role role) {
        if (role == null)
            return;
        role = dao.fetch(Role.class, role.getId());
        if (role == null)
            return;
        // 不允许删除admin角色
        if ("admin".equals(role.getName()))
            return;
        dao.delete(Role.class, role.getId());
    }

    /**
     * 更新权限的一般信息或所拥有的权限
     */
    @POST
    @AdaptBy(type = JsonAdaptor.class)
    @RequiresPermissions("authority:role:update")
    @At("/role/update")
    @Aop(TransAop.SERIALIZABLE) // 关键操作,强事务操作
    public void updateRole(@Param("role") Role role, @Param("permissions") List<Long> permissions) {
        if (role == null)
            return;
        if (dao.fetch(Role.class, role.getId()) == null)
            return;
        if (!Strings.isBlank(role.getAlias()) || !Strings.isBlank(role.getDescription())) {
            Daos.ext(dao, FieldFilter.create(Role.class, "alias|desc")).update(role);
        }
        if (permissions != null) {
            List<Permission> ps = new ArrayList<Permission>();
            for (Long permission : permissions) {
                Permission p = dao.fetch(Permission.class, permission);
                if (p != null)
                    ps.add(p);
            }
            // 如果有老的权限,先清空,然后插入新的记录
            // TODO 优化为直接清理中间表
            dao.fetchLinks(role, "permissions");
            if (role.getPermissions().size() > 0) {
                dao.clearLinks(role, "permissions");
            }
            role.setPermissions(ps);
            dao.insertRelation(role, "permissions");
        }
        // TODO 修改Role的updateTime
    }

    /**
     * 用于显示角色-权限修改对话框的信息
     */
    @Ok("json")
    @RequiresPermissions("authority:role:update")
    @At("/role/fetch")
    public Object fetchRolePermissions(@Param("id") long id) {
        Role role = dao.fetch(Role.class, id);
        if (role == null)
            return ajaxFail("not such role");
        role = dao.fetchLinks(role, null);
        // TODO 优化为逐步加载
        List<Permission> permissions = dao.query(Permission.class, Cnd.orderBy().asc("name"));
        NutMap data = new NutMap();
        data.put("role", role);
        data.put("permissions", permissions);
        return ajaxOk(data);
    }

    //--------------------------------------------------------------------
    // Permission操作

    /**
     * 新增一个权限
     */
    @POST
    @AdaptBy(type = JsonAdaptor.class)
    @RequiresPermissions("authority:permission:add")
    @At("/permission/add")
    public void addPermission(@Param("..") Permission permission) {
        if (permission == null)
            return;
        dao.insert(permission);
    }

    /**
     * 删除一个角色
     *
     * @param permission
     */
    @POST
    @AdaptBy(type = JsonAdaptor.class)
    @RequiresPermissions("authority:permission:delete")
    @At("/permission/delete")
    public void delPermission(@Param("..") Permission permission) {
        if (permission == null)
            return;
        // TODO 禁止删除authority相关的默认权限
        dao.delete(Permission.class, permission.getId());
    }

    /**
     * 修改权限的一般信息
     */
    @POST
    @AdaptBy(type = JsonAdaptor.class)
    @RequiresPermissions("authority:permission:update")
    @At("/permission/update")
    public void updateRole(@Param("..") Permission permission) {
        if (permission == null)
            return;
        if (dao.fetch(Permission.class, permission.getId()) == null)
            return;
        permission.setUpdateTime(new Date());
        permission.setCreateTime(null);
        Daos.ext(dao, FieldFilter.create(Permission.class, null, "name", true)).update(permission);
    }
}

修改UserModule的Shiro注解

比如add方法 @RequiresUser 修改为 @RequiresPermissions(“user:add”)
比如update方法 @RequiresUser 修改为 @RequiresPermissions(“user:update”)
如此类推.

UserProfileModule继续使用 @RequiresUser

MainSetup中触发AuthorityService

打开MainSetup类,在init方法末尾添加如下代码

        User admin = dao.fetch(User.class, "admin");
        AuthorityService as = ioc.get(AuthorityService.class);
        as.initFormPackage("net.javablog");
        as.checkBasicRoles(admin);

以上代码就能在启动时扫描注解,初始化最基本的权限模型,即:

  • 用户admin存在
  • 角色admin存在
  • 用户admin属于admin角色
  • admin角色拥有所有user:和authority:开头的权限

添加管理页面

第一个是 webapp/page/simple_role.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>无框架的权限管理界面</title>
    <script src="${base}/rs/js/jquery-1.12.3.min.js"></script>
</head>
<body>
<jsp:include page="authority.jsp"></jsp:include>

</body>
</html>

第二个是 webapp/page/authority.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>

<!-- 用bootstrap先应付一下 -->
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="http://apps.bdimg.com/libs/bootstrap/3.3.4/css/bootstrap.min.css">
<!-- Optional theme -->
<link rel="stylesheet" href="http://apps.bdimg.com/libs/bootstrap/3.3.4/css/bootstrap-theme.min.css">
<!-- Latest compiled and minified JavaScript -->
<script src="${base}/rs/js/jquery-1.12.3.min.js"></script>
<script src="http://apps.bdimg.com/libs/bootstrap/3.3.4/js/bootstrap.min.js"></script>


<div class="row">
    <!-- 下面的ul是3个Table -->
    <ul class="md-tab-group">
        <li>
            <div class="ripple-button" id="_user_role" onclick="showTab('user_role')">用户权限一览</div>
        </li>
        <li>
            <div class="ripple-button" id="_roles" onclick="showTab('roles')">角色一览</div>
        </li>
        <li>
            <div class="ripple-button" id="_permissions" onclick="showTab('permissions')">权限一览</div>
        </li>
        <div class="tab-bottom"></div>
    </ul>
</div>
<div>

    <!-- 用户列表 -->
    <div id="user_role">
        <h2>用户管理</h2>

        <p id="user_count"></p>

        <form action="#" id="user_query">
            用户过滤<input name="query">
            页数<input name="pageNumber" type="number" value="1" onchange="loadUsers();">
            每页大小<input name="pageSize" type="number" value="10" onchange="loadUsers();">
        </form>

        <div class="panel panel-default">
            <div class="panel-heading">用户一览</div>
            <table class="table">
                <thead>
                <tr>
                    <th>#</th>
                    <th>名称</th>
                    <th>别称</th>
                    <th>角色</th>
                    <th>特许权限</th>
                    <th>操作</th>
                </tr>
                </thead>
                <tbody id="user_list"></tbody>
            </table>
        </div>
    </div>


    <!-- 角色列表 -->
    <div id="roles">
        <h2>角色管理</h2>

        <p id="role_count"></p>

        <form action="#" id="role_query">
            角色过滤<input name="query">
            页数<input name="pageNumber" type="number" value="1" onchange="loadRoles();">
            每页大小<input name="pageSize" type="number" value="10" onchange="loadRoles();">
        </form>
        <div>

        </div>
        <button onclick="role_add();" class="btn btn-default">新增角色</button>
        <div class="panel panel-default">
            <div class="panel-heading">角色一览</div>
            <table class="table">
                <thead>
                <tr>
                    <th>#</th>
                    <th>角色</th>
                    <th>别称</th>
                    <th>描述</th>
                    <th>权限</th>
                    <th>操作</th>
                </tr>
                </thead>
                <tbody id="role_list"></tbody>
            </table>
        </div>
    </div>
    <!-- 权限列表 -->
    <div id="permissions">
        <h2>权限管理</h2>

        <p id="permission_count"></p>

        <form action="#" id="permission_query">
            权限过滤<input name="query">
            页数<input name="pageNumber" type="number" value="1" onchange="loadPermissions();">
            每页大小<input name="pageSize" type="number" value="10" onchange="loadPermissions();">
        </form>
        <button onclick="permission_add();" class="btn btn-default">新增</button>

        <div class="panel panel-default">
            <div class="panel-heading">权限一览</div>
            <table class="table">
                <thead>
                <tr>
                    <th>#</th>
                    <th>权限</th>
                    <th>别称</th>
                    <th>描述</th>
                    <th>操作</th>
                </tr>
                </thead>
                <tbody id="permission_list"></tbody>
            </table>
        </div>
    </div>
</div>

<!-- 各种默认隐藏的div -->
<!-- 修改用户的特许权限 -->
<div style="display: none;" id="user_permission_modify">
    <p>
        <input id="user_permission_modify_id" value="" hidden="true">
        <input id="user_permission_modify_name" value="" hidden="true">
    </p>

    <form action="#">
        <div id="user_permissions_div"></div>
    </form>
    <button onclick="user_permission_modify_submit();">提交</button>
</div>
<!-- 修改用户所属的角色 -->
<div style="display: none;" id="user_role_modify">
    <p>
        <input id="user_role_modify_id" value="" hidden="true">
        <input id="user_role_modify_name" value="" hidden="true">
    </p>

    <form action="#">
        <div id="user_roles_div"></div>
    </form>
    <button onclick="user_role_modify_submit();">提交</button>
</div>
<!-- 修改角色所拥有的权限 -->
<div style="display: none;" id="role_permission_modify">
    <p>
        <input id="role_permission_modify_id" value="" hidden="true">
        <input id="role_permission_modify_name" value="" hidden="true">
    </p>

    <form action="#">
        <div id="role_permissions_div"></div>
    </form>
    <button onclick="role_permission_modify_submit();">提交</button>
</div>
<!-- 修改角色的一般属性,如别称,描述 -->
<div style="display: none;" id="role_modify">
    <div style="display: none;">
        <input name="role_modify_id" id="role_modify_id">
    </div>
    <div>
        <div class="md-text-field has-float-label">
            <label>${msg['authority.role.alias']}</label>
            <input type="text" id="role_modify_alias" name="alias" nm="${msg['authority.role.alias']}" value="">
            <hr class="underline">
            <hr class="underline-focus">
            <div class="err-tip">别名不能为空</div>
        </div>
    </div>
    <div>
        <div class="md-text-field has-float-label">
            <label>${msg['authority.role.description']}</label>
            <input type="text" id="role_modify_description" name="description" nm="${msg['authority.role.description']}"
                   value="">
            <hr class="underline">
            <hr class="underline-focus">
            <div class="err-tip">描述不能为空</div>
        </div>
    </div>
    <div>
        <button class="md-button raised-button is-primary" type="submit" onclick="role_update_submit();">
            <span class="md-button-label">修改</span>
        </button>
        <button class="md-button raised-button is-primary" type="submit" onclick="$('#role_modify').hide();">
            <span class="md-button-label">取消</span>
        </button>
    </div>
</div>
<!-- 修改权限的一般属性 -->
<div style="display: none;" id="permission_modify">
    <div style="display: none;">
        <input name="permission_modify_id" id="permission_modify_id">
    </div>
    <div>
        <div class="md-text-field has-float-label">
            <label>${msg['authority.permission.alias']}</label>
            <input type="text" id="permission_modify_alias" name="alias" nm="${msg['authority.permission.alias']}"
                   value="">
            <hr class="underline">
            <hr class="underline-focus">
            <div class="err-tip">别名不能为空</div>
        </div>
    </div>
    <div>
        <div class="md-text-field has-float-label">
            <label>${msg['authority.permission.description']}</label>
            <input type="text" id="permission_modify_description" name="description"
                   nm="${msg['authority.permission.description']}" value="">
            <hr class="underline">
            <hr class="underline-focus">
            <div class="err-tip">描述不能为空</div>
        </div>
    </div>
    <div>
        <button class="md-button raised-button is-primary" type="submit" onclick="permission_update_submit();">
            <span class="md-button-label">修改</span>
        </button>
        <button class="md-button raised-button is-primary" type="submit" onclick="$('#permission_modify').hide();">
            <span class="md-button-label">取消</span>
        </button>
    </div>
</div>

<script type="text/javascript">
    _r = {};
    /*页面片段的初始化方法*/
    function myInit(args) {
        // 载入用户列表
        loadUsers();
        // 载入角色列表
        loadRoles();
        // 载入权限列表
        loadPermissions();
        // 默认显示用户列表的Tab
        $("#_user_role").click();
    }
    /*切换Tab的函数*/
    function showTab(tab) {
        $(".ripple-button").each(function (_, z) {
            z = $(z);
            tabId = z.attr("id");
            if (tabId == undefined)
                return;
            tabId = tabId.substring(1);
            TAB = $("#" + tabId);
            if (tabId == tab) {
                TAB.show();
            }
            else {
                TAB.hide();
            }
        });
    }
    /*载入用户列表*/
    function loadUsers() {
        $.ajax({
            url: home_base + "/admin/authority/users",
            data: $("#user_query").serialize(),
            dataType: "json",
            type: "POST",
            success: function (re) {
                if (!re.ok) {
                    alert(re.msg);
                    return;
                }
                data = re.data;
                //console.log(data);
                $("#user_count").html("共" + data.pager.recordCount + "个用户, 总计" + data.pager.pageCount + "页");
                var list_html = "";
                //console.log(data.list);
                for (var i = 0; i < data.list.length; i++) {
                    var user = data.list[i];
                    console.log(user);
                    var pstr = "";
                    for (var j = 0; j < user.permissions.length; j++) {
                        var p = user.permissions[j];
                        if (p.alias)
                            pstr += p.alias;
                        else
                            pstr += p.name;
                        pstr += " ";
                        //console.log(p);
                        if (j > 4 && user.permissions.length > 4) {
                            pstr += " 等" + user.permissions.length + "种权限";
                            break;
                        }
                    }
                    var rstr = "";
                    for (var j = 0; j < user.roles.length; j++) {
                        var r = user.roles[j];
                        if (r.alias)
                            rstr += r.alias;
                        else
                            rstr += r.name;
                        rstr += " ";
                        //console.log(p);
                        if (j > 4 && user.roles.length > 4) {
                            rstr += " 等" + user.roles.length + "种角色";
                            break;
                        }
                    }
                    var tmp = "\n<tr>"
                            + "<td>" + user.id + "</td>"
                            + "<td>" + user.name + "</td>"
                            + "<td>" + (user.alias ? user.alias : "" ) + "</td>"
                            + "<td>" + rstr + "</td>"
                            + "<td>" + pstr + "</td>"
                            + "<td> "
                            + " <button onclick='user_role_update(" + user.id + ");' class='btn btn-default'>修改角色</button> "
                            + " <button onclick='user_permission_update(" + user.id + ");' class='btn btn-default'>修改特许权限</button> "
                            + "</td>"
                            + "</tr>";
                    list_html += tmp;
                }
                $("#user_list").html(list_html);
                _r._user_roles = data;
                //console.log(window._user_roles);
            }
        });
    }
    /*载入角色列表*/
    function loadRoles() {
        $.ajax({
            url: home_base + "/admin/authority/roles",
            data: $("#role_query").serialize(),
            dataType: "json",
            type: "POST",
            success: function (re) {
                if (!re.ok) {
                    alert(re.msg);
                    return;
                }
                data = re.data;
                //console.log(data);
                $("#role_count").html("共" + data.pager.recordCount + "个角色, 总计" + data.pager.pageCount + "页");
                var list_html = "";
                //console.log(data.list);
                for (var i = 0; i < data.list.length; i++) {
                    var role = data.list[i];
                    var pstr = "";
                    for (var j = 0; j < role.permissions.length; j++) {
                        var p = role.permissions[j];
                        if (p.alias)
                            pstr += p.alias;
                        else
                            pstr += p.name;
                        pstr += " ";
                        //console.log(p);
                        if (j > 4 && role.permissions.length > 4) {
                            pstr += " 等" + role.permissions.length + "种权限";
                            break;
                        }
                    }
                    var tmp = "\n<tr>"
                            + "<td>" + role.id + "</td>"
                            + "<td>" + role.name + "</td>"
                            + "<td>" + (role.alias ? role.alias : "" ) + "</td>"
                            + "<td></td>"
                            + "<td>" + pstr + "</td>"
                            + "<td> "
                            + "<button onclick='role_update(" + role.id + ");' class='btn btn-default'>修改描述</button> "
                            + "<button onclick='role_permission_update(" + role.id + ");' class='btn btn-default'>修改权限</button> "
                            + "<button onclick='role_delete(" + role.id + ");' class='btn btn-default'>删除</button> "
                            + "</td>"
                            + "</tr>";
                    list_html += tmp;
                }
                $("#role_list").html(list_html);
                _r._roles = data;
                //console.log(window._user_roles);
            }
        });
    }
    /*载入权限列表*/
    function loadPermissions() {
        $.ajax({
            url: home_base + "/admin/authority/permissions",
            data: $("#permission_query").serialize(),
            dataType: "json",
            type: "POST",
            success: function (re) {
                if (!re.ok) {
                    alert(re.msg);
                    return;
                }
                data = re.data;
                //console.log(data);
                $("#permission_count").html("共" + data.pager.recordCount + "个权限, 总计" + data.pager.pageCount + "页");
                var list_html = "";
                //console.log(data.list);
                for (var i = 0; i < data.list.length; i++) {
                    var permission = data.list[i];
                    var tmp = "\n<tr>"
                            + "<td>" + permission.id + "</td>"
                            + "<td>" + permission.name + "</td>"
                            + "<td>" + (permission.alias ? permission.alias : "" ) + "</td>"
                            + "<td>" + (permission.description ? permission.description : "") + "</td>"
                            + "<td> "
                            + "<button onclick='permission_update(" + permission.id + ");' class='btn btn-default'>修改</button> "
                            + "<button onclick='permission_delete(" + permission.id + ");' class='btn btn-default'>删除</button> "
                            + "</td>"
                            + "</tr>";
                    list_html += tmp;
                }
                $("#permission_list").html(list_html);
                _r._permissions = data;
                //console.log(window._user_roles);
            }
        });
    }
    // 各种操作哦哦哦

    /*更新用户特许权限*/
    function user_permission_update(user_id) {
        $.ajax({
            url: home_base + "/admin/authority/user/fetch/permission",
            dataType: "json",
            data: {id: user_id},
            success: function (re) {
                if (re && re.ok) {
                    console.log(re.data);
                    var html = "";
                    var ps = re.data.permissions;
                    for (var i = 0; i < ps.length; i++) {
                        var p = ps[i];
                        var flag = false;
                        for (var j = 0; j < re.data.user.permissions.length; j++) {
                            if (re.data.user.permissions[j].id == p.id) {
                                flag = true;
                                break;
                            }
                        }
                        if (p.alias) {
                            html += p.alias;
                        } else {
                            html += p.name;
                        }
                        if (flag) {
                            html += "<input type='checkbox' t='checkbox_user_permission' pid='" + p.id + "' checked='true'>\n"
                        } else {
                            html += "<input type='checkbox' t='checkbox_user_permission' pid='" + p.id + "'>\n"
                        }
                    }
                    $("#user_permission_modify_id").val("" + user_id);
                    $("#user_permission_modify_name").val("" + re.data.user.name);
                    $("#user_permissions_div").html(html);
                    $("#user_permission_modify").show();
                }
            }
        });
    }
    /*将用户的特许权限提交到服务器*/
    function user_permission_modify_submit() {
        var user_id = $("#user_permission_modify_id").val();
        var ps = $("input[t='checkbox_user_permission']:checked");
        console.log(ps);
        console.log(user_id);
        var pids = [];
        ps.each(function (i, p_input) {
            pids.push($(p_input).attr("pid"));
        });
        $.ajax({
            url: home_base + "/admin/authority/user/update",
            type: "POST",
            data: JSON.stringify({"user": {id: user_id}, "permissions": pids}),
            success: function () {
                loadUsers();
                $("#user_permission_modify").hide();
            }
        });
    }
    function user_role_update(user_id) {
        $.ajax({
            url: home_base + "/admin/authority/user/fetch/role",
            dataType: "json",
            data: {id: user_id},
            success: function (re) {
                if (re && re.ok) {
                    console.log(re.data);
                    var html = "";
                    var ps = re.data.roles;
                    for (var i = 0; i < ps.length; i++) {
                        var p = ps[i];
                        var flag = false;
                        for (var j = 0; j < re.data.user.roles.length; j++) {
                            if (re.data.user.roles[j].id == p.id) {
                                flag = true;
                                break;
                            }
                        }
                        if (p.alias) {
                            html += p.alias;
                        } else {
                            html += p.name;
                        }
                        if (flag) {
                            html += "<input type='checkbox' t='checkbox_user_role' pid='" + p.id + "' checked='true'>\n"
                        } else {
                            html += "<input type='checkbox' t='checkbox_user_role' pid='" + p.id + "'>\n"
                        }
                    }
                    $("#user_role_modify_id").val("" + user_id);
                    $("#user_role_modify_name").val("" + re.data.user.name);
                    $("#user_roles_div").html(html);
                    $("#user_role_modify").show();
                }
            }
        });
    }
    function user_role_modify_submit() {
        var user_id = $("#user_role_modify_id").val();
        var ps = $("input[t='checkbox_user_role']:checked");
        console.log(ps);
        console.log(user_id);
        var pids = [];
        ps.each(function (i, p_input) {
            pids.push($(p_input).attr("pid"));
        });
        $.ajax({
            url: home_base + "/admin/authority/user/update",
            type: "POST",
            data: JSON.stringify({"user": {id: user_id}, "roles": pids}),
            success: function () {
                loadUsers();
                $("#user_role_modify").hide();
            }
        });
    }
    //----------------------------------------------------
    // 角色相关的操作
    /*更新角色的一般属性,显示所需要的输入框*/
    function role_update(role_id) {
        for (var i = 0; i < _r._roles.list.length; i++) {
            var role = _r._roles.list[i];
            if (role.id == role_id) {
                $("#role_modify_id").attr("value", role_id);
                $("#role_modify_alias").attr("value", role.alias);
                $("#role_modify_description").attr("value", role.description);
                $("#role_modify").show();
                return;
            }
        }
    }
    /*将角色的一般属性的修改发送到服务器进行修改*/
    function role_update_submit() {
        var role_id = $("#role_modify_id").val();
        var p = {id: role_id};
        p["alias"] = $("#role_modify_alias").val();
        p["description"] = $("#role_modify_description").val();
        console.log(p);
        $.ajax({
            url: home_base + "/admin/authority/role/update",
            type: "POST",
            data: JSON.stringify({"role": p}),
            success: function () {
                loadRoles();
                $("#role_modify").hide();
            }
            // TODO 处理异常
        });
    }
    /*删除一个角色*/
    function role_delete(role_id) {
        // TODO 提示用户确认
        $.ajax({
            url: home_base + "/admin/authority/role/delete",
            type: "POST",
            data: JSON.stringify({id: role_id})
        });
        loadRoles();
    }
    /*新增角色*/
    function role_add() {
        var role_name = prompt("请输入新角色的名称,仅限英文字母,长度3到10个字符");
        var re = /[a-zA-Z]{3,10}/;
        if (role_name && re.exec(role_name)) {
            $.ajax({
                url: home_base + "/admin/authority/role/add",
                type: "POST",
                data: JSON.stringify({name: role_name}),
                success: function () {
                    loadRoles();
                }
            });
        }
    }
    /*更新角色所拥有的权限列表,这个方法用于显示多选框*/
    function role_permission_update(role_id) {
        $.ajax({
            url: home_base + "/admin/authority/role/fetch",
            dataType: "json",
            data: {id: role_id},
            success: function (re) {
                if (re && re.ok) {
                    console.log(re.data);
                    var html = "";
                    var ps = re.data.permissions;
                    for (var i = 0; i < ps.length; i++) {
                        var p = ps[i];
                        var flag = false;
                        for (var j = 0; j < re.data.role.permissions.length; j++) {
                            if (re.data.role.permissions[j].id == p.id) {
                                flag = true;
                                break;
                            }
                        }
                        if (p.alias) {
                            html += p.alias;
                        } else {
                            html += p.name;
                        }
                        if (flag) {
                            html += "<input type='checkbox' t='checkbox_role_permission' pid='" + p.id + "' checked='true'>\n"
                        } else {
                            html += "<input type='checkbox' t='checkbox_role_permission' pid='" + p.id + "'>\n"
                        }
                    }
                    $("#role_permission_modify_id").val("" + role_id);
                    $("#role_permission_modify_name").val("" + re.data.role.name);
                    $("#role_permissions_div").html(html);
                    $("#role_permission_modify").show();
                }
            }
        });
    }
    /*将角色的权限列表提交到服务器去*/
    function role_permission_modify_submit() {
        var role_id = $("#role_permission_modify_id").val();
        var ps = $("input[t='checkbox_role_permission']:checked");
        console.log(ps);
        console.log(role_id);
        var pids = [];
        ps.each(function (i, p_input) {
            pids.push($(p_input).attr("pid"));
        });
        $.ajax({
            url: home_base + "/admin/authority/role/update",
            type: "POST",
            data: JSON.stringify({"role": {id: role_id}, "permissions": pids}),
            success: function () {
                loadRoles();
                $("#role_permission_modify").hide();
            }
        });
    }
    /*更新权限的一般信息,显示输入框*/
    function permission_update(permission_id) {
        for (var i = 0; i < _r._permissions.list.length; i++) {
            var permission = _r._permissions.list[i];
            if (permission.id == permission_id) {
                $("#permission_modify_id").attr("value", permission_id);
                $("#permission_modify_alias").attr("value", permission.alias);
                $("#permission_modify_description").attr("value", permission.description);
                $("#permission_modify").show();
                return;
            }
        }
    }
    /*把权限的一般信息的修改提交到服务器*/
    function permission_update_submit() {
        var permission_id = $("#permission_modify_id").val();
        var p = {id: permission_id};
        p["alias"] = $("#permission_modify_alias").val();
        p["description"] = $("#permission_modify_description").val();
        console.log(p);
        $.ajax({
            url: home_base + "/admin/authority/permission/update",
            type: "POST",
            data: JSON.stringify(p),
            success: function () {
                loadPermissions();
                $("#permission_modify").hide();
            }
        });
    }
    /*删除一个权限*/
    function permission_delete(permission_id) {
        $.ajax({
            url: home_base + "/admin/authority/permission/delete",
            type: "POST",
            data: JSON.stringify({id: permission_id}),
            success: function () {
                loadPermissions();
                $("#permission_modify").hide();
            }
        });
        loadPermissions();
    }
    /*新增一个权限*/
    function permission_add() {
        var permission_name = prompt("请输入新角色的名词,仅限英文字母/冒号/米号,长度3到30个字符");
        var re = /[a-zA-Z\:\*]{3,10}/;
        if (permission_name && re.exec(permission_name)) {
            $.ajax({
                url: home_base + "/admin/authority/permission/add",
                type: "POST",
                data: JSON.stringify({name: permission_name}),
                success: function () {
                    loadPermissions();
                }
            });
        }
    }


    var home_base = '${base}';
    $(function () {
        myInit();
    });


</script>

测试页面

重启jetty 访问 http://127.0.0.1:8080/ 并登陆
再访问 http://127.0.0.1:8080/page/simple_role.jsp

默显示用户列表及其权限

点击顶部的角色一览,权限一览也可以对角色和权限管理。
访问 http://127.0.0.1:8080/user/logout 强制退出后

用没有角色的用户qq登陆后再访问 http://127.0.0.1:8080/page/simple_role.jsp 就会提示user.require.auth