diff options
-rw-r--r-- | tinydns-controller.lua | 28 | ||||
-rw-r--r-- | tinydns-html.lsp | 12 | ||||
-rw-r--r-- | tinydns-listpermissions-html.lsp | 17 | ||||
-rw-r--r-- | tinydns-model.lua | 115 | ||||
-rw-r--r-- | tinydns.menu | 1 | ||||
-rw-r--r-- | tinydns.roles | 2 |
6 files changed, 141 insertions, 34 deletions
diff --git a/tinydns-controller.lua b/tinydns-controller.lua index 1856fa2..4030cf3 100644 --- a/tinydns-controller.lua +++ b/tinydns-controller.lua @@ -5,11 +5,11 @@ require("validator") default_action = "status" function status(self) - return self.model.getstatus(self) + return self.model.getstatus() end function view(self) - return self.model.getconfigobjects(self.clientdata.filename, sessiondata.userinfo.dnsfiles) + return self.model.getconfigobjects(self, self.clientdata.filename, sessiondata.userinfo.userid) end function startstop(self) @@ -22,15 +22,15 @@ end function newfile(self) return controllerfunctions.handle_form(self, self.model.getnewconfigfile, function(value) - return self.model.createconfigfile(self, value, sessiondata.userinfo.dnsfiles) + return self.model.createconfigfile(self, value, sessiondata.userinfo.userid) end, self.clientdata, "Create", "Create New Config File", "Config File Created", "listfiles") end function listfiles(self) - local configfiles = self.model.getfilelist(sessiondata.userinfo.dnsfiles) + local configfiles = self.model.getfilelist(self, sessiondata.userinfo.userid) local config = {} for k,v in pairs(configfiles.value) do - local filedetails = self.model.get_filedetails(v, sessiondata.userinfo.dnsfiles) + local filedetails = self.model.get_filedetails(self, v, sessiondata.userinfo.userid) table.insert(config,filedetails) end @@ -39,9 +39,9 @@ end function editfile(self) config = controllerfunctions.handle_form(self, function() - return self.model.get_filedetails(self.clientdata.filename, sessiondata.userinfo.dnsfiles) + return self.model.get_filedetails(self, self.clientdata.filename, sessiondata.userinfo.userid) end, function(value) - return self.model.set_filedetails(value, sessiondata.userinfo.dnsfiles) + return self.model.set_filedetails(self, value, sessiondata.userinfo.userid) end, self.clientdata, "Save", "Edit Config File", "Config File Saved") if self.clientdata.linenumber and validator.is_integer(self.clientdata.linenumber) then @@ -51,5 +51,17 @@ function editfile(self) end function delete(self) - return self:redirect_to_referrer(self.model.remove_file(self.clientdata.filename, sessiondata.userinfo.dnsfiles)) + return self:redirect_to_referrer(self.model.remove_file(self, self.clientdata.filename, sessiondata.userinfo.userid)) +end + +function listpermissions(self) + return self.model:getpermissionslist() +end + +function edituserpermissions(self) + return controllerfunctions.handle_form(self, function() + return self.model:getuserpermissions(self.clientdata.userid) + end, function(value) + return self.model:setuserpermissions(value) + end, self.clientdata, "Save", "Edit User Permissions", "User permissions set") end diff --git a/tinydns-html.lsp b/tinydns-html.lsp new file mode 100644 index 0000000..383906a --- /dev/null +++ b/tinydns-html.lsp @@ -0,0 +1,12 @@ +<? local form, viewlibrary, page_info = ... +require("viewfunctions") +?> + +<H1><?= form.label ?></H1> +<? + form.action = page_info.script .. page_info.prefix .. page_info.controller .. "/" .. page_info.action + if form.value.userid then form.value.userid.contenteditable = false end + if form.value.role then form.value.role.contenteditable = false end + local order = { "userid", "role" } + displayform(form, order) +?> diff --git a/tinydns-listpermissions-html.lsp b/tinydns-listpermissions-html.lsp new file mode 100644 index 0000000..0fd235e --- /dev/null +++ b/tinydns-listpermissions-html.lsp @@ -0,0 +1,17 @@ +<? local view, viewlibrary, page_info = ... ?> +<? --[[ + io.write(html.cfe_unpack(view)) +--]] ?> + +<H1><?= view.label ?></H1> + +<TABLE> +<TR><TD CLASS='header'>User</TD><TD CLASS='header'>Permissions</TD> +<? for i,user in ipairs(view.value) do ?> + <TR><TD><?= html.link{value=page_info.script .. page_info.prefix .. page_info.controller .. "/edituserpermissions?userid=" .. user.id, label=user.id} ?></TD><TD> + <? for y,allowed in pairs(user.allowed) do + print(allowed, "<BR>") + end ?> + <TD></TR> +<? end ?> +</TABLE> diff --git a/tinydns-model.lua b/tinydns-model.lua index 9f73000..f623851 100644 --- a/tinydns-model.lua +++ b/tinydns-model.lua @@ -6,9 +6,11 @@ require("getopts") require("fs") require("format") require("validator") +require("authenticator") -- Set variables local configfiles = {} +local configuser local packagename = "tinydns" local processname = "tinydns" local configfile = "/etc/conf.d/" .. processname @@ -91,12 +93,25 @@ local function split_config_items(orgitem) return output end --- Feed the configfiles table with list of all available and allowed configfiles -local function searchforconfigfiles(allowedlist) - if #configfiles > 0 then return configfiles end +local function getallowedlist(self, userid) + local allowedlist = {} + local entry = authenticator.read_userentry(self, "tinydns", userid) or "" + for x in string.gmatch(entry, "([^,]+),?") do allowedlist[#allowedlist + 1] = x end + -- FIXME also check to see if there are allowed files for this user's roles +-- local roles = authenticator.get_userinfo_roles(self, userid) + return allowedlist +end + +-- Feed the configfiles table with list of all configfiles that are available and allowed +-- Default to allowing all files if no userid or allowed list +local function searchforconfigfiles(self, userid) + if #configfiles > 0 and configuser == userid then + return configfiles + end local cnffile = {} recursedir(configdir, cnffile) - if allowedlist then + local allowedlist = getallowedlist(self, userid) + if allowedlist and #allowedlist > 0 then local reverseallowed = {} for x,name in ipairs(allowedlist) do reverseallowed[name] = x end for k,v in pairs(cnffile) do @@ -107,6 +122,7 @@ local function searchforconfigfiles(allowedlist) else configfiles = cnffile end + configuser = userid return configfiles end @@ -171,8 +187,8 @@ end -- If you enter 'filter_type' (this should be one of the options found in local function check_signs() ) then -- the output will be filtered to only contain this type of data. -function getconfigobjects(file_name, allowedfiles, filter_type) - configfiles = searchforconfigfiles(allowedfiles) +function getconfigobjects(self, file_name, userid, filter_type) + configfiles = searchforconfigfiles(self, userid) local configobjects = {} --Loop through all available configfiles for i,filename in pairs(configfiles) do @@ -229,13 +245,13 @@ function getconfigobjects(file_name, allowedfiles, filter_type) return cfe({ type="structure", value=configobjects, label="DNS Entries", filename=file_name, fieldlabels=descr.fieldlabels }) end -function getfilelist(allowedfiles) - configfiles = searchforconfigfiles(allowedfiles) +function getfilelist(self, userid) + configfiles = searchforconfigfiles(self, userid) return cfe({ type="list", value=configfiles, label="List of config files" }) end -function get_filedetails(path, allowedfiles) - configfiles = searchforconfigfiles(allowedfiles) +function get_filedetails(self, path, userid) + configfiles = searchforconfigfiles(self, userid) if not validfilename(path) then local result = modelfunctions.getfiledetails("") result.value.filename.value = path @@ -245,8 +261,8 @@ function get_filedetails(path, allowedfiles) end end -function set_filedetails (filedetails, allowedfiles) - configfiles = searchforconfigfiles(allowedfiles) +function set_filedetails (self, filedetails, userid) + configfiles = searchforconfigfiles(self, userid) filedetails.value.filecontent.value = string.gsub(format.dostounix(filedetails.value.filecontent.value), "\n+$", "") local success, errtxt = validfilename(filedetails.value.filename.value) if success then @@ -266,7 +282,7 @@ function getnewconfigfile() return cfe({ type="group", value=options, label="New config file" }) end -function createconfigfile(self, configfile, allowedfiles) +function createconfigfile(self, configfile, userid) configfile.errtxt = "Failed to create file" local path = configfile.value.filename.value local validfilepath, filepatherror = validator.is_valid_filename(path,configdir) @@ -278,16 +294,12 @@ function createconfigfile(self, configfile, allowedfiles) file:close() configfile.errtxt = nil - -- We have to add this file to the allowed list - local found = false - for i,name in ipairs(allowedfiles) do - if name == configfile.value.filename.value then found = true break end - end - if not found then - -- this modifies the session - allowedfiles[#allowedfiles + 1] = configfile.value.filename.value - require("authenticator") - authenticator.change_setting(self, self.sessiondata.userinfo.userid, "dnsfiles", allowedfiles) + -- We have to add this file to the allowed list, if there is one + -- FIXME - what do we do here when there is role support? + local perm = getuserpermissions(self, userid) + if #perm.value.allowed.value then + perm.value.allowed.value[#perm.value.allowed.value + 1] = path + setuserpermissions(self, perm) end end else @@ -297,8 +309,8 @@ function createconfigfile(self, configfile, allowedfiles) return configfile end -function remove_file(path, allowedfiles) - configfiles = searchforconfigfiles(allowedfiles) +function remove_file(self, path, userid) + configfiles = searchforconfigfiles(self, userid) local success = "Failed to delete file" local errtxt if not (fs.is_file(path)) then @@ -313,3 +325,56 @@ function remove_file(path, allowedfiles) end return cfe({ value=success, label="Delete config file result", errtxt=errtxt }) end + +function getpermissionslist(self) + local users = authenticator.list_users(self) + local output = {} + for i,user in ipairs(users) do + local allowedlist = {} + local entry = authenticator.read_userentry(self, "tinydns", user) or "" + for x in string.gmatch(entry, "([^,]+),?") do allowedlist[#allowedlist + 1] = x end + output[#output + 1] = {id=user, allowed=allowedlist} + end + table.sort(output, function(a,b) return a.id < b.id end) + -- FIXME - need to check for roles as well as users + return cfe({ type="structure", value=output, label="TinyDNS Permissions" }) +end + +local function validateuserpermissions(self, userpermissions) + local success = false + userpermissions.value.userid.errtxt = "Invalid user" + local users = authenticator.list_users(self) + for i,user in ipairs(users) do + if userpermissions.value.userid.value == user then + userpermissions.value.userid.errtxt = nil + success = true + break + end + end + success = success and modelfunctions.validatemulti(userpermissions.value.allowed) + return success, userpermissions +end + +function getuserpermissions(self, userid) + local allowedlist = {} + local entry = authenticator.read_userentry(self, "tinydns", userid) or "" + for x in string.gmatch(entry, "([^,]+),?") do allowedlist[#allowedlist + 1] = x end + local cnffile = {} + recursedir(configdir, cnffile) + local allowed = cfe({ type="multi", value=allowedlist, label="TinyDNS Permissions", option=cnffile, descr="If no permissions are defined, then all are allowed" }) + local user = cfe({ value=userid, label="User Name" }) + local output = cfe({ type="group", value={userid=user, allowed=allowed}, label="TinyDNS Permissions" }) + validateuserpermissions(self, output) + return output +end + +function setuserpermissions(self, userpermissions) + local success, userpermissions = validateuserpermissions(self, userpermissions) + + if success then + authenticator.write_userentry(self, "tinydns", userpermissions.value.userid.value, table.concat(userpermissions.value.allowed.value, ",")) + else + userpermissions.errtxt = "Failed to set user permissions" + end + return userpermissions +end diff --git a/tinydns.menu b/tinydns.menu index 5243d05..16728fe 100644 --- a/tinydns.menu +++ b/tinydns.menu @@ -3,3 +3,4 @@ Networking 10DNS Status status Networking 10DNS View view Networking 10DNS List_Domains listfiles Networking 10DNS Config config +Networking 10DNS Permissions listpermissions diff --git a/tinydns.roles b/tinydns.roles index 09cfaf8..04e46ef 100644 --- a/tinydns.roles +++ b/tinydns.roles @@ -1,2 +1,2 @@ READ=tinydns:status,tinydns:view -UPDATE=tinydns:config,tinydns:listfiles,tinydns:delete,tinydns:edit,tinydns:editfile,tinydns:newfile,tinydns:startstop +UPDATE=tinydns:config,tinydns:listfiles,tinydns:delete,tinydns:edit,tinydns:editfile,tinydns:newfile,tinydns:startstop,tinydns:listpermissions,tinydns:edituserpermissions |