summaryrefslogtreecommitdiffhomepage
path: root/modules/luci-base/luasrc
diff options
context:
space:
mode:
Diffstat (limited to 'modules/luci-base/luasrc')
-rw-r--r--modules/luci-base/luasrc/dispatcher.lua15
-rw-r--r--modules/luci-base/luasrc/model/uci.lua92
-rw-r--r--modules/luci-base/luasrc/util.lua16
-rw-r--r--modules/luci-base/luasrc/view/cbi/apply_widget.htm10
-rw-r--r--modules/luci-base/luasrc/view/cbi/cell_valueheader.htm6
-rw-r--r--modules/luci-base/luasrc/view/cbi/map.htm15
-rw-r--r--modules/luci-base/luasrc/view/cbi/tblsection.htm4
-rw-r--r--modules/luci-base/luasrc/view/cbi/ucisection.htm8
-rw-r--r--modules/luci-base/luasrc/view/cbi/value.htm10
-rw-r--r--modules/luci-base/luasrc/view/footer.htm25
10 files changed, 137 insertions, 64 deletions
diff --git a/modules/luci-base/luasrc/dispatcher.lua b/modules/luci-base/luasrc/dispatcher.lua
index 6d5a8f4d3d..6cf2712eb4 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 92c0d8f699..b2c1e463bf 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/util.lua b/modules/luci-base/luasrc/util.lua
index 10428b0b35..f16b3afb2e 100644
--- a/modules/luci-base/luasrc/util.lua
+++ b/modules/luci-base/luasrc/util.lua
@@ -16,7 +16,7 @@ local _ubus = require "ubus"
local _ubus_connection = nil
local getmetatable, setmetatable = getmetatable, setmetatable
-local rawget, rawset, unpack = rawget, rawset, unpack
+local rawget, rawset, unpack, select = rawget, rawset, unpack, select
local tostring, type, assert, error = tostring, type, assert, error
local ipairs, pairs, next, loadstring = ipairs, pairs, next, loadstring
local require, pcall, xpcall = require, pcall, xpcall
@@ -647,6 +647,17 @@ local ubus_codes = {
"CONNECTION_FAILED"
}
+local function ubus_return(...)
+ if select('#', ...) == 2 then
+ local rv, err = select(1, ...), select(2, ...)
+ if rv == nil and type(err) == "number" then
+ return nil, err, ubus_codes[err]
+ end
+ end
+
+ return ...
+end
+
function ubus(object, method, data)
if not _ubus_connection then
_ubus_connection = _ubus.connect()
@@ -657,8 +668,7 @@ function ubus(object, method, data)
if type(data) ~= "table" then
data = { }
end
- local rv, err = _ubus_connection:call(object, method, data)
- return rv, err, ubus_codes[err]
+ return ubus_return(_ubus_connection:call(object, method, data))
elseif object then
return _ubus_connection:signatures(object)
else
diff --git a/modules/luci-base/luasrc/view/cbi/apply_widget.htm b/modules/luci-base/luasrc/view/cbi/apply_widget.htm
index f76846ee87..4d7e9c56ea 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/cell_valueheader.htm b/modules/luci-base/luasrc/view/cbi/cell_valueheader.htm
index dbb0e1120b..ea0568f409 100644
--- a/modules/luci-base/luasrc/view/cbi/cell_valueheader.htm
+++ b/modules/luci-base/luasrc/view/cbi/cell_valueheader.htm
@@ -1,10 +1,12 @@
<%-
local title = luci.util.trim(striptags(self.title))
- local ftype = self.template and self.template:gsub("^.+/", "")
+ local descr = luci.util.trim(striptags(self.description))
+ local ftype = self.typename or (self.template and self.template:gsub("^.+/", ""))
-%>
<div class="td cbi-value-field<% if self.error and self.error[section] then %> cbi-value-error<% end %>"<%=
attr("data-name", self.option) ..
ifattr(ftype and #ftype > 0, "data-type", ftype) ..
- ifattr(title and #title > 0, "data-title", title)
+ ifattr(title and #title > 0, "data-title", title) ..
+ ifattr(descr and #descr > 0, "data-description", descr)
%>>
<div id="cbi-<%=self.config.."-"..section.."-"..self.option%>" data-index="<%=self.index%>" data-depends="<%=pcdata(self:deplist2json(section))%>">
diff --git a/modules/luci-base/luasrc/view/cbi/map.htm b/modules/luci-base/luasrc/view/cbi/map.htm
index 83c3cb2170..d65a161673 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/cbi/tblsection.htm b/modules/luci-base/luasrc/view/cbi/tblsection.htm
index 9505f4ac4e..408dfa7fe8 100644
--- a/modules/luci-base/luasrc/view/cbi/tblsection.htm
+++ b/modules/luci-base/luasrc/view/cbi/tblsection.htm
@@ -4,9 +4,9 @@ local rowcnt = 0
function rowstyle()
rowcnt = rowcnt + 1
if rowcnt % 2 == 0 then
- return "cbi-rowstyle-1"
+ return " cbi-rowstyle-1"
else
- return "cbi-rowstyle-2"
+ return " cbi-rowstyle-2"
end
end
diff --git a/modules/luci-base/luasrc/view/cbi/ucisection.htm b/modules/luci-base/luasrc/view/cbi/ucisection.htm
index 2cb1e75d0e..8fa11d68f8 100644
--- a/modules/luci-base/luasrc/view/cbi/ucisection.htm
+++ b/modules/luci-base/luasrc/view/cbi/ucisection.htm
@@ -32,25 +32,25 @@
<% if self.optionals[section] and #self.optionals[section] > 0 or self.dynamic then %>
<div class="cbi-optionals" data-index="<%=#self.children + 1%>">
- <%
+ <%-
if self.dynamic then
local keys, vals, name, opt = { }, { }
for name, opt in pairs(self.optionals[section]) do
keys[#keys+1] = name
vals[#vals+1] = opt.title
end
- %>
+ -%>
<input type="text" id="cbi.opt.<%=self.config%>.<%=section%>" name="cbi.opt.<%=self.config%>.<%=section%>" data-type="uciname" data-optional="true"<%=
ifattr(#keys > 0, "data-choices", luci.util.json_encode({keys, vals}))
%> />
- <% else %>
+ <%- else -%>
<select id="cbi.opt.<%=self.config%>.<%=section%>" name="cbi.opt.<%=self.config%>.<%=section%>" data-optionals="true">
<option><%: -- Additional Field -- %></option>
<% for key, val in pairs(self.optionals[section]) do -%>
<option id="cbi-<%=self.config.."-"..section.."-"..val.option%>" value="<%=val.option%>" data-index="<%=val.index%>" data-depends="<%=pcdata(val:deplist2json(section))%>"><%=striptags(val.title)%></option>
<%- end %>
</select>
- <% end %>
+ <%- end -%>
<input type="submit" class="cbi-button cbi-button-fieldadd" value="<%:Add%>" />
</div>
<% end %>
diff --git a/modules/luci-base/luasrc/view/cbi/value.htm b/modules/luci-base/luasrc/view/cbi/value.htm
index c8c905eb11..942ab72e77 100644
--- a/modules/luci-base/luasrc/view/cbi/value.htm
+++ b/modules/luci-base/luasrc/view/cbi/value.htm
@@ -1,10 +1,16 @@
<%+cbi/valueheader%>
+ <%- if self.password then -%>
+ <input type="password" style="position:absolute; left:-1000px"<%=
+ attr("name", "password." .. cbid)
+ %> />
+ <%- end -%>
<input data-update="change"<%=
attr("id", cbid) ..
attr("name", cbid) ..
attr("type", self.password and "password" or "text") ..
attr("class", self.password and "cbi-input-password" or "cbi-input-text") ..
attr("value", self:cfgvalue(section) or self.default) ..
+ ifattr(self.password, "autocomplete", "new-password") ..
ifattr(self.size, "size") ..
ifattr(self.placeholder, "placeholder") ..
ifattr(self.readonly, "readonly") ..
@@ -14,5 +20,7 @@
ifattr(self.combobox_manual, "data-manual", self.combobox_manual) ..
ifattr(#self.keylist > 0, "data-choices", { self.keylist, self.vallist })
%> />
- <% if self.password then %><img src="<%=resource%>/cbi/reload.gif" style="vertical-align:middle" title="<%:Reveal/hide password%>" onclick="var e = document.getElementById('<%=cbid%>'); e.type = (e.type=='password') ? 'text' : 'password';" /><% end %>
+ <%- if self.password then -%>
+ <div class="cbi-button cbi-button-neutral" title="<%:Reveal/hide password%>" onclick="var e = this.previousElementSibling; e.type = (e.type === 'password') ? 'text' : 'password'">∗</div>
+ <% end %>
<%+cbi/valuefooter%>
diff --git a/modules/luci-base/luasrc/view/footer.htm b/modules/luci-base/luasrc/view/footer.htm
index f3574b6b10..1667d3aa9a 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
+<%
+ 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
+
+ include("themes/" .. theme .. "/footer")
+%>