summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/Makefile4
-rwxr-xr-xapp/acf-util/password-controller.lua18
-rwxr-xr-xapp/acf-util/password-html.lsp1
-rwxr-xr-xapp/acf-util/password-model.lua6
-rw-r--r--app/acf-util/roles-controller.lua113
-rw-r--r--app/acf-util/roles-editrole-html.lsp20
-rw-r--r--app/acf-util/roles-html.lsp20
-rw-r--r--app/acf-util/roles-newrole-html.lsp20
-rw-r--r--app/acf-util/roles-viewroles-html.lsp43
-rwxr-xr-xapp/acf-util/roles.menu4
-rw-r--r--app/acf_www-controller.lua14
-rw-r--r--lib/authenticator-plaintext.lua12
-rw-r--r--lib/roles.lua123
-rw-r--r--lib/viewfunctions.lua2
-rw-r--r--roles2
15 files changed, 352 insertions, 50 deletions
diff --git a/app/Makefile b/app/Makefile
index f7e42dc..ffa03ed 100644
--- a/app/Makefile
+++ b/app/Makefile
@@ -8,6 +8,10 @@ APP_DIST= \
acf-util/roles-controller.lua \
acf-util/roles-model.lua \
acf-util/roles-html.lsp \
+ acf-util/roles-viewroles-html.lsp \
+ acf-util/roles-editrole-html.lsp \
+ acf-util/roles-newrole-html.lsp \
+ acf-util/roles.menu \
acf-util/password-controller.lua \
acf-util/password-html.lsp \
acf-util/password-model.lua \
diff --git a/app/acf-util/password-controller.lua b/app/acf-util/password-controller.lua
index 1d3aa7a..809e766 100755
--- a/app/acf-util/password-controller.lua
+++ b/app/acf-util/password-controller.lua
@@ -29,15 +29,6 @@ function edituser(self)
if self.clientdata.password == "" then self.clientdata.password = nil end
if self.clientdata.password_confirm == "" then self.clientdata.password_confirm = nil end
- -- 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
-
-- Update userinfo
local output = self.model.update_user(self, self.clientdata, false)
@@ -51,15 +42,6 @@ function edituser(self)
end
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
-
-- Update userinfo
local output = self.model.update_user(self, self.clientdata, true)
diff --git a/app/acf-util/password-html.lsp b/app/acf-util/password-html.lsp
index a11d9e3..9de2d4f 100755
--- a/app/acf-util/password-html.lsp
+++ b/app/acf-util/password-html.lsp
@@ -4,7 +4,6 @@
--[[ 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>")
--]]
diff --git a/app/acf-util/password-model.lua b/app/acf-util/password-model.lua
index 553abca..e3d58f1 100755
--- a/app/acf-util/password-model.lua
+++ b/app/acf-util/password-model.lua
@@ -37,9 +37,6 @@ function update_user(self, clientdata, newuser)
end
userinfo = userinfo or {}
- -- Get list of available roles
- local avail_roles=auth.list_roles()
-
config.userid = cfe({
label="User id",
value=(userinfo.userid or clientdata.userid or ""),
@@ -54,7 +51,7 @@ function update_user(self, clientdata, newuser)
label="Roles",
value=(userinfo.roles or clientdata.roles or {}),
type="multi",
- option=avail_roles,
+ option=auth.list_roles(),
errtxt = errormessage.roles
})
config.password = cfe({
@@ -73,6 +70,7 @@ function get_users(self)
--List all users and their userinfo
local users = {}
local userlist = auth.list_users(self)
+
for x,user in pairs(userlist) do
local userinfo = auth.get_userinfo(self,user)
users[user] = cfe({
diff --git a/app/acf-util/roles-controller.lua b/app/acf-util/roles-controller.lua
index 4363cb6..1d69b8b 100644
--- a/app/acf-util/roles-controller.lua
+++ b/app/acf-util/roles-controller.lua
@@ -5,6 +5,25 @@ module (..., package.seeall)
auth = require("authenticator-plaintext")
roll = require("roles")
+local get_all_permissions = function(self)
+ -- need to get a list of all the controllers
+ controllers = roles.get_controllers(self)
+ local table_perm = {}
+ local array_perm = {}
+ for a,b in pairs(controllers) do
+ if nil == table_perm[b.sname] then
+ table_perm[b.sname] = {}
+ end
+ temp = roles.get_controllers_func(self,b)
+ for x,y in ipairs(temp) do
+ table_perm[b.sname][y] = {}
+ array_perm[#array_perm + 1] = b.sname .. ":" .. y
+ end
+ end
+
+ return table_perm, array_perm
+end
+
default_action = "read"
-- Return your own roles/permissions
@@ -16,7 +35,7 @@ read = function(self)
end
-- Return roles/permissions for specified user
-viewroles = function(self)
+viewuserroles = function(self)
if not (self.clientdata.userid) then
redirect(self)
end
@@ -27,7 +46,7 @@ viewroles = function(self)
end
-- Return permissions for specified role
-viewperms = function(self)
+viewroleperms = function(self)
if not (self.clientdata.role) then
redirect(self, "getlist")
end
@@ -37,6 +56,92 @@ viewperms = function(self)
end
-- Return list of all permissions
-getlist = function(self)
- return cfe({ type="group", value={permissions=self.model:getcont(self)} })
+getpermslist = function(self)
+ permissions = cfe({ type="table", value=get_all_permissions(self), label="All Permissions" })
+ return cfe({ type="group", value={permissions=permissions} })
+end
+
+viewroles = function(self)
+ -- Get command result out of session data
+ local cmdresult = self.sessiondata.cmdresult
+ self.sessiondata.cmdresult = nil
+
+ local defined_roles, default_roles = roll.list_roles()
+ local defined_roles_cfe=cfe({ type="list", value=defined_roles, label="Locally-defined roles" })
+ local default_roles_cfe=cfe({ type="list", value=default_roles, label="System-defined roles" })
+
+ return cfe({ type="group", value={defined_roles=defined_roles_cfe, default_roles=default_roles_cfe, cmdresult=cmdresult} })
+end
+
+local setpermissions = function(self, role, permissions, newrole)
+ local errtxt
+ local my_perms = {}
+ if permissions then
+ -- we're changing permissions
+ local result = true
+ if newrole then
+ -- make sure not overwriting role
+ for x,ro in ipairs(roles.list_roles()) do
+ if role==ro then
+ result = false
+ errtxt = "Role already exists"
+ break
+ end
+ end
+ end
+ if result==true then
+ result, errtxt = roles.set_role_perm(role, nil, permissions)
+ end
+ my_perms = self.clientdata.permissions
+ else
+ if role then
+ tmp, my_perms = roles.get_role_perm(self.conf.appdir, role)
+ else
+ role = ""
+ end
+ end
+
+ local tmp, all_perms = get_all_permissions(self)
+ table.sort(all_perms)
+
+ local permissions_cfe = cfe({ type="multi", value=my_perms, option=all_perms, label="Role permissions" })
+ local role_cfe = cfe({ value=role, label="Role", errtxt=errtxt })
+
+ return cfe({ type="table", value={role=role_cfe, permissions=permissions_cfe} })
+end
+
+newrole = function(self)
+ local form = setpermissions(self, self.clientdata.role, self.clientdata.permissions, true)
+ form.type = "form"
+ form.label = "Edit new role"
+ if form.value.role.errtxt then
+ form.errtxt = "Failed to create role"
+ elseif self.clientdata.permissions then
+ -- If we have permissions, we tried to set
+ local cmdresult = cfe({ value="New role created" })
+ self.sessiondata.cmdresult = cmdresult
+ redirect(self, "viewroles")
+ end
+ return form
+end
+
+editrole = function(self)
+ local form = setpermissions(self, self.clientdata.role, self.clientdata.permissions, false)
+ form.type = "form"
+ form.label = "Edit role"
+ if form.value.role.errtxt then
+ form.errtxt = "Failed to save role"
+ elseif self.clientdata.permissions then
+ -- If we have permissions, we tried to set
+ local cmdresult = cfe({ value="Role saved" })
+ self.sessiondata.cmdresult = cmdresult
+ redirect(self, "viewroles")
+ end
+ return form
+end
+
+deleterole = function(self)
+ local result, cmdresult = roles.delete_role(self.clientdata.role)
+ self.sessiondata.cmdresult = cfe({ value=cmdresult })
+ redirect(self, "viewroles")
end
diff --git a/app/acf-util/roles-editrole-html.lsp b/app/acf-util/roles-editrole-html.lsp
new file mode 100644
index 0000000..bf42f28
--- /dev/null
+++ b/app/acf-util/roles-editrole-html.lsp
@@ -0,0 +1,20 @@
+<? local form= ... ?>
+<? --[[
+ io.write(html.cfe_unpack(form))
+ io.write(html.cfe_unpack(FORM))
+--]] ?>
+
+<? ---[[ ?>
+<H1><?= form.label ?></H1>
+<?
+ require("viewfunctions")
+ form.action = ""
+ form.submit = "Save"
+ -- If editing existing role, disable role
+ if form.value.role and "GET" == ENV["REQUEST_METHOD"] then
+ form.value.role.contenteditable = false
+ end
+ local order = { "role", "permissions" }
+ displayform(form, order)
+?>
+<? --]] ?>
diff --git a/app/acf-util/roles-html.lsp b/app/acf-util/roles-html.lsp
index 4a23c25..2f4c8b1 100644
--- a/app/acf-util/roles-html.lsp
+++ b/app/acf-util/roles-html.lsp
@@ -27,10 +27,22 @@
<? elseif view.value.role then ?>
<H2><?= view.value.role.value ?>'s full permissions are</H2>
<? end ?>
- <? for x,cont in pairs(view.value.permissions.value) do
- print("<b>",x,"</b>")
- for y,act in pairs(cont) do
- print(y)
+ <? local controllers = {}
+ -- It's nice to have it in alphabetical order
+ for cont in pairs(view.value.permissions.value) do
+ controllers[#controllers + 1] = cont
+ end
+ table.sort(controllers)
+ for x,cont in ipairs(controllers) do
+ print("<b>",cont,"</b>")
+ -- Again, alphabetical order
+ local actions = {}
+ for act in pairs(view.value.permissions.value[cont]) do
+ actions[#actions + 1] = act
+ end
+ table.sort(actions)
+ for y,act in pairs(actions) do
+ print(act)
end
print("<br>")
end ?>
diff --git a/app/acf-util/roles-newrole-html.lsp b/app/acf-util/roles-newrole-html.lsp
new file mode 100644
index 0000000..bf42f28
--- /dev/null
+++ b/app/acf-util/roles-newrole-html.lsp
@@ -0,0 +1,20 @@
+<? local form= ... ?>
+<? --[[
+ io.write(html.cfe_unpack(form))
+ io.write(html.cfe_unpack(FORM))
+--]] ?>
+
+<? ---[[ ?>
+<H1><?= form.label ?></H1>
+<?
+ require("viewfunctions")
+ form.action = ""
+ form.submit = "Save"
+ -- If editing existing role, disable role
+ if form.value.role and "GET" == ENV["REQUEST_METHOD"] then
+ form.value.role.contenteditable = false
+ end
+ local order = { "role", "permissions" }
+ displayform(form, order)
+?>
+<? --]] ?>
diff --git a/app/acf-util/roles-viewroles-html.lsp b/app/acf-util/roles-viewroles-html.lsp
new file mode 100644
index 0000000..a98f5b9
--- /dev/null
+++ b/app/acf-util/roles-viewroles-html.lsp
@@ -0,0 +1,43 @@
+<? local view= ... ?>
+<? --[[
+ io.write(html.cfe_unpack(view))
+--]] ?>
+
+<? ---[[ ?>
+<H1>ROLES</H1>
+
+<? if view.value.cmdresult then ?>
+<H2>Command Result</H2>
+<dl><?= view.value.cmdresult.value ?></dl>
+<? end ?>
+
+<H2>Create new role</H2>
+<form action="newrole" method="POST">
+<dl><dt><input class="submit" type="submit" value="New Role"></dt></dl>
+</form>
+
+<H2>Existing roles</H2>
+<? if view.value.default_roles then ?>
+ <dl>
+ <? for x,role in pairs(view.value.default_roles.value) do ?>
+ <dt><img src='/static/tango/16x16/categories/applications-system.png' height='16' width='16'> <?= role ?></dt>
+ <dd>
+ [<a href='viewroleperms?role=<?= role ?>'>View this role</a>]
+ </dd>
+ <? end ?>
+ </dl>
+<? end ?>
+<? if view.value.defined_roles then ?>
+ <dl>
+ <? table.sort(view.value.defined_roles.value) ?>
+ <? for x,role in pairs(view.value.defined_roles.value) do ?>
+ <dt><img src='/static/tango/16x16/apps/system-users.png' height='16' width='16'> <?= role ?></dt>
+ <dd>
+ [<a href='viewroleperms?role=<?= role ?>'>View this role</a>]
+ [<a href='editrole?role=<?= role ?>'>Edit this role</a>]
+ [<a href='deleterole?role=<?= role ?>'>Delete this role</a>]
+ </dd>
+ <? end ?>
+ </dl>
+<? end ?>
+<? --]] ?>
diff --git a/app/acf-util/roles.menu b/app/acf-util/roles.menu
new file mode 100755
index 0000000..7bcca30
--- /dev/null
+++ b/app/acf-util/roles.menu
@@ -0,0 +1,4 @@
+#CAT GROUP/DESC TAB ACTION
+System 02Roles_management Administration viewroles
+System 02Roles_management My_Roles read
+
diff --git a/app/acf_www-controller.lua b/app/acf_www-controller.lua
index 98b732f..67e95ad 100644
--- a/app/acf_www-controller.lua
+++ b/app/acf_www-controller.lua
@@ -75,6 +75,20 @@ mvc.on_load = function (self, parent)
self.clientdata = FORM
self.conf.clientip = ENV.REMOTE_ADDR
+ -- FIXME this is because multi selects don't work in haserl
+ for name,oldtable in pairs(self.clientdata) do
+ if type(oldtable) == "table" then
+ -- Assume it's a sparse array, and remove blanks
+ local newtable={}
+ for x=1,table.maxn(oldtable) do
+ if oldtable[x] then
+ newtable[#newtable + 1] = oldtable[x]
+ end
+ end
+ self.clientdata[name] = newtable
+ end
+ end
+
parent_exception_handler = parent.exception_handler
-- this sets the package path for us and our children
diff --git a/lib/authenticator-plaintext.lua b/lib/authenticator-plaintext.lua
index c68ec2b..6c4cbbd 100644
--- a/lib/authenticator-plaintext.lua
+++ b/lib/authenticator-plaintext.lua
@@ -12,6 +12,7 @@ userid:password:username:role1[,role2...]
module (..., package.seeall)
local sess = require ("session")
+require("roles")
local pvt={}
@@ -181,8 +182,15 @@ list_users = function (self)
end
list_roles = function (self)
- local output = {"CREATE","UPDATE","DELETE","READ"}
- return output
+ -- Get list of available roles (everything except ALL)
+ local avail_roles = roles.list_all_roles()
+ for x,role in ipairs(avail_roles) do
+ if role=="ALL" then
+ table.remove(avail_roles,x)
+ break
+ end
+ end
+ return avail_roles
end
change_setting = function (self, userid, parameter, value)
diff --git a/lib/roles.lua b/lib/roles.lua
index 768e96f..53409c0 100644
--- a/lib/roles.lua
+++ b/lib/roles.lua
@@ -7,12 +7,28 @@ require ("format")
module (..., package.seeall)
+local roles_file = "/etc/acf/roles"
+local default_roles = { "CREATE", "UPDATE", "DELETE", "READ", "ALL" }
+
+-- returns a table of the *.roles files
+-- startdir should be the app dir
+local get_roles_candidates = function (startdir)
+ local t = {}
+ local fh = io.popen('find ' .. startdir .. ' -name "*.roles"')
+ for x in fh:lines() do
+ t[#t + 1] = x
+ end
+ return t
+end
+
-- Return a list of *controller.lua files
list_controllers = function(self)
local list = {}
local f = io.popen("/usr/bin/find /usr/share/acf/ |/bin/grep \"controller.lua$\" ")
for a in f:lines() do
- list[#list + 1 ] = a
+ if not string.find(a, "acf_") then
+ list[#list + 1 ] = a
+ end
end
f:close()
return list
@@ -58,24 +74,45 @@ get_controllers_func = function(self,controller_info)
end
end
--- returns a table of the *.roles files
--- startdir should be the app dir
-local get_roles_candidates = function (startdir)
- local t = {}
- local fh = io.popen('find ' .. startdir .. ' -name "*.roles"')
- for x in fh:lines() do
- t[#t + 1] = x
+list_default_roles = function()
+ return default_roles
+end
+
+list_roles = function()
+ local defined_roles = {}
+ local reverseroles = {}
+ for x,role in ipairs(default_roles) do
+ reverseroles[role] = x
end
- return t
+
+ -- Open the roles file and parse for defined roles
+ f = fs.read_file_as_array(roles_file)
+ for x,line in pairs(f) do
+ temprole = string.match(line,"^[%a]+")
+ if not reverseroles[temprole] then
+ defined_roles[#defined_roles + 1] = temprole
+ end
+ end
+
+ return defined_roles, default_roles
end
+list_all_roles = function()
+ local defined_roles, default_roles = list_roles()
+ for x,role in ipairs(defined_roles) do
+ default_roles[#default_roles + 1] = role
+ end
+ return default_roles
+end
+
-- Go through the roles files and determine the permissions for the specified roles
get_roles_perm = function(startdir,roles)
permissions = {}
+ permissions_array = {}
-- find all of the roles files and add in the master file
local rolesfiles = get_roles_candidates(startdir)
- rolesfiles[#rolesfiles + 1] = "/etc/acf/roles"
+ rolesfiles[#rolesfiles + 1] = roles_file
local reverseroles = {}
for x,role in ipairs(roles) do
@@ -94,8 +131,9 @@ get_roles_perm = function(startdir,roles)
if nil == permissions[control] then
permissions[control] = {}
end
- if action and nil == permissions[control][action] then
+ if action then
permissions[control][action] = {}
+ permissions_array[#permissions_array + 1] = control .. ":" .. action
end
end
end
@@ -103,16 +141,17 @@ get_roles_perm = function(startdir,roles)
end
end
- return permissions
+ return permissions, permissions_array
end
-- Go through the roles files and determine the permissions for the specified role
get_role_perm = function(startdir,role)
permissions = {}
+ permissions_array = {}
-- find all of the roles files and add in the master file
local rolesfiles = get_roles_candidates(startdir)
- rolesfiles[#rolesfiles + 1] = "/etc/acf/roles"
+ rolesfiles[#rolesfiles + 1] = roles_file
for x,file in ipairs(rolesfiles) do
f = fs.read_file_as_array(file)
@@ -125,8 +164,9 @@ get_role_perm = function(startdir,role)
if nil == permissions[control] then
permissions[control] = {}
end
- if action and nil == permissions[control][action] then
+ if action then
permissions[control][action] = {}
+ permissions_array[#permissions_array + 1] = control .. ":" .. action
end
end
end
@@ -134,6 +174,59 @@ get_role_perm = function(startdir,role)
end
end
- return permissions
+ return permissions, permissions_array
+end
+
+-- Delete a role from role file
+delete_role = function(role)
+ for x,ro in ipairs(default_roles) do
+ if role==ro then
+ return false, "Cannot delete default roles"
+ end
+ end
+ local rolecontent = fs.read_file_as_array(roles_file)
+ local output = {}
+ local result = false
+ local cmdresult = "Role entry not found"
+ for x,line in pairs(rolecontent) do
+ if not string.match(line, "^" .. role .. "=") then
+ table.insert(output,line)
+ else
+ result = true
+ cmdresult = "Role deleted"
+ end
+ end
+
+ if result == true then
+ fs.write_file(roles_file, table.concat(output,"\n"))
+ end
+
+ return result, cmdresult
end
+-- Set permissions for a role in role file
+set_role_perm = function(role, permissions, permissions_array)
+ if role==nil or role=="" then
+ return false, "Invalid Role"
+ end
+ for x,ro in ipairs(default_roles) do
+ if role==ro then
+ return false, "Cannot modify default roles"
+ end
+ end
+ if permissions and not permissions_array then
+ permissions_array = {}
+ for cont,actions in pairs(permissions) do
+ for action in pairs(actions) do
+ permissions_array[#permissions_array + 1] = cont .. ":" .. action
+ end
+ end
+ end
+ if permissions_array==nil or #permissions_array==0 then
+ return false, "No permissions set"
+ end
+
+ delete_role(role)
+ fs.write_line_file(roles_file, role .. "=" .. table.concat(permissions_array,","))
+ return true
+end
diff --git a/lib/viewfunctions.lua b/lib/viewfunctions.lua
index c7aa53f..5080a34 100644
--- a/lib/viewfunctions.lua
+++ b/lib/viewfunctions.lua
@@ -99,7 +99,7 @@ function displayitem(myitem, viewtype)
for x,val in ipairs(myitem.option) do
myitem.value = val
myitem.checked = reverseval[val]
- myitem.name = tempname .. "." .. val
+ myitem.name = tempname .. "." .. x
io.write(html.form.checkbox(myitem) .. val .. "<br>\n")
end
myitem.name = tempname
diff --git a/roles b/roles
index e4300cf..90e3221 100644
--- a/roles
+++ b/roles
@@ -1,3 +1,3 @@
ALL=welcome:read,logon:logon,logon:logout,logon:status
-CREATE=password:status,password:edituser,password:newuser,password:deleteuser,roles:getlist,roles:viewroles,roles:viewperms
+CREATE=password:status,password:edituser,password:newuser,password:deleteuser,roles:getpermslist,roles:viewuserroles,roles:viewroleperms,roles:viewroles,roles:editrole,roles:deleterole,roles:newrole
READ=password:editme,roles:read