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