Merge branch 'menu'

This commit is contained in:
Steven Barth 2008-05-22 14:04:03 +00:00
parent f738eb786e
commit 6604399aa8
55 changed files with 627 additions and 541 deletions

View file

@ -0,0 +1,2 @@
include ../../build/config.mk
include ../../build/module.mk

View file

@ -0,0 +1,16 @@
#!/bin/sh
uci batch <<-EOF
set freifunk.community.name='Freifunk Halle'
set freifunk.community.homepage=http://halle.freifunk.net
set freifunk.community.essid=halle.freifunk.net
set freifunk.community.bssid=02:CA:FF:EE:BA:BE
set freifunk.community.realm=pool.freifunk-halle.net
set freifunk.community.channel=1
set freifunk.community.net=104.0.0.0
set freifunk.community.mask=255.0.0.0
set freifunk.community.dhcp=10.0.0.0
set freifunk.community.dhcpmask=255.255.255.0
set freifunk.community.dns='88.198.178.18 141.54.1.1 212.204.49.83 208.67.220.220 208.67.222.222'
commit freifunk
EOF

View file

@ -0,0 +1,18 @@
module("ffluci.controller.luci_fw.luci_fw", package.seeall)
function index()
local page = node("admin", "network", "portfw")
page.target = cbi("luci_fw/portfw")
page.title = "Portweiterleitung"
page.order = 70
local page = node("admin", "network", "routing")
page.target = cbi("luci_fw/routing")
page.title = "Routing"
page.order = 72
local page = node("admin", "network", "firewall")
page.target = cbi("luci_fw/firewall")
page.title = "Firewall"
page.order = 74
end

View file

@ -1,4 +0,0 @@
sel("admin", "network")
act("portfw", "Portweiterleitung")
act("routing", "Routing")
act("firewall", "Firewall")

View file

@ -1,5 +1,16 @@
module("ffluci.controller.splash.splash", package.seeall)
function index()
local page = node("admin", "services", "splash")
page.target = cbi("splash/splash")
page.title = "Client-Splash"
node("splash", "splash", "activate").target = action_activate
node("splash", "splash", "allowed").target = action_allowed
node("splash", "splash", "unknown").target = action_unknown
node("splash", "splash", "splash").target = template("splash_splash/splash")
end
function action_activate()
local mac = ffluci.sys.net.ip4mac(ffluci.http.env.REMOTE_ADDR)
if mac and ffluci.http.formvalue("accept") then
@ -10,7 +21,7 @@ function action_activate()
end
end
function action_accepted()
function action_allowed()
ffluci.http.redirect(ffluci.dispatcher.build_url())
end

View file

@ -1,2 +0,0 @@
sel("admin", "services")
act("splash", "Client-Splash")

View file

@ -1,4 +1,3 @@
#!/usr/bin/haserl --shell=luac
package.path = "/usr/lib/lua/?.lua;/usr/lib/lua/?/init.lua;" .. package.path
package.cpath = "/usr/lib/lua/?.so;" .. package.cpath
require("ffluci.dispatcher").httpdispatch()
require("ffluci.dispatcher").createindex()
ffluci.dispatcher.httpdispatch()

View file

@ -1,11 +1,9 @@
package.path = "/usr/lib/lua/?.lua;/usr/lib/lua/?/init.lua;" .. package.path
package.cpath = "/usr/lib/lua/?.so;" .. package.cpath
module("webuci", package.seeall)
function prepare_req(uri)
env = {}
env.REQUEST_URI = uri
require("ffluci.menu").get()
require("ffluci.dispatcher").createindex()
end
function init_req(context)
@ -19,5 +17,5 @@ function init_req(context)
end
function handle_req(context)
require("ffluci.dispatcher").httpdispatch()
ffluci.dispatcher.httpdispatch()
end

View file

@ -1,3 +1,3 @@
LUAC = luac
LUAC_OPTIONS = -s
LUCI_INSTALLDIR = /usr/lib/lua/ffluci
LUCI_INSTALLDIR = /usr/lib/lua/5.1/ffluci

View file

@ -5,7 +5,7 @@ PKG_SOURCE_URL:=https://dev.leipzig.freifunk.net/svn/ff-luci/$(PKG_BRANCH)
PKG_REV:=$(shell LC_ALL=C svn info ${PKG_SOURCE_URL} | sed -ne's/^Last Changed Rev: //p')
PKG_NAME:=ffluci
PKG_VERSION:=0.4+svn$(PKG_REV)
PKG_VERSION:=0.5+svn$(PKG_REV)
PKG_RELEASE:=1
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)

View file

