diff options
author | Daniel Silverstone <dsilvers@digital-scurf.org> | 2012-07-01 10:55:59 +0100 |
---|---|---|
committer | Daniel Silverstone <dsilvers@digital-scurf.org> | 2012-07-01 10:55:59 +0100 |
commit | a3d23fccc24dfb9b5c96c3d5f76cb648104a1907 (patch) | |
tree | 4dc693d49fdcd313965e856af30c72c258415db0 | |
parent | da5e283a0040a0c0f176ec31ab2f0fb010f8d158 (diff) | |
download | gitano-a3d23fccc24dfb9b5c96c3d5f76cb648104a1907.tar.gz |
ADMINCOMMAND: Add group command for managing groups
-rw-r--r-- | lib/gitano/admincommand.lua | 258 |
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 { |