summaryrefslogtreecommitdiff
path: root/bin/gitano-auth.in
diff options
context:
space:
mode:
Diffstat (limited to 'bin/gitano-auth.in')
-rw-r--r--bin/gitano-auth.in159
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