diff options
author | Ted Trask <ttrask01@yahoo.com> | 2008-07-24 20:43:15 +0000 |
---|---|---|
committer | Ted Trask <ttrask01@yahoo.com> | 2008-07-24 20:43:15 +0000 |
commit | 0b933c7c8b5daf0fd62d9f9dfef973b8383250f1 (patch) | |
tree | cf1e20cc81b6c81a6bd0d91fabafcc3c5c7c316f | |
parent | 178b4bec7aa886f08687a9518bc0f1a996fc7372 (diff) | |
download | acf-core-0b933c7c8b5daf0fd62d9f9dfef973b8383250f1.tar.bz2 acf-core-0b933c7c8b5daf0fd62d9f9dfef973b8383250f1.tar.xz |
Another rewrite of validator to remove dnsfiles and add a generic way for other controllers to save user-based settings. Also added fs.create_file function.
git-svn-id: svn://svn.alpinelinux.org/acf/core/trunk@1317 ab2d0c66-481e-0410-8bed-d214d4d58bed
-rwxr-xr-x | app/acf-util/password-status-html.lsp | 3 | ||||
-rw-r--r-- | lib/authenticator-plaintext.lua | 80 | ||||
-rw-r--r-- | lib/authenticator.lua | 137 | ||||
-rw-r--r-- | lib/fs.lua | 9 |
4 files changed, 128 insertions, 101 deletions
diff --git a/app/acf-util/password-status-html.lsp b/app/acf-util/password-status-html.lsp index 8091316..c16e0d6 100755 --- a/app/acf-util/password-status-html.lsp +++ b/app/acf-util/password-status-html.lsp @@ -30,9 +30,6 @@ io.write("</span>") <TD STYLE='border:none;'><B><?= user.value.roles.label ?></B></TD> <TD STYLE='border:none;'><?= table.concat(user.value.roles.value, " / ") ?></TD> </TR><TR> - <TD STYLE='border:none;'><B><?= user.value.dnsfiles.label ?></B></TD> - <TD STYLE='border:none;'><?= table.concat(user.value.dnsfiles.value, "<br>") ?></TD> - </TR><TR> <TD STYLE='border:none;'><B>Option</B></TD> <TD STYLE='border:none;'> [<A HREF='edituser?userid=<?= name ?>'>Edit this account</A>] diff --git a/lib/authenticator-plaintext.lua b/lib/authenticator-plaintext.lua index e2262b3..c72b7c5 100644 --- a/lib/authenticator-plaintext.lua +++ b/lib/authenticator-plaintext.lua @@ -2,39 +2,30 @@ Copyright (c) 2007 Nathan Angelacos GPL2 license - -The password file is in the format: - -userid:password:username:role1[,role2...]:dnsfile1[,dnsfile2...] +Rather than come up with a way to name fields in the plaintext files, we +create a different file for each field. ]]-- module (..., package.seeall) -load_database = function(self) - local row = {} +read_field = function(self, tabl, field) + if not tabl or tabl == "" or not field then + return nil + end + local row = {} -- open our password file - local passwd_path = self.conf.confdir .. "/passwd" + local passwd_path = self.conf.confdir .. tabl .. field local f = io.open(passwd_path) if f then local m = (f:read("*all") or "" ).. "\n" f:close() for l in string.gmatch(m, "([^\n]+)\n?") do - local fields = {} - for x in string.gmatch(l, "([^:]*):?") do - fields[#fields + 1] = x - end - if fields[1] and fields[1] ~= "" then - local a = {} - a.userid = fields[1] or "" - a.password = fields[2] or "" - a.username = fields[3] or "" - a.roles = fields[4] or "" - a.dnsfiles = fields[5] or "" - table.insert (row, a) - end + local a = {} + a.id, a.entry = string.match(l, "^([^:]*):(.*)") + table.insert(row, a) end return row else @@ -42,24 +33,57 @@ load_database = function(self) end end -write_entry = function(self, entry) - delete_entry(self, entry.userid) +delete_field = function(self, tabl, field) + if not tabl or tabl == "" or not field then + return false + end + local passwd_path = self.conf.confdir .. tabl .. field + os.remove(passwd_path) + return true +end + +write_entry = function(self, tabl, field, id, entry) + if not self or not tabl or tabl == "" or not field or not id or not entry then + return false + end + delete_entry(self, tabl, field, id) -- Set path to passwordfile - local passwd_path = self.conf.confdir .. "/passwd" + local passwd_path = self.conf.confdir .. tabl .. field -- Write the newline into the file - fs.write_line_file(passwd_path, (entry.userid or "") .. ":" .. (entry.password or "") .. ":" .. (entry.username or "") .. ":" .. (entry.roles or "") .. ":" .. (entry.dnsfiles or "") ) + if fs.is_file(passwd_path) == false then fs.create_file(passwd_path) end + if fs.is_file(passwd_path) == false then return false end + fs.write_line_file(passwd_path, id .. ":" .. entry) return true end -delete_entry = function (self, userid) +read_entry = function(self, tabl, field, id) + if not self or not tabl or tabl == "" or not field or not id then + return nil + end + -- Set path to passwordfile + local passwd_path = self.conf.confdir .. tabl .. field + local passwdfilecontent = fs.read_file_as_array(passwd_path) or {} + local entry + for k,v in pairs(passwdfilecontent) do + if string.match(v, "^".. id .. ":") then + return string.match(v, "^"..id..":(.*)") + end + end + return nil +end + +delete_entry = function (self, tabl, field, id) + if not self or not tabl or tabl == "" or not field or not id then + return false + end local result = false - local passwd_path = self.conf.confdir .. "/passwd" - local passwdfilecontent = fs.read_file_as_array(passwd_path) + local passwd_path = self.conf.confdir .. tabl .. field + local passwdfilecontent = fs.read_file_as_array(passwd_path) or {} local output = {} for k,v in pairs(passwdfilecontent) do - if not ( string.match(v, "^".. userid .. ":") ) and not string.match(v, "^%s*$") then + if not ( string.match(v, "^".. id .. ":") ) and not string.match(v, "^%s*$") then table.insert(output, v) else result = true diff --git a/lib/authenticator.lua b/lib/authenticator.lua index 5d6bb98..3438c19 100644 --- a/lib/authenticator.lua +++ b/lib/authenticator.lua @@ -1,4 +1,6 @@ -- ACF Authenticator - does validation and loads sub-authenticator to read/write database +-- We store the login info in the passwd table, "" field. It looks like +-- password:username:ROLE1[,ROLE2...] module (..., package.seeall) require("modelfunctions") @@ -11,13 +13,12 @@ local authstruct -- This is a list of fields in the database that we are allowed to use. -- Could be used to check that right variable-name is used. local availablefields = { - ['userid']=true, + --['userid']=true, ['password']=true, ['username']=true, ['roles']=true, - ['dnsfiles']=true, } - +local passwdtable = "passwd" local load_auth = function(self) -- For now, just loads the plaintext version @@ -26,7 +27,24 @@ end local load_database = function(self) load_auth(self) - authstruct = authstruct or auth.load_database(self) + if not authstruct then + local authtable = auth.read_field(self, passwdtable, "") + authstruct = {} + for i,value in ipairs(authtable) do + if value.id ~= "" then + local fields = {} + for x in string.gmatch(value.entry, "([^:]*):?") do + fields[#fields + 1] = x + end + local a = {} + a.userid = value.id + a.password = fields[1] or "" + a.username = fields[2] or "" + a.roles = fields[3] or "" + table.insert(authstruct, a) + end + end + end end local get_id = function(userid) @@ -55,19 +73,18 @@ end local write_settings = function(self, settings, id) load_database() id = id or get_id(settings.value.userid.value) or {} - -- Password, password_confirm, roles, dnsfiles are allowed to not exist, just leave the same + -- Password, password_confirm, roles are allowed to not exist, just leave the same id.userid = settings.value.userid.value id.username = settings.value.username.value if settings.value.password then id.password = fs.md5sum_string(settings.value.password.value) end if settings.value.roles then id.roles = table.concat(settings.value.roles.value, ",") end - if settings.value.dnsfiles then id.dnsfiles = table.concat(settings.value.dnsfiles.value, ",") end - return auth.write_entry(self, id) + return auth.write_entry(self, passwdtable, "", id.userid, (id.password or "")..":"..(id.username or "")..":"..(id.roles or "")) end -- validate the settings (ignore password if it's nil) local validate_settings = function(settings) - -- Password, password_confirm, roles, dnsfiles are allowed to not exist, just leave the same + -- Password, password_confirm, roles are allowed to not exist, just leave the same -- Set errtxt when entering invalid values if (#settings.value.userid.value == 0) then settings.value.userid.errtxt = "You need to enter a valid userid!" end if string.find(settings.value.userid.value, "[^%w_]") then settings.value.userid.errtxt = "Can only contain letters, numbers, and '_'" end @@ -83,7 +100,6 @@ local validate_settings = function(settings) end end if settings.value.roles then modelfunctions.validatemulti(settings.value.roles) end - if settings.value.dnsfiles then modelfunctions.validatemulti(settings.value.dnsfiles) end -- Return false if any errormessages are set for name,value in pairs(settings.value) do @@ -107,7 +123,7 @@ authenticate = function(self, userid, password) else load_database(self) - if authstruct == false then + if not authstruct then errtxt = "Could not load authentication database" else local id = get_id(userid) @@ -136,9 +152,8 @@ get_userinfo = function(self, userid) local password = cfe({ label="Password" }) local password_confirm = cfe({ label="Password (confirm)" }) local roles = get_userinfo_roles(self, userid) - local dnsfiles = get_userinfo_dnsfiles(self, userid) - return cfe({ type="group", value={ userid=user, username=username, password=password, password_confirm=password_confirm, roles=roles, dnsfiles=dnsfiles }, label="User Config" }) + return cfe({ type="group", value={ userid=user, username=username, password=password, password_confirm=password_confirm, roles=roles }, label="User Config" }) end get_userinfo_roles = function(self, userid) @@ -166,26 +181,6 @@ get_userinfo_roles = function(self, userid) return roles end -get_userinfo_dnsfiles = function(self, userid) - load_database(self) - local id = get_id(userid) - local dnsfiles = cfe({ type="multi", value={}, label="DNS Files", option={} }) - if id then - for x in string.gmatch(id.dnsfiles or "", "([^,]+),?") do - dnsfiles.value[#dnsfiles.value + 1] = x - end - elseif userid then - dnsfiles.errtxt = "Could not load DNS files" - end - local dns = self:new("tinydns/tinydns") - if dns then - local avail_files = dns.model.getfilelist() - dnsfiles.option = avail_files.value - dns:destroy() - end - return dnsfiles -end - list_users = function (self) load_database(self) local output = {} @@ -197,42 +192,6 @@ list_users = function (self) return output end --- This function will change one user setting by name --- Cannot be used for password or userid -change_setting = function (self, userid, parameter, value) - local success = false - local cmdresult = "Failed to change setting" - local errtxt - - -- Get the current user info - local userinfo = get_userinfo(self, userid) - if not userinfo then - errtxt = "This userid does not exist" - end - - -- Check if user entered available commands - if not value then - errtxt = "Invalid value" - elseif not (availablefields[parameter]) then - errtxt = "Invalid parameter" - elseif parameter == "userid" or parameter == "password" then - errtxt = "Cannot change "..parameter.." with this function" - else - userinfo.value[parameter].value = value - userinfo.value.password = nil - userinfo.value.password_confirm = nil - if not validate_settings(userinfo) then - errtxt = userinfo.value[parameter].errtxt - else - success = write_settings(self, userinfo) - end - end - - if success then cmdresult = "Changed setting" end - - return cfe({ value=cmdresult, label="Change setting result", errtxt=errtxt }) -end - -- For an existing user, change the settings that are non-nil change_settings = function (self, settings) local success, settings = validate_settings(settings) @@ -285,8 +244,48 @@ end delete_user = function (self, userid) load_auth(self) local cmdresult = "Failed to delete user" - if auth.delete_entry(self, userid) then + if auth.delete_entry(self, passwdtable, "", userid) then cmdresult = "User deleted" end return cfe({ value=cmdresult, label="Delete user result" }) end + +read_userfield = function(self, name) + load_auth(self) + if auth and name ~= "" then + return auth.read_field(self, passwdtable, name) + end + return nil +end + +delete_userfield = function(self, name) + load_auth(self) + if auth and name ~= "" then + return auth.delete_field(self, passwdtable, name) + end + return false +end + +write_userentry = function(self, name, userid, entry) + load_auth(self) + if auth and name ~= "" then + return auth.write_entry(self, passwdtable, name, userid, entry) + end + return false +end + +read_userentry = function(self, name, userid) + load_auth(self) + if auth and name ~= "" then + return auth.read_entry(self, passwdtable, name, userid) + end + return nil +end + +delete_userentry = function (self, name, userid) + load_auth(self) + if auth and name ~= "" then + return auth.delete_entry(self, passwdtable, name, userid) + end + return false +end @@ -23,7 +23,14 @@ function is_link ( pathstr ) end - +-- Creates a blank file +function create_file ( path ) + local cmd = "touch "..path + local f = io.popen(cmd) + f:close() + return is_file(path) +end + -- Returns the contents of a file as a string function read_file ( path ) local file = io.open(path) |