luci-app-splash: convert luci.sys.net.arptable() to luci.ip.neighbors()
[project/luci.git] / applications / luci-app-splash / luasrc / controller / splash / splash.lua
1 module("luci.controller.splash.splash", package.seeall)
2
3 local uci = luci.model.uci.cursor()
4 local util = require "luci.util"
5
6 function index()
7         entry({"admin", "services", "splash"}, cbi("splash/splash"), _("Client-Splash"), 90)
8         entry({"admin", "services", "splash", "splashtext" }, form("splash/splashtext"), _("Splashtext"), 10)
9
10         local e
11         
12         e = node("splash")
13         e.target = call("action_dispatch")
14
15         node("splash", "activate").target = call("action_activate")
16         node("splash", "splash").target   = template("splash_splash/splash")
17         node("splash", "blocked").target  = template("splash/blocked")
18
19         entry({"admin", "status", "splash"}, call("action_status_admin"), _("Client-Splash"))
20
21         local page  = node("splash", "publicstatus")
22         page.target = call("action_status_public")
23         page.leaf   = true
24 end
25
26 function action_dispatch()
27         local uci = luci.model.uci.cursor_state()
28         local ipc = require "luci.ip"
29
30         local i, n
31         local mac = ""
32         local access = false
33
34         for i, n in ipairs(ipc.neighbors()) do
35                 if n.mac and n.dest and n.dest:equal(luci.http.getenv("REMOTE_ADDR")) then
36                         mac = n.mac
37                 end
38         end
39
40         uci:foreach("luci_splash", "lease", function(s)
41                 if s.mac and s.mac:lower() == mac then access = true end
42         end)
43         uci:foreach("luci_splash", "whitelist", function(s)
44                 if s.mac and s.mac:lower() == mac then access = true end
45         end)
46
47         if #mac > 0 and access then
48                 luci.http.redirect(luci.dispatcher.build_url())
49         else
50                 luci.http.redirect(luci.dispatcher.build_url("splash", "splash"))
51         end
52 end
53
54 function blacklist()
55         leased_macs = { }
56         uci:foreach("luci_splash", "blacklist",
57                 function(s) leased_macs[s.mac:lower()] = true
58         end)
59         return leased_macs
60 end
61
62 function action_activate()
63         local ip = luci.http.getenv("REMOTE_ADDR") or "127.0.0.1"
64         local mac = luci.sys.net.ip4mac(ip:match("^[\[::ffff:]*(%d+.%d+%.%d+%.%d+)\]*$"))
65         local uci_state = require "luci.model.uci".cursor_state()
66         local blacklisted = false
67         if mac and luci.http.formvalue("accept") then
68                 uci:foreach("luci_splash", "blacklist",
69                         function(s) if s.mac:lower() == mac or s.mac == mac then blacklisted = true end
70                 end)
71                 if blacklisted then     
72                         luci.http.redirect(luci.dispatcher.build_url("splash" ,"blocked"))
73                 else
74                         local redirect_url = uci:get("luci_splash", "general", "redirect_url")
75                         if not redirect_url then
76                                 redirect_url = uci_state:get("luci_splash_locations", mac:gsub(':', ''):lower(), "location")
77                         end
78                         if not redirect_url then
79                                 redirect_url = luci.model.uci.cursor():get("freifunk", "community", "homepage") or 'http://www.freifunk.net'
80                         end
81                         remove_redirect(mac:gsub(':', ''):lower())
82                         os.execute("luci-splash lease "..mac.." >/dev/null 2>&1")
83                         luci.http.redirect(redirect_url)
84                 end
85         else
86                 luci.http.redirect(luci.dispatcher.build_url())
87         end
88 end
89
90 function action_status_admin()
91         local uci = luci.model.uci.cursor_state()
92         local macs = luci.http.formvaluetable("save")
93
94         local changes = { 
95                 whitelist = { },
96                 blacklist = { },
97                 lease     = { },
98                 remove    = { }
99         }
100
101         for key, _ in pairs(macs) do
102                 local policy = luci.http.formvalue("policy.%s" % key)
103                 local mac    = luci.http.protocol.urldecode(key)
104
105                 if policy == "whitelist" or policy == "blacklist" then
106                         changes[policy][#changes[policy]+1] = mac
107                 elseif policy == "normal" then
108                         changes["lease"][#changes["lease"]+1] = mac
109                 elseif policy == "kicked" then
110                         changes["remove"][#changes["remove"]+1] = mac
111                 end
112         end
113
114         if #changes.whitelist > 0 then
115                 os.execute("luci-splash whitelist %s >/dev/null"
116                         % table.concat(changes.whitelist))
117         end
118
119         if #changes.blacklist > 0 then
120                 os.execute("luci-splash blacklist %s >/dev/null"
121                         % table.concat(changes.blacklist))
122         end
123
124         if #changes.lease > 0 then
125                 os.execute("luci-splash lease %s >/dev/null"
126                         % table.concat(changes.lease))
127         end
128
129         if #changes.remove > 0 then
130                 os.execute("luci-splash remove %s >/dev/null"
131                         % table.concat(changes.remove))
132         end
133
134         luci.template.render("admin_status/splash", { is_admin = true })
135 end
136
137 function action_status_public()
138         luci.template.render("admin_status/splash", { is_admin = false })
139 end
140
141 function remove_redirect(mac)
142         local mac = mac:lower()
143         mac = mac:gsub(":", "")
144         local uci = require "luci.model.uci".cursor_state()
145         local redirects = uci:get_all("luci_splash_locations")
146         --uci:load("luci_splash_locations")
147         uci:revert("luci_splash_locations")
148         -- For all redirects
149         for k, v in pairs(redirects) do
150                 if v[".type"] == "redirect" then
151                         if v[".name"] ~= mac then
152                                 -- Rewrite state
153                                 uci:section("luci_splash_locations", "redirect", v[".name"], {
154                                         location = v.location
155                                 })
156                         end
157                 end
158         end
159         uci:save("luci_splash_redirects")
160 end