@ -1,15 +1,36 @@
--- b/src/luaconf.h 2008-05-06 20:10:46.000000000 +0200
+++ a/src/luaconf.h 2008-05-06 20:10:27.000000000 +0200
@@ -95,9 +95,9 @@
".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
diff -ur lua-5.1.3/etc/lua.pc lua-5.1.3-new/etc/lua.pc
--- lua-5.1.3/etc/lua.pc 2008-01-11 14:12:59.000000000 +0100
+++ lua-5.1.3-new/etc/lua.pc 2008-05-18 22:09:24.000000000 +0200
@@ -8,7 +8,7 @@
R= 5.1.3
# grep '^INSTALL_.*=' ../Makefile | sed 's/INSTALL_TOP/prefix/'
-prefix= /usr/local
+prefix= /usr
INSTALL_BIN= ${prefix}/bin
INSTALL_INC= ${prefix}/include
INSTALL_LIB= ${prefix}/lib
diff -ur lua-5.1.3/Makefile lua-5.1.3-new/Makefile
--- lua-5.1.3/Makefile 2008-05-18 22:06:55.000000000 +0200
+++ lua-5.1.3-new/Makefile 2008-05-18 22:09:13.000000000 +0200
@@ -12,7 +12,7 @@
# doc directory.) You may want to make these paths consistent with LUA_ROOT,
# LUA_LDIR, and LUA_CDIR in luaconf.h (and also with etc/lua.pc).
#
-INSTALL_TOP= /usr/local
+INSTALL_TOP= /usr
INSTALL_BIN= $(INSTALL_TOP)/bin
INSTALL_INC= $(INSTALL_TOP)/include
INSTALL_LIB= $(INSTALL_TOP)/lib
diff -ur lua-5.1.3/src/luaconf.h lua-5.1.3-new/src/luaconf.h
--- lua-5.1.3/src/luaconf.h 2008-05-18 22:07:11.000000000 +0200
+++ lua-5.1.3-new/src/luaconf.h 2008-05-18 22:09:50.000000000 +0200
@@ -95,7 +95,7 @@
".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
#else
-#define LUA_ROOT "/usr/local/"
-#define LUA_LDIR LUA_ROOT "share/lua/5.1/"
-#define LUA_CDIR LUA_ROOT "lib/lua/5.1/"
+#define LUA_ROOT "/usr/"
+#define LUA_LDIR LUA_ROOT "share/lua/"
+#define LUA_CDIR LUA_ROOT "lib/lua/"
-#define LUA_ROOT "/usr/local/"
+#define LUA_ROOT "/usr/"
#define LUA_LDIR LUA_ROOT "share/lua/5.1/"
#define LUA_CDIR LUA_ROOT "lib/lua/5.1/"
#define LUA_PATH_DEFAULT \
"./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \
LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua"

View file

@ -1,10 +1,9 @@
config core main
option lang de
option mediaurlbase /ffluci/media
option imagebase /ffluci/images
config core category_privileges
option public nobody:nogroup
option lang de
option mediaurlbase /ffluci/media
option resourcebase /ffluci/images
option title "Freifunk Kamikaze"
option subtitle Fledermausedition
config extern flash_keep
option uci "/etc/config"

View file

