summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/acf-util/logon-controller.lua3
-rw-r--r--app/acf_www-controller.lua421
-rw-r--r--app/template-html.lsp4
-rwxr-xr-xwww/cgi-bin/mvc.lua114
4 files changed, 307 insertions, 235 deletions
diff --git a/app/acf-util/logon-controller.lua b/app/acf-util/logon-controller.lua
index 8d4f57e..2a55c7a 100644
--- a/app/acf-util/logon-controller.lua
+++ b/app/acf-util/logon-controller.lua
@@ -13,8 +13,7 @@ logon = function(self)
local logon = self.model:logon(clientdata, conf.clientip, conf.sessiondir, sessiondata)
-- If successful logon, redirect to welcome-page, otherwise try again
if logon.value then
- self.conf.controller = ""
- redirect(self, "")
+ redirect(self, "/welcome/read")
else
cmdresult.errtxt = "Logon Attempt Failed"
end
diff --git a/app/acf_www-controller.lua b/app/acf_www-controller.lua
index 8f2a33f..55602fa 100644
--- a/app/acf_www-controller.lua
+++ b/app/acf_www-controller.lua
@@ -20,11 +20,11 @@ local function build_menus(self)
-- Build the permissions table
local roles = {}
- if sessiondata.userinfo and sessiondata.userinfo.roles then
- roles = sessiondata.userinfo.roles
+ if self.sessiondata.userinfo and self.sessiondata.userinfo.roles then
+ roles = self.sessiondata.userinfo.roles
end
local permissions = roll.get_roles_perm(self.conf.appdir,roles)
- sessiondata.permissions = permissions
+ self.sessiondata.permissions = permissions
--Build the menu
local cats = m.get_menuitems(self.conf.appdir)
@@ -52,11 +52,69 @@ local function build_menus(self)
table.remove(cats, x)
end
end
- sessiondata.menu = {}
- sessiondata.menu.cats = cats
+ self.sessiondata.menu = {}
+ self.sessiondata.menu.cats = cats
-- Debug: Timestamp on menu creation
- sessiondata.menu.timestamp = {tab="Menu_created: " .. os.date(),action="Menu_created: " .. os.date(),}
+ self.sessiondata.menu.timestamp = {tab="Menu_created: " .. os.date(),action="Menu_created: " .. os.date(),}
+end
+
+local check_permission = function(self, controller, action)
+ logevent("Trying " .. (controller or "nil") .. ":" .. (action or "nil"))
+ if nil == self.sessiondata.permissions then return false end
+ if controller then
+ if nil == self.sessiondata.permissions[controller] then return false end
+ if action and nil == self.sessiondata.permissions[controller][action] then return false end
+ end
+ return true
+end
+
+-- look for a template
+-- ctlr-action-view, then ctlr-view, then action-view, then view
+-- cannot be local function because of recursion
+find_template = function ( appdir, prefix, controller, action, viewtype )
+ local targets = {
+ appdir .. prefix .. "template-" .. controller .. "-" ..
+ action .. "-" .. viewtype .. ".lsp",
+ appdir .. prefix .. "template-" .. controller .. "-" ..
+ viewtype .. ".lsp",
+ appdir .. prefix .. "template-" .. action .. "-" ..
+ viewtype .. ".lsp",
+ appdir .. prefix .. "template-" .. viewtype .. ".lsp"
+ }
+ local file
+ for k,v in pairs(targets) do
+ file = io.open (v)
+ if file then
+ io.close (file)
+ return v
+ end
+ end
+ -- not found, so try one level higher
+ if prefix == "" then -- already at the top level - fail
+ return nil
+ end
+ prefix = dirname (prefix)
+ return find_template ( appdir, prefix, controller, action, viewtype )
+end
+
+-- look for a view
+-- ctlr-action-view, then ctlr-view
+local find_view = function ( appdir, prefix, controller, action, viewtype )
+ local names = { appdir .. prefix .. controller .. "-" ..
+ action .. "-" .. viewtype .. ".lsp",
+ appdir .. prefix .. controller .. "-" ..
+ viewtype .. ".lsp" }
+ local file
+ -- search for view
+ for i,filename in ipairs (names) do
+ file = io.open(filename)
+ if file then
+ file:close()
+ return filename
+ end
+ end
+ return nil
end
-- This function is made available within the view to allow loading of components
@@ -99,13 +157,75 @@ local create_helper_library = function ( self )
return library
end
+-- Our local view resolver called by our dispatch
+local view_resolver = function(self)
+ local template, viewname, viewlibrary
+ local viewtype = self.conf.viewtype or "html"
+
+ -- search for template
+ if self.conf.component ~= true then
+ template = find_template ( self.conf.appdir, self.conf.prefix,
+ self.conf.controller, self.conf.action, viewtype )
+ end
+
+ -- search for view
+ viewname = find_view ( self.conf.appdir, self.conf.prefix,
+ self.conf.controller, self.conf.action, viewtype )
+
+ -- create the view helper library
+ viewlibrary = create_helper_library ( self )
+
+ -- ***************************************************
+ -- This is how to call another controller (APP or self
+ -- can be used... m will contain worker and model,
+ -- with conf, and other "missing" parts pointing back
+ -- to APP or self
+ -- ***************************************************
+
+ local m,worker_loaded,model_loaded = self:new("alpine-baselayout/hostname")
+
+ -- If the worker and model loaded correctly, then
+ -- use the sub-controller
+ local h
+ if worker_loaded and model_loaded then
+ h = m.worker.read(m)
+ else
+ h = {}
+ h.hostname = { value = "unknown" }
+ end
+
+ local pageinfo = { viewfile = viewname,
+ controller = m.conf.controller,
+ -- ^^^ see.. m.conf doesnt exist - but it works
+ -- the inheritance means self.conf is used instead
+ action = self.conf.action,
+ hostname = h.hostname.value,
+ -- alpineversion = alpineversion.worker.read(alpineversion),
+ prefix = self.conf.prefix,
+ script = self.conf.appuri,
+ skin = self.conf.skin or ""
+ }
+
+ m:destroy()
+
+ local func = function() end
+ if template then
+ -- We have a template
+ func = haserl.loadfile (template)
+ elseif viewname then
+ -- No template, but have a view
+ func = haserl.loadfile (viewname)
+ end
+ return func, viewlibrary, pageinfo, self.sessiondata
+end
+
mvc = {}
mvc.on_load = function (self, parent)
-- open the log file
self.conf.logfile = io.open ("/var/log/acf.log", "a+")
--logevent("acf_www-controller mvc.on_load")
-
+
-- Make sure we have some kind of sane defaults for libdir and sessiondir
self.conf.libdir = self.conf.libdir or ( self.conf.appdir .. "/lib/" )
self.conf.sessiondir = self.conf.sessiondir or "/tmp/"
@@ -180,152 +300,22 @@ end
mvc.on_unload = function (self)
sessionlib=require ("session")
- if sessiondata.id then
- sessionlib.save_session(conf.sessiondir, sessiondata)
+ if self.sessiondata.id then
+ sessionlib.save_session(self.conf.sessiondir, self.sessiondata)
end
-- Close the logfile
--logevent("acf_www-controller mvc.on_unload")
- conf.logfile:close()
-end
-
-mvc.check_permission = function(self, controller, action)
- logevent("Trying " .. (controller or "nil") .. ":" .. (action or "nil"))
- if nil == self.sessiondata.permissions then return false end
- if controller then
- if nil == self.sessiondata.permissions[controller] then return false end
- if action and nil == self.sessiondata.permissions[controller][action] then return false end
- end
- return true
-end
-
--- look for a template
--- ctlr-action-view, then ctlr-view, then action-view, then view
-
-find_template = function ( appdir, prefix, controller, action, viewtype )
- local targets = {
- appdir .. prefix .. "template-" .. controller .. "-" ..
- action .. "-" .. viewtype .. ".lsp",
- appdir .. prefix .. "template-" .. controller .. "-" ..
- viewtype .. ".lsp",
- appdir .. prefix .. "template-" .. action .. "-" ..
- viewtype .. ".lsp",
- appdir .. prefix .. "template-" .. viewtype .. ".lsp"
- }
- local file
- for k,v in pairs(targets) do
- file = io.open (v)
- if file then
- io.close (file)
- return v
- end
- end
- -- not found, so try one level higher
- if prefix == "" then -- already at the top level - fail
- return nil
- end
- prefix = dirname (prefix)
- return find_template ( appdir, prefix, controller, action, viewtype )
-end
-
--- look for a view
--- ctlr-action-view, then ctlr-view
-
-find_view = function ( appdir, prefix, controller, action, viewtype )
- local names = { appdir .. prefix .. controller .. "-" ..
- action .. "-" .. viewtype .. ".lsp",
- appdir .. prefix .. controller .. "-" ..
- viewtype .. ".lsp" }
- local file
- -- search for view
- for i,filename in ipairs (names) do
- file = io.open(filename)
- if file then
- file:close()
- return filename
- end
- end
- return nil
-end
-
--- Overload the MVC's view resolver with our own
-
-view_resolver = function(self)
- local template, viewname, viewlibrary
- local viewtype = self.conf.viewtype or "html"
-
- -- search for template
- if self.conf.component ~= true then
- template = find_template ( self.conf.appdir, self.conf.prefix,
- self.conf.controller, self.conf.action, viewtype )
- end
-
- -- search for view
- viewname = find_view ( self.conf.appdir, self.conf.prefix,
- self.conf.controller, self.conf.action, viewtype )
-
- -- create the view helper library
- viewlibrary = create_helper_library ( self )
-
- -- We have a template
- if template then
- -- ***************************************************
- -- This is how to call another controller (APP or self
- -- can be used... m will contain worker and model,
- -- with conf, and other "missing" parts pointing back
- -- to APP or self
- -- ***************************************************
-
- local m,worker_loaded,model_loaded = self:new("alpine-baselayout/hostname")
- --local alpineversion = self:new("alpine-baselayout/alpineversion")
-
- -- If the worker and model loaded correctly, then
- -- use the sub-controller
- local h
- if worker_loaded and model_loaded then
- h = m.worker.read(m)
- else
- h = {}
- h.hostname = { value = "unknown" }
- end
-
- local pageinfo = { viewfile = viewname,
- controller = m.conf.controller,
- -- ^^^ see.. m.conf doesnt exist - but it works
- -- the inheritance means self.conf is used instead
- action = self.conf.action,
- hostname = h.hostname.value,
- -- alpineversion = alpineversion.worker.read(alpineversion),
- prefix = self.conf.prefix,
- script = self.conf.appuri,
- skin = self.conf.skin or ""
- }
-
- m:destroy()
-
- return function (viewtable)
- local template = haserl.loadfile (template)
- return template ( pageinfo, viewtable, self.sessiondata, viewlibrary )
- end
- end
-
- -- No template, but have a view
- if viewname then
- return function (viewtable)
- local viewfunction = haserl.loadfile (viewname)
- return viewfunction ( viewtable, viewlibrary )
- end
- else
- return function() end
- end
+ self.conf.logfile:close()
end
+-- Overload the MVC's exception handler with our own to handle redirection
exception_handler = function (self, message )
local html = require ("html")
if type(message) == "table" then
if message.type == "redir" and self.conf.component == true then
io.write ("Component cannot be found")
elseif message.type == "redir" or message.type == "redir_to_referrer" then
- if sessiondata.id then logevent("Redirecting " .. sessiondata.id) end
+ if self.sessiondata.id then logevent("Redirecting " .. self.sessiondata.id) end
io.write ("Status: 302 Moved\n")
if message.type == "redir" then
io.write ("Location: " .. ENV["SCRIPT_NAME"] ..
@@ -349,6 +339,147 @@ exception_handler = function (self, message )
end
end
+-- Overload the MVC's dispatch function with our own
+-- check permissions and redirect if not allowed to see
+-- pass more parameters to the view
+dispatch = function (self, userprefix, userctlr, useraction)
+ local controller = nil
+ local success, err = xpcall ( function ()
+
+ if userprefix == nil then
+ self.conf.prefix, self.conf.controller, self.conf.action =
+ parse_path_info(ENV["PATH_INFO"])
+ else
+ self.conf.prefix = userprefix
+ self.conf.controller = userctlr or ""
+ self.conf.action = useraction or ""
+ end
+
+ -- Find the proper controller/action combo
+ local origconf = {controller = self.conf.controller, action = self.conf.action}
+ local action = ""
+ local default_prefix = self.conf.default_prefix or "/"
+ local default_controller = self.conf.default_controller or ""
+ if "" == self.conf.controller then
+ self.conf.prefix = default_prefix
+ self.conf.controller = default_controller
+ self.conf.action = ""
+ end
+ while "" ~= self.conf.controller do
+ -- We now know the controller / action combo, check if we're allowed to do it
+ local perm = check_permission(self, self.conf.controller)
+ local worker_loaded = false
+
+ if perm then
+ controller, worker_loaded = self:new(self.conf.prefix .. self.conf.controller)
+ end
+ if worker_loaded then
+ local default_action = rawget(controller.worker, "default_action") or ""
+ action = self.conf.action
+ if action == "" then action = default_action end
+ while "" ~= action do
+ local perm = check_permission(controller, self.conf.controller, action)
+ -- Because of the inheritance, normally the
+ -- controller.worker.action will flow up, so that all children have
+ -- actions of all parents. We use rawget to make sure that only
+ -- controller defined actions are used on dispatch
+ if perm and (type(rawget(controller.worker, action)) == "function") then
+ -- We have a valid and permissible controller / action
+ self.conf.action = action
+ break
+ end
+ if action ~= default_action then
+ action = default_action
+ else
+ action = ""
+ end
+ end
+ if "" ~= action then break end
+ end
+ if controller then
+ controller:destroy()
+ controller = nil
+ end
+ self.conf.action = ""
+ if self.conf.controller ~= default_controller then
+ self.conf.prefix = default_prefix
+ self.conf.controller = default_controller
+ else
+ self.conf.controller = ""
+ end
+ end
+
+ -- If the controller or action are missing, raise an error
+ if nil == controller then
+ origconf.type = "dispatch"
+ error (origconf)
+ end
+
+ -- If we have different controller / action, redirect
+ if self.conf.controller ~= origconf.controller or self.conf.action ~= origconf.action then
+ redirect(self, self.conf.action) -- controller and prefix already in self.conf
+ end
+
+ -- run the (first found) pre_exec code, starting at the controller
+ -- and moving up the parents
+ if type(controller.worker.mvc.pre_exec) == "function" then
+ controller.worker.mvc.pre_exec ( controller )
+ end
+
+ -- run the action
+ local viewtable = controller.worker[action](controller)
+
+ -- run the post_exec code
+ if type(controller.worker.mvc.post_exec) == "function" then
+ controller.worker.mvc.post_exec ( controller )
+ end
+
+ local viewfunc, p1, p2, p3 = view_resolver(self)
+
+ -- we're done with the controller, destroy it
+ controller:destroy()
+ controller = nil
+
+ viewfunc (viewtable, p1, p2, p3)
+ end,
+ self:soft_traceback(message)
+ )
+
+ if not success then
+ local handler
+ if controller then
+ handler = controller.worker or controller
+ if handler then handler:exception_handler(err) end
+ controller:destroy()
+ controller = nil
+ end
+ if nil == handler then
+ handler = self.worker or mvc
+ handler:exception_handler(err)
+ end
+ end
+end
+
+-- Cause a redirect to specified (or default) action
+-- We use the self.conf table because it already has prefix,controller,etc
+-- The actual redirection is defined in exception_handler above
+redirect = function (self, str)
+ local prefix, controller, action = self.parse_path_info("/" .. (str or ""))
+ if prefix ~= "/" then self.conf.prefix = prefix end
+ if controller ~= "" then self.conf.controller = controller end
+
+ if "" == action then
+ action = rawget(self.worker, "default_action") or ""
+ end
+ self.conf.action = action
+ self.conf.type = "redir"
+ error(self.conf)
+end
+
+redirect_to_referrer = function(self)
+ error({type="redir_to_referrer"})
+end
+
-- create a Configuration Framework Entity (cfe)
-- returns a table with at least "value", "type", and "label"
cfe = function ( optiontable )
@@ -364,9 +495,5 @@ end
-- FIXME - need to think more about this..
logevent = function ( message )
- conf.logfile:write (string.format("%s: %s\n", os.date(), message))
-end
-
-redirect_to_referrer = function(self)
- error({type="redir_to_referrer"})
+ conf.logfile:write (string.format("%s: %s\n", os.date(), message or ""))
end
diff --git a/app/template-html.lsp b/app/template-html.lsp
index 1c61f46..a60f2b5 100644
--- a/app/template-html.lsp
+++ b/app/template-html.lsp
@@ -1,4 +1,4 @@
-<? local pageinfo , viewtable, session, viewlibrary = ...
+<? local viewtable, viewlibrary, pageinfo, session = ...
html=require("html") ?>
Status: 200 OK
Content-Type: text/html
@@ -121,7 +121,7 @@ Content-Type: text/html
</div>
<? local func = haserl.loadfile(pageinfo.viewfile) ?>
- <? func (viewtable, viewlibrary) ?>
+ <? func (viewtable, viewlibrary, pageinfo, session) ?>
<div class="tailer">
</div>
diff --git a/www/cgi-bin/mvc.lua b/www/cgi-bin/mvc.lua
index 432b591..86a1bb4 100755
--- a/www/cgi-bin/mvc.lua
+++ b/www/cgi-bin/mvc.lua
@@ -6,6 +6,8 @@
]]--
module(..., package.seeall)
+mvc = {}
+
-- the constructor
--[[ Builds a new MVC object. If "module" is given, then tries to load
self.conf.appdir .. module "-controller.lua" in c.worker and
@@ -63,12 +65,13 @@ new = function (self, modname)
setmetatable (c.model, c.model )
c.model.__index = c.worker
- -- the worker looks in the main table for missing
+ -- the worker looks in the parent table for missing
setmetatable (c.worker, c.worker)
- c.worker.__index = c
+ c.worker.__index = self
- -- the table looks in the parent worker for missing
+ -- the table looks in the worker for missing
setmetatable (c, c)
+ c.__index = c.worker
-- ensure an "mvc" table exists, even if empty
if (type(rawget(c.worker, "mvc")) ~= "table") then
@@ -79,14 +82,11 @@ new = function (self, modname)
-- If creating a new parent container, then
-- we are the top of the chain.
if (modname) then
- c.__index = self.worker
c.worker.mvc.__index = self.worker.mvc
else
- c.__index = self
c.worker.mvc.__index = self.mvc
end
-
-- run the worker on_load code
if type(rawget(c.worker.mvc, "on_load")) == "function" then
c.worker.mvc.on_load(c, self)
@@ -117,75 +117,35 @@ dispatch = function (self, userprefix, userctlr, useraction)
self.conf.action = useraction or ""
end
- -- Find the proper controller/action combo
- local origconf = {controller = self.conf.controller, action = self.conf.action}
- local action = ""
- local default_prefix = self.conf.default_prefix or ""
- local default_controller = self.conf.default_controller or ""
- if "" == self.conf.controller then
- self.conf.prefix = default_prefix
- self.conf.controller = default_controller
- self.conf.action = ""
+ -- If they didn't provide a controller, and a default was specified
+ -- use it
+ if self.conf.controller == "" and self.conf.default_controller then
+ self.conf.controller = self.conf.default_controller
+ self.conf.prefix = self.conf.default_prefix or "/"
end
- while "" ~= self.conf.controller do
- -- We now know the controller / action combo, check if we're allowed to do it
- local perm = true
- local worker_loaded = false
- if type(self.worker.mvc.check_permission) == "function" then
- perm = self.worker.mvc.check_permission(self, self.conf.controller)
- end
- if perm then
- controller, worker_loaded = self:new(self.conf.prefix .. self.conf.controller)
- end
- if worker_loaded then
- local default_action = rawget(controller.worker, "default_action") or ""
- action = self.conf.action
- if action == "" then action = default_action end
- while "" ~= action do
- local perm = true
- if type(controller.worker.mvc.check_permission) == "function" then
- perm = controller.worker.mvc.check_permission(controller, self.conf.controller, action)
- end
- -- Because of the inheritance, normally the
- -- controller.worker.action will flow up, so that all children have
- -- actions of all parents. We use rawget to make sure that only
- -- controller defined actions are used on dispatch
- if perm and (type(rawget(controller.worker, action)) == "function") then
- -- We have a valid and permissible controller / action
- self.conf.action = action
- break
- end
- if action ~= default_action then
- action = default_action
- else
- action = ""
- end
- end
- if "" ~= action then break end
- end
- if controller then
- controller:destroy()
- controller = nil
- end
- self.conf.action = ""
- if self.conf.controller ~= default_controller then
- self.conf.prefix = default_prefix
- self.conf.controller = default_controller
- else
- self.conf.controller = ""
- end
+ local worker_loaded
+ controller, worker_loaded = self:new(self.conf.prefix .. self.conf.controller)
+
+ if not worker_loaded then
+ self.conf.type = "dispatch"
+ error(self.conf)
end
- -- If the controller or action are missing, raise an error
- if nil == controller then
- origconf.type = "dispatch"
- error (origconf)
+ if controller.conf.action == "" then
+ controller.conf.action = rawget(controller.worker, "default_action") or ""
end
- -- If we have different controller / action, redirect
- if self.conf.controller ~= origconf.controller or self.conf.action ~= origconf.action then
- redirect(self, self.conf.action)
+ local action = controller.conf.action
+
+ -- Because of the inheritance, normally the
+ -- controller.worker.action will flow up, so that all children have
+ -- actions of all parents. We use rawget to make sure that only
+ -- controller defined aictions are used on dispatch
+ -- If the action is missing, raise an error
+ if ( type(rawget(controller.worker, action)) ~= "function") then
+ self.conf.type = "dispatch"
+ error (self.conf)
end
-- run the (first found) pre_exec code, starting at the controller
@@ -202,7 +162,7 @@ dispatch = function (self, userprefix, userctlr, useraction)
controller.worker.mvc.post_exec ( controller )
end
- local viewfunc = controller.worker:view_resolver(viewtable)
+ local viewfunc = controller:view_resolver()
-- we're done with the controller, destroy it
controller:destroy()
@@ -228,20 +188,6 @@ dispatch = function (self, userprefix, userctlr, useraction)
end
end
--- Cause a redirect to specified (or default) action
--- We use the self.conf table because it already has prefix,controller,etc
--- The actual redirection is defined in the application error handler (acf-controller)
-redirect = function (self, action, controller, prefix)
- if prefix then self.conf.prefix = prefix end
- if controller then self.conf.controller = controller end
- if nil == action then
- action = rawget(self.worker, "default_action") or ""
- end
- self.conf.action = action
- self.conf.type = "redir"
- error(self.conf)
-end
-
-- Tries to see if name exists in the self.conf.appdir, and if so, it loads it.
-- otherwise, returns nil, but no error
soft_require = function (self, name )