summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTed Trask <ttrask01@yahoo.com>2008-04-30 20:36:02 +0000
committerTed Trask <ttrask01@yahoo.com>2008-04-30 20:36:02 +0000
commit378e53f20a0f11c36afffbaef78f47a5303df9ce (patch)
treea39e3c216dc10f919ef272c53b67a8f01f001be0
parent82fd96bdcc5b721d8fc208fe4edba54f4dc6fdb7 (diff)
downloadacf-core-378e53f20a0f11c36afffbaef78f47a5303df9ce.tar.bz2
acf-core-378e53f20a0f11c36afffbaef78f47a5303df9ce.tar.xz
Modified cfe, removing option, errtxt, and name, and adding label - This may break things.
Rewrote password module, adding model Modified authenticator to make password module work git-svn-id: svn://svn.alpinelinux.org/acf/core/trunk@1052 ab2d0c66-481e-0410-8bed-d214d4d58bed
-rw-r--r--app/Makefile1
-rw-r--r--app/acf-util/logon-controller.lua8
-rw-r--r--app/acf-util/logon-html.lsp21
-rw-r--r--app/acf-util/logon-model.lua6
-rwxr-xr-xapp/acf-util/password-controller.lua382
-rwxr-xr-xapp/acf-util/password-html.lsp74
-rwxr-xr-xapp/acf-util/password-status-html.lsp92
-rw-r--r--app/acf_cli-controller.lua6
-rw-r--r--app/acf_www-controller.lua7
-rw-r--r--lib/authenticator-plaintext.lua148
-rw-r--r--lib/html.lua22
-rw-r--r--lib/viewfunctions.lua109
-rw-r--r--roles4
13 files changed, 332 insertions, 548 deletions
diff --git a/app/Makefile b/app/Makefile
index b71b10f..cdd42bb 100644
--- a/app/Makefile
+++ b/app/Makefile
@@ -11,6 +11,7 @@ APP_DIST= \
acf-util/roles-read-html.lsp \
acf-util/password-controller.lua \
acf-util/password-html.lsp \
+ acf-util/password-model.lua \
acf-util/password-status-html.lsp \
acf-util/password.menu \
acf_www-controller.lua\
diff --git a/app/acf-util/logon-controller.lua b/app/acf-util/logon-controller.lua
index 7d4447b..1dc3360 100644
--- a/app/acf-util/logon-controller.lua
+++ b/app/acf-util/logon-controller.lua
@@ -6,7 +6,9 @@ default_action = "status"
-- Logon a new user based upon id and password in clientdata
logon = function(self)
- local cmdresult = cfe({ value=clientdata.userid or "", name="User ID" })
+ local userid = cfe({ value=clientdata.userid or "", label="User ID" })
+ local password = cfe({ label="Password" })
+ local cmdresult = cfe({ type="form", value={userid=userid, password=password}, label="Logon" })
if clientdata.userid and clientdata.password then
local logon = self.model:logon(clientdata, conf.clientip, conf.sessiondir, sessiondata)
-- If successful logon, redirect to status, otherwise try again
@@ -28,8 +30,8 @@ end
-- Report the login status
status = function(self)
- local name = cfe({ name="User Name" })
- local sessionid = cfe({ value=self.sessiondata.id or "", name="Session ID" })
+ local name = cfe({ label="User Name" })
+ local sessionid = cfe({ value=self.sessiondata.id or "", label="Session ID" })
if self.sessiondata.userinfo then
name.value = self.sessiondata.userinfo.username or ""
end
diff --git a/app/acf-util/logon-html.lsp b/app/acf-util/logon-html.lsp
index 20aa0ee..f503a9b 100644
--- a/app/acf-util/logon-html.lsp
+++ b/app/acf-util/logon-html.lsp
@@ -1,20 +1,19 @@
<? local form = ... ?>
+<? require("viewfunctions") ?>
<? --[[
io.write(html.cfe_unpack(form))
--]] ?>
-<? if form.errtxt ~= "" then ?>
+<? if form.errtxt then ?>
<h1>Command Result</h1>
<p class='error'> <?= form.errtxt ?></p>
<? end ?>
-<h1>Logon</h1>
-<form action="logon" method="POST">
-<DL>
- <DT>User id</DT>
- <DD><input class="text" type="text" name="userid" value="<?= form.value ?>"></DD>
- <DT>Password</DT>
- <DD><input class="password" type="password" name="password" value=""></DD>
- <DT><input class="submit" type="submit" name="Logon" value="Logon"></DD>
-</DL>
-</form>
+<h1><?= form.label ?></h1>
+<?
+ form.action = "logon"
+ form.submit = "Logon"
+ form.value.password.type = "password"
+ local order = { "userid", "password" }
+ displayform(form, order)
+?>
diff --git a/app/acf-util/logon-model.lua b/app/acf-util/logon-model.lua
index 7e8a21e..16e9f7f 100644
--- a/app/acf-util/logon-model.lua
+++ b/app/acf-util/logon-model.lua
@@ -29,7 +29,7 @@ logoff = function (sessiondir, sessiondata)
sessiondata[a] = nil
end
- return cfe({ type="boolean", value=success, name="Logoff Success" })
+ return cfe({ type="boolean", value=success, label="Logoff Success" })
end
-- Log on new user if possible and set up userinfo in session
@@ -57,12 +57,12 @@ logon = function (self, clientdata, ip_addr, sessiondir, sessiondata)
sessiondata.id = session.random_hash(512)
local t = auth.get_userinfo (self, clientdata.userid)
sessiondata.userinfo = t or {}
- return cfe({ type="boolean", value=true, name="Logon Success" })
+ return cfe({ type="boolean", value=true, label="Logon Success" })
else
-- We have a bad login, log the event
session.record_event(sessiondir, clientdata.userid, session.hash_ip_addr(ip_addr))
end
end
- return cfe({ type="boolean", value=false, name="Logon Success" })
+ return cfe({ type="boolean", value=false, label="Logon Success" })
end
diff --git a/app/acf-util/password-controller.lua b/app/acf-util/password-controller.lua
index 4dbe1eb..1d3aa7a 100755
--- a/app/acf-util/password-controller.lua
+++ b/app/acf-util/password-controller.lua
@@ -1,360 +1,78 @@
module(..., package.seeall)
-local auth=require("authenticator-plaintext")
-
-default_action = "status"
-
-local function admin_permission()
--- if (sessiondata.userinfo) and (sessiondata.userinfo.userid == "alpine") then
- return true
--- else
--- return false
--- end
-end
-
-local function check_logonstatus(self)
- -- Redirect the user if he's not logged in.
- if not (self.sessiondata.userinfo) then
- redirect(self, "logon", "logon")
- end
-end
-
-local function get_config(self,userid)
- local config = {}
- local userinfo = {}
- if (#userid > 0) then
- userinfo=auth.get_userinfo(self,userid)
- end
- if not (userinfo) then
- userinfo = {userid = "", username = "", roles = {} }
- end
-
- -- Get list of available roles
- local avail_roles=auth.list_roles()
-
--- config.debug = userid -- Debug info
-
- config.userid = cfe({
- name="userid",
- label="User id",
- value=(userinfo.userid or ""),
- })
- config.orguserid = cfe({
- name="orguserid",
- value=(userinfo.userid or ""),
- type="hidden",
- })
- config.username = cfe({
- name="username",
- label="Real name",
- value=userinfo.username,
- })
- config.roles = cfe({
- name="roles",
- label="Roles",
- option=userinfo.roles,
- type="select",
- size=#avail_roles,
- })
- config.password = cfe({
- name="password",
- label="Password",
- type="passwd",
- })
- config.password_confirm = cfe({
- name="password_confirm",
- label="Password (confirm)",
- type="passwd",
- })
-
- config.availableroles = cfe({
- name="availableroles",
- label="Available roles",
- type="select",
- option=avail_roles,
- })
-
- return config
-end
+default_action = "editme"
function status(self)
-
- -- Redirect the user if he's not logged in.
- check_logonstatus(self)
-
- local status = {}
-
- -- Check for admin persmissions - else redirect to personal options
- if not (admin_permission()) then
- self.conf.action = "editme"
- return editme(self)
- end
-
- -- Redirect when creating a new account
- if (clientdata.cmdnew) then
- self.conf.action = "administrator"
- self.conf.type = "redir"
-
- return administrator(self)
- end
-
- --List all users and their userinfo
- status.users = {}
- local userlist = auth.list_users(self)
- for k,v in pairs(userlist) do
- local userinfo = auth.get_userinfo(self,v)
- status.users[k] = cfe({
- name=v,
- label=v,
--- debug=userinfo, -- Debug info
- value={ userid=cfe ({
- name="userid",
- label="User ID",
- value=userinfo.userid,
- }),
- username=cfe ({
- name="username",
- label="Real name",
- value=userinfo.username,
- }),
- roles=cfe ({
- name="roles",
- label="Roles",
- value=table.concat(userinfo.roles," / "),
- option=userinfo.roles,
- type="select",
- }),
- },
-
- })
- local errormessage = ""
- -- Check if this user has got any errors in the config
- if (userinfo.password == "") or (userinfo.password == nil) then
- errormessage = "This user has no password! ".. errormessage
- end
- -- Check if user has no roles
- if (table.maxn(userinfo.roles) == 0) then
- errormessage = "This user has no roles! " .. errormessage
- end
- -- If there where any errormessages, then present them
- if (#errormessage > 0) then
- status.users[k].value.errors = cfe ({
- name="errors",
- label="Attention",
- value=errormessage,
- })
- end
- end
-
- --Create a button for 'New user account'
- status.cmdnew = cfe ({
- name="cmdnew",
- type="submit",
- label="Create new account",
- value="Create",
--- disabled="yes",
- })
- return { status=status }
-end
-
-function administrator(self)
-
- -- Redirect the user if he's not logged in.
- check_logonstatus(self)
-
- local output = {}
-
- -- Check for admin persmissions - else redirect to personal options
- if not (admin_permission()) then
- self.conf.action = "editme"
- self.conf.type = "redir"
- return editme(self)
- end
-
- -- Output userinfo
- output = get_config(self,(self.clientdata.orguserid or self.clientdata.userid or ""))
-
- -- Clear password-field
- output.password.value = ""
-
- -- Add some buttons
- output.cmdsave = cfe ({
- name="cmdsave",
- type="submit",
- label="Save changes",
- value="Save",
- })
- output.cmddelete = cfe ({
- name="cmddelete",
- type="submit",
- label="Delete this account",
- value="Delete",
- })
-
- return {config=output}
+ return self.model.get_users(self)
end
function editme(self)
+ -- just to make sure can't modify any other user from this action
+ self.clientdata.userid = sessiondata.userinfo.userid
+ self.clientdata.roles = nil
+ -- if password is blank, don't update it or require it
+ if self.clientdata.password == "" then self.clientdata.password = nil end
+ if self.clientdata.password_confirm == "" then self.clientdata.password_confirm = nil end
- -- Redirect the user if he's not logged in.
- check_logonstatus(self)
-
- -- Output userinfo
- local output = get_config(self,sessiondata.userinfo.userid)
+ -- Update userinfo
+ local output = self.model.update_user(self, self.clientdata, false)
- -- Hide roles/cmddelete for current the user
- output.roles = nil
- output.cmddelete = nil
+ -- Don't allow changing of roles for yourself
+ output.value.roles = nil
- -- Disable userid
- output.userid.disabled = "yes"
-
- -- Set userid
- output.orguserid.value = self.sessiondata.userinfo.userid
-
- -- Add save-button
- output.cmdsave = cfe ({
- name="cmdsave",
- type="submit",
- label="Save changes",
- value="Save",
- })
-
- return {config=output}
+ output.label = "Edit My Settings"
+ return output
end
-local clientdata_from_roles = function(self)
- local output = {}
+function edituser(self)
+ -- if password is blank, don't update it or require it
+ if self.clientdata.password == "" then self.clientdata.password = nil end
+ if self.clientdata.password_confirm == "" then self.clientdata.password_confirm = nil end
- for k,v in pairs(auth.list_roles()) do
- if (self.clientdata[v]) then
- table.insert(output, v)
+ -- FIXME this is because multi selects don't work in haserl
+ if self.clientdata.roles then
+ local newroles = {}
+ for x,role in pairs(self.clientdata.roles) do
+ newroles[#newroles + 1] = role
end
+ self.clientdata.roles = newroles
end
-
- return output
-end
-
-function save(self)
- -- Redirect the user if he's not logged in.
- check_logonstatus(self)
-
- local errormessage = {}
- local cmdresult = {}
- -- FIXME: Check if user is allowed to save settings
- -- FIXME: If user has little priviliges, then see to that he only can change hes own settings
- -- At the moment... the user could send self.clientdata.orguserid = 'someoneelseid' and change hes settings.
- -- This field is hidden for user... but advanced users could probably workaround somehow.
+ -- Update userinfo
+ local output = self.model.update_user(self, self.clientdata, false)
- -- Delete selected user
- if (clientdata.cmddelete) then
- cmdresult["delete"],errormessage["delete"] = auth.delete_user(self,self.clientdata.orguserid)
+ -- result
+ if output.descr and output.errtxt == nil then
+ redirect(self, "status")
end
- -- If userid-filed is disabled, then use orguserid instead (hidden filed)
- if not (self.clientdata.userid) then
- self.clientdata.userid = self.clientdata.orguserid
- end
-
- -- We start changing things based on input
- if (clientdata.cmdsave) then
- -- Check if password is written correct
- if (self.clientdata.password == self.clientdata.password_confirm) and
- (#self.clientdata.userid > 0) then
- -- Check if we are editing a existing user or creating a new one
- if (#clientdata.orguserid > 0) then
- local variables="username userid roles"
- -- Change password if user entered any values
- if (#self.clientdata.password > 0) then
- variables = variables .. " password"
- end
- -- Concate roles into one chunk of data (needed by the model)
- self.clientdata.roles = table.concat(clientdata_from_roles(self), ",")
+ output.label = "Edit User Settings"
+ return output
+end
--- cmdresult.debugs = self.clientdata.orguserid -- Debug information
- for var in string.gmatch(variables, "%S+") do
- if (self.clientdata[var]) then
- cmdresult["cmdtype"] = "change"
- cmdresult[var],errormessage[var] = auth.change_settings(
- self,
- self.clientdata.orguserid,
- var, self.clientdata[var]
- )
- end
- end
- else
- -- We are about to create a new user
- cmdresult["cmdtype"] = "new"
- cmdresult["new"],errormessage["new"] = auth.new_settings(
- self,
- self.clientdata.userid,
- self.clientdata.username,
- self.clientdata.password,
- self.clientdata.password_confirm,
- clientdata_from_roles(self)
- )
- end
- elseif (self.clientdata.password ~= self.clientdata.password_confirm) then
- errormessage.none = {password_confirm = "You entered wrong password/confirmation"}
- elseif (#self.clientdata.userid == 0) then
- errormessage.none = {userid = "Userid can not be blank!"}
+function newuser(self)
+ -- FIXME this is because multi selects don't work in haserl
+ if self.clientdata.roles then
+ local newroles = {}
+ for x,role in pairs(self.clientdata.roles) do
+ newroles[#newroles + 1] = role
end
+ self.clientdata.roles = newroles
end
- -- Fetch saved values
- local output = administrator(self)
+ -- Update userinfo
+ local output = self.model.update_user(self, self.clientdata, true)
- -- Report errors from previously entered values (present this error for the user)
- if (cmdresult["cmdtype"] == "new") then
- -- Report where the user entered som errors
- for k,v in pairs(errormessage["new"]) do
- output.config[k].errtxt = v
- end
- else
- -- Report where the user entered som errors
- for k,v in pairs(errormessage) do
- for kk,vv in pairs(v) do
- output.config[kk].errtxt = vv
- end
- end
+ -- result
+ if output.descr and output.errtxt == nil then
+ redirect(self, "status")
end
- -- If there was any errormessage then return to previous page and present the errormessage
- for k,v in pairs(errormessage) do
- for kk,vv in pairs(v) do
-
- -- Incase we entered some invalid options, but entered correct Password (and it has been changed)
- -- then inform the user that the password has been changed
- if (cmdresult.password) then
- output.config.password.descr = "* Password has been changed!"
- end
-
- -- Write the previously entered information on the screen.
- for k,v in pairs(self.clientdata) do
- if (output.config[k]) and (k == roles) then
- table.insert(output.config[k].option, v)
- elseif (output.config[k]) then
- output.config[k].value = v
- end
- end
-
- -- Because something went wrong... clear the password and let the user re-enter the password/confirmation
- output.config.password.value = ""
- output.config.password_confirm.value = ""
-
- -- Debug information
--- output.config.debugcmdresult = cmdresult -- Debug information
-
- -- Redirect page
- self.conf.action = "administrator"
- self.conf.type = "redir"
- return output
- end
- end
+ output.label = "New User Settings"
+ return output
+end
- --If everything went OK then redirect to main page
- self.conf.action = "status"
- self.conf.type = "redir"
- return status(self)
+function deleteuser(self)
+ self.model.delete_user(self, self.clientdata.userid)
+ redirect(self, "status")
end
diff --git a/app/acf-util/password-html.lsp b/app/acf-util/password-html.lsp
index 5d4d488..a11d9e3 100755
--- a/app/acf-util/password-html.lsp
+++ b/app/acf-util/password-html.lsp
@@ -1,72 +1,30 @@
<? local form = ... ?>
+<? require("viewfunctions") ?>
<?
--[[ DEBUG INFORMATION
io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>")
io.write(html.cfe_unpack(form))
+io.write(html.cfe_unpack(ENV))
+io.write(html.cfe_unpack(FORM))
io.write("</span>")
--]]
?>
-<?
-function displayinfo(myform,tags,viewtype)
- io.write("\n<DL>")
- for k,v in pairs(tags) do
- if (myform) and (myform[v]) and (myform[v]["value"]) then
- local val = myform[v]
- if (val.type) and not (val.type == "hidden") then
- io.write("\n\t<DT")
- if (#val.errtxt > 0) then
- val.class = "error"
- io.write(" class='error'")
- end
- io.write(">" .. val.label .. "</DT>")
- io.write("\n\t\t<DD>")
- if (viewtype == "viewonly") then
- io.write(val.value)
- elseif (viewtype == "roles") then
- for k,v in pairs(form.config.availableroles.option) do
- local checked = ""
- if (type(form.config.roles.option) == "table") then
- for kk,vv in pairs(form.config.roles.option) do
- if (v == vv) then
- checked = "checked='yes'"
- break
- end
- end
- end
- io.write("\n\t\t\t" ..v .. ":<input class='checkbox' type='checkbox' name='"..v.."' value='"..v.."' " .. checked .. " > ")
- end
- else
- io.write(html.form[val.type](val))
- end
- if (val.descr) and (#val.descr > 0) then io.write("\t\t<P CLASS='descr'>" .. string.gsub(val.descr, "\n", "<BR>") .. "</P>\n") end
- if (#val.errtxt > 0) then io.write("\t\t<P CLASS='error'>" .. string.gsub(val.errtxt, "\n", "<BR>") .. "</P>") end
- io.write("\n\t\t</DD>")
- else
- io.write(html.form[val.type](val))
- end
- end
- end
- io.write("\n</DL>")
-end
-?>
-
-<H1>CONFIG</H1>
-<H2>Settings</H2>
-<form name="settings" action="save" method="POST">
-<?
-local myform = form.config
-displayinfo(myform,{ "userid","orguserid", "username" })
-displayinfo(myform,{ "roles" },"roles")
-displayinfo(myform,{ "password","password_confirm" })
-?>
-<H2>Actions</H2>
+<H1><?= form.label ?></H1>
<?
-local myform = form.config
-local tags = { "cmdsave", "cmddelete", }
-displayinfo(myform,tags)
+ form.action = ""
+ form.submit = "Save"
+ if form.value.password and form.value.password_confirm then
+ form.value.password.type = "password"
+ form.value.password_confirm.type = "password"
+ end
+ -- If not in newuser action, disable userid
+ if nil == string.find(ENV["PATH_INFO"], "/newuser") then
+ form.value.userid.contenteditable = false
+ end
+ local order = { "userid", "username", "roles", "password", "password_confirm" }
+ displayform(form, order)
?>
-</form>
<?
--[[ DEBUG INFORMATION
diff --git a/app/acf-util/password-status-html.lsp b/app/acf-util/password-status-html.lsp
index e6d15b0..b7c9b05 100755
--- a/app/acf-util/password-status-html.lsp
+++ b/app/acf-util/password-status-html.lsp
@@ -7,77 +7,35 @@ io.write("</span>")
--]]
?>
-<?
-function displayinfo(myform,tags,viewonly)
- io.write("<DL>")
- for k,v in pairs(tags) do
- if (myform[v]) and (myform[v]["value"]) then
- local val = myform[v]
- io.write("\t<DT")
- if (#val.errtxt > 0) then
- val.class = "error"
- io.write(" class='error'")
- end
- io.write(">" .. val.label .. "</DT>\n")
- if (viewonly) then
- io.write("\t\t<DD>" .. val.value .. "\n")
- else
- io.write("\t\t<DD>" .. html.form[val.type](val) .. "\n")
- end
- if (val.descr) and (#val.descr > 0) then io.write("\t\t<P CLASS='descr'>" .. string.gsub(val.descr, "\n", "<BR>") .. "</P>\n") end
- if (#val.errtxt > 0) then io.write("\t\t<P CLASS='error'>" .. string.gsub(val.errtxt, "\n", "<BR>") .. "</P>\n") end
- io.write("\t\t</DD>\n")
- end
- end
- io.write("</DL>")
-end
-?>
-
<H1>USER ACCOUNTS</H1>
<H2>Create new account</H2>
-<form name="createnew" action="" method="POST">
-<?
-local myform = form.status
-local tags = { "cmdnew", }
-displayinfo(myform,tags)
-?>
+<form action="newuser" method="POST">
+<dl><dt><input class="submit" type="submit" value="New User"></dt></dl>
</form>
<H2>Existing account</H2>
-<?
---function displayinfo(myform,tags,viewonly)
-local myform = form.status.users
-
-io.write("<DL>")
-if (type(myform) == "table") then
- for k,v in pairs(myform) do
- local myform = myform[k]
- io.write("\t<DT")
- if (#myform.errtxt > 0) then
- myform.class = "error"
- io.write(" class='error'")
- end
- io.write("><IMG SRC='/static/tango/16x16/apps/system-users.png' HEIGHT='16' WIDTH='16'> " .. myform.label .. "</DT>\n")
- io.write("\t\t<DD>\n\t\t<TABLE>")
- io.write("\n\t\t\t<TR>\n\t\t\t\t<TD><B>".. myform.value.userid.label ..
- "</B></TD>\n\t\t\t\t<TD WIDTH='90%'>" .. myform.value.userid.value .. "</TD>\n\t\t\t</TR>")
- io.write("\n\t\t\t<TR>\n\t\t\t\t<TD><B>".. myform.value.username.label ..
- "</B></TD>\n\t\t\t\t<TD>" .. myform.value.username.value .. "</TD>\n\t\t\t</TR>")
- io.write("\n\t\t\t<TR>\n\t\t\t\t<TD><B>".. myform.value.roles.label ..
- "</B></TD>\n\t\t\t\t<TD>" .. myform.value.roles.value .. "</TD>\n\t\t\t</TR>")
- if (myform.value.errors) then
- io.write("\n\t\t\t<TR>\n\t\t\t\t<TD CLASS='error'><B>".. myform.value.errors.label ..
- "</B></TD>\n\t\t\t\t<TD CLASS='error'>" .. myform.value.errors.value .. "</TD>\n\t\t\t</TR>")
- end
- io.write("</TD>\n\t\t\t</TR>")
- io.write("\n\t\t\t<TR>\n\t\t\t\t<TD><B>Option</B></TD>\n\t\t\t\t<TD>[<A HREF='administrator?orguserid=".. myform.value.userid.value .. "'>Edit this account</A>]</TD>\n\t\t\t</TR>")
- io.write("\n\t\t</TABLE>\n")
- if (#myform.errtxt > 0) then io.write("\t\t<P CLASS='error'>" .. string.gsub(myform.errtxt, "\n", "<BR>") .. "</P>\n") end
- io.write("\t\t</DD>\n")
- end
-end
-io.write("</DL>")
-?>
-
+<DL>
+<? for name,user in pairs(form.value) do ?>
+ <DT><IMG SRC='/static/tango/16x16/apps/system-users.png' HEIGHT='16' WIDTH='16'> <?= name ?></DT>
+ <DD><TABLE>
+ <TR>
+ <TD><B><?= user.value.userid.label ?></B></TD>
+ <TD WIDTH='90%'><?= user.value.userid.value ?></TD>
+ </TR><TR>
+ <TD><B><?= user.value.username.label ?></B></TD>
+ <TD><?= user.value.username.value ?></TD>
+ </TR><TR>
+ <TD><B><?= user.value.roles.label ?></B></TD>
+ <TD><?= table.concat(user.value.roles.value, " / ") ?></TD>
+ </TR><TR>
+ <TD><B>Option</B></TD>
+ <TD>
+ [<A HREF='edituser?userid=<?= name ?>'>Edit this account</A>]
+ [<A HREF='deleteuser?userid=<?= name ?>'>Delete this account</A>]
+ </TD>
+ </TR>
+ </TABLE></DD>
+<? end ?>
+</DL>
<?
--[[ DEBUG INFORMATION
diff --git a/app/acf_cli-controller.lua b/app/acf_cli-controller.lua
index 2287067..7bd283d 100644
--- a/app/acf_cli-controller.lua
+++ b/app/acf_cli-controller.lua
@@ -39,14 +39,12 @@ exception_handler = function (self, message )
end
-- create a Configuration Framework Entity (cfe)
--- returns a table with at least "value", "type", "option" and "errtxt"
+-- returns a table with at least "value", "type", and "label"
cfe = function ( optiontable )
optiontable = optiontable or {}
me = { value="",
type="text",
- option="",
- errtxt="",
- name="" }
+ label="" }
for key,value in pairs(optiontable) do
me[key] = value
end
diff --git a/app/acf_www-controller.lua b/app/acf_www-controller.lua
index 9983293..98b732f 100644
--- a/app/acf_www-controller.lua
+++ b/app/acf_www-controller.lua
@@ -275,15 +275,12 @@ exception_handler = function (self, message )
end
end
--- create a Configuration Framework Entity (cfe)
--- returns a table with at least "value", "type", "option" and "errtxt"
+-- create a Configuration Framework Entity (cfe)
+-- returns a table with at least "value", "type", and "label"
cfe = function ( optiontable )
optiontable = optiontable or {}
me = { value="",
type="text",
- option="",
- errtxt="",
- name="",
label="" }
for key,value in pairs(optiontable) do
me[key] = value
diff --git a/lib/authenticator-plaintext.lua b/lib/authenticator-plaintext.lua
index 4c9bf08..b8cf598 100644
--- a/lib/authenticator-plaintext.lua
+++ b/lib/authenticator-plaintext.lua
@@ -47,12 +47,14 @@ pvt.parse_authfile = function(filename)
end
pvt.get_id = function(userid, authstruct)
- if authstruct == nil then return nil end
- for x = 1,#authstruct do
- if authstruct[x].userid == userid then
- return authstruct[x]
+ if authstruct ~= nil then
+ for x = 1,#authstruct do
+ if authstruct[x].userid == userid then
+ return authstruct[x]
+ end
end
end
+ return nil
end
--- public methods
@@ -111,6 +113,42 @@ pvt.availablefields = function (field)
}
return availablefileds[field]
end
+
+-- validate the settings (ignore password if it's nil)
+local validate_settings = function (self, userid, username, password, password_confirm, roles)
+ local errormessage = {}
+
+ -- Set errormessages when entering invalid values
+ if (#userid == 0) then errormessage.userid = "You need to enter a valid userid!" end
+ if password then
+ if (#password == 0) then
+ errormessage.password = "Password cannot be blank!"
+ elseif (password ~= password_confirm) then
+ errormessage.password_confirm = "You entered wrong password/confirmation"
+ else
+ local weak_password_result, weak_password_errormessage = pvt.weak_password(password)
+ if (weak_password_result) then errormessage.password = weak_password_errormessage end
+ end
+ end
+ local reverseroles = {}
+ for x,role in pairs(list_roles(self)) do
+ reverseroles[role] = x
+ end
+ for x,role in pairs(roles) do
+ if reverseroles[role] == nil then
+ errormessage.roles = "Invalid role"
+ break
+ end
+ end
+
+ -- Return false if any errormessages are set
+ for k,v in pairs(errormessage) do
+ return false, errormessage
+ end
+
+ return true, errormessage
+end
+
-- This function returns the username and roles
-- or false on an error
get_userinfo = function ( self, userid )
@@ -150,7 +188,7 @@ list_roles = function (self)
return output
end
-change_settings = function (self, userid,parameter,value)
+change_settings = function (self, userid, parameter, value)
local errormessage = {}
local passwd_path = self.conf.confdir .. "/passwd"
@@ -212,60 +250,102 @@ change_settings = function (self, userid,parameter,value)
return true
end
-new_settings = function ( self, userid, username, password, password_confirm, roles)
+-- For an existing user, change the settings that are non-nil
+change_settings = function (self, userid, username, password, password_confirm, roles)
+ local result = true
local errormessage = {}
- -- We start by checking if user is allowed to do changes
- if not (pvt.permission_to_change) then
- errormessage.permissions = "No permission to change!"
+
+ -- Get the current user info
+ local userinfo = get_userinfo(self, userid)
+ if userinfo == nil then
+ errormessage.userid = "This userid does not exist!"
+ result = false
end
- -- Set path to passwordfile
- local passwd_path = self.conf.confdir .. "/passwd"
+ local change = username or password or password_confirm or roles
+ if change then
+ -- Validate the inputs
+ if (result == true) then
+ -- Use the current settings if new ones are nil, except for password
+ result, errormessage = validate_settings(self, userid, username or userinfo.username, password, password_confirm, roles or userinfo.roles)
+ end
+
+ -- Update all the fields
+ if (result == true) then
+ userinfo.username = username or userinfo.username
+ if password then
+ userinfo.password = fs.md5sum_string(password)
+ end
+ userinfo.roles = roles or userinfo.roles
+
+ -- write the updated user
+ delete_user(self, userid)
+
+ -- Set path to passwordfile
+ local passwd_path = self.conf.confdir .. "/passwd"
+ -- Write the newline into the file
+ fs.write_line_file(passwd_path, userid .. ":" .. userinfo.password .. ":" .. userinfo.username .. ":" .. table.concat(userinfo.roles,",") )
+ end
+ end
+
+ return result, errormessage
+end
+
+new_settings = function (self, userid, username, password, password_confirm, roles)
+ local result = true
+ local errormessage = {}
+ -- make sure to check all fields
+ userid = userid or ""
+ username = username or ""
+ password = password or ""
+ password_confirm = password_confirm or ""
+ roles = roles or {}
- -- Set errormessages when entering invalid values
- if (#userid == 0) then errormessage.userid = "You need to enter a valid userid!" end
- if (password ~= password_confirm) then errormessage.password_confirm = "You entered wrong password/confirmation" end
- if not (password) or (#password == 0) then errormessage.password = "Password cant be blank!" end
--- if not (roles) or (#roles == 0) then errormessage.roles = "You need to enter some roles!" end
- local weak_password_result, weak_password_errormessage = pvt.weak_password(password)
- if (weak_password_result) then errormessage.password = weak_password_errormessage end
-- Check if userid already used
for k,v in pairs(list_users(self)) do
if (v == userid) then
errormessage.userid = "This userid already exists!"
+ result = false
end
end
- -- Return false if some errormessages is set
- for k,v in pairs(errormessage) do
- return false, errormessage
+ -- validate the settings
+ if (result == true) then
+ result, errormessage = validate_settings(self, userid, username, password, password_confirm, roles)
end
- -- Write the newline into the file
- fs.write_line_file(passwd_path, userid .. ":" .. fs.md5sum_string(password) .. ":" .. username .. ":" .. table.concat(roles,",") )
+ -- write the new user
+ if (result == true) then
+ -- Set path to passwordfile
+ local passwd_path = self.conf.confdir .. "/passwd"
- return true, errormessage
+ -- Write the newline into the file
+ fs.write_line_file(passwd_path, userid .. ":" .. fs.md5sum_string(password) .. ":" .. username .. ":" .. table.concat(roles,",") )
+ end
+
+ return result, errormessage
end
-delete_user = function( self, userid)
- local errormessage = {}
- local passwd_path = self.conf.confdir .. "/passwd"
-
- -- We start by checking if user is allowed to do changes
- if not (pvt.permission_to_change) then
- errormessage.permissions = "No permission to change!"
- end
+delete_user = function (self, userid)
+ local result = false
+ local errormessage = {userid="User not found"}
+ local passwd_path = self.conf.confdir .. "/passwd"
local passwdfilecontent = fs.read_file_as_array(passwd_path)
local output = {}
for k,v in pairs(passwdfilecontent) do
if not ( string.match(v, "^".. userid .. ":") ) then
table.insert(output, v)
+ else
+ result = true
+ errormessage = {}
end
end
--Save the updated table
- fs.write_file(passwd_path, table.concat(output,"\n"))
+ if result == true then
+ fs.write_file(passwd_path, table.concat(output,"\n"))
+ end
- return true, errormessage
+ return result, errormessage
end
diff --git a/lib/html.lua b/lib/html.lua
index 136ce2b..0a23184 100644
--- a/lib/html.lua
+++ b/lib/html.lua
@@ -92,7 +92,7 @@ local generic_input = function ( field_type, v )
for i,k in ipairs ( {
"name", "size", "checked", "maxlength",
"value", "length", "class", "id", "src",
- "align", "alt",
+ "align", "alt", "contenteditable",
"tabindex", "accesskey", "onfocus", "onblur"
} ) do
str = str .. nv_pair ( k, v[k] )
@@ -129,7 +129,7 @@ form.longtext = function ( v )
end
-function form.passwd ( v )
+function form.password ( v )
return generic_input ( "password", v )
end
@@ -156,7 +156,7 @@ function form.image ( v )
end
--- v.value is the selected item
+-- v.value is the selected item (or an array if multiple)
-- v.option is an array of valid options
-- NOTE use of value and values (plural)
function form.select ( v )
@@ -177,6 +177,12 @@ function form.select ( v )
end
str = str .. ">"
-- now the options
+ local reverseval = {}
+ if type(v.value) == "table" then
+ for x,val in ipairs(v.value) do
+ reverseval[val]=x
+ end
+ end
for i, k in ipairs ( v.option ) do
local val = k
local txt = nil
@@ -184,9 +190,13 @@ function form.select ( v )
txt=val[1]
val=val[0]
end
- str = str .. "<option "
- if ( v.value == val ) then
- str = str .. " selected "
+ str = str .. "<option "
+ if type(v.value) == "table" then
+ if reverseval[val] then
+ str = str .. " selected"
+ end
+ elseif ( v.value == val ) then
+ str = str .. " selected"
end
str = str .. nv_pair("value", val) .. ">" .. k .. "</option>"
end
diff --git a/lib/viewfunctions.lua b/lib/viewfunctions.lua
index d69f2cc..c7aa53f 100644
--- a/lib/viewfunctions.lua
+++ b/lib/viewfunctions.lua
@@ -4,14 +4,14 @@ function displayinfo(myform,tags,viewtype)
if (myform[v]) and (myform[v]["value"]) then
local val = myform[v]
io.write("\n\t<DT")
- if (#val.errtxt > 0) then
+ if (val.errtxt) then
val.class = "error"
io.write(" class='error'")
end
io.write(">" .. val.label .. "</DT>")
io.write("\n\t\t<DD>")
if (viewtype == "viewonly") then
- if (val.value == "") and (val.errtxt == "") and ((val.descr) and (val.descr == "")) then val.value = "&nbsp;" end
+ if (val.value == "") and (val.errtxt == nil) and ((val.descr) and (val.descr == "")) then val.value = "&nbsp;" end
io.write(val.value)
elseif (val.type == "radio") and (type(val.option) == "table") and (#val.option > 0) then
io.write("<span style='display:inline' class='" .. ( val.class or "") .. "'>")
@@ -26,7 +26,7 @@ function displayinfo(myform,tags,viewtype)
io.write(html.form[val.type](val))
end
if (val.descr) and (#val.descr > 0) then io.write("\n\t\t<P CLASS='descr'>" .. string.gsub(val.descr, "\n", "<BR>") .. "</P>") end
- if (#val.errtxt > 0) then io.write("\n\t\t<P CLASS='error'>" .. string.gsub(val.errtxt, "\n", "<BR>") .. "</P>") end
+ if (val.errtxt) then io.write("\n\t\t<P CLASS='error'>" .. string.gsub(val.errtxt, "\n", "<BR>") .. "</P>") end
io.write("\n\t\t</DD>\n")
end
end
@@ -46,31 +46,94 @@ function displaymanagement (myform,tags)
end
if (myform) and (myform[tags[1]]) then
- io.write('<dt>' .. (myform[tags[1]]["label"] or myform[tags[1]]["name"]) .. '</dt>')
- io.write('<dd>')
- --Show buttons
- for k,v in pairs(tags) do
- if (myform[v]) then
- io.write(html.form[myform[v].type](myform[v]))
+ io.write('<dt>' .. (myform[tags[1]]["label"] or myform[tags[1]]["name"]) .. '</dt>')
+ io.write('<dd>')
+ --Show buttons
+ for k,v in pairs(tags) do
+ if (myform[v]) then
+ io.write(html.form[myform[v].type](myform[v]))
+ end
+ end
+ if (descriptions) and (#descriptions > 0) then
+ io.write("\n\t\t<P CLASS='descr'>" .. string.gsub(descriptions, "\n", "<BR>") .. "</P>")
+ end
+ if (errors) and (#errors > 0) then
+ io.write("\n\t\t<P CLASS='error'>" .. string.gsub(errors, "\n", "<BR>") .. "</P>")
end
+ io.write('</dd>')
+
+ -- Display the result of previous action
+ if (myform) and (myform['actionresult']) then
+ if (myform['actionresult']['errtxt']) and (#myform['actionresult']['errtxt'] > 0) then
+ io.write('<dt class="error">' .. myform['actionresult']['label'] .. '</dt>')
+ io.write('<dd><pre class="error">' .. (myform['actionresult']['errtxt'] or "") .. '</pre></dd>')
+ elseif (myform['actionresult']['descr']) and (#myform['actionresult']['descr'] > 0) then
+ io.write('<dt>' .. myform['actionresult']['label'] .. '</dt>')
+ io.write('<dd><pre>' .. (myform['actionresult']['descr'] or "") .. '</pre></dd>')
+ end
+ end
+ end
+end
+
+function displayitem(myitem, viewtype)
+ io.write("<DT")
+ if myitem.errtxt then
+ myitem.class = "error"
+ io.write(" class='error'")
end
- if (descriptions) and (#descriptions > 0) then
- io.write("\n\t\t<P CLASS='descr'>" .. string.gsub(descriptions, "\n", "<BR>") .. "</P>")
+ io.write(">" .. myitem.label .. "</DT>\n")
+ io.write("<DD>")
+ if (viewtype == "viewonly") then
+ myitem.disabled = "true"
end
- if (errors) and (#errors > 0) then
- io.write("\n\t\t<P CLASS='error'>" .. string.gsub(errors, "\n", "<BR>") .. "</P>")
+ if myitem.type == "multi" then
+ -- FIXME multiple select doesn't work in haserl, so use series of checkboxes
+ --myitem.type = "select"
+ --myitem.multiple = "true"
+ local tempname = myitem.name
+ local tempval = myitem.value
+ local reverseval = {}
+ for x,val in ipairs(tempval) do
+ reverseval[val] = x
+ end
+ for x,val in ipairs(myitem.option) do
+ myitem.value = val
+ myitem.checked = reverseval[val]
+ myitem.name = tempname .. "." .. val
+ io.write(html.form.checkbox(myitem) .. val .. "<br>\n")
+ end
+ myitem.name = tempname
+ myitem.value = tempval
+ else
+ io.write(html.form[myitem.type](myitem) .. "\n")
end
- io.write('</dd>')
+ if myitem.descr then io.write("<P CLASS='descr'>" .. string.gsub(myitem.descr, "\n", "<BR>") .. "</P>\n") end
+ if myitem.errtxt then io.write("<P CLASS='error'>" .. string.gsub(myitem.errtxt, "\n", "<BR>") .. "</P>\n") end
+ io.write("</DD>\n")
+end
- -- Display the result of previous action
- if (myform) and (myform['actionresult']) then
- if (myform['actionresult']['errtxt']) and (#myform['actionresult']['errtxt'] > 0) then
- io.write('<dt class="error">' .. myform['actionresult']['label'] .. '</dt>')
- io.write('<dd><pre class="error">' .. (myform['actionresult']['errtxt'] or "") .. '</pre></dd>')
- elseif (myform['actionresult']['descr']) and (#myform['actionresult']['descr'] > 0) then
- io.write('<dt>' .. myform['actionresult']['label'] .. '</dt>')
- io.write('<dd><pre>' .. (myform['actionresult']['descr'] or "") .. '</pre></dd>')
+function displayform(myform, order)
+ if myform.descr then io.write("<P CLASS='descr'>" .. string.gsub(myform.descr, "\n", "<BR>") .. "</P>\n") end
+ if myform.errtxt then io.write("<P CLASS='error'>" .. string.gsub(myform.errtxt, "\n", "<BR>") .. "</P>\n") end
+ io.write('<form action="' .. myform.action .. '" method="POST">\n')
+ io.write('<DL>\n')
+ local reverseorder= {}
+ if order then
+ for x,name in ipairs(order) do
+ reverseorder[name] = x
+ if myform.value[name] then
+ myform.value[name].name = name
+ displayitem(myform.value[name])
+ end
end
end
-end
+ for name,item in pairs(myform.value) do
+ if nil == reverseorder[name] then
+ item.name = name
+ displayitem(item)
+ end
+ end
+ io.write('<DT><input class="submit" type="submit" value="' .. myform.submit .. '"></DT>\n')
+ io.write('</DL>\n')
+ io.write('</FORM>')
end
diff --git a/roles b/roles
index 09b7c37..0eadd69 100644
--- a/roles
+++ b/roles
@@ -1,4 +1,4 @@
ALL=welcome:read,logon:logon,logon:logout,logon:status
-CREATE=password:administrator,password:status
-READ=password:editme,password:save
+CREATE=password:status,password:edituser,password:newuser,password:deleteuser
+READ=password:editme
NONE=roles:read,roles:getlist