@ -4,63 +4,6 @@ FFLuCI - Dispatcher
Description:
The request dispatcher and module dispatcher generators
The dispatching process:
For a detailed explanation of the dispatching process we assume:
You have installed the FFLuCI CGI-Dispatcher in /cgi-bin/ffluci
To enforce a higher level of security only the CGI-Dispatcher
resides inside the web server's document root, everything else
stays inside an external directory, we assume this is /lua/ffluci
for this explanation.
All controllers and action are reachable as sub-objects of /cgi-bin/ffluci
as if they were virtual folders and files
e.g.: /cgi-bin/ffluci/public/info/about
/cgi-bin/ffluci/admin/network/interfaces
and so on.
The PATH_INFO variable holds the dispatch path and
will be split into three parts: /category/module/action
Category: This is the category in which modules are stored in
By default there are two categories:
"public" - which is the default public category
"admin" - which is the default protected category
As FFLuCI itself does not implement authentication
you should make sure that "admin" and other sensitive
categories are protected by the webserver.
E.g. for busybox add a line like:
/cgi-bin/ffluci/admin:root:$p$root
to /etc/httpd.conf to protect the "admin" category
Module: This is the controller which will handle the request further
It is always a submodule of ffluci.controller, so a module
called "helloworld" will be stored in
/lua/ffluci/controller/helloworld.lua
You are free to submodule your controllers any further.
Action: This is action that will be invoked after loading the module.
The kind of how the action will be dispatched depends on
the module dispatcher that is defined in the controller.
See the description of the default module dispatcher down
on this page for some examples.
The main dispatcher at first searches for the module by trying to
include ffluci.controller.category.module
(where "category" is the category name and "module" is the module name)
If this fails a 404 status code will be send to the client and FFLuCI exits
Then the main dispatcher calls the module dispatcher
ffluci.controller.category.module.dispatcher with the request object
as the only argument. The module dispatcher is then responsible
for the further dispatching process.
FileId:
$Id$
@ -80,48 +23,24 @@ See the License for the specific language governing permissions and
limitations under the License.
]]--
module("ffluci.dispatcher", package.seeall)
require("ffluci.http")
require("ffluci.template")
require("ffluci.config")
require("ffluci.sys")
require("ffluci.fs")
-- Sets privilege for given category
function assign_privileges(category)
local cp = ffluci.config.category_privileges
if cp and cp[category] then
local u, g = cp[category]:match("([^:]+):([^:]+)")
ffluci.sys.process.setuser(u)
ffluci.sys.process.setgroup(g)
end
end
-- Local dispatch database
local tree = {nodes={}}
-- Global request object
request = {}
-- Active dispatched node
dispatched = nil
-- Builds a URL from a triple of category, module and action
function build_url(category, module, action)
category = category or "public"
module = module or "index"
action = action or "index"
local pattern = ffluci.http.dispatcher() .. "/%s/%s/%s"
return pattern:format(category, module, action)
end
-- Dispatches the "request"
function dispatch(req)
request = req
local m = "ffluci.controller." .. request.category .. "." .. request.module
local stat, module = pcall(require, m)
if not stat then
return error404()
else
module.request = request
module.dispatcher = module.dispatcher or dynamic
setfenv(module.dispatcher, module)
return module.dispatcher(request)
end
-- Builds a URL
function build_url(...)
return ffluci.http.dispatcher() .. "/" .. table.concat(arg, "/")
end
-- Sends a 404 error code and renders the "error404" template if available
@ -129,6 +48,7 @@ function error404(message)
ffluci.http.status(404, "Not Found")
message = message or "Not Found"
require("ffluci.template")
if not pcall(ffluci.template.render, "error404") then
ffluci.http.prepare_content("text/plain")
print(message)
@ -140,6 +60,7 @@ end
function error500(message)
ffluci.http.status(500, "Internal Server Error")
require("ffluci.template")
if not pcall(ffluci.template.render, "error500", {message=message}) then
ffluci.http.prepare_content("text/plain")
print(message)
@ -147,154 +68,124 @@ function error500(message)
return false
end
-- Dispatches a request depending on the PATH_INFO variable
function httpdispatch()
local pathinfo = ffluci.http.env.PATH_INFO or ""
local parts = pathinfo:gmatch("/[%w-]+")
local c = tree
local sanitize = function(s, default)
return s and s:sub(2) or default
for s in pathinfo:gmatch("/([%w-]+)") do
table.insert(request, s)
end
local cat = sanitize(parts(), "public")
local mod = sanitize(parts(), "index")
local act = sanitize(parts(), "index")
dispatch()
end
function dispatch()
local c = tree
local track = {}
assign_privileges(cat)
dispatch({category=cat, module=mod, action=act})
end
-- Dispatchers --
-- The Action Dispatcher searches the module for any function called
-- action_"request.action" and calls it
function action(...)
local disp = require("ffluci.dispatcher")
if not disp._action(...) then
disp.error404()
end
end
-- The CBI dispatcher directly parses and renders the CBI map which is
-- placed in ffluci/modles/cbi/"request.module"/"request.action"
function cbi(...)
local disp = require("ffluci.dispatcher")
if not disp._cbi(...) then
disp.error404()
for i, s in ipairs(request) do
c = c.nodes[s]
if not c then
break
end
for k, v in pairs(c) do
track[k] = v
end
end
end
-- The dynamic dispatcher chains the action, submodule, simpleview and CBI dispatcher
-- in this particular order. It is the default dispatcher.
function dynamic(...)
local disp = require("ffluci.dispatcher")
if not disp._action(...)
and not disp._submodule(...)
and not disp._simpleview(...)
and not disp._cbi(...) then
disp.error404()
end
end
-- The Simple View Dispatcher directly renders the template
-- which is placed in ffluci/views/"request.module"/"request.action"
function simpleview(...)
local disp = require("ffluci.dispatcher")
if not disp._simpleview(...) then
disp.error404()
end
end
-- The submodule dispatcher tries to load a submodule of the controller
-- and calls its "action"-function
function submodule(...)
local disp = require("ffluci.dispatcher")
if not disp._submodule(...) then
disp.error404()
end
end
-- Internal Dispatcher Functions --
function _action(request)
local action = getfenv(2)["action_" .. request.action:gsub("-", "_")]
local i18n = require("ffluci.i18n")
if action then
i18n.loadc(request.category .. "_" .. request.module)
i18n.loadc(request.category .. "_" .. request.module .. "_" .. request.action)
action()
return true
else
return false
if track.i18n then
require("ffluci.i18n").loadc(track.i18n)
end
end
function _cbi(request)
local disp = require("ffluci.dispatcher")
local tmpl = require("ffluci.template")
local cbi = require("ffluci.cbi")
local i18n = require("ffluci.i18n")
local path = request.category.."_"..request.module.."/"..request.action
if track.setuser then
ffluci.sys.process.setuser(track.setuser)
end
local stat, map = pcall(cbi.load, path)
if stat and map then
local stat, err = pcall(map.parse, map)
if track.setgroup then
ffluci.sys.process.setgroup(track.setgroup)
end
if c and type(c.target) == "function" then
dispatched = c
stat, err = pcall(c.target)
if not stat then
disp.error500(err)
error500(err)
end
else
error404()
end
end
-- Calls the index function of all available controllers
function createindex()
local root = ffluci.sys.libpath() .. "/controller/"
local suff = ".lua"
for i,c in ipairs(ffluci.fs.glob(root .. "*/*" .. suff)) do
c = "ffluci.controller." .. c:sub(#root+1, #c-#suff):gsub("/", ".", 1)
stat, mod = pcall(require, c)
if stat and mod and type(mod.index) == "function" then
ffluci.util.updfenv(mod.index, ffluci.dispatcher)
pcall(mod.index)
end
end
end
-- Fetch a dispatching node
function node(...)
local c = tree
for k,v in ipairs(arg) do
if not c.nodes[v] then
c.nodes[v] = {nodes={}}
end
c = c.nodes[v]
end
return c
end
-- Subdispatchers --
function alias(...)
local req = arg
return function()
request = req
dispatch()
end
end
function template(name)
require("ffluci.template")
return function() ffluci.template.render(name) end
end
function cbi(model)
require("ffluci.cbi")
require("ffluci.template")
return function()
local stat, res = pcall(ffluci.cbi.load, model)
if not stat then
error500(res)
return true
end
i18n.loadc(request.category .. "_" .. request.module)
i18n.loadc(request.category .. "_" .. request.module .. "_" .. request.action)
tmpl.render("cbi/header")
map:render()
tmpl.render("cbi/footer")
return true
elseif not stat then
disp.error500(map)
return true
else
return false
local stat, err = pcall(res.parse, res)
if not stat then
error500(err)
return true
end
ffluci.template.render("cbi/header")
res:render()
ffluci.template.render("cbi/footer")
end
end
function _simpleview(request)
local i18n = require("ffluci.i18n")
local tmpl = require("ffluci.template")
local path = request.category.."_"..request.module.."/"..request.action
local stat, t = pcall(tmpl.Template, path)
if stat then
i18n.loadc(request.category .. "_" .. request.module)
i18n.loadc(request.category .. "_" .. request.module .. "_" .. request.action)
t:render()
return true
else
return false
end
end
function _submodule(request)
local i18n = require("ffluci.i18n")
local m = "ffluci.controller." .. request.category .. "." ..
request.module .. "." .. request.action
local stat, module = pcall(require, m)
if stat and module.action then
i18n.loadc(request.category .. "_" .. request.module)
i18n.loadc(request.category .. "_" .. request.module .. "_" .. request.action)
return pcall(module.action)
end
return false
end

View file

@ -10,13 +10,5 @@ apply = "Apply"
changes = "Changes"
revert = "Revert"
index = "Overview"
system = "System"
services = "Services"
network = "Network"
wifi = "Wifi"
status = "Status"
statistic = "Statistic"
config = "Configuration"
path = "Path"

View file

@ -25,5 +25,5 @@ limitations under the License.
]]--
module("ffluci", package.seeall)
__version__ = "0.4"
__version__ = "0.5"
__appname__ = "FFLuCI"

