summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Ipsum <richard.ipsum@codethink.co.uk>2014-01-08 16:46:43 +0000
committerRichard Ipsum <richard.ipsum@codethink.co.uk>2014-01-23 17:18:41 +0000
commit0d4a9b22594a3973b1d54a51d9c123671af5a503 (patch)
treec37c658d67f68fb08b66165bfd4cab9908d150fe
parent989779be747661660aad655befa2d77ad14a6430 (diff)
downloadgitano-0d4a9b22594a3973b1d54a51d9c123671af5a503.tar.gz
Add the seed of our cgi script
-rwxr-xr-xcgi/command.cgi204
1 files changed, 204 insertions, 0 deletions
diff --git a/cgi/command.cgi b/cgi/command.cgi
new file mode 100755
index 0000000..041d6ca
--- /dev/null
+++ b/cgi/command.cgi
@@ -0,0 +1,204 @@
+#!/usr/bin/lua5.1
+
+print "Content-type:text/plain\r\n\r\n"
+io.flush()
+os.execute("env")
+print "\n"
+
+local function run_command(user)
+ -- we may need to do some kind of input validation on the query string
+ local query_string = os.getenv("QUERY_STRING")
+
+ --local cmdline = query_string
+
+ local _, e = string.find(query_string, "cmd=")
+
+ local cmdline = string.sub(query_string, e + 1, #query_string) -- select command from query string
+
+ print("cmdline: " .. cmdline)
+ print("package.path: " .. package.path .. '\n')
+
+ local gitano = require "gitano"
+ local gall = require "gall"
+ local luxio = require "luxio"
+ local sio = require "luxio.simple"
+ local sp = require "luxio.subprocess"
+
+ gitano.config.lib_bin_path("/usr/lib/gitano/bin")
+ gitano.config.share_path("/usr/share/gitano")
+
+ -- local repo_root, username, keytag = "..."
+ -- fake this for now
+ local repo_root = "/home/git/repos"
+ local username = user
+ local keytag = "default"
+
+ gitano.config.repo_path(repo_root)
+
+ gitano.log.set_source("http")
+
+ local transactionid = gitano.log.syslog.open()
+
+ if cmdline:match("^[ \t\n]*$") then
+ gitano.log.fatal("cmdline: " .. cmdline)
+ 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 = gall.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
+
+
+ -- ip = string.match(luxio.getenv "SSH_CLIENT", "^[^ ]+") or ""
+
+ gitano.log.syslog.info("Client connected from", ip, "as", username,
+ "(" .. keytag .. ")", "Executing command:",
+ cmdline)
+
+ 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 = user,
+ keytag = keytag,
+ }
+
+ 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",
+ ["GITANO_TRANSACTION_ID"] = transactionid,
+ }
+
+ local how, why = cmd.run(config, repo, parsed_cmdline, env)
+
+ if how ~= "exit" or why ~= 0 then
+ gitano.log.critical("Error running sub-process:",
+ ("%s (%d)"):format(how, why))
+ gitano.log.fatal("Unable to continue")
+ else
+ gitano.log.syslog.info(cmdline, "completed successfully")
+ end
+
+ gitano.log.syslog.close()
+
+ print(gitano.log.get_stream())
+end
+
+local authenticated_user = os.getenv("REMOTE_USER")
+
+if authenticated_user then
+ run_command(authenticated_user)
+else
+ -- ask the browser to authenticate
+ print "Status:401 Unauthorized"
+ print "WWW-Authenticate: Basic realm=\"foorealm\"\r\n\r\n"
+end