diff options
Diffstat (limited to 'bin/gitano-auth.in')
-rw-r--r-- | bin/gitano-auth.in | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/bin/gitano-auth.in b/bin/gitano-auth.in new file mode 100644 index 0000000..a16c4df --- /dev/null +++ b/bin/gitano-auth.in @@ -0,0 +1,159 @@ +-- @@SHEBANG +-- -*- Lua -*- +-- gitano-auth +-- +-- Git (with) Augmented network operations -- User authentication wrapper +-- +-- Copyright 2012 Daniel Silverstone <dsilvers@digital-scurf.org> +-- +-- + +-- @@GITANO_LUA_PATH + +local gitano = require "gitano" +local luxio = require "luxio" +local sio = require "luxio.simple" +local sp = require "luxio.subprocess" + +local repo_root, username, keytag = ... + +local cmdline = luxio.getenv "SSH_ORIGINAL_COMMAND" or "" + +if cmdline:match("^[ \t\n]*$") then + gitano.log.fatal("No command provided, cannot continue") +end + +local parsed_cmdline, warnings = gitano.util.parse_cmdline(cmdline) + +local start_log_level = gitano.log.get_level() +-- Clamp level at info until we have checked if the caller +-- is an admin or not +gitano.log.cap_level(gitano.log.level.INFO) + +if (#warnings > 0) then + gitano.log.error("Warnings encountered parsing commandline."); + gitano.log.warn("\t" .. cmdline) + gitano.log.warn("") + gitano.log.warn("Parsed as:") + for i = 1, #parsed_cmdline do + gitano.log.warn((" =[%2d]> %s"):format(i, parsed_cmdline[i])) + end + gitano.log.warn("\nWarnings were:") + for i = 1, #warnings do + gitano.log.warn(" * " .. warnings[i]) + end + gitano.log.warn("") + gitano.log.fatal("Game over, sorry\n") +end + +-- Now load the administration data + +local admin_repo = gitano.git.repository.new((repo_root or "") .. "/gitano-admin.git") + +if not admin_repo then + gitano.log.fatal("Unable to locate administration repository. Cannot continue"); +end + +local admin_head = admin_repo:get(admin_repo.HEAD) + +if not admin_head then + gitano.log.fatal("Unable to find the HEAD of the administration repository. Cannot continue"); +end + +local config, msg = gitano.config.parse(admin_head) + +if not config then + gitano.log.critical("Unable to parse administration repository.") + gitano.log.critical(" * " .. (msg or "No error?")) + gitano.log.fatal("Cannot continue") +end + +-- Now, are we an admin? +if config.groups["gitano-admin"].filtered_members[username] then + -- Yep, so blithely reset logging level + gitano.log.set_level(start_log_level) +end + +if not config.global.silent then + -- Not silent, bump to chatty level automatically + gitano.log.bump_level(gitano.log.level.CHAT) +end + +local repo + +-- Find the command + +local cmd = gitano.command.get(parsed_cmdline[1]) + +if not cmd then + gitano.log.fatal("Unknown command: " .. parsed_cmdline[1]) +end + +if cmd.takes_repo and #parsed_cmdline > 1 then + -- Acquire the repository object for the target repo + local msg + repo, msg = gitano.repository.find(config, parsed_cmdline[2]) + if not repo then + gitano.log.critical("Unable to locate repository.") + gitano.log.critical(" * " .. (tostring(msg))) + gitano.log.fatal("Cannot continue") + end + + if repo.is_nascent then + gitano.log.info("Repository " .. repo.name .. " is nascent") + end +end + +-- Validate the commandline, massaging it as necessary. + +if not cmd.validate(config, repo, parsed_cmdline) then + gitano.log.fatal("Validation of command line failed") +end + +-- Construct our context ready for prep +local context = { + source = "ssh", + user = username, +} + +local action, reason = cmd.prep(config, repo, parsed_cmdline, context) + +if not action then + gitano.log.crit(reason) + gitano.log.fatal("Ruleset did not complete cleanly") +end + +if action == "allow" then + gitano.log.info(reason or "Ruleset permitted action") +else + gitano.log.critical(reason) + gitano.log.fatal("Ruleset denied action. Sorry.") +end + +gitano.log.debug("Welcome to " .. config.global.site_name) +gitano.log.debug("Running:") +for i = 1, #parsed_cmdline do + gitano.log.debug(" => " .. parsed_cmdline[i]) +end +gitano.log.debug("") +gitano.log.debug("On behalf of " .. username .. " using key " .. keytag) + +-- Set up some useful environment variables + +local env = { + ["GITANO_ROOT"] = repo_root, + ["GITANO_USER"] = username, + ["GITANO_KEYTAG"] = keytag, + ["GITANO_PROJECT"] = (repo or {}).name, + ["GITANO_SOURCE"] = "ssh", +} + +local how, why = cmd.run(config, repo, parsed_cmdline, env) + +if how ~= "exit" or why ~= 0 then + gitano.log.critical("Error running sub-process:") + gitano.log.critical(("%s (%d)\n"):format(how, why)) + gitano.log.fatal("Unable to continue") +end + +return 0 |