View file

@ -28,6 +28,7 @@ module("ffluci.menu", package.seeall)
require("ffluci.fs")
require("ffluci.util")
require("ffluci.sys")
require("ffluci.dispatcher")
-- Default modelpath
modelpattern = ffluci.sys.libpath() .. "/model/menu/*.lua"
@ -39,98 +40,7 @@ scope = {
isfile = ffluci.fs.isfile
}
-- Local menu database
local menu = nil
-- The current pointer
local menuc = {}
-- Adds a menu category to the current menu and selects it
function add(cat, controller, title, order)
order = order or 100
if not menu[cat] then
menu[cat] = {}
end
local entry = {}
entry[".descr"] = title
entry[".order"] = order
entry[".contr"] = controller
menuc = entry
local i = 0
for k,v in ipairs(menu[cat]) do
if v[".order"] > entry[".order"] then
break
end
i = k
end
table.insert(menu[cat], i+1, entry)
return true
end
-- Adds an action to the current menu
function act(action, title)
table.insert(menuc, {action = action, descr = title})
return true
end
-- Selects a menu category
function sel(cat, controller)
if not menu[cat] then
return nil
end
menuc = menu[cat]
local stat = nil
for k,v in ipairs(menuc) do
if v[".contr"] == controller then
menuc = v
stat = true
end
end
return stat
end
-- Collect all menu information provided in the model dir
function collect()
local generators = {}
local m = ffluci.fs.glob(modelpattern) or {}
for k, menu in pairs(m) do
local f = loadfile(menu)
if f then
table.insert(generators, f)
end
end
return generators
end
-- Parse the collected information
function parse(generators)
menu = {}
for i, f in pairs(generators) do
local env = ffluci.util.clone(scope)
env.add = add
env.sel = sel
env.act = act
setfenv(f, env)
f()
end
return menu
end
-- Returns the menu information
function get()
if not menu then
menu = parse(collect())
end
return menu
end

View file

@ -55,7 +55,7 @@ viewns = {
controller = ffluci.http.dispatcher(),
uploadctrl = ffluci.http.dispatcher_upload(),
media = ffluci.config.main.mediaurlbase,
images = ffluci.config.main.imagebase,
resource = ffluci.config.main.resourcebase,
write = io.write,
include = function(name) Template(name):render(getfenv(2)) end,
}

View file

@ -2,6 +2,6 @@
<div class="clear"></div>
</div></div>
<div class="separator magenta bold"><a href="http://luci.freifunk-halle.net">FFLuCI 0.3 - Freifunk Lua Configuration Interface</a></div>
<div class="separator magenta bold"><a href="http://luci.freifunk-halle.net"><%=require("ffluci").__appname__ .. " " .. ffluci.__version__%> - Freifunk Lua Configuration Interface</a></div>
</body>
</html>

View file

