Merge pull request #396 from fanthos/master
[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"}, post("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 ip_to_mac(ip)
27         local ipc = require "luci.ip"
28         local i, n
29
30         for i, n in ipairs(ipc.neighbors()) do
31                 if n.mac and n.dest and n.dest:equal(ip) then
32                         return n.mac
33                 end
34         end
35 end
36
37 function action_dispatch()
38         local uci = luci.model.uci.cursor_state()
39         local mac = ip_to_mac(luci.http.getenv("REMOTE_ADDR")) or ""
40         local access = false
41
42         uci:foreach("luci_splash", "lease", function(s)
43                 if s.mac and s.mac:lower() == mac then access = true end
44         end)
45
46         uci:foreach("luci_splash", "whitelist", function(s)
47                 if s.mac and s.mac:lower() == mac then access = true end
48         end)
49
50         if #mac > 0 and access then
51                 luci.http.redirect(luci.dispatcher.build_url())
52         else
53                 luci.http.redirect(luci.dispatcher.build_url("splash", "splash"))
54         end
55 end
56
57 function blacklist()
58         leased_macs = { }
59         uci:foreach("luci_splash", "blacklist",
60                 function(s) leased_macs[s.mac:lower()] = true
61         end)
62         return leased_macs
63 end
64
65 function action_activate()
66         local ipc = require "luci.ip"
67         local mac = ip_to_mac(luci.http.getenv("REMOTE_ADDR") or "127.0.0.1") or ""
68         local uci_state = require "luci.model.uci".cursor_state()
69         local blacklisted = false
70         if mac and luci.http.formvalue("accept") then
71                 uci:foreach("luci_splash", "blacklist",
72                         function(s) if s.mac and s.mac:lower() == mac then blacklisted = true end
73                 end)
74                 if blacklisted then     
75                         luci.http.redirect(luci.dispatcher.build_url("splash" ,"blocked"))
76                 else
77                         local redirect_url = uci:get("luci_splash", "general", "redirect_url")
78                         if not redirect_url then
79                                 redirect_url = uci_state:get("luci_splash_locations", mac:gsub(':', ''):lower(), "location")
80                         end
81                         if not redirect_url then
82                                 redirect_url = luci.model.uci.cursor():get("freifunk", "community", "homepage") or 'http://www.freifunk.net'
83                         end
84                         remove_redirect(mac:gsub(':', ''):lower())
85                         os.execute("luci-splash lease "..mac.." >/dev/null 2>&1")
86                         luci.http.redirect(redirect_url)
87                 end
88         else
89                 luci.http.redirect(luci.dispatcher.build_url())
90         end
91 end
92
93 function action_status_admin()
94         local uci = luci.model.uci.cursor_state()
95         local macs = luci.http.formvaluetable("save")
96
97         local changes = { 
98                 whitelist = { },
99                 blacklist = { },
100                 lease     = { },
101                 remove    = { }
102         }
103
104         for key, _ in pairs(macs) do
105                 local policy = luci.http.formvalue("policy.%s" % key)
106                 local mac    = luci.http.protocol.urldecode(key)
107
108                 if policy == "whitelist" or policy == "blacklist" then
109                         changes[policy][#changes[policy]+1] = mac
110                 elseif policy == "normal" then
111                         changes["lease"][#changes["lease"]+1] = mac
112                 elseif policy == "kicked" then
113                         changes["remove"][#changes["remove"]+1] = mac
114                 end
115         end
116
117         if #changes.whitelist > 0 then
118                 os.execute("luci-splash whitelist %s >/dev/null"
119                         % table.concat(changes.whitelist))
120         end
121
122         if #changes.blacklist > 0 then
123                 os.execute("luci-splash blacklist %s >/dev/null"
124                         % table.concat(changes.blacklist))
125         end
126
127         if #changes.lease > 0 then
128                 os.execute("luci-splash lease %s >/dev/null"
129                         % table.concat(changes.lease))
130         end
131
132         if #changes.remove > 0 then
133                 os.execute("luci-splash remove %s >/dev/null"
134                         % table.concat(changes.remove))
135         end
136
137         luci.template.render("admin_status/splash", { is_admin = true })
138 end
139
140 function action_status_public()
141         luci.template.render("admin_status/splash", { is_admin = false })
142 end
143
144 function remove_redirect(mac)
145         local mac = mac:lower()
146         mac = mac:gsub(":", "")
147         local uci = require "luci.model.uci".cursor_state()
148         local redirects = uci:get_all("luci_splash_locations")
149         --uci:load("luci_splash_locations")
150         uci:revert("luci_splash_locations")
151         -- For all redirects
152         for k, v in pairs(redirects) do
153                 if v[".type"] == "redirect" then
154                         if v[".name"] ~= mac then
155                                 -- Rewrite state
156                                 uci:section("luci_splash_locations", "redirect", v[".name"], {
157                                         location = v.location
158                                 })
159                         end
160                 end
161         end
162         uci:save("luci_splash_redirects")
163 end