require("fwutils.webapi") -- CREATE TABLE `fw_role_permissions` ( -- `id` int NOT NULL AUTO_INCREMENT, -- `path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '路径', -- `role_id` int DEFAULT NULL COMMENT '角色', -- `action` varchar(2048) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '动作', -- `desc` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '描述', -- `create_time` datetime DEFAULT NULL COMMENT '创建时间', -- `update_time` datetime DEFAULT NULL COMMENT '更新时间', -- `delete_time` datetime DEFAULT NULL COMMENT '删除时间', -- PRIMARY KEY (`id`), -- UNIQUE KEY `path` (`path`,`role_id`) -- ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Fastweb-角色访问权限'; local M = {} M.get_by_id = function(id,conn) local select = conn:select() select:table("fw_role_permissions LEFT JOIN fw_role ON fw_role_permissions.role_id = fw_role.id") select:field({ "fw_role_permissions.id", "fw_role_permissions.path", "fw_role_permissions.role_id", "fw_role_permissions.action", "fw_role_permissions.`desc`", "fw_role_permissions.create_time", "fw_role_permissions.update_time", "fw_role_permissions.delete_time", "fw_role.title as role_title", "fw_role.id as role_id", }) select:where_i32("fw_role_permissions.id","=",id) select:where_expression("AND fw_role_permissions.delete_time IS NULL") select:limit(0,1) local result = select:query() if result:row_count() == 0 then return nil end local d = result:table()[1] return d end M.add = function(data,conn) local insert = conn:insert() insert:table("fw_role_permissions") insert:set_str("path",data.path) insert:set_i32("role_id",data.role_id) if data.action ~= nil then insert:set_str("action",data.action) end if data.desc ~= nil then insert:set_str("`desc`",data.desc) end insert:set_not_ppst("create_time","NOW()") local d = insert:exec() return d == 1 end M.update = function(data,conn) local update = conn:update() update:table("fw_role_permissions") if data.path ~= nil then update:set_str("path",data.path) end if data.action ~= nil then update:set_str("action",data.action) end if data.desc ~= nil then update:set_str("`desc`",data.desc) end if data.role_id ~= nil then update:set_i32("role_id",data.role_id) end update:set("update_time=NOW()") update:where_i32("id","=",data.id) local d = update:exec() return d == 1 end M.delete = function(id,conn) local update = conn:update() update:table("fw_role_permissions") update:set("delete_time=NOW()") update:where_i32("id","=",id) local d = update:exec() return d == 1 end M.list = function(search,limit,conn) if search.role_id == -1 then return { count = 0, data = {} } end return query_model_ex(conn,[=[ fw_role_permissions LEFT JOIN fw_role ON fw_role_permissions.role_id = fw_role.id ]=],{ "fw_role_permissions.id", "fw_role_permissions.path", "fw_role_permissions.role_id", "fw_role_permissions.action", "fw_role_permissions.`desc`", "fw_role_permissions.create_time", "fw_role_permissions.update_time", "fw_role_permissions.delete_time", "fw_role.title as role_title", "fw_role.id as role_id", },limit.start,limit.length,function(sel) if search.role_id ~= nil and search.role_id ~= 0 then sel:where_i32("fw_role_permissions.role_id","=",search.role_id) end sel:where_expression("AND fw_role_permissions.delete_time IS NULL") end,function(sel_data) sel_data:orderby("fw_role_permissions.create_time DESC") end) end -- 更新 M.make_bytecode = function(role_id,conn) -- 查询权限表 local select = conn:select() select:table("fw_role_permissions") select:where_expression("AND delete_time IS NULL") if role_id ~= nil then select:where_i32("role_id", "=", role_id) end local result = select:query() local bc = {} while result:next() do local id = result:get("id") local path = result:get("path") local role_id = tostring(result:get("role_id")) local action = result:get("action") local desc = result:get("desc") local create_time = result:get("create_time") local update_time = result:get("update_time") local delete_time = result:get("delete_time") -- local public = result:get("public") if bc[role_id] == nil then bc[role_id] = {} end if bc[role_id]["public"] == nil then bc[role_id]["public"] = {} end if bc[role_id]["private"] == nil then bc[role_id]["private"] = {} end -- 处理 action 字段,将其切分为表或空表 local actions_tbl = {} if action and action ~= "" then for act in string.gmatch(action, "([^,]+)") do table.insert(actions_tbl, act) end end local item = { create_time = create_time, update_time = update_time, delete_time = delete_time, action = actions_tbl, desc = desc, } -- if public == 1 then -- bc[role_id]["public"][path] = item -- else -- bc[role_id]["private"][path] = item -- end bc[role_id][path] = item end local code = "return " .. require("serpent").serialize(bc, {comment = false}) utils.save_file(fw.website_dir().."/"..(fwutils_config.path.luabytecode:gsub("%.", "/")).."/acl_bc.lua",code) return true end -- 匹配 M.match = function(cfg) local function match_path(path, patterns) -- print("[match_path] path:",path) for pattern, v in pairs(patterns) do -- 如果是正则(以^开头),用string.match,否则精确匹配 if string.sub(pattern, 1, 1) == "^" then if string.match(path, pattern) then -- print("[TRUE] pattern:",pattern,",path:",path) return true, v -- else -- print("[FALSE] pattern:",pattern,",path:",path) end else if path == pattern then return true, v end end end return false, nil end -- 检查action local function check_action(actions,action) if actions == nil or #actions == 0 then return true end for _,v in pairs(actions) do if v == action then return true end end return false, "action not match" end local role_id_str = string.format("%d",cfg.role_id()) local acl_bc = require(fwutils_config.path.luabytecode..".acl_bc") if acl_bc[role_id_str] == nil then return false,"role id("..role_id_str..") acl not found" end local result, item = match_path(cfg.filepath(), acl_bc[role_id_str]) if result then return check_action(item.action,cfg.action()) end return false,"path("..cfg.filepath()..") acl not found" end return M