diff options
author | Richard Ipsum <richard.ipsum@codethink.co.uk> | 2014-02-18 17:48:22 +0000 |
---|---|---|
committer | Richard Ipsum <richard.ipsum@codethink.co.uk> | 2014-02-18 17:48:22 +0000 |
commit | ad9c49d2969332638f3e5b37ff6720c574bc4fbb (patch) | |
tree | dd798ac31fca707c4f1199e8da393261947b8eb4 /bin | |
parent | 1df10596bc55e92cb2d8a73ed3c8e2ec8d246c40 (diff) | |
parent | 95ba6fb18fedf7d0b9ff66a8f344c94dfe4a0632 (diff) | |
download | gitano-baserock/master.tar.gz |
Merge branch 'baserock/richardipsum/http_v3' into baserock/masterbaserock/master
Reviewed-by:
Daniel Silverstone
Richard Maw
Diffstat (limited to 'bin')
-rwxr-xr-x | bin/gitano-command.cgi.in | 91 | ||||
-rw-r--r-- | bin/gitano-setup.in | 2 | ||||
-rwxr-xr-x | bin/gitano-smart-http.cgi.in | 76 |
3 files changed, 169 insertions, 0 deletions
diff --git a/bin/gitano-command.cgi.in b/bin/gitano-command.cgi.in new file mode 100755 index 0000000..bc280b2 --- /dev/null +++ b/bin/gitano-command.cgi.in @@ -0,0 +1,91 @@ +-- @@SHEBANG +-- -*- Lua -*- +-- command cgi +-- +-- Git (with) Augmented network operations -- User authentication wrapper +-- +-- Copyright 2014 Codethink Ltd +-- +-- + +-- @@GITANO_LUA_PATH + +local gitano = require "gitano" +local gall = require "gall" +local luxio = require "luxio" +local sio = require "luxio.simple" + +-- @@GITANO_BIN_PATH +-- @@GITANO_SHARE_PATH + +local stdout = sio.stdout + +function url_decode(str) + str = string.gsub (str, "+", " ") + str = string.gsub (str, "%%(%x%x)", + function(h) return string.char(tonumber(h,16)) end) + str = string.gsub (str, "\r\n", "\n") + return str +end + +function run_command(cmd, cmdline, parsed_cmdline, user, config, env) + 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 " .. user .. " using key " .. env["GITANO_KEYTAG"]) + + local how, why = cmd.run(config, repo, parsed_cmdline, env) + + if how ~= "exit" or why ~= 0 then + gitano.log.critical("Error running " .. parsed_cmdline[1] .. ": " .. how) + return why + else + gitano.log.syslog.info(cmdline, "completed successfully") + return 0 + end +end + +if os.getenv("QUERY_STRING") then + local query_string = url_decode(os.getenv("QUERY_STRING")) + local cmdline = query_string + + local _, e = string.find(query_string, "cmd=") + + if not e then + stdout:write("Status: 400 Bad request\r\n\r\n") + stdout:write("Malformed command line, format: ?cmd=arg0 arg1 ... argn\n") + return + end + + cmdline = string.sub(query_string, e + 1, #query_string) + + if cmdline == '' then + stdout:write("Status: 400 Bad request\r\n\r\n") + stdout:write("Malformed command line, format: ?cmd=arg0 arg1 ... argn\n") + return + end + + local user = os.getenv("REMOTE_USER") or "gitano/anonymous" + + gitano.log.buffer_output() + + local authorized, cmd, parsed_cmdline, config, env = + gitano.auth.is_authorized(user, "http", cmdline) + + if authorized then + local exit = run_command(cmd, cmdline, parsed_cmdline, user, config, env) + + stdout:write("Status: " .. (exit == 0 and "200 OK" or "400 Bad request") + .. "\r\n\r\n") + stdout:write(gitano.log.get_buffered_output() or "") + else + stdout:write("Status: 403 Forbidden\r\n\r\n") + stdout:write(gitano.log.get_buffered_output() or "") + end +else + stdout:write("Status: 400 Bad request\r\n\r\n") + stdout:write("Malformed command line, format: ?cmd=arg0 arg1 ... argn\n") +end diff --git a/bin/gitano-setup.in b/bin/gitano-setup.in index fbfa58a..61a3246 100644 --- a/bin/gitano-setup.in +++ b/bin/gitano-setup.in @@ -161,6 +161,7 @@ validate_name(ask_for("admin.keyname", "Key name for administrator", ask_for("site.name", "Site name", "a random Gitano instance") ask_for("log.prefix", "Site log prefix", "gitano") +ask_for("use.htpasswd", "Store passwords with htpasswd? (needed for http authentication)", "no") gitano.log.chat("Step 2: Gather required content") @@ -169,6 +170,7 @@ local completely_flat = {} local site_conf = clod.parse("") site_conf.settings["site_name"] = get "site.name" site_conf.settings["log.prefix"] = get "log.prefix" +site_conf.settings["use_htpasswd"] = get "use.htpasswd" completely_flat["site.conf"] = site_conf:serialise() -- Acquire the contents of the skeleton gitano-admin repository diff --git a/bin/gitano-smart-http.cgi.in b/bin/gitano-smart-http.cgi.in new file mode 100755 index 0000000..8fb0240 --- /dev/null +++ b/bin/gitano-smart-http.cgi.in @@ -0,0 +1,76 @@ +-- @@SHEBANG +-- -*- Lua -*- +-- gitano-smart-http +-- +-- Git (with) Augmented network operations -- User authentication wrapper +-- +-- Copyright 2014 Codethink Ltd +-- +-- + +-- @@GITANO_LUA_PATH + +local gitano = require "gitano" +local gall = require "gall" +local luxio = require "luxio" +local subprocess = require "luxio.subprocess" +local sio = require "luxio.simple" + +-- @@GITANO_BIN_PATH +-- @@GITANO_SHARE_PATH + +local stdout = sio.stdout + +function parse_get_request() + query_string = os.getenv("QUERY_STRING") + + if query_string then + command = string.gsub(query_string, "^service=", "") + repo = string.match(os.getenv("PATH_INFO"), '/(.+)/info/refs') + return command .. " '" .. repo .. "'" + end + + return nil +end + +function parse_post_request() + path_info = os.getenv("PATH_INFO") + + if path_info then + repo, command = string.match(path_info, "/(.+)/(.+)") + return command .. " '" .. repo .. "'" + end + + return nil +end + +function parse_request(request_method) + if request_method == "GET" then + return parse_get_request() + elseif request_method == "POST" then + return parse_post_request() + end +end + +request_method = os.getenv("REQUEST_METHOD") + +if request_method == "GET" or request_method == "POST" then + local user = os.getenv("REMOTE_USER") or "gitano/anonymous" + local cmdline = parse_request(request_method) + + if cmdline and gitano.auth.is_authorized(user, "http", cmdline) then + local proc = subprocess.spawn_simple({"git", "http-backend"}) + local exit_code + + _, exit_code = proc:wait() + + if exit_code ~= 0 then + stdout:write("Status: 500 Internal Server Error\r\n\r\n") + end + else + stdout:write("Status: 403 Forbidden\r\n\r\n") + end +else + stdout:write("Status: 405 Method Not Allowed\r\n") + stdout:write("Allow: GET, POST\r\n\r\n") +end |