luci-base: Make default for FileUpload 'safe'

Some files and pointers to files are not safe to remove without a replacement
file and config pointing to the file.  For instance for uhttpd application in
the works, removing the certificate or key config or files without having the
replacements in places renders the WeUI inaccessible.

The only other place where FileUpload is currently used is for wifi certificates
for which the 'safe' handling is also preferred.  Therefore make the default for
the FileUpload widget the safe handling and add a property self.unsafeupload that
allows for the old unsafe handling should it prove useful in some case.

Also allow to specify a file already on router instead of uploading a file.

Signed-off By: Daniel Dickinson <openwrt@daniel.thecshore.com>
This commit is contained in:
Daniel Dickinson 2015-12-01 23:02:38 -05:00
parent f25c4e07bc
commit b475ec699d
2 changed files with 57 additions and 17 deletions

View file

@ -1811,6 +1811,7 @@ function Button.__init__(self, ...)
self.template = "cbi/button" self.template = "cbi/button"
self.inputstyle = nil self.inputstyle = nil
self.rmempty = true self.rmempty = true
self.unsafeupload = false
end end
@ -1827,9 +1828,15 @@ function FileUpload.__init__(self, ...)
end end
function FileUpload.formcreated(self, section) function FileUpload.formcreated(self, section)
return AbstractValue.formcreated(self, section) or if self.unsafeupload then
self.map:formvalue("cbi.rlf."..section.."."..self.option) or return AbstractValue.formcreated(self, section) or
self.map:formvalue("cbi.rlf."..section.."."..self.option..".x") self.map:formvalue("cbi.rlf."..section.."."..self.option) or
self.map:formvalue("cbi.rlf."..section.."."..self.option..".x") or
self.map:formvalue("cbid."..self.map.config.."."..section.."."..self.option..".textbox")
else
return AbstractValue.formcreated(self, section) or
self.map:formvalue("cbid."..self.map.config.."."..section.."."..self.option..".textbox")
end
end end
function FileUpload.cfgvalue(self, section) function FileUpload.cfgvalue(self, section)
@ -1840,27 +1847,50 @@ function FileUpload.cfgvalue(self, section)
return nil return nil
end end
-- If we have a new value, use it
-- otherwise use old value
-- deletion should be managed by a separate button object
-- unless self.unsafeupload is set in which case if the user
-- choose to remove the old file we do so.
-- Also, allow to specify (via textbox) a file already on router
function FileUpload.formvalue(self, section) function FileUpload.formvalue(self, section)
local val = AbstractValue.formvalue(self, section) local val = AbstractValue.formvalue(self, section)
if val then if val then
if not self.map:formvalue("cbi.rlf."..section.."."..self.option) and if self.unsafeupload then
not self.map:formvalue("cbi.rlf."..section.."."..self.option..".x") if not self.map:formvalue("cbi.rlf."..section.."."..self.option) and
then not self.map:formvalue("cbi.rlf."..section.."."..self.option..".x")
then
return val
end
fs.unlink(val)
self.value = nil
return nil
elseif val ~= "" then
return val return val
end end
fs.unlink(val)
self.value = nil
end end
return nil val = luci.http.formvalue("cbid."..self.map.config.."."..section.."."..self.option..".textbox")
if val == "" then
val = nil
end
if not self.unsafeupload then
if not val then
val = self.map:formvalue("cbi.rlf."..section.."."..self.option)
end
end
return val
end end
function FileUpload.remove(self, section) function FileUpload.remove(self, section)
local val = AbstractValue.formvalue(self, section) if self.unsafeupload then
if val and fs.access(val) then fs.unlink(val) end local val = AbstractValue.formvalue(self, section)
return AbstractValue.remove(self, section) if val and fs.access(val) then fs.unlink(val) end
return AbstractValue.remove(self, section)
else
return nil
end
end end
FileBrowser = class(AbstractValue) FileBrowser = class(AbstractValue)
function FileBrowser.__init__(self, ...) function FileBrowser.__init__(self, ...)

View file

@ -6,9 +6,19 @@
<%+cbi/valueheader%> <%+cbi/valueheader%>
<% if s then %> <% if s then %>
<%:Uploaded File%> (<%=t.byte_format(s.size)%>) <%:Uploaded File%> (<%=t.byte_format(s.size)%>)
<input type="hidden"<%= attr("value", v) .. attr("name", cbid) .. attr("id", cbid) %> /> <% if self.unsafeupload then %>
<input class="cbi-button cbi-input-image" type="image" value="<%:Replace entry%>" name="cbi.rlf.<%=section .. "." .. self.option%>" alt="<%:Replace entry%>" title="<%:Replace entry%>" src="<%=resource%>/cbi/reload.gif" /> <input type="hidden"<%= attr("value", v) .. attr("name", cbid) .. attr("id", cbid) %> />
<% else %> <input class="cbi-button cbi-input-image" type="image" value="<%:Replace entry%>" name="cbi.rlf.<%=section .. "." .. self.option%>" alt="<%:Replace entry%>" title="<%:Replace entry%>" src="<%=resource%>/cbi/reload.gif" />
<% end %>
<% end %>
<% if not self.unsafeupload then %>
<input type="hidden"<%= attr("value", v) .. attr("name", "cbi.rlf." .. section .. "." .. self.option) .. attr("id", "cbi.rlf." .. section .. "." .. self.option) %> />
<% end %>
<% if (not s) or (s and not self.unsafeupload) then %>
<input class="cbi-input-file" type="file"<%= attr("name", cbid) .. attr("id", cbid) %> /> <input class="cbi-input-file" type="file"<%= attr("name", cbid) .. attr("id", cbid) %> />
<% end %> <% end %>
<input type="text" class="cbi-input-text" onchange="cbi_d_update(this.id)"<%=
attr("name", cbid .. ".textbox") .. attr("id", cbid .. ".textbox") .. attr("value", luci.cbi.AbstractValue.cfgvalue(self, section) or self.default) .. ifattr(self.size, "size") .. ifattr(self.placeholder, "placeholder") .. ifattr(self.readonly, "readonly") .. ifattr(self.maxlength, "maxlength") %> />
<%+cbi/valuefooter%> <%+cbi/valuefooter%>