github-web-hooks-receiver 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.travis.yml +8 -0
- data/Gemfile +3 -0
- data/README.md +212 -0
- data/Rakefile +23 -0
- data/config.ru +52 -0
- data/config.yaml.example +20 -0
- data/github-web-hooks-receiver.gemspec +28 -0
- data/lib/github-web-hooks-receiver.rb +29 -0
- data/lib/github-web-hooks-receiver/app.rb +239 -0
- data/lib/github-web-hooks-receiver/base.rb +98 -0
- data/lib/github-web-hooks-receiver/path-resolver.rb +31 -0
- data/lib/github-web-hooks-receiver/payload.rb +56 -0
- data/lib/github-web-hooks-receiver/repository.rb +192 -0
- data/lib/github-web-hooks-receiver/version.rb +18 -0
- data/license/GPL-3.txt +674 -0
- data/test/fixtures/config-multi-site.yaml +75 -0
- data/test/fixtures/mock-commit-email.rb +22 -0
- data/test/fixtures/stub-git.rb +5 -0
- data/test/github-web-hooks-receiver-test-utils.rb +50 -0
- data/test/multi-site-receiver-test.rb +345 -0
- data/test/receiver-config-test.rb +240 -0
- data/test/receiver-test.rb +386 -0
- data/test/run-test.rb +35 -0
- data/test/test-unit.yml +1 -0
- metadata +164 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: de99b9c01f899326fd8b4cf3422244ab1afbe6bc
|
4
|
+
data.tar.gz: 0638ab1bc10af285fce9e117074df11959e02975
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9e1ef74e2f4d9d411c7d69e4e9cb87b56c5396db505534b7cd3f51b85e31778255deaea5a6a6dadd90d0d4437b84c6214980b6557371067ffa7b5cea8938d94b
|
7
|
+
data.tar.gz: fd4b1e4779938c54b116d4d7a1ccddbf77699c0f4ec97bf61747578dced26904a7622394fa12be39d2373010e8dddb3d27f23451409d362c0d52b9bfc9f08147
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,212 @@
|
|
1
|
+
[](https://travis-ci.org/clear-code/github-web-hooks-receiver)
|
2
|
+
|
3
|
+
# GitHub Web hooks receiver
|
4
|
+
|
5
|
+
This is a Rack based web application that can process POST request from GitHub, GitLab and GHE.
|
6
|
+
|
7
|
+
## Set up
|
8
|
+
|
9
|
+
Prepare following files.
|
10
|
+
|
11
|
+
/home/github-web-hooks-receiver/github-web-hooks-receiver/Gemfile:
|
12
|
+
```
|
13
|
+
source "https://rubygems.org"
|
14
|
+
gem "github-web-hooks-receiver"
|
15
|
+
# gem "unicorn" # Enable this line if you use Unicorn.
|
16
|
+
# gem "passenger" # Enable this line if you use latest Passenger.
|
17
|
+
```
|
18
|
+
|
19
|
+
/home/github-web-hooks-receiver/github-web-hooks-receiver/config.ru:
|
20
|
+
```ruby
|
21
|
+
require "yaml"
|
22
|
+
require "pathname"
|
23
|
+
require "github-web-hooks-receiver"
|
24
|
+
|
25
|
+
use Rack::CommonLogger
|
26
|
+
use Rack::Runtime
|
27
|
+
use Rack::ContentLength
|
28
|
+
|
29
|
+
base_dir = Pathname(__FILE__).dirname
|
30
|
+
config_file = base_dir + "config.yaml"
|
31
|
+
|
32
|
+
options = YAML.load_file(config_file.to_s)
|
33
|
+
|
34
|
+
map "/post-receiver/" do
|
35
|
+
run GitHubWebHooksReceiver::App.new(options)
|
36
|
+
end
|
37
|
+
```
|
38
|
+
|
39
|
+
/home/github-web-hooks-receiver/github-web-hooks-receiver/config.yaml:
|
40
|
+
```
|
41
|
+
to: receiver@example.com
|
42
|
+
sender: sender@example.com
|
43
|
+
add_html: true
|
44
|
+
owners:
|
45
|
+
groonga:
|
46
|
+
to: groonga-commit@lists.sourceforge.jp
|
47
|
+
```
|
48
|
+
|
49
|
+
### Apache + Passenger
|
50
|
+
|
51
|
+
On Debian GNU/Linux wheezy.
|
52
|
+
|
53
|
+
See also [Phusion Passenger users guide, Apache version](https://www.phusionpassenger.com/documentation/Users%20guide%20Apache.html).
|
54
|
+
|
55
|
+
Install Passenger or write `gem "passenger"` in your Gemfile.
|
56
|
+
|
57
|
+
```
|
58
|
+
$ sudo apt-get install -y ruby-passenger
|
59
|
+
```
|
60
|
+
|
61
|
+
Install gems.
|
62
|
+
|
63
|
+
```
|
64
|
+
$ sudo -u github-web-hooks-receiver -H bundle install --path vendor/bundle
|
65
|
+
```
|
66
|
+
|
67
|
+
Prepare following files.
|
68
|
+
|
69
|
+
/etc/apache2/mods-available.conf:
|
70
|
+
```
|
71
|
+
PassengerRoot /path/to/passenger-x.x.x
|
72
|
+
PassengerRuby /path/to/ruby
|
73
|
+
|
74
|
+
PassengerMaxRequests 100
|
75
|
+
```
|
76
|
+
|
77
|
+
/etc/apache2/mods-available.load:
|
78
|
+
```
|
79
|
+
LoadModule passenger_module /path/to/mod_passenger.so
|
80
|
+
```
|
81
|
+
|
82
|
+
/etc/apache2/sites-available/github-web-hooks-receiver:
|
83
|
+
```
|
84
|
+
<VirtualHost *:80>
|
85
|
+
ServerName github-web-hooks-receiver.example.com
|
86
|
+
DocumentRoot /home/github-web-hooks-receiver/github-web-hooks-receiver/public
|
87
|
+
<Directory /home/github-web-hooks-receiver/github-web-hooks-receiver/public>
|
88
|
+
AllowOverride all
|
89
|
+
Options -MultiViews
|
90
|
+
</Directory>
|
91
|
+
|
92
|
+
ErrorLog ${APACHE_LOG_DIR}/github-web-hooks-receiver_error.log
|
93
|
+
CustomLog ${APACHE_LOG_DIR}/github-web-hooks-receiver_access.log combined
|
94
|
+
|
95
|
+
AllowEncodedSlashes On
|
96
|
+
AcceptPathInfo On
|
97
|
+
</VirtualHost>
|
98
|
+
```
|
99
|
+
|
100
|
+
Enable the module.
|
101
|
+
|
102
|
+
```
|
103
|
+
$ sudo a2enmod passenger
|
104
|
+
```
|
105
|
+
|
106
|
+
Enable the virtual host.
|
107
|
+
|
108
|
+
```
|
109
|
+
$ sudo a2ensite github-web-hooks-receiver
|
110
|
+
```
|
111
|
+
|
112
|
+
Restart web server.
|
113
|
+
|
114
|
+
```
|
115
|
+
$ sudo service apache2 restart
|
116
|
+
```
|
117
|
+
|
118
|
+
### Nginx + Unicorn
|
119
|
+
|
120
|
+
Prepare following files.
|
121
|
+
|
122
|
+
/etc/nginx/sites-enabled/github-web-hooks-receiver:
|
123
|
+
```
|
124
|
+
upstream github-web-hooks-receiver {
|
125
|
+
server unix:/tmp/unicorn-github-web-hooks-receiver.sock;
|
126
|
+
}
|
127
|
+
|
128
|
+
server {
|
129
|
+
listen 80;
|
130
|
+
server_name github-web-hooks-receiver.example.com;
|
131
|
+
access_log /var/log/nginx/github-web-hooks-receiver.example.com-access.log combined;
|
132
|
+
|
133
|
+
root /srv/www/github-web-hooks-receiver;
|
134
|
+
index index.html;
|
135
|
+
|
136
|
+
proxy_set_header X-Real-IP $remote_addr;
|
137
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
138
|
+
proxy_set_header Host $http_host;
|
139
|
+
#proxy_redirect off;
|
140
|
+
|
141
|
+
location / {
|
142
|
+
root /home/github-web-hooks-receiver/github-web-hooks-receiver/public;
|
143
|
+
include maintenance;
|
144
|
+
if (-f $request_filename){
|
145
|
+
break;
|
146
|
+
}
|
147
|
+
if (!-f $request_filename){
|
148
|
+
proxy_pass http://github-web-hooks-receiver;
|
149
|
+
break;
|
150
|
+
}
|
151
|
+
}
|
152
|
+
}
|
153
|
+
```
|
154
|
+
|
155
|
+
/home/github-web-hooks-receiver/github-web-hooks-receiver/unicorn.conf:
|
156
|
+
```
|
157
|
+
# -*- ruby -*-
|
158
|
+
worker_processes 2
|
159
|
+
working_directory "/home/github-web-hooks-receiver/github-web-hooks-receiver"
|
160
|
+
listen '/tmp/unicorn-github-post-receiver.sock', :backlog => 1
|
161
|
+
timeout 120
|
162
|
+
pid 'tmp/pids/unicorn.pid'
|
163
|
+
preload_app true
|
164
|
+
stderr_path 'log/unicorn.log'
|
165
|
+
stdout_path "log/stdout.log"
|
166
|
+
user "github-web-hooks-receiver", "github-web-hooks-receiver"
|
167
|
+
```
|
168
|
+
|
169
|
+
/home/github-web-hooks-receiver/bin/github-web-hooks-receiver:
|
170
|
+
```
|
171
|
+
#! /bin/zsh
|
172
|
+
BASE_DIR=/home/github-web-hooks-receiver/github-web-hooks-receiver
|
173
|
+
export RACK_ENV=production
|
174
|
+
cd $BASE_DIR
|
175
|
+
rbenv version
|
176
|
+
|
177
|
+
command=$1
|
178
|
+
|
179
|
+
function start() {
|
180
|
+
mkdir -p $BASE_DIR/tmp/pids
|
181
|
+
mkdir -p $BASE_DIR/log
|
182
|
+
bundle exec unicorn -D -c unicorn.conf config.ru
|
183
|
+
}
|
184
|
+
|
185
|
+
function stop() {
|
186
|
+
kill $(cat $BASE_DIR/tmp/pids/unicorn.pid)
|
187
|
+
}
|
188
|
+
|
189
|
+
function restart() {
|
190
|
+
kill -USR2 $(cat $BASE_DIR/tmp/pids/unicorn.pid)
|
191
|
+
}
|
192
|
+
|
193
|
+
$command
|
194
|
+
```
|
195
|
+
|
196
|
+
Install gems.
|
197
|
+
|
198
|
+
```
|
199
|
+
$ sudo -u github-web-hooks-receiver -H bundle install --path vendor/bundle
|
200
|
+
```
|
201
|
+
|
202
|
+
Run the application.
|
203
|
+
|
204
|
+
```
|
205
|
+
$ sudo -u github-web-hooks-receiver -H ~github-web-hooks-receiver/bin/github-web-hooks-receiver start
|
206
|
+
```
|
207
|
+
|
208
|
+
## Configuration
|
209
|
+
|
210
|
+
You need to edit config.yaml to configure this web application.
|
211
|
+
See config.yaml.example and test codes.
|
212
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# Copyright (C) 2012-2013 Kouhei Sutou <kou@clear-code.com>
|
2
|
+
#
|
3
|
+
# This program is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
require "bundler/gem_tasks"
|
17
|
+
|
18
|
+
task :default => :test
|
19
|
+
|
20
|
+
desc "Run test"
|
21
|
+
task :test do
|
22
|
+
ruby("test/run-test.rb")
|
23
|
+
end
|
data/config.ru
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# -*- mode: ruby; coding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Copyright (C) 2010-2013 Kouhei Sutou <kou@clear-code.com>
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This program is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
13
|
+
# GNU General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU General Public License
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
|
18
|
+
require "yaml"
|
19
|
+
|
20
|
+
require "pathname"
|
21
|
+
|
22
|
+
base_dir = Pathname(__FILE__).dirname
|
23
|
+
lib_dir = base_dir + "lib"
|
24
|
+
|
25
|
+
racknga_base_dir = base_dir.parent.parent + "racknga"
|
26
|
+
racknga_lib_dir = racknga_base_dir + "lib"
|
27
|
+
|
28
|
+
$LOAD_PATH.unshift(racknga_lib_dir.to_s)
|
29
|
+
$LOAD_PATH.unshift(lib_dir.to_s)
|
30
|
+
|
31
|
+
require "github-web-hooks-receiver"
|
32
|
+
|
33
|
+
require "racknga/middleware/exception_notifier"
|
34
|
+
|
35
|
+
use Rack::CommonLogger
|
36
|
+
use Rack::Runtime
|
37
|
+
use Rack::ContentLength
|
38
|
+
|
39
|
+
config_file = base_dir + "config.yaml"
|
40
|
+
options = YAML.load_file(config_file.to_s)
|
41
|
+
notifier_options = options.dup
|
42
|
+
if options[:error_to]
|
43
|
+
notifier_options[:to] = options[:error_to]
|
44
|
+
end
|
45
|
+
notifier_options.merge!(options["exception_notifier"] || {})
|
46
|
+
notifiers = [Racknga::ExceptionMailNotifier.new(notifier_options)]
|
47
|
+
use Racknga::Middleware::ExceptionNotifier, :notifiers => notifiers
|
48
|
+
|
49
|
+
map "/post-receiver/" do
|
50
|
+
run GitHubWebHooksReceiver::App.new(options)
|
51
|
+
end
|
52
|
+
|
data/config.yaml.example
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
private_token: VERYSECRETTOKEN
|
2
|
+
gitlab_api_end_point: https://gitlab.example.com/api/v3
|
3
|
+
web_hooks:
|
4
|
+
- http://gh.example.com/post-receiver1
|
5
|
+
- http://gh.example.com/post-receiver2
|
6
|
+
- http://gh.example.com/post-receiver3
|
7
|
+
to: receiver@example.com
|
8
|
+
error_to: admin@example.com
|
9
|
+
exception_notifier:
|
10
|
+
subject_label: "[git-utils]"
|
11
|
+
sender: sender@example.com
|
12
|
+
add_html: true
|
13
|
+
owners:
|
14
|
+
ranguba:
|
15
|
+
to: groonga-commit@rubyforge.org
|
16
|
+
repositories:
|
17
|
+
examples:
|
18
|
+
to: null@example.com
|
19
|
+
groonga:
|
20
|
+
to: groonga-commit@lists.sourceforge.jp
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'github-web-hooks-receiver/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "github-web-hooks-receiver"
|
8
|
+
spec.version = GitHubWebHooksReceiver::VERSION
|
9
|
+
spec.authors = ["Kouhei Sutou", "Kenji Okimoto"]
|
10
|
+
spec.email = ["kou@clear-code.com", "okimoto@clear-code.com"]
|
11
|
+
spec.summary = %q{GitHub web hook receiver}
|
12
|
+
spec.description = %q{GitHub web hook receiver}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "GPL-3.0+"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_runtime_dependency "rack"
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler"
|
24
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
25
|
+
spec.add_development_dependency "test-unit"
|
26
|
+
spec.add_development_dependency "test-unit-rr"
|
27
|
+
spec.add_development_dependency "test-unit-capybara"
|
28
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Copyright (C) 2010-2013 Kouhei Sutou <kou@clear-code.com>
|
2
|
+
# Copyright (C) 2015 Kenji Okimoto <okimoto@clear-code.com>
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
require "fileutils"
|
18
|
+
require "webrick/httpstatus"
|
19
|
+
require "shellwords"
|
20
|
+
require "uri"
|
21
|
+
|
22
|
+
require "rubygems"
|
23
|
+
require "json"
|
24
|
+
|
25
|
+
module GitHubWebHooksReceiver
|
26
|
+
end
|
27
|
+
|
28
|
+
require "github-web-hooks-receiver/app"
|
29
|
+
require "github-web-hooks-receiver/version"
|
@@ -0,0 +1,239 @@
|
|
1
|
+
# Copyright (C) 2010-2013 Kouhei Sutou <kou@clear-code.com>
|
2
|
+
# Copyright (C) 2015 Kenji Okimoto <okimoto@clear-code.com>
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
require "github-web-hooks-receiver/base"
|
18
|
+
require "github-web-hooks-receiver/path-resolver"
|
19
|
+
require "github-web-hooks-receiver/payload"
|
20
|
+
require "github-web-hooks-receiver/repository"
|
21
|
+
|
22
|
+
module GitHubWebHooksReceiver
|
23
|
+
class App < Base
|
24
|
+
include PathResolver
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def process_payload(request, response, raw_payload)
|
29
|
+
metadata = {
|
30
|
+
"x-github-event" => github_event(request),
|
31
|
+
}
|
32
|
+
payload = Payload.new(raw_payload, metadata)
|
33
|
+
case payload.event_name
|
34
|
+
when "ping"
|
35
|
+
# Do nothing
|
36
|
+
when "push", nil # nil is for GitLab
|
37
|
+
process_push_payload(request, response, payload)
|
38
|
+
when "gollum"
|
39
|
+
process_gollum_payload(request, response, payload)
|
40
|
+
else
|
41
|
+
set_error_response(response,
|
42
|
+
:bad_request,
|
43
|
+
"Unsupported event: <#{payload.event_name}>")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def github_event(request)
|
48
|
+
request.env["HTTP_X_GITHUB_EVENT"]
|
49
|
+
end
|
50
|
+
|
51
|
+
def process_push_payload(request, response, payload)
|
52
|
+
repository = process_payload_repository(request, response, payload)
|
53
|
+
return if repository.nil?
|
54
|
+
change = process_push_parameters(request, response, payload)
|
55
|
+
return if change.nil?
|
56
|
+
repository.process(*change)
|
57
|
+
end
|
58
|
+
|
59
|
+
def process_gollum_payload(request, response, payload)
|
60
|
+
repository = process_payload_repository(request, response, payload)
|
61
|
+
return if repository.nil?
|
62
|
+
change = process_gollum_parameters(request, response, payload)
|
63
|
+
return if change.nil?
|
64
|
+
repository.process(*change)
|
65
|
+
end
|
66
|
+
|
67
|
+
def process_payload_repository(request, response, payload)
|
68
|
+
repository = payload["repository"]
|
69
|
+
if repository.nil?
|
70
|
+
set_error_response(response, :bad_request,
|
71
|
+
"repository information is missing")
|
72
|
+
return
|
73
|
+
end
|
74
|
+
|
75
|
+
unless repository.is_a?(Hash)
|
76
|
+
set_error_response(response, :bad_request,
|
77
|
+
"invalid repository information format: " +
|
78
|
+
"<#{repository.inspect}>")
|
79
|
+
return
|
80
|
+
end
|
81
|
+
|
82
|
+
repository_uri = repository["url"]
|
83
|
+
domain = extract_domain(repository_uri)
|
84
|
+
if domain.nil?
|
85
|
+
set_error_response(response, :bad_request,
|
86
|
+
"invalid repository URI: <#{repository.inspect}>")
|
87
|
+
return
|
88
|
+
end
|
89
|
+
|
90
|
+
repository_name = repository["name"]
|
91
|
+
if repository_name.nil?
|
92
|
+
set_error_response(response, :bad_request,
|
93
|
+
"repository name is missing: <#{repository.inspect}>")
|
94
|
+
return
|
95
|
+
end
|
96
|
+
|
97
|
+
owner_name = extract_owner_name(repository_uri, payload)
|
98
|
+
if owner_name.nil?
|
99
|
+
set_error_response(response, :bad_request,
|
100
|
+
"repository owner or owner name is missing: " +
|
101
|
+
"<#{repository.inspect}>")
|
102
|
+
return
|
103
|
+
end
|
104
|
+
|
105
|
+
options = repository_options(domain, owner_name, repository_name)
|
106
|
+
repository = repository_class.new(domain, owner_name, repository_name,
|
107
|
+
payload, options)
|
108
|
+
unless repository.target?
|
109
|
+
set_error_response(response, :forbidden,
|
110
|
+
"unacceptable repository: " +
|
111
|
+
"<#{owner_name.inspect}>:<#{repository_name.inspect}>")
|
112
|
+
return
|
113
|
+
end
|
114
|
+
|
115
|
+
repository
|
116
|
+
end
|
117
|
+
|
118
|
+
def extract_domain(repository_uri)
|
119
|
+
domain = nil
|
120
|
+
case repository_uri
|
121
|
+
when /\Agit@/
|
122
|
+
domain = repository_uri[/@(.+):/, 1]
|
123
|
+
when /\Ahttps:\/\//
|
124
|
+
domain = URI.parse(repository_uri).hostname
|
125
|
+
else
|
126
|
+
return
|
127
|
+
end
|
128
|
+
domain
|
129
|
+
end
|
130
|
+
|
131
|
+
def extract_owner_name(repository_uri, payload)
|
132
|
+
owner_name = nil
|
133
|
+
repository = payload["repository"]
|
134
|
+
if payload.gitlab?
|
135
|
+
case repository_uri
|
136
|
+
when /\Agit@/
|
137
|
+
owner_name = repository_uri[%r!git@.+:(.+)/.+(?:.git)?!, 1]
|
138
|
+
when /\Ahttps:\/\//
|
139
|
+
owner_name = URI.parse(repository_uri).path.sub(/\A\//, "")
|
140
|
+
else
|
141
|
+
return
|
142
|
+
end
|
143
|
+
else
|
144
|
+
owner = repository["owner"]
|
145
|
+
return if owner.nil?
|
146
|
+
|
147
|
+
owner_name = owner["name"] || owner["login"]
|
148
|
+
return if owner_name.nil?
|
149
|
+
end
|
150
|
+
owner_name
|
151
|
+
end
|
152
|
+
|
153
|
+
def process_push_parameters(request, response, payload)
|
154
|
+
before = payload["before"]
|
155
|
+
if before.nil?
|
156
|
+
set_error_response(response, :bad_request,
|
157
|
+
"before commit ID is missing")
|
158
|
+
return
|
159
|
+
end
|
160
|
+
|
161
|
+
after = payload["after"]
|
162
|
+
if after.nil?
|
163
|
+
set_error_response(response, :bad_request,
|
164
|
+
"after commit ID is missing")
|
165
|
+
return
|
166
|
+
end
|
167
|
+
|
168
|
+
reference = payload["ref"]
|
169
|
+
if reference.nil?
|
170
|
+
set_error_response(response, :bad_request,
|
171
|
+
"reference is missing")
|
172
|
+
return
|
173
|
+
end
|
174
|
+
|
175
|
+
[before, after, reference]
|
176
|
+
end
|
177
|
+
|
178
|
+
def process_gollum_parameters(request, response, payload)
|
179
|
+
pages = payload["pages"]
|
180
|
+
if pages.nil?
|
181
|
+
set_error_response(response, :bad_request,
|
182
|
+
"pages are missing")
|
183
|
+
return
|
184
|
+
end
|
185
|
+
if pages.empty?
|
186
|
+
set_error_response(response, :bad_request,
|
187
|
+
"no pages")
|
188
|
+
end
|
189
|
+
|
190
|
+
revisions = pages.collect do |page|
|
191
|
+
page["sha"]
|
192
|
+
end
|
193
|
+
|
194
|
+
if revisions.size == 1
|
195
|
+
after = revisions.first
|
196
|
+
before = "#{after}^"
|
197
|
+
else
|
198
|
+
before = revisions.first
|
199
|
+
after = revisions.last
|
200
|
+
end
|
201
|
+
|
202
|
+
reference = "refs/heads/master"
|
203
|
+
[before, after, reference]
|
204
|
+
end
|
205
|
+
|
206
|
+
def set_error_response(response, status_keyword, message)
|
207
|
+
response.status = status(status_keyword)
|
208
|
+
response["Content-Type"] = "text/plain"
|
209
|
+
response.write(message)
|
210
|
+
end
|
211
|
+
|
212
|
+
def repository_class
|
213
|
+
@options[:repository_class] || Repository
|
214
|
+
end
|
215
|
+
|
216
|
+
def repository_options(domain, owner_name, repository_name)
|
217
|
+
domain_options = (@options[:domains] || {})[domain] || {}
|
218
|
+
domain_options = symbolize_options(domain_options)
|
219
|
+
domain_owner_options = (domain_options[:owners] || {})[owner_name] || {}
|
220
|
+
domain_owner_options = symbolize_options(domain_owner_options)
|
221
|
+
domain_repository_options = (domain_owner_options[:repositories] || {})[repository_name] || {}
|
222
|
+
domain_repository_options = symbolize_options(domain_repository_options)
|
223
|
+
|
224
|
+
owner_options = (@options[:owners] || {})[owner_name] || {}
|
225
|
+
owner_options = symbolize_options(owner_options)
|
226
|
+
_repository_options = (owner_options[:repositories] || {})[repository_name] || {}
|
227
|
+
_repository_options = symbolize_options(_repository_options)
|
228
|
+
|
229
|
+
options = @options.merge(owner_options)
|
230
|
+
options = options.merge(owner_options)
|
231
|
+
options = options.merge(_repository_options)
|
232
|
+
|
233
|
+
options = options.merge(domain_options)
|
234
|
+
options = options.merge(domain_owner_options)
|
235
|
+
options = options.merge(domain_repository_options)
|
236
|
+
options
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|