lib/cbi: Added support for multiple CBI maps per model
[project/luci.git] / libs / web / luasrc / dispatcher.lua
index 5bf3fc1..735e2a7 100644 (file)
@@ -43,18 +43,6 @@ function build_url(...)
        return luci.http.getenv("SCRIPT_NAME") .. "/" .. table.concat(arg, "/")
 end
 
--- Prints an error message or renders the "error401" template if available
-function error401(message)
-       message = message or "Unauthorized"
-
-       require("luci.template")
-       if not luci.util.copcall(luci.template.render, "error401") then
-               luci.http.prepare_content("text/plain")
-               luci.http.write(message)
-       end
-       return false
-end
-
 -- Sends a 404 error code and renders the "error404" template if available
 function error404(message)
        luci.http.status(404, "Not Found")
@@ -80,6 +68,25 @@ function error500(message)
        return false
 end
 
+-- Renders an authorization form
+function sysauth(default)
+       local user = luci.http.formvalue("username")
+       local pass = luci.http.formvalue("password")
+       
+       if user and luci.sys.user.checkpasswd(user, pass) then
+               local sid = luci.sys.uniqueid(16)
+               luci.http.header("Set-Cookie", "sysauth=" .. sid.."; path=/")
+               luci.sauth.write(sid, user)
+               return true
+       else
+               require("luci.i18n")
+               require("luci.template")
+               context.path = {}
+               luci.template.render("sysauth", {duser=default, fuser=user})
+               return false
+       end
+end
+
 -- Creates a request object for dispatching
 function httpdispatch(request)
        luci.http.context.request = request
@@ -119,34 +126,9 @@ function dispatch(request)
                end
        end
 
-       if track.sysauth then
-               local accs = track.sysauth
-               accs = (type(accs) == "string") and {accs} or accs
-               
-               --[[
-               local function sysauth(user, password)
-                       return (luci.util.contains(accs, user)
-                               and luci.sys.user.checkpasswd(user, password)) 
-               end
-               
-               if not luci.http.basic_auth(sysauth) then
-                       error401()
-                       return
-               end
-               ]]--
-       end
-
        if track.i18n then
                require("luci.i18n").loadc(track.i18n)
        end
-
-       if track.setgroup then
-               luci.sys.process.setgroup(track.setgroup)
-       end
-
-       if track.setuser then
-               luci.sys.process.setuser(track.setuser)
-       end
        
        -- Init template engine
        local tpl = require("luci.template")
@@ -159,6 +141,27 @@ function dispatch(request)
        viewns.resource    = luci.config.main.resourcebase
        viewns.REQUEST_URI = luci.http.getenv("SCRIPT_NAME") .. (luci.http.getenv("PATH_INFO") or "")
        
+       if track.sysauth then
+               require("luci.sauth")
+               local def  = (type(track.sysauth) == "string") and track.sysauth
+               local accs = def and {track.sysauth} or track.sysauth
+               local user = luci.sauth.read(luci.http.getcookie("sysauth"))
+               
+               
+               if not luci.util.contains(accs, user) then
+                       if not sysauth(def) then
+                               return
+                       end
+               end
+       end
+
+       if track.setgroup then
+               luci.sys.process.setgroup(track.setgroup)
+       end
+
+       if track.setuser then
+               luci.sys.process.setuser(track.setuser)
+       end
 
        if c and type(c.target) == "function" then
                context.dispatched = c
@@ -280,6 +283,7 @@ function createtree()
                local stat, err = luci.util.copcall(v)
                if not stat then
                        error500("createtree failed: " .. k .. ": " .. err)
+                       luci.http.close()
                        os.exit(1)
                end
        end
@@ -287,7 +291,7 @@ end
 
 -- Reassigns a node to another position
 function assign(path, clone, title, order)
-       local obj  = node(path)
+       local obj  = node(unpack(path))
        obj.nodes  = nil
        obj.module = nil
        
@@ -310,7 +314,7 @@ end
 
 -- Shortcut for creating a dispatching node
 function entry(path, target, title, order)
-       local c = node(path)
+       local c = node(unpack(path))
        
        c.target = target
        c.title  = title
@@ -324,11 +328,6 @@ end
 function node(...)
        local c = context.tree
        arg.n = nil
-       if arg[1] then
-               if type(arg[1]) == "table" then
-                       arg = arg[1]
-               end
-       end
 
        for k,v in ipairs(arg) do
                if not c.nodes[v] then
@@ -382,20 +381,24 @@ function cbi(model)
        require("luci.template")
 
        return function()
-               local stat, res = luci.util.copcall(luci.cbi.load, model)
+               local stat, maps = luci.util.copcall(luci.cbi.load, model)
                if not stat then
-                       error500(res)
+                       error500(maps)
                        return true
                end
 
-               local stat, err = luci.util.copcall(res.parse, res)
-               if not stat then
-                       error500(err)
-                       return true
+               for i, res in ipairs(maps) do
+                       local stat, err = luci.util.copcall(res.parse, res)
+                       if not stat then
+                               error500(err)
+                               return true
+                       end
                end
 
                luci.template.render("cbi/header")
-               res:render()
+               for i, res in ipairs(maps) do
+                       res:render()
+               end
                luci.template.render("cbi/footer")
        end
 end