diff options
-rw-r--r-- | modules/luci-base/luasrc/dispatcher.lua | 15 | ||||
-rw-r--r-- | modules/luci-base/luasrc/model/uci.lua | 92 | ||||
-rw-r--r-- | modules/luci-base/luasrc/view/cbi/apply_widget.htm | 10 | ||||
-rw-r--r-- | modules/luci-base/luasrc/view/cbi/map.htm | 15 | ||||
-rw-r--r-- | modules/luci-base/luasrc/view/footer.htm | 25 | ||||
-rw-r--r-- | modules/luci-mod-admin-full/luasrc/controller/admin/uci.lua | 26 | ||||
-rw-r--r-- | modules/luci-mod-admin-full/luasrc/view/admin_uci/changes.htm | 10 | ||||
-rw-r--r-- | modules/luci-mod-admin-full/luasrc/view/admin_uci/revert.htm | 11 |
8 files changed, 129 insertions, 75 deletions
diff --git a/modules/luci-base/luasrc/dispatcher.lua b/modules/luci-base/luasrc/dispatcher.lua index 6d5a8f4d3..6cf2712eb 100644 --- a/modules/luci-base/luasrc/dispatcher.lua +++ b/modules/luci-base/luasrc/dispatcher.lua @@ -893,8 +893,6 @@ local function _cbi(self, ...) local pageaction = true local parsechain = { } - local is_rollback, time_remaining = uci:rollback_pending() - for i, res in ipairs(maps) do if res.apply_needed and res.parsechain then local c @@ -921,8 +919,6 @@ local function _cbi(self, ...) for i, res in ipairs(maps) do res:render({ firstmap = (i == 1), - applymap = applymap, - confirmmap = (is_rollback and time_remaining or nil), redirect = redirect, messages = messages, pageaction = pageaction, @@ -932,11 +928,12 @@ local function _cbi(self, ...) if not config.nofooter then tpl.render("cbi/footer", { - flow = config, - pageaction = pageaction, - redirect = redirect, - state = state, - autoapply = config.autoapply + flow = config, + pageaction = pageaction, + redirect = redirect, + state = state, + autoapply = config.autoapply, + trigger_apply = applymap }) end end diff --git a/modules/luci-base/luasrc/model/uci.lua b/modules/luci-base/luasrc/model/uci.lua index 92c0d8f69..b2c1e463b 100644 --- a/modules/luci-base/luasrc/model/uci.lua +++ b/modules/luci-base/luasrc/model/uci.lua @@ -147,19 +147,31 @@ function apply(self, rollback) local _, err if rollback then + local sys = require "luci.sys" local conf = require "luci.config" - local timeout = tonumber(conf and conf.apply and conf.apply.rollback or "") or 0 + local timeout = tonumber(conf and conf.apply and conf.apply.rollback or 30) or 0 _, err = call("apply", { - timeout = (timeout > 30) and timeout or 30, + timeout = (timeout > 30) and timeout or 30, rollback = true }) if not err then + local now = os.time() + local token = sys.uniqueid(16) + util.ubus("session", "set", { - ubus_rpc_session = session_id, - values = { rollback = os.time() + timeout } + ubus_rpc_session = "00000000000000000000000000000000", + values = { + rollback = { + token = token, + session = session_id, + timeout = now + timeout + } + } }) + + return token end else _, err = call("changes", {}) @@ -184,40 +196,72 @@ function apply(self, rollback) return (err == nil), ERRSTR[err] end -function confirm(self) - local _, err = call("confirm", {}) - if not err then - util.ubus("session", "set", { - ubus_rpc_session = session_id, - values = { rollback = 0 } +function confirm(self, token) + local is_pending, time_remaining, rollback_sid, rollback_token = self:rollback_pending() + + if is_pending then + if token ~= rollback_token then + return false, "Permission denied" + end + + local _, err = util.ubus("uci", "confirm", { + ubus_rpc_session = rollback_sid }) + + if not err then + util.ubus("session", "set", { + ubus_rpc_session = "00000000000000000000000000000000", + values = { rollback = {} } + }) + end + + return (err == nil), ERRSTR[err] end - return (err == nil), ERRSTR[err] + + return false, "No data" end function rollback(self) - local _, err = call("rollback", {}) - if not err then - util.ubus("session", "set", { - ubus_rpc_session = session_id, - values = { rollback = 0 } + local is_pending, time_remaining, rollback_sid = self:rollback_pending() + + if is_pending then + local _, err = util.ubus("uci", "rollback", { + ubus_rpc_session = rollback_sid }) + + if not err then + util.ubus("session", "set", { + ubus_rpc_session = "00000000000000000000000000000000", + values = { rollback = {} } + }) + end + + return (err == nil), ERRSTR[err] end - return (err == nil), ERRSTR[err] + + return false, "No data" end function rollback_pending(self) - local deadline, err = util.ubus("session", "get", { - ubus_rpc_session = session_id, + local rv, err = util.ubus("session", "get", { + ubus_rpc_session = "00000000000000000000000000000000", keys = { "rollback" } }) - if type(deadline) == "table" and - type(deadline.values) == "table" and - type(deadline.values.rollback) == "number" and - deadline.values.rollback > os.time() + local now = os.time() + + if type(rv) == "table" and + type(rv.values) == "table" and + type(rv.values.rollback) == "table" and + type(rv.values.rollback.token) == "string" and + type(rv.values.rollback.session) == "string" and + type(rv.values.rollback.timeout) == "number" and + rv.values.rollback.timeout > now then - return true, deadline.values.rollback - os.time() + return true, + rv.values.rollback.timeout - now, + rv.values.rollback.session, + rv.values.rollback.token end return false, ERRSTR[err] diff --git a/modules/luci-base/luasrc/view/cbi/apply_widget.htm b/modules/luci-base/luasrc/view/cbi/apply_widget.htm index f76846ee8..4d7e9c56e 100644 --- a/modules/luci-base/luasrc/view/cbi/apply_widget.htm +++ b/modules/luci-base/luasrc/view/cbi/apply_widget.htm @@ -1,4 +1,4 @@ -<% export("cbi_apply_widget", function(redirect_ok) -%> +<% export("cbi_apply_widget", function(redirect_ok, rollback_token) -%> <style type="text/css"> #cbi_apply_overlay { position: absolute; @@ -51,6 +51,7 @@ uci_apply_holdoff = <%=math.max(luci.config and luci.config.apply and luci.config.apply.holdoff or 4, 1)%>, uci_apply_timeout = <%=math.max(luci.config and luci.config.apply and luci.config.apply.timeout or 5, 1)%>, uci_apply_display = <%=math.max(luci.config and luci.config.apply and luci.config.apply.display or 1.5, 1)%>, + uci_confirm_auth = <% if rollback_token then %>{ token: '<%=rollback_token%>' }<% else %>null<% end %>, was_xhr_poll_running = false; function uci_status_message(type, content) { @@ -148,7 +149,7 @@ var delay = isNaN(duration) ? 0 : Math.max(1000 - duration, 0); window.setTimeout(function() { - xhr.post('<%=url("admin/uci/confirm")%>', uci_apply_auth, call, uci_apply_timeout * 1000); + xhr.post('<%=url("admin/uci/confirm")%>', uci_confirm_auth, call, uci_apply_timeout * 1000); }, delay); }; @@ -177,8 +178,11 @@ '<img src="<%=resource%>/icons/loading.gif" alt="" style="vertical-align:middle" /> ' + '<%:Starting configuration apply…%>'); - xhr.post('<%=url("admin/uci")%>/' + (checked ? 'apply_rollback' : 'apply_unchecked'), uci_apply_auth, function(r) { + xhr.post('<%=url("admin/uci")%>/' + (checked ? 'apply_rollback' : 'apply_unchecked'), uci_apply_auth, function(r, tok) { if (r.status === (checked ? 200 : 204)) { + if (checked && tok !== null && typeof(tok) === 'object' && typeof(tok.token) === 'string') + uci_confirm_auth = tok; + uci_confirm(checked, Date.now() + uci_apply_rollback * 1000); } else if (checked && r.status === 204) { diff --git a/modules/luci-base/luasrc/view/cbi/map.htm b/modules/luci-base/luasrc/view/cbi/map.htm index 83c3cb217..d65a16167 100644 --- a/modules/luci-base/luasrc/view/cbi/map.htm +++ b/modules/luci-base/luasrc/view/cbi/map.htm @@ -5,21 +5,6 @@ <div class="cbi-map" id="cbi-<%=self.config%>"> <% if self.title and #self.title > 0 then %><h2 name="content"><%=self.title%></h2><% end %> <% if self.description and #self.description > 0 then %><div class="cbi-map-descr"><%=self.description%></div><% end %> - <%- if firstmap and (applymap or confirmmap) then -%> - <%+cbi/apply_widget%> - <% cbi_apply_widget(redirect) %> - <div class="alert-message" id="cbi_apply_status" style="display:none"></div> - <script type="text/javascript"> - document.addEventListener("DOMContentLoaded", function() { - <% if confirmmap then -%> - uci_confirm(true, Date.now() + <%=confirmmap%> * 1000); - <%- else -%> - uci_apply(true); - <%- end %> - }); - </script> - <%- end -%> - <% if self.tabbed then %> <ul class="cbi-tabmenu map"> <%- self.selected_tab = luci.http.formvalue("tab.m-" .. self.config) %> diff --git a/modules/luci-base/luasrc/view/footer.htm b/modules/luci-base/luasrc/view/footer.htm index f3574b6b1..d268d71cf 100644 --- a/modules/luci-base/luasrc/view/footer.htm +++ b/modules/luci-base/luasrc/view/footer.htm @@ -4,4 +4,27 @@ Licensed to the public under the Apache License 2.0. -%> -<% include("themes/" .. theme .. "/footer") %>
\ No newline at end of file +<% + include("themes/" .. theme .. "/footer") + + local is_rollback_pending, rollback_time_remaining, rollback_session, rollback_token = luci.model.uci:rollback_pending() + + if is_rollback_pending or trigger_apply or trigger_revert then + include("cbi/apply_widget") + cbi_apply_widget(redirect, rollback_token) +%> + <div class="alert-message" id="cbi_apply_status" style="display:none"></div> + <script type="text/javascript"> + document.addEventListener("DOMContentLoaded", function() { + <% if trigger_apply then -%> + uci_apply(true); + <%- elseif trigger_revert then -%> + uci_revert(); + <%- else -%> + uci_confirm(true, Date.now() + <%=rollback_time_remaining%> * 1000); + <%- end %> + }); + </script> +<% + end +%> diff --git a/modules/luci-mod-admin-full/luasrc/controller/admin/uci.lua b/modules/luci-mod-admin-full/luasrc/controller/admin/uci.lua index 9533ff5e6..1d955dd98 100644 --- a/modules/luci-mod-admin-full/luasrc/controller/admin/uci.lua +++ b/modules/luci-mod-admin-full/luasrc/controller/admin/uci.lua @@ -9,7 +9,7 @@ function index() or table.concat(luci.dispatcher.context.request, "/") entry({"admin", "uci"}, nil, _("Configuration")) - entry({"admin", "uci", "changes"}, call("action_changes"), _("Changes"), 40).query = {redir=redir} + entry({"admin", "uci", "changes"}, post_on({ trigger_apply = true }, "action_changes"), _("Changes"), 40).query = {redir=redir} entry({"admin", "uci", "revert"}, post("action_revert"), _("Revert"), 30).query = {redir=redir} local node @@ -25,9 +25,9 @@ function index() node.cors = true node.sysauth_authenticator = authen - node = entry({"admin", "uci", "confirm"}, post("action_confirm"), nil) + node = entry({"admin", "uci", "confirm"}, call("action_confirm"), nil) node.cors = true - node.sysauth_authenticator = authen + node.sysauth = false end @@ -36,8 +36,9 @@ function action_changes() local changes = uci:changes() luci.template.render("admin_uci/changes", { - changes = next(changes) and changes, - timeout = timeout + changes = next(changes) and changes, + timeout = timeout, + trigger_apply = luci.http.formvalue("trigger_apply") and true or false }) end @@ -52,7 +53,8 @@ function action_revert() end luci.template.render("admin_uci/revert", { - changes = next(changes) and changes + changes = next(changes) and changes, + trigger_revert = true }) end @@ -84,8 +86,13 @@ end function action_apply_rollback() local uci = require "luci.model.uci" - local _, errstr = uci:apply(true) - ubus_state_to_http(errstr) + local token, errstr = uci:apply(true) + if token then + luci.http.prepare_content("application/json") + luci.http.write_json({ token = token }) + else + ubus_state_to_http(errstr) + end end function action_apply_unchecked() @@ -96,6 +103,7 @@ end function action_confirm() local uci = require "luci.model.uci" - local _, errstr = uci:confirm() + local token = luci.http.formvalue("token") + local _, errstr = uci:confirm(token) ubus_state_to_http(errstr) end diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_uci/changes.htm b/modules/luci-mod-admin-full/luasrc/view/admin_uci/changes.htm index 628224475..43bd7c23f 100644 --- a/modules/luci-mod-admin-full/luasrc/view/admin_uci/changes.htm +++ b/modules/luci-mod-admin-full/luasrc/view/admin_uci/changes.htm @@ -8,11 +8,9 @@ <%- local node, redir_url = luci.dispatcher.lookup(luci.http.formvalue("redir")) + export("redirect", redir_url or url("admin/uci/changes")) - include("cbi/apply_widget") include("admin_uci/changelog") - - cbi_apply_widget(redir_url or url("admin/uci/changes")) -%> <h2 name="content"><%:Configuration%> / <%:Changes%></h2> @@ -32,7 +30,11 @@ </form> <% end %> - <input class="cbi-button cbi-button-save" type="button" id="apply_button" value="<%:Save & Apply%>" onclick="uci_apply(true); this.blur()" /> + <form method="post" action="<%=url("admin/uci/changes")%>"> + <input type="hidden" name="token" value="<%=token%>" /> + <input type="hidden" name="redir" value="<%=pcdata(luci.http.formvalue("redir"))%>" /> + <input class="cbi-button cbi-button-save" type="submit" name="trigger_apply" value="<%:Save & Apply%>" /> + </form> <form method="post" action="<%=url("admin/uci/revert")%>"> <input type="hidden" name="token" value="<%=token%>" /> <input type="hidden" name="redir" value="<%=pcdata(luci.http.formvalue("redir"))%>" /> diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_uci/revert.htm b/modules/luci-mod-admin-full/luasrc/view/admin_uci/revert.htm index ff23d568d..d8fd3de01 100644 --- a/modules/luci-mod-admin-full/luasrc/view/admin_uci/revert.htm +++ b/modules/luci-mod-admin-full/luasrc/view/admin_uci/revert.htm @@ -8,11 +8,9 @@ <%- local node, redir_url = luci.dispatcher.lookup(luci.http.formvalue("redir")) + export("redirect", redir_url or url("admin/uci/changes")) - include("cbi/apply_widget") include("admin_uci/changelog") - - cbi_apply_widget(redir_url or url("admin/uci/revert")) -%> <h2 name="content"><%:Configuration%> / <%:Revert%></h2> @@ -24,13 +22,6 @@ <p><strong><%:There are no pending changes to revert!%></strong></p> <% end %> -<div class="alert-message" id="cbi_apply_status" style="display:none"></div> -<script type="text/javascript"> - document.addEventListener("DOMContentLoaded", function() { - uci_revert(); - }); -</script> - <% if redir_url then %> <div class="cbi-page-actions"> <form class="inline" method="get" action="<%=luci.util.pcdata(redir_url)%>"> |