1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
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
}
|