summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2012-07-01 10:55:59 +0100
committerDaniel Silverstone <dsilvers@digital-scurf.org>2012-07-01 10:55:59 +0100
commita3d23fccc24dfb9b5c96c3d5f76cb648104a1907 (patch)
tree4dc693d49fdcd313965e856af30c72c258415db0
parentda5e283a0040a0c0f176ec31ab2f0fb010f8d158 (diff)
downloadgitano-a3d23fccc24dfb9b5c96c3d5f76cb648104a1907.tar.gz
ADMINCOMMAND: Add group command for managing groups
-rw-r--r--lib/gitano/admincommand.lua258
1 files changed, 258 insertions, 0 deletions
diff --git a/lib/gitano/admincommand.lua b/lib/gitano/admincommand.lua
index 3d3ffc3..4b28fcd 100644
--- a/lib/gitano/admincommand.lua
+++ b/lib/gitano/admincommand.lua
@@ -248,6 +248,259 @@ local function builtin_user_run(conf, _, cmdline, env)
return "exit", 0
end
+local builtin_group_short = "Manage groups in Gitano"
+local builtin_group_helptext = [[
+usage: group [list]
+ group show <groupname>
+ group add <groupname> <description>
+ group del <groupname [confirm token]
+ group description <groupname> <description>
+ group adduser <groupname> <username>
+ group deluser <groupname> <username> [confirm token]
+ group addgroup <groupname> <groupname>
+ group delgroup <groupname> <groupname> [confirm token]
+
+With no subcommand, or the subcommand 'list' the user command will
+show a list of all the users, along with their descriptions
+
+Showing a group will display membership information
+
+Adding a user to a group adds the user to the direct membership list.
+Removing a user from a group removes them from the direct membership
+list only.
+
+If you add a group to a group, you are stating that everyone in the
+sub group is to be considered a member of this group also. Removing a
+group undoes this effect.
+
+To delete a group, remove a user from a group or remove a group from a
+group requires a confirmation token which will be supplied to you if
+missing.
+]]
+
+local function builtin_group_validate(conf, _, cmdline)
+ if not cmdline[2] then
+ cmdline[2] = "list"
+ end
+ local groupsubs = util.set {"list", "show", "add", "del",
+ "adduser", "deluser", "addgroup", "delgroup", "description"}
+ if not groupsubs[cmdline[2]] then
+ log.error("Unknown sub command", cmdline[2], "for group")
+ return false
+ end
+ if cmdline[2] == "list" and #cmdline ~= 2 then
+ log.error("List takes no arguments")
+ return false
+ end
+ if cmdline[2] == "show" and #cmdline ~= 3 then
+ log.error("Show takes a group name")
+ return false
+ end
+ if cmdline[2] == "add" and #cmdline < 4 then
+ log.error("Add takes a group name and a description")
+ return false
+ end
+ if cmdline[2] == "del" and (#cmdline < 3 or #cmdline > 4) then
+ log.error("Del takes a group name and a confirmation token")
+ return false
+ end
+ if cmdline[2] == "description" and #cmdline < 4 then
+ log.error("Description takes a group name and a description")
+ return false
+ end
+ if cmdline[2] == "adduser" and #cmdline ~= 4 then
+ log.error("Adduser takes a group name and a username")
+ return false
+ end
+ if cmdline[2] == "deluser" and (#cmdline < 4 or #cmdline > 5) then
+ log.error("Deluser takes a group name, a username and a confirmation token")
+ return false
+ end
+ if cmdline[2] == "addgroup" and #cmdline ~= 4 then
+ log.error("Addgroup takes a group name and a second group name")
+ return false
+ end
+ if cmdline[2] == "delgroup" and (#cmdline < 4 or #cmdline > 5) then
+ log.error("Delgroup takes a group name, a second group name, and a confirmation token")
+ return false
+ end
+ return true
+end
+
+local function builtin_group_prep(conf, _, cmdline, context)
+ context.operation = "group" .. cmdline[2]
+ context.targetgroup = cmdline[3]
+ if cmdline[2]:match("user") or cmdline[2]:match("group") then
+ context.member = cmdline[4]
+ end
+ return conf.repo:run_lace(context)
+end
+
+local function builtin_group_run(conf, _, cmdline, env)
+ local reason = nil
+ if cmdline[2] == "list" then
+ local groups = {}
+ for g in pairs(conf.groups) do
+ groups[#groups+1] = g
+ end
+ table.sort(groups)
+ for _, g in ipairs(groups) do
+ log.stdout(g .. ":" .. conf.groups[g].description)
+ end
+ elseif cmdline[2] == "show" then
+ local g, gtab = cmdline[3], conf.groups[cmdline[3]]
+ if not gtab then
+ log.fatal("Unknown group", g)
+ end
+ log.stdout(g .. ":" .. gtab.description)
+ for i, m in ipairs(gtab.members) do
+ log.stdout(" => " .. m)
+ end
+ for i, gg in ipairs(gtab.subgroups) do
+ log.stdout(" [] " .. gg)
+ end
+ elseif cmdline[2] == "add" then
+ local g = cmdline[3]
+ if conf.groups[g] then
+ log.fatal("Group", g, "already exists")
+ end
+ local new_desc = util.deep_copy(cmdline)
+ table.remove(new_desc, 1)
+ table.remove(new_desc, 1)
+ table.remove(new_desc, 1)
+ new_desc = table.concat(new_desc, " ")
+ local gtab = {
+ description = new_desc,
+ members = {},
+ subgroups = {},
+ meta = { prefix = "groups/" }
+ }
+ conf.groups[g] = gtab
+ reason = "Create group " .. g
+ elseif cmdline[2] == "description" then
+ local g, gtab = cmdline[3], conf.groups[cmdline[3]]
+ if not gtab then
+ log.fatal("Unknown group", g)
+ end
+ local new_desc = util.deep_copy(cmdline)
+ table.remove(new_desc, 1)
+ table.remove(new_desc, 1)
+ table.remove(new_desc, 1)
+ new_desc = table.concat(new_desc, " ")
+ if gtab.description ~= new_desc then
+ gtab.description = new_desc
+ reason = "Change group description of " .. g
+ end
+ elseif cmdline[2] == "del" then
+ local g = cmdline[3]
+ if not conf.groups[g] then
+ log.fatal("Unknown group", g)
+ end
+ local token = conf.repo:generate_confirmation()
+ if not cmdline[4] then
+ log.state("In order to delete group", g, "you must supply the following token:")
+ log.state(token)
+ elseif cmdline[4] ~= token then
+ log.fatal("Token does not match. Has someone else done administrative actions?")
+ else
+ conf.groups[g] = nil
+ reason = "Delete group " .. g
+ end
+ elseif cmdline[2] == "adduser" then
+ local g, gtab, u, utab =
+ cmdline[3], conf.groups[cmdline[3]],
+ cmdline[4], conf.users[cmdline[4]]
+ if not gtab then
+ log.fatal("Unknown group", g)
+ end
+ if not utab then
+ log.fatal("Unknown user", u)
+ end
+ if not gtab.members[u] then
+ gtab.members[#gtab.members+1] = u
+ gtab.members[u] = #gtab.members
+ reason = "Add " .. u .. " to " .. g
+ else
+ log.state("User", u, "already a member of", g)
+ end
+ elseif cmdline[2] == "deluser" then
+ local g, gtab, u, utab =
+ cmdline[3], conf.groups[cmdline[3]],
+ cmdline[4], conf.users[cmdline[4]]
+ if not gtab then
+ log.fatal("Unknown group", g)
+ end
+ if not utab then
+ log.fatal("Unknown user", u)
+ end
+ if not gtab.members[u] then
+ log.fatal("User", u, "is not a member of", g)
+ end
+ local token = conf.repo:generate_confirmation()
+ if not cmdline[5] then
+ log.state("To delete user", u, "from group", g, "you will need this token:")
+ log.state(token)
+ elseif cmdline[5] ~= token then
+ log.fatal("Token does not match. Did someone else do administrative actions?")
+ else
+ table.remove(gtab.members, gtab.members[u])
+ gtab.members[u] = nil
+ reason = "Remove " .. u .. " from " .. g
+ end
+ elseif cmdline[2] == "addgroup" then
+ local g, gtab, g2, g2tab =
+ cmdline[3], conf.groups[cmdline[3]],
+ cmdline[4], conf.groups[cmdline[4]]
+ if not gtab then
+ log.fatal("Unknown group", g)
+ end
+ if not g2tab then
+ log.fatal("Unknown group", g2)
+ end
+ if not gtab.subgroups[g2] then
+ gtab.subgroups[#gtab.subgroups+1] = g2
+ gtab.subgroups[g2] = #gtab.subgroups
+ reason = "Add group " .. g2 .. " to " .. g
+ else
+ log.state("Group", g2, "already a subgroup of", g)
+ end
+ elseif cmdline[2] == "delgroup" then
+ local g, gtab, g2, g2tab =
+ cmdline[3], conf.groups[cmdline[3]],
+ cmdline[4], conf.groups[cmdline[4]]
+ if not gtab then
+ log.fatal("Unknown group", g)
+ end
+ if not g2tab then
+ log.fatal("Unknown group", g2)
+ end
+ if not gtab.subgroups[g2] then
+ log.fatal("Group", g2, "is not a subgroup of", g)
+ end
+ local token = conf.repo:generate_confirmation()
+ if not cmdline[5] then
+ log.state("To delete group", g2, "from group", g, "you will need this token:")
+ log.state(token)
+ elseif cmdline[5] ~= token then
+ log.fatal("Token does not match. Did someone else do administrative actions?")
+ else
+ table.remove(gtab.subgroups, gtab.subgroups[g2])
+ gtab.members[g2] = nil
+ reason = "Remove group " .. g2 .. " from " .. g
+ end
+ else
+ log.fatal("Unknown sub command", cmdline[2])
+ end
+ if reason then
+ local ok, commit = config.commit(conf, reason, env.GITANO_USER)
+ if not ok then
+ log.fatal(commit)
+ end
+ log.state("Committed: " .. reason)
+ end
+ return "exit", 0
+end
+
local function register_commands(reg)
assert(reg("as", builtin_as_short, builtin_as_helptext,
builtin_as_validate, builtin_as_prep, builtin_as_run,
@@ -256,6 +509,11 @@ local function register_commands(reg)
assert(reg("user", builtin_user_short, builtin_user_helptext,
builtin_user_validate, builtin_user_prep,
builtin_user_run, false, false, true))
+
+ assert(reg("group", builtin_group_short, builtin_group_helptext,
+ builtin_group_validate, builtin_group_prep,
+ builtin_group_run, false, false, true))
+
end
return {