@ -1,21 +1,33 @@
<%
require("ffluci.sys")
local load1, load5, load15 = ffluci.sys.loadavg()
local req = require("ffluci.dispatcher").request
local menu = require("ffluci.menu").get()[req.category]
menu = menu or {}
local request = require("ffluci.dispatcher").request
local category = request[1]
local tree = ffluci.dispatcher.node()
local cattree = category and ffluci.dispatcher.node(category)
local node = ffluci.dispatcher.dispatched
local c = tree
for i,r in ipairs(request) do
if c.nodes and c.nodes[r] then
c = c.nodes[r]
c._menu_selected = true
end
end
require("ffluci.i18n").loadc("default")
require("ffluci.http").prepare_content("text/html")
%><?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" type="text/css" href="<%=media%>/cascade.css" />
<link rel="stylesheet" type="text/css" href="<%=media%>/css/<%=req.category%>_<%=req.module%>.css" />
<link rel="stylesheet" type="text/css" href="<%=media%>/css/<%=req.category%>_<%=req.module%>_<%=req.action%>.css" />
<% if node and node.css then %><link rel="stylesheet" type="text/css" href="<%=resource%>/<%=node.css%>" /><% end %>
<meta http-equiv="content-type" content="text/xhtml+xml; charset=utf-8" />
<meta http-equiv="content-script-type" content="text/javascript" />
<title>FFLuCI</title>
<title>FFLuCI - Freifunk Lua Configuration Interface</title>
</head>
<body>
<div id="header">
@ -27,37 +39,82 @@ require("ffluci.http").prepare_content("text/html")
<%:hostname Hostname%>: <%=ffluci.sys.hostname()%>
</div>
<div>
<span class="headertitle">Freifunk Kamikaze</span><br />
<span class="whitetext bold"><%:batmanedition Fledermausedition%></span>
<span class="headertitle"><%~luci.main.title%></span><br />
<span class="whitetext bold"><%~luci.main.subtitle%></span>
</div>
</div>
<div class="separator yellow bold">
<%:path Pfad%>: <a href="<%=controller .. "/" .. req.category%>"><%=translate(req.category, req.category)%></a>
&#187; <a href="<%=controller .. "/" .. req.category .. "/" .. req.module %>"><%=translate(req.module, req.module)%></a>
&#187; <a href="<%=controller .. "/" .. req.category .. "/" .. req.module .. "/" .. req.action %>"><%=translate(req.action, req.action)%></a>
<%:path Pfad%>: <%
local c = tree
local url = controller
for k,v in pairs(request) do
if c.nodes and c.nodes[v] then
c = c.nodes[v]
url = url .. "/" .. v
%><a href="<%=url%>"><%=c.title or v%></a> <% if k ~= #request then %>&#187; <% end
end
end
%>
</div>
<div id="columns"><div id="columnswrapper">
<div class="sidebar left">
<% for k,v in pairs(menu) do %>
<div<% if v[".contr"] == req.module then %> class="yellowtext"<% end %>><a href="<%=controller.."/"..req.category.."/"..v[".contr"]%>"><%=translate(v[".contr"], v[".descr"])%></a><%
if v[".contr"] == req.module then %>
<ul><% for key,val in ipairs(v) do %>
<li<% if val.action == req.action then %> class="yellowtext"<% end %>><a href="<%=controller.."/"..req.category.."/"..req.module.."/"..val.action%>"><%=translate(val.action, val.descr)%></a></li>
<% end %></ul>
<% end %></div>
<%
local function submenu(prefix, node)
if not node._menu_selected or not node.nodes then
return false
end
local index = {}
for k, n in pairs(node.nodes) do
table.insert(index, {name=k, order=n.order or 100})
end
table.sort(index, function(a, b) return a.order < b.order end)
%>
<ul>
<% for j, v in pairs(index) do
local nnode = node.nodes[v.name]%>
<li>
<span<% if nnode._menu_selected then %> class="yellowtext"<%end%>><a href="<%=controller .. prefix .. v.name%>"><%=nnode.title%></a></span>
<% submenu(prefix .. v.name .. "/", nnode) %>
</li>
<% end %>
</ul>
<%
end
if cattree and cattree.nodes then
local index = {}
for k, node in pairs(cattree.nodes) do
table.insert(index, {name=k, order=node.order or 100})
end
table.sort(index, function(a, b) return a.order < b.order end)
for i, k in ipairs(index) do
node = cattree.nodes[k.name]
if node.title then %>
<div<% if node._menu_selected then %> class="yellowtext"<%end%>><a href="<%=controller%>/<%=category%>/<%=k.name%>"><%=node.title%></a>
<%submenu("/" .. category .. "/" .. k.name .. "/", node)%>
</div>
<% end
end
end
%>
</div>
<div class="sidebar right">
<div><%:webif Weboberfläche%>
<ul>
<li<% if "public" == req.category then %> class="yellowtext"<% end %>><a href="<%=controller%>/public"><%:public Öffentlich%></a></li>
<li<% if "admin" == req.category then %> class="yellowtext"<% end %>><a href="<%=controller%>/admin"><%:admin Verwaltung%></a></li>
<ul><%
for k,node in pairs(tree.nodes) do
if node.title then %>
<li<% if request[1] == k then %> class="yellowtext"<%end%>><a href="<%=controller%>/<%=k%>"><%=node.title%></a></li>
<% end
end%>
</ul>
</div>
<%
if "admin" == req.category then
if "admin" == request[1] then
require("ffluci.model.uci")
local ucic = ffluci.model.uci.changes()
if ucic then

View file

@ -1 +1,24 @@
module("ffluci.controller.admin.index", package.seeall)
module("ffluci.controller.admin.index", package.seeall)
function index()
local root = node()
if not root.target then
root.target = alias("admin")
end
local page = node("admin")
page.target = alias("admin", "index")
page.title = "Administration"
page.order = 10
local page = node("admin", "index")
page.target = template("admin_index/index")
page.title = "Übersicht"
page.order = 10
local page = node("admin", "index", "luci")
page.target = cbi("admin_index/luci")
page.title = "Oberfläche"
end

View file

@ -1 +1,39 @@
module("ffluci.controller.admin.network", package.seeall)
module("ffluci.controller.admin.network", package.seeall)
function index()
local page = node("admin", "network")
page.target = template("admin_network/index")
page.title = "Netzwerk"
page.order = 50
local page = node("admin", "network", "vlan")
page.target = cbi("admin_network/vlan")
page.title = "Switch"
page.order = 10
local page = node("admin", "network", "ifaces")
page.target = cbi("admin_network/ifaces")
page.title = "Schnittstellen"
page.order = 20
local page = node("admin", "network", "dhcp")
page.target = cbi("admin_network/dhcp")
page.title = "DHCP-Server"
page.order = 30
local page = node("admin", "network", "ptp")
page.target = cbi("admin_network/ptp")
page.title = "PPPoE / PPTP"
page.order = 40
local page = node("admin", "network", "routes")
page.target = cbi("admin_network/routes")
page.title = "Statische Routen"
page.order = 50
if ffluci.fs.isfile("/etc/config/qos") then
local page = node("admin", "network", "qos")
page.target = cbi("admin_network/qos")
page.title = "Quality of Service"
end
end

View file

