summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Ipsum <richard.ipsum@codethink.co.uk>2014-01-28 16:15:15 +0000
committerRichard Ipsum <richard.ipsum@codethink.co.uk>2014-02-18 16:39:03 +0000
commit37a1b130afee037dc2e3c156032c9e17792c7c11 (patch)
tree73147c1ed5dced1ca7e8f3351c8be31e4209eb1c
parent786286638d1f2bb300246400010adcd32bb047d3 (diff)
downloadgitano-37a1b130afee037dc2e3c156032c9e17792c7c11.tar.gz
Add auth.lua
We now perform auth in 2 cgis as well as gitano-auth, so auth needs to be in the library
-rw-r--r--lib/gitano.lua2
-rw-r--r--lib/gitano/auth.lua140
2 files changed, 142 insertions, 0 deletions
diff --git a/lib/gitano.lua b/lib/gitano.lua
index ad3cd7c..b57bd71 100644
--- a/lib/gitano.lua
+++ b/lib/gitano.lua
@@ -14,6 +14,7 @@ local actions = require 'gitano.actions'
local lace = require 'gitano.lace'
local markdown = require 'gitano.markdown'
local supple = require 'gitano.supple'
+local auth = require 'gitano.auth'
return {
util = util,
@@ -25,4 +26,5 @@ return {
lace = lace,
markdown = markdown,
supple = supple,
+ auth = auth
}
diff --git a/lib/gitano/auth.lua b/lib/gitano/auth.lua
new file mode 100644
index 0000000..8cdd8ec
--- /dev/null
+++ b/lib/gitano/auth.lua
@@ -0,0 +1,140 @@
+local config = require 'gitano.config'
+local command = require 'gitano.command'
+local log = require 'gitano.log'
+local repository = require 'gitano.repository'
+local util = require 'gitano.util'
+local gall = require 'gall'
+
+local function load_admin_conf(repo_root)
+ local admin_repo = gall.repository.new((repo_root or "") ..
+ "/gitano-admin.git")
+
+ if not admin_repo then
+ log.critical("Unable to locate administration repository.")
+ return nil
+ end
+
+ local admin_head = admin_repo:get(admin_repo.HEAD)
+
+ if not admin_head then
+ log.critical("Unable to find the HEAD of the administration repository.")
+ return nil
+ end
+
+ local admin_conf, msg = config.parse(admin_head)
+
+ if not admin_conf then
+ log.critical("Unable to parse administration repository.")
+ log.critical(" * " .. (msg or "No error?"))
+ return nil
+ end
+
+ return admin_conf
+end
+
+local function set_environment(repo_root, repo, context, transactionid)
+ local env = {
+ ["GITANO_ROOT"] = repo_root,
+ ["GITANO_USER"] = context.user,
+ ["GITANO_KEYTAG"] = context.keytag,
+ ["GITANO_PROJECT"] = (repo or {}).name or "",
+ ["GITANO_SOURCE"] = context.source,
+ ["GITANO_TRANSACTION_ID"] = transactionid,
+ }
+
+ for k, v in pairs(env) do
+ luxio.setenv(k, v)
+ end
+
+ return env
+end
+
+local function is_authorized(user, source, cmdline)
+ local repo_root = os.getenv("GITANO_ROOT")
+ local keytag = ""
+ local authorized = false
+
+ local start_log_level = log.get_level()
+ log.cap_level(log.level.INFO)
+ local transactionid = log.syslog.open()
+
+ config.repo_path(repo_root)
+
+ if not user or not cmdline then
+ return nil
+ end
+
+ local parsed_cmdline, warnings = util.parse_cmdline(cmdline)
+
+ if (#warnings > 0) then
+ log.error("Error parsing command");
+ return nil
+ end
+
+ local admin_conf = load_admin_conf(repo_root)
+ if admin_conf == nil then
+ log.fatal("Couldn't load a config from the admin repository")
+ end
+
+ if admin_conf.groups["gitano-admin"].filtered_members[user] then
+ log.set_level(start_log_level)
+ end
+
+ if not admin_conf.global.silent then
+ log.bump_level(log.level.CHAT)
+ end
+
+ ip = os.getenv("REMOTE_ADDR") or "unknown ip"
+ log.syslog.info("Client connected from", ip, "as", user,
+ "(" .. keytag .. ")", "Executing command:", cmdline)
+
+ local cmd = command.get(parsed_cmdline[1])
+
+ if not cmd then
+ log.critical("Unknown command: " .. parsed_cmdline[1])
+ return nil
+ end
+
+ local repo
+ if cmd.takes_repo and #parsed_cmdline > 1 then
+ -- Acquire the repository object for the target repo
+ local msg
+ repo, msg = repository.find(admin_conf, parsed_cmdline[2])
+
+ if not repo then
+ log.critical("Unable to locate repository.")
+ log.critical(" * " .. (tostring(msg) or "No error"))
+ return nil
+ end
+ end
+
+ if not cmd.validate(admin_conf, repo, parsed_cmdline) then
+ log.critical("Validation of command line failed")
+ return nil
+ end
+
+ local context = {source = source, user = user, keytag = keytag}
+ local action, reason = cmd.prep(admin_conf, repo, parsed_cmdline, context)
+
+ if not action then
+ log.critical(reason)
+ log.critical("Ruleset did not complete cleanly")
+ return nil
+ end
+
+ local env
+ if action == "allow" then
+ log.info(reason or "Ruleset permitted action")
+ authorized = true
+ env = set_environment(repo_root, repo, context, transactionid)
+ else
+ log.critical(reason)
+ log.critical("Ruleset denied action. Sorry.")
+ end
+
+ return authorized, cmd, parsed_cmdline, admin_conf, env
+end
+
+return {
+ is_authorized = is_authorized
+}