summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorTed Trask <ttrask01@yahoo.com>2008-04-21 20:55:44 +0000
committerTed Trask <ttrask01@yahoo.com>2008-04-21 20:55:44 +0000
commit5e1d9734d9dc849c21e84a45913fb2d22b7dfdf0 (patch)
tree7845e677b2b36c3f8090b7e424284a28fa397713 /lib
parented9bf961c16e1f9d58f39ebb1afc289e5564ebfe (diff)
downloadacf-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.lua214
-rw-r--r--lib/roles.lua109
-rw-r--r--lib/session.lua95
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)