@ -1 +1,29 @@
module("ffluci.controller.admin.services", package.seeall)
module("ffluci.controller.admin.services", package.seeall)
function index()
local page = node("admin", "services")
page.target = template("admin_services/index")
page.title = "Dienste"
page.order = 40
local page = node("admin", "services", "httpd")
page.target = cbi("admin_services/httpd")
page.title = "HTTP-Server"
page.order = 10
local page = node("admin", "services", "dropbear")
page.target = cbi("admin_services/dropbear")
page.title = "SSH-Server"
page.order = 20
local page = node("admin", "services", "dnsmasq")
page.target = cbi("admin_services/dnsmasq")
page.title = "Dnsmasq"
page.order = 30
if ffluci.fs.isfile("/etc/config/olsr") then
local page = node("admin", "services", "olsr")
page.target = cbi("admin_services/olsrd")
page.title = "OLSR"
end
end

View file

@ -1,5 +1,16 @@
module("ffluci.controller.admin.status", package.seeall)
function index()
local page = node("admin", "status")
page.target = template("admin_status/index")
page.title = "Status"
page.order = 20
local page = node("admin", "status", "syslog")
page.target = action_syslog
page.title = "Systemprotokoll"
end
function action_syslog()
local syslog = ffluci.sys.syslog()
ffluci.template.render("admin_status/syslog", {syslog=syslog})

View file

@ -7,6 +7,52 @@ require("ffluci.fs")
require("ffluci.model.ipkg")
require("ffluci.model.uci")
function index()
local page = node("admin", "system")
page.target = template("admin_system/index")
page.title = "System"
page.order = 30
local page = node("admin", "system", "packages")
page.target = action_packages
page.title = "Paketverwaltung"
page.order = 10
local page = node("admin", "system", "packages", "ipkg")
page.target = action_ipkg
page.title = "IPKG-Konfiguration"
local page = node("admin", "system", "passwd")
page.target = action_passwd
page.title = "Passwort ändern"
page.order = 20
local page = node("admin", "system", "sshkeys")
page.target = action_sshkeys
page.title = "SSH-Schlüssel"
page.order = 30
local page = node("admin", "system", "hostname")
page.target = cbi("admin_system/hostname")
page.title = "Hostname"
page.order = 40
local page = node("admin", "system", "fstab")
page.target = cbi("admin_system/fstab")
page.title = "Einhängepunkte"
page.order = 50
local page = node("admin", "system", "upgrade")
page.target = action_upgrade
page.title = "Firmwareupgrade"
page.order = 60
local page = node("admin", "system", "reboot")
page.target = action_reboot
page.title = "Neu starten"
page.order = 70
end
function action_editor()
local file = ffluci.http.formvalue("file", "")
local data = ffluci.http.formvalue("data")

View file

@ -2,6 +2,12 @@ module("ffluci.controller.admin.uci", package.seeall)
require("ffluci.util")
require("ffluci.sys")
function index()
node("admin", "uci", "changes").target = template("admin_uci/changes")
node("admin", "uci", "revert").target = action_revert
node("admin", "uci", "apply").target = action_apply
end
-- This function has a higher priority than the admin_uci/apply template
function action_apply()
local changes = ffluci.model.uci.changes()

View file

@ -1 +1,18 @@
module("ffluci.controller.admin.wifi", package.seeall)
module("ffluci.controller.admin.wifi", package.seeall)
function index()
local page = node("admin", "wifi")
page.target = template("admin_wifi/index")
page.title = "Drahtlos"
page.order = 60
local page = node("admin", "wifi", "devices")
page.target = cbi("admin_wifi/devices")
page.title = "Geräte"
page.order = 10
local page = node("admin", "wifi", "networks")
page.target = cbi("admin_wifi/networks")
page.title = "Netze"
page.order = 20
end

View file

@ -13,10 +13,6 @@ team = "The FFLuCI Team"
luci1 = "Here you can customize the settings and the functionality of FFLuCI."
language = "Language"
general = "General"
catpriv = "Category Privileges"
catpriv1 = [[To secure FFLuCI even further the user and group privileges of
each category can be decreased. Therefore an attacker cannot takeover the whole system
when a security exploit for any publicly available page is found.]]
ucicommit = "Post-commit actions"
ucicommit1 = [[These commands will be executed automatically when a given UCI configuration is committed allowing
changes to be applied instantly.]]

View file

@ -19,12 +19,6 @@ for k, v in pairs(ffluci.config.themes) do
end
end
p = m:section(NamedSection, "category_privileges", "core", translate("catpriv", "Kategorieprivilegien"),
translate("catpriv1", [[Zur zusätzlichen Sicherung der Oberfläche gegen Angreifer, können hier die
Ausführungsrechte der Seiten für einzelne Kategorien reduziert werden. So können z.B. Sicherheitslücken im
ungeschützten Bereich der Oberfläche nicht mehr zur Übernahme des Routers genutzt werden.]]))
p.dynamic = true
u = m:section(NamedSection, "uci_oncommit", "event", translate("ucicommit", "UCI-Befehle beim Anwenden"),
translate("ucicommit1", [[Beim Anwenden
der Konfiguration aus der Oberflächliche heraus können automatisch die relevanten Dienste neugestart werden,

View file

@ -1,36 +0,0 @@
add("admin", "index", "Übersicht", 10)
act("luci", "Oberfläche")
add("admin", "status", "Status", 20)
act("syslog", "Systemprotokoll")
add("admin", "system", "System", 30)
act("packages", "Paketverwaltung")
act("passwd", "Passwort ändern")
act("sshkeys", "SSH-Schlüssel")
act("hostname", "Hostname")
act("fstab", "Einhängepunkte")
act("upgrade", "Firmwareupgrade")
act("reboot", "Neu starten")
add("admin", "services", "Dienste", 40)
if isfile("/etc/config/olsr") then
act("olsrd", "OLSR")
end
act("httpd", "HTTP-Server")
act("dropbear", "SSH-Server")
act("dnsmasq", "Dnsmasq")
add("admin", "network", "Netzwerk", 50)
act("vlan", "Switch")
act("ifaces", "Schnittstellen")
act("dhcp", "DHCP-Server")
act("ptp", "PPPoE / PPTP")
act("routes", "Statische Routen")
if isfile("/etc/config/qos") then
act("qos", "Quality of Service")
end
add("admin", "wifi", "Drahtlos", 60)
act("devices", "Geräte")
act("networks", "Netze")

View file

@ -1,6 +1,79 @@
module("ffluci.controller.admin.index.wizard", package.seeall)
module("ffluci.controller.freifunk.freifunk", package.seeall)
function action()
function index()
local page = node()
page.target = alias("freifunk")
local page = node("freifunk")
page.title = "Freifunk"
page.target = alias("freifunk", "index")
page.order = 5
page.setuser = "nobody"
page.setgroup = "nogroup"
local page = node("freifunk", "index")
page.target = template("freifunk/index")
page.title = "Übersicht"
page.order = 10
local page = node("freifunk", "index", "contact")
page.target = template("freifunk/contact")
page.title = "Kontakt"
local page = node("freifunk", "status")
page.target = action_status
page.title = "Status"
page.order = 20
page.setuser = false
page.setgroup = false
local page = node("freifunk", "status", "routes")
page.target = template("public_status/routes")
page.title = "Routingtabelle"
page.order = 10
local page = node("freifunk", "status", "iwscan")
page.target = template("public_status/iwscan")
page.title = "WLAN-Scan"
page.order = 20
local page = node("admin", "index", "wizard")
page.target = action_wizard
page.title = "Freifunkassistent"
page.order = 20
local page = node("admin", "index", "freifunk")
page.target = cbi("freifunk/freifunk")
page.title = "Freifunk"
page.order = 30
local page = node("admin", "index", "contact")
page.target = cbi("freifunk/contact")
page.title = "Kontakt"
page.order = 40
end
function action_status()
local data = {}
data.s, data.m, data.r = ffluci.sys.sysinfo()
data.wifi = ffluci.sys.wifi.getiwconfig()
data.routes = {}
for i, r in pairs(ffluci.sys.net.routes()) do
if r.Destination == "00000000" then
table.insert(data.routes, r)
end
end
ffluci.template.render("public_status/index", data)
end
function action_wizard()
if ffluci.http.formvalue("ip") then
return configure_freifunk()
end
@ -16,7 +89,7 @@ function action()
end
end
ffluci.template.render("admin_index/wizard", {ifaces=ifaces})
ffluci.template.render("freifunk/wizard", {ifaces=ifaces})
end
function configure_freifunk()

View file

@ -1,4 +1,8 @@
module("ffluci.controller.rpc.luciinfo", package.seeall)
module("ffluci.controller.freifunk.luciinfo", package.seeall)
function index()
node("freifunk", "luciinfo").target = action_index
end
function action_index()
local uci = ffluci.model.uci.StateSession()
@ -7,7 +11,7 @@ function action_index()
-- General
print("luciinfo.api=1")
print("luciinfo.version=" .. tostring(ffluci.__version__))
print("luciinfo.version=" .. tostring(require("ffluci").__version__))
-- Sysinfo
local s, m, r = ffluci.sys.sysinfo()
@ -28,11 +32,11 @@ function action_index()
-- Freifunk
local ff = uci:sections("freifunk") or {}
for k, v in pairs(ff) do
if k:sub(1, 1) ~= "." then
for i, j in pairs(v) do
print("freifunk." .. k .. "." .. i .. "=" .. j)
if i:sub(1, 1) ~= "." then
print("freifunk." .. k .. "." .. i .. "=" .. j)
end
end
end
end
end

View file

@ -1,11 +1,38 @@
module("ffluci.controller.public.olsr", package.seeall)
module("ffluci.controller.freifunk.olsr", package.seeall)
require("ffluci.sys")
function index()
local page = node("freifunk", "olsr")
page.target = action_index
page.title = "OLSR"
page.order = 30
local page = node("freifunk", "olsr", "routes")
page.target = action_routes
page.title = "Routen"
page.order = 10
local page = node("freifunk", "olsr", "topology")
page.target = action_topology
page.title = "Topologie"
page.order = 20
local page = node("freifunk", "olsr", "hna")
page.target = action_hna
page.title = "HNA"
page.order = 30
local page = node("freifunk", "olsr", "mid")
page.target = action_mid
page.title = "MID"
page.order = 50
end
function action_index()
local data = fetch_txtinfo("links")
if not data or not data.Links then
ffluci.template.render("public_olsr/error_olsr")
ffluci.template.render("freifunk-olsr/error_olsr")
return nil
end
@ -23,14 +50,14 @@ function action_index()
table.sort(data.Links, compare)
ffluci.template.render("public_olsr/index", {links=data.Links})
ffluci.template.render("freifunk-olsr/index", {links=data.Links})
end
function action_routes()
local data = fetch_txtinfo("routes")
if not data or not data.Routes then
ffluci.template.render("public_olsr/error_olsr")
ffluci.template.render("freifunk-olsr/error_olsr")
return nil
end
@ -48,14 +75,14 @@ function action_routes()
table.sort(data.Routes, compare)
ffluci.template.render("public_olsr/routes", {routes=data.Routes})
ffluci.template.render("freifunk-olsr/routes", {routes=data.Routes})
end
function action_topology()
local data = fetch_txtinfo("topology")
if not data or not data.Topology then
ffluci.template.render("public_olsr/error_olsr")
ffluci.template.render("freifunk-olsr/error_olsr")
return nil
end
@ -65,14 +92,14 @@ function action_topology()
table.sort(data.Topology, compare)
ffluci.template.render("public_olsr/topology", {routes=data.Topology})
ffluci.template.render("freifunk-olsr/topology", {routes=data.Topology})
end
function action_hna()
local data = fetch_txtinfo("hna")
if not data or not data.HNA then
ffluci.template.render("public_olsr/error_olsr")
ffluci.template.render("freifunk-olsr/error_olsr")
return nil
end
@ -82,14 +109,14 @@ function action_hna()
table.sort(data.HNA, compare)
ffluci.template.render("public_olsr/hna", {routes=data.HNA})
ffluci.template.render("freifunk-olsr/hna", {routes=data.HNA})
end
function action_mid()
local data = fetch_txtinfo("mid")
if not data or not data.MID then
ffluci.template.render("public_olsr/error_olsr")
ffluci.template.render("freifunk-olsr/error_olsr")
return nil
end
@ -99,7 +126,7 @@ function action_mid()
table.sort(data.MID, compare)
ffluci.template.render("public_olsr/mid", {mids=data.MID})
ffluci.template.render("freifunk-olsr/mid", {mids=data.MID})
end

View file

@ -1 +0,0 @@
module("ffluci.controller.public.index", package.seeall)

View file

@ -1,21 +0,0 @@
module("ffluci.controller.public.status", package.seeall)
function action_index()
local data = {}
data.s, data.m, data.r = ffluci.sys.sysinfo()
data.wifi = ffluci.sys.wifi.getiwconfig()
data.routes = {}
for i, r in pairs(ffluci.sys.net.routes()) do
if r.Destination == "00000000" then
table.insert(data.routes, r)
end
end
ffluci.template.render("public_status/index", data)
end

View file

@ -1 +0,0 @@
module("ffluci.controller.sudo.status", package.seeall)

View file

@ -1,18 +0,0 @@
add("public", "index", "Übersicht", 10)
act("contact", "Kontakt")
add("public", "status", "Status", 20)
act("routes", "Routingtabelle")
act("iwscan", "WLAN-Scan")
add("public", "olsr", "OLSR", 30)
act("routes", "Routen")
act("topology", "Topologie")
act("hna", "HNA")
act("mid", "MID")
sel("admin", "index")
act("wizard", "Freifunkassistent")
act("contact", "Kontakt")
act("freifunk", "Freifunk")

View file

@ -34,7 +34,25 @@
<th><%:signal Signal%></th>
<th><%:noise Rausch%></th>
</tr>
<%=ffluci.sys.httpget("http://127.0.0.1" .. controller .. "/sudo/status/iwconfig")%>
<%for k, v in pairs(ffluci.sys.wifi.getiwconfig()) do
%>
<tr>
<td rowspan="2"><%=k%></td>
<td><%=v[1]%></td>
<td><%=v.Frequency%></td>
<td><%=v["Tx-Power"]%></td>
<td><%=v["Bit Rate"]%></td>
<td><%=v["RTS thr"]%></td>
<td><%=v["Fragment thr"]%></td>
<td><%=v["Link Quality"]%></td>
<td><%=v["Signal level"]%></td>
<td><%=v["Noise level"]%></td>
</tr>
<tr>
<td colspan="4"><strong>ESSID: </strong><%=v.ESSID%></td>
<td colspan="5"><strong>BSSID: </strong><%=(v.Cell or v["Access Point"])%></td>
</tr>
<%end%>
</table>
<br />
<br />

View file

@ -15,7 +15,24 @@
<th><%:signal Signal%></th>
<th><%:noise Rausch%></th>
</tr>
<%=ffluci.sys.httpget("http://127.0.0.1" .. controller .. "/sudo/status/iwscan")%>
<%for iface, cells in pairs(ffluci.sys.wifi.iwscan()) do
for i, cell in ipairs(cells) do
%>
<tr>
<td><%=iface%></td>
<td><%=cell.ESSID%></td>
<td><%=cell.Address%></td>
<td><%=cell.Mode%></td>
<td><%=(cell.Channel or cell.Frequency or "")%></td>
<td><%=cell["Encryption key"]%></td>
<td><%=cell.Quality%></td>
<td><%=cell["Signal level"]%></td>
<td><%=cell["Noise level"]%></td>
</tr>
<%
end
end
%>
</table>
<br />
<%+footer%>

View file

@ -1,21 +0,0 @@
<%
ffluci.http.prepare_content("text/plain")
for k, v in pairs(ffluci.sys.wifi.getiwconfig()) do
%>
<tr>
<td rowspan="2"><%=k%></td>
<td><%=v[1]%></td>
<td><%=v.Frequency%></td>
<td><%=v["Tx-Power"]%></td>
<td><%=v["Bit Rate"]%></td>
<td><%=v["RTS thr"]%></td>
<td><%=v["Fragment thr"]%></td>
<td><%=v["Link Quality"]%></td>
<td><%=v["Signal level"]%></td>
<td><%=v["Noise level"]%></td>
</tr>
<tr>
<td colspan="4"><strong>ESSID: </strong><%=v.ESSID%></td>
<td colspan="5"><strong>BSSID: </strong><%=(v.Cell or v["Access Point"])%></td>
</tr>
<%end%>

View file

@ -1,22 +0,0 @@
<%
ffluci.http.prepare_content("text/plain")
for iface, cells in pairs(ffluci.sys.wifi.iwscan()) do
for i, cell in ipairs(cells) do
%>
<tr>
<td><%=iface%></td>
<td><%=cell.ESSID%></td>
<td><%=cell.Address%></td>
<td><%=cell.Mode%></td>
<td><%=(cell.Channel or cell.Frequency or "")%></td>
<td><%=cell["Encryption key"]%></td>
<td><%=cell.Quality%></td>
<td><%=cell["Signal level"]%></td>
<td><%=cell["Noise level"]%></td>
</tr>
<%
end
end
%>