diff options
author | Ted Trask <ttrask01@yahoo.com> | 2008-04-21 20:55:44 +0000 |
---|---|---|
committer | Ted Trask <ttrask01@yahoo.com> | 2008-04-21 20:55:44 +0000 |
commit | 5e1d9734d9dc849c21e84a45913fb2d22b7dfdf0 (patch) | |
tree | 7845e677b2b36c3f8090b7e424284a28fa397713 /lib | |
parent | ed9bf961c16e1f9d58f39ebb1afc289e5564ebfe (diff) | |
download | acf-core-5e1d9734d9dc849c21e84a45913fb2d22b7dfdf0.tar.bz2 acf-core-5e1d9734d9dc849c21e84a45913fb2d22b7dfdf0.tar.xz |
Ted's Logon/permissions changes
git-svn-id: svn://svn.alpinelinux.org/acf/core/trunk@1030 ab2d0c66-481e-0410-8bed-d214d4d58bed
Diffstat (limited to 'lib')
-rw-r--r-- | lib/menubuilder.lua | 214 | ||||
-rw-r--r-- | lib/roles.lua | 109 | ||||
-rw-r--r-- | lib/session.lua | 95 |
3 files changed, 189 insertions, 229 deletions
diff --git a/lib/menubuilder.lua b/lib/menubuilder.lua index 1d4c974..c7ff075 100644 --- a/lib/menubuilder.lua +++ b/lib/menubuilder.lua @@ -10,157 +10,115 @@ module(..., package.seeall) -- startdir should be the app dir. local get_candidates = function (startdir) local t = {} - startdir = startdir .. "/" local fh = io.popen('find ' .. startdir .. ' -name "*.menu"') - - local start = string.gsub(startdir, "/$", "") for x in fh:lines() do - table.insert (t, (string.gsub(x, start, ""))) + t[#t + 1] = x end - return t end +-- Split string into priority and name, convert '_' to space +local parse_menu_entry = function (entry) + local name, priority + if (string.match(entry, "^%d")) then + priority, name = string.match(entry, "(%d+)(.*)") + else + name = entry + end + name = string.gsub(name, "_", " ") + return name, priority +end --- internal function for table.sort -local t_compare = function (x,y,f) - for k,v in pairs(f) do - local a = x[v] - local b = y[v] - if tonumber(a) and tonumber(b) then - a=tonumber(a) - b=tonumber(b) - end - if a < b then return true end - if a > b then return false end +-- Parse menu file entry, returning cat, group, tab, action and priorities +local parse_menu_line = function (line) + local result = nil + --skip comments and blank lines + if nil == (string.match(line, "^#") or string.match(line,"^$")) then + local item = {} + for i in string.gmatch(line, "%S+") do + item[#item + 1] = i end - return false - end - --- Returns a table of all submenu items found --- Displayorder of the tabs comes from the order in the .menu files -get_submenuitems = function (startdir) - local t = {} - local menuitems = get_menuitems(startdir) - - for k,v in pairs(menuitems) do - if (menuitems[k]["tab"] ~= "") then - if not (t[menuitems[k]["controller"]]) then t[menuitems[k]["controller"]] = {} end - table.insert (t[menuitems[k]["controller"]], {tab=menuitems[k]["tab"],action=menuitems[k]["action"]}) + if #item >= 1 then + result = {} + result.cat, result.cat_prio = parse_menu_entry(item[1]) + if (item[2]) then result.group, result.group_prio = parse_menu_entry(item[2]) end + if (item[3]) then result.tab = parse_menu_entry(item[3]) end + if (item[4]) then result.action = parse_menu_entry(item[4]) end end end + return result +end - return t +-- Function to compare priorities, missing priority moves to the front, same priority sorted alphabetically +local prio_compare = function(x,y) + if x.priority == y.priority then + if x.name < y.name then return true end + return false + end + if nil == x.priority then return true end + if nil == y.priority then return false end + if tonumber(x.priority) < tonumber(y.priority) then return true end + return false end -- returns a table of all the menu items found, sorted by priority --- Table format: prefix controller cat group tab action get_menuitems = function (startdir) - local t = {} - for k,v in pairs(get_candidates(startdir)) do - local prefix, controller = mvc.dirname(v), mvc.basename(v, ".menu") - -- open the thing, and parse the contents - local fh = io.open(startdir .. "/" .. v) - local prio = 10 - for x in fh:lines() do - local c = string.match(x, "^#") or string.match(x,"^$") - if c == nil then - local item = {} - for i in string.gmatch(x, "%S+") do - table.insert(item, i) + local cats = {} + local reversecats = {} + startdir = (string.gsub(startdir, "/$", "")) --remove trailing / + for k,filename in pairs(get_candidates(startdir)) do + local controller = mvc.basename(filename, ".menu") + local prefix = (string.gsub(mvc.dirname(filename), startdir, "")) + + -- open the menu file, and parse the contents + local handle = io.open(filename) + for x in handle:lines() do + local result = parse_menu_line(x) + if result then + for i = 1,1 do -- loop so break works + -- Add the category + if nil == reversecats[result.cat] then + table.insert ( cats, + { name=result.cat, + groups = {}, + reversegroups = {} } ) + reversecats[result.cat] = #cats + end + local cat = cats[reversecats[result.cat]] + cat.priority = cat.priority or result.cat_prio + -- Add the group + if nil == result.group then break end + if nil == cat.groups[cat.reversegroups[result.group]] then + table.insert ( cat.groups, + { name = result.group, + controller = controller, + prefix = prefix, + tabs = {} } ) + cat.reversegroups[result.group] = #cat.groups + end + local group = cat.groups[cat.reversegroups[result.group]] + group.priority = group.priority or result.group_prio + -- Add the tab + if nil == result.tab or nil == result.action then break end + local tab = { name = result.tab, action = result.action } + table.insert(group.tabs, tab) end - table.insert(t, { prefix=prefix, - controller=controller, - catprio="nan", - cat=item[1] or "", - groupprio="nan", - group=item[2] or "", - tabprio=tostring(prio), - tab=item[3] or "", - action=item[4] or "" }) - prio=prio+5 - end - end - fh:close() - end - -- Ok, we now have the raw menu table - -- now try to parse out numbers in front of any cat, group or tabs - for x in ipairs(t) do - local f = t[x] - if (string.match(f.cat, "^%d")) then - f.catprio, f.cat = string.match(f.cat, "(%d+)(.*)") - end - if (string.match(f.group, "^%d")) then - f.groupprio, f.group = string.match(f.group, "(%d+)(.*)") - end - if (string.match(f.tab, "^%d")) then - f.tabprio, f.tab = string.match(f.tab, "(%d+)(.*)") - end - end - - -- Convert underscores to spaces - for x in ipairs(t) do - t[x].cat = string.gsub(t[x].cat, "_", " ") - t[x].group = string.gsub(t[x].group, "_", " ") - t[x].tab = string.gsub(t[x].tab, "_", " ") - end - - -- Now alpha sort - table.sort(t, function(x,y) - return t_compare (x,y,{"cat", "catprio", "group", "groupprio", "tab", "tabprio"} ) - end) - - -- Fill in the priorities - local fill_prio = function (t, start, stop, col) - local prio = t[start][col] - if prio == "nan" then prio = "0" end - while start <= stop do - t[start][col] = prio - start = start + 1 - end - end - - --- Fill in the priorities --- Warning - UGLY code ahead. --- Basic rules, for each cat and group, if the prio is nan, then set it --- to the lowest value for that group or cat. - local k = 1 - while ( k <= table.maxn(t) ) do - local c = k - while ( c <= table.maxn(t) and t[c].cat == t[k].cat ) do - c=c+1 - end - c=c-1 -- back up one - we only want whats the same - fill_prio(t,k,c,"catprio") - -- from k,c is a mini table, do the same for groupprio - local g = k - while ( g <= c ) do - local h = g - while ( h <= c and t[h].group == t[g].group ) do - h=h+1 end - h=h-1 --- back up one (again) - fill_prio(t,g,h,"groupprio") - g=h+1 end - k = c + 1 + handle:close() end - - -- Now priority sort - table.sort(t, function(x,y) - return t_compare (x,y,{"catprio", "cat", "groupprio", "group", "tabprio", "tab"} ) - end) + -- Now that we have the entire menu, sort by priority + -- Categories first + table.sort(cats, prio_compare) - -- drop the priorities - they were internal - for k,v in ipairs(t) do - v.catprio = nil - v.groupprio = nil - v.tabprio = nil + -- Then groups + for x, cat in ipairs(cats) do + cat.reversegroups = nil -- don't need reverse table anymore + table.sort(cat.groups, prio_compare) end - return t + return cats end diff --git a/lib/roles.lua b/lib/roles.lua index bdaf635..806be67 100644 --- a/lib/roles.lua +++ b/lib/roles.lua @@ -7,75 +7,102 @@ require ("format") module (..., package.seeall) +-- Return a list of *controller.lua files list_controllers = function(self) -local list = {} -local f = io.popen("/usr/bin/find /usr/share/acf/ |/bin/grep \"controller.lua$\" ") - for a in f:lines() do - list[#list + 1 ] = a - end -f:close() -return list + local list = {} + local f = io.popen("/usr/bin/find /usr/share/acf/ |/bin/grep \"controller.lua$\" ") + for a in f:lines() do + list[#list + 1 ] = a + end + f:close() + return list end +-- Return information about all or specified controller files get_controllers = function(self,controller) --we get all the controllers local list = roles.list_controllers() --we need to grab the directory and name of file local temp = {} for k,v in pairs(list) do - path = string.match(v,"[/%w-]+/") - filename = string.match(v,"[^/]*.lua") - name = string.match(filename,"[^.]*") - sname = string.match(filename,"[^-]*") - temp[sname] = {path=path,filename=filename,name=name,sname=sname} + path = string.match(v,"[/%w-]+/") + filename = string.match(v,"[^/]*.lua") + name = string.match(filename,"[^.]*") + sname = string.match(filename,"[^-]*") + temp[sname] = {path=path,filename=filename,name=name,sname=sname} + end + if controller then + return temp[controller] + else + return temp end - if controller then - return temp[controller] - else - return temp - end - end +-- Find all public functions in a controller get_controllers_func = function(self,controller_info) if controller_info == nil then - return "Could not be processed" + return "Could not be processed" else package.path=package.path .. ";" .. controller_info.path .. "?.lua" temp = require (controller_info.name) temp1 = {} for a,b in pairs(temp) do - local c = string.match(a,"mvc") or string.match(a,"^_") - if c == nil then - temp1[#temp1 +1] = a + local c = string.match(a,"mvc") or string.match(a,"^_") + if c == nil then + temp1[#temp1 +1] = a + end end -end --require (controller_info.name) --we need to go through bobo and take out the mvc func and locals and -- return temp1 end end -get_roles_perm = function(self,roles) - --for now we are using the file static - --this will go through and search from the roles in sessionid to get the real - --permission list - local rolesfile = "/etc/acf/roles" - f = fs.read_file_as_array(rolesfile) - local temp = {} - for k,v in pairs(roles) do - for a,b in pairs(f) do - match = "^" .. v - c = string.match(b,match) - if c then - inval = string.match(b,"[,%w:]+$") - temp[#temp +1] = inval - end +-- returns a table of the *.roles files +-- startdir should be the app dir +local get_roles_candidates = function (startdir) + local t = {} + local fh = io.popen('find ' .. startdir .. ' -name "*.roles"') + for x in fh:lines() do + t[#t + 1] = x + end + return t +end + +-- Go through the roles files and determine the permissions for the specified roles +get_roles_perm = function(startdir,roles) + permissions = {} + + -- find all of the roles files and add in the master file + local rolesfiles = get_roles_candidates(startdir) + rolesfiles[#rolesfiles + 1] = "/etc/acf/roles" + + local reverseroles = {} + for x,role in ipairs(roles) do + reverseroles[role] = {} + end + reverseroles["ALL"] = {} -- always include ALL role + + for x,file in ipairs(rolesfiles) do + f = fs.read_file_as_array(file) + for y,line in pairs(f) do + if reverseroles[string.match(line,"^[%a]+")] then + temp = format.string_to_table(string.match(line,"[,%a:]+$"),",") + for z,perm in pairs(temp) do + local control,action = string.match(perm,"(%a+):(%a+)") + if control then + if nil == permissions[control] then + permissions[control] = {} + end + if action and nil == permissions[control][action] then + permissions[control][action] = {} + end + end + end + end end end - temp1 = format.table_to_string(temp,",") - --we now can return the first level of roles perms. What if a role is a member of a role... - return temp1 + return permissions end diff --git a/lib/session.lua b/lib/session.lua index 18a0c7b..bd2bdf6 100644 --- a/lib/session.lua +++ b/lib/session.lua @@ -91,29 +91,30 @@ function serialize (name, value, saved ) return str end -save_session = function( sessionpath, session, sessiontable) - local file = io.open(sessionpath .. "/session." .. session , "w") - if file == nil then - return nil - end - - local id = sessiontable.id +-- Save the session (unless all it contains is the id) +-- return true or false for success +save_session = function( sessionpath, sessiontable) + if nil == sessiontable or nil == sessiontable.id then return false end - -- clear the id key + -- clear the id key, don't need to store that + local id = sessiontable.id sessiontable.id = nil - -- count the keys - local count = 0 - for k,v in pairs (sessiontable) do - count = count + 1 - end + -- If the table only has an "id" field, then don't save it - if count > 1 and file then + if #sessiontable then + local file = io.open(sessionpath .. "/session." .. id , "w") + if file == nil then + sessiontable.id=id + return false + end + file:write ( "-- This is an ACF session table.\n") file:write ( "\nlocal " ) file:write ( serialize("s", sessiontable) ) file:write ( "return s\n") + file:close() end - file:close() + sessiontable.id=id return true end @@ -121,8 +122,9 @@ end -- Loads a session -- Returns a timestamp (when the session data was saved) and the session table. --- We insert a "id" field from the "session" +-- Insert the session into the "id" field load_session = function ( sessionpath, session ) + if type(session) ~= "string" then return nil, {} end local s = {} -- session can only have b64 characters in it session = string.gsub ( session or "", "[^" .. b64 .. "]", "") @@ -140,7 +142,8 @@ load_session = function ( sessionpath, session ) end end --- unlinks a session +-- Unlinks a session (deletes the session file) +-- return nil for failure, ?? for success unlink_session = function (sessionpath, session) if type(session) ~= "string" then return nil end local s = string.gsub (session, "[^" .. b64 .. "]", "") @@ -152,28 +155,6 @@ unlink_session = function (sessionpath, session) return statos end ---need to see if this is a "real"-user session or just a temp one. -check_session = function (sessionpath, session ) - if session == nil then return "an unknown user" end - local fullpath = sessionpath .. "/session." .. session - if posix.stat(fullpath) == nil then return "an unknown user" end - if type(session) ~= "string" then return nil end - local s = string.gsub (session, "[^" .. b64 .. "]", "") - if s ~= session then - return nil - end - check_size = posix.stat(fullpath,"size") - if check_size == 0 then - return "an unknown user" - else - local c = dofile(fullpath).userinfo.userid - local d = dofile(fullpath).userinfo.roles - return c,d - end - - -end - -- Record an invalid login event -- ID would typically be an ip address or username -- the format is lockevent.id.datetime.processid @@ -197,29 +178,23 @@ count_events = function (sessionpath, id_user, ipaddr) local t = posix.glob(searchfor) if t == nil or id_user == nil or ipaddr == nil then - return false - else - - local temp = {} - for a,b in pairs(t) do - if posix.stat(b,"mtime") > minutes_ago then - temp[#temp + 1] = b end - end - - local temp2 = {} - for k,v in pairs(temp) do - local c = string.match(v,id_user) or string.match(v,ipaddr) - if c ~= nil then temp2[#temp2 + 1] = v end - end - - if #temp2 > limit_count_events then - return true + return false else - return false - end - end - + local count = 0 + for a,b in pairs(t) do + if posix.stat(b,"mtime") > minutes_ago then + if string.match(b,id_user) or string.match(b,ipaddr) then + count = count + 1 + end + end + end + if count>limit_count_events then + return true + else + return false + end end +end -- Clear events that are older than n minutes expired_events = function (sessionpath) |