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
|
require 'net/http'
require 'openssl'
require 'json'
require_relative 'gitlab_config'
require_relative 'gitlab_logger'
require_relative 'gitlab_access'
class GitlabNet
def check_access(cmd, repo, actor, changes)
project_name = repo.gsub("'", "")
project_name = project_name.gsub(/\.git\Z/, "")
project_name = project_name.gsub(/\A\//, "")
changes = changes.join("\n") unless changes.kind_of?(String)
params = {
action: cmd,
changes: changes,
project: project_name,
}
if actor =~ /\Akey\-\d+\Z/
params.merge!(key_id: actor.gsub("key-", ""))
elsif actor =~ /\Auser\-\d+\Z/
params.merge!(user_id: actor.gsub("user-", ""))
end
url = "#{host}/allowed"
resp = post(url, params)
if resp.code == '200'
GitAccessStatus.create_from_json(resp.body)
else
GitAccessStatus.new(false, 'API is not accessible')
end
end
def discover(key)
key_id = key.gsub("key-", "")
resp = get("#{host}/discover?key_id=#{key_id}")
JSON.parse(resp.body) rescue nil
end
def broadcast_message
resp = get("#{host}/broadcast_message")
if resp.code == '200'
JSON.parse(resp.body) rescue nil
else
nil
end
end
def check
get("#{host}/check")
end
protected
def config
@config ||= GitlabConfig.new
end
def host
"#{config.gitlab_url}/api/v3/internal"
end
def http_client_for(url)
Net::HTTP.new(url.host, url.port).tap do |http|
if URI::HTTPS === url
http.use_ssl = true
http.cert_store = cert_store
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if config.http_settings['self_signed_cert']
end
end
end
def http_request_for(url, method = :get)
user = config.http_settings['user']
password = config.http_settings['password']
if method == :get
Net::HTTP::Get.new(url.request_uri).tap { |r| r.basic_auth(user, password) if user && password }
else
Net::HTTP::Post.new(url.request_uri).tap { |r| r.basic_auth(user, password) if user && password }
end
end
def get(url)
$logger.debug "Performing GET #{url}"
url = URI.parse(url)
http = http_client_for url
request = http_request_for url
request.set_form_data(secret_token: secret_token)
http.start { |http| http.request(request) }.tap do |resp|
if resp.code == "200"
$logger.debug { "Received response #{resp.code} => <#{resp.body}>." }
else
$logger.error { "API call <GET #{url}> failed: #{resp.code} => <#{resp.body}>." }
end
end
end
def post(url, params)
$logger.debug "Performing POST #{url}"
url = URI.parse(url)
http = http_client_for(url)
request = http_request_for(url, :post)
request.set_form_data(params.merge(secret_token: secret_token))
http.start { |http| http.request(request) }.tap do |resp|
if resp.code == "200"
$logger.debug { "Received response #{resp.code} => <#{resp.body}>." }
else
$logger.error { "API call <POST #{url}> failed: #{resp.code} => <#{resp.body}>." }
end
end
end
def cert_store
@cert_store ||= OpenSSL::X509::Store.new.tap do |store|
store.set_default_paths
if ca_file = config.http_settings['ca_file']
store.add_file(ca_file)
end
if ca_path = config.http_settings['ca_path']
store.add_path(ca_path)
end
end
end
def secret_token
@secret_token ||= File.read File.join(ROOT_PATH, '.gitlab_shell_secret')
end
end
|