github_webhook 1.1.1 → 1.4.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 +4 -4
- data/.github/workflows/ruby.yml +24 -0
- data/.ruby-version +1 -1
- data/Appraisals +4 -0
- data/README.md +12 -4
- data/github_webhook.gemspec +2 -4
- data/lib/github_webhook/processor.rb +26 -19
- data/lib/github_webhook/version.rb +1 -1
- data/spec/github_webhook/processor_spec.rb +27 -11
- metadata +11 -40
- data/.travis.yml +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ec22b9a09fcb0d2833a46cffacf39ac9703b33fd0b909bfee2258f4191fdfc21
|
4
|
+
data.tar.gz: 0f0fc361b3f1ccccb93dc66baf1b75d3ebc1f34fa3ef6022a0598dd6abc20c1b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4292322d0e533e85de5fdedf0c67efe57847114beda60ba710a3fe191d9a59ad3c61fe8ead9c68272ba8067b53f709a10980059c6cb4a37f3898a6bc6b0b1f3a
|
7
|
+
data.tar.gz: 767ce312e69c381ac91cc6bd4c9cf913b1297ca9d4ee990f38cf8e55f306c8607421dcaf1b0ab9941da41003f20674346512c53595d5d61c6a9866cdb6f5a559
|
@@ -0,0 +1,24 @@
|
|
1
|
+
name: Ruby
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ master ]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
build:
|
11
|
+
|
12
|
+
runs-on: ubuntu-latest
|
13
|
+
|
14
|
+
steps:
|
15
|
+
- uses: actions/checkout@v2
|
16
|
+
- name: Set up Ruby 2.7
|
17
|
+
uses: actions/setup-ruby@v1
|
18
|
+
with:
|
19
|
+
ruby-version: 2.7.x
|
20
|
+
- name: Build and test with Rake
|
21
|
+
run: |
|
22
|
+
gem install bundler
|
23
|
+
bundle install --jobs 4 --retry 3
|
24
|
+
bundle exec rake
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.4
|
1
|
+
2.7.4
|
data/Appraisals
CHANGED
data/README.md
CHANGED
@@ -1,19 +1,27 @@
|
|
1
|
-
|
2
|
-
[](https://codeclimate.com/github/ssaunier/github_webhook)
|
1
|
+
|
3
2
|
[](http://badge.fury.io/rb/github_webhook)
|
4
3
|
|
5
4
|
|
6
|
-
#
|
5
|
+
# Github Webhook for Rails
|
7
6
|
|
8
7
|
This gem will help you to quickly setup a route in your Rails application which listens
|
9
8
|
to a [GitHub webhook](https://developer.github.com/webhooks/)
|
10
9
|
|
10
|
+
## Alternatives
|
11
|
+
|
12
|
+
If you want to use this logic outside of Rails, you should consider the following gems (cf [#19](https://github.com/ssaunier/github_webhook/issues/19)):
|
13
|
+
|
14
|
+
- [`sinatra-github_webhooks`](https://github.com/chrismytton/sinatra-github_webhooks)
|
15
|
+
- [`rack-github_webhooks`](https://github.com/chrismytton/rack-github_webhooks)
|
16
|
+
|
17
|
+
If you are on Rails, please read on!
|
18
|
+
|
11
19
|
## Installation
|
12
20
|
|
13
21
|
Add this line to your application's Gemfile:
|
14
22
|
|
15
23
|
```ruby
|
16
|
-
gem 'github_webhook', '~> 1.
|
24
|
+
gem 'github_webhook', '~> 1.4'
|
17
25
|
```
|
18
26
|
|
19
27
|
And then execute:
|
data/github_webhook.gemspec
CHANGED
@@ -22,9 +22,7 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_dependency "activesupport", ">= 4"
|
23
23
|
spec.add_dependency "railties", ">= 4"
|
24
24
|
|
25
|
-
spec.add_development_dependency "
|
26
|
-
spec.add_development_dependency "
|
27
|
-
spec.add_development_dependency "rspec", "~> 2.14"
|
28
|
-
spec.add_development_dependency "codeclimate-test-reporter", "~> 1.0"
|
25
|
+
spec.add_development_dependency "rake", "~> 12.3"
|
26
|
+
spec.add_development_dependency "rspec", "~> 3.9"
|
29
27
|
spec.add_development_dependency "appraisal"
|
30
28
|
end
|
@@ -1,44 +1,44 @@
|
|
1
1
|
module GithubWebhook::Processor
|
2
2
|
extend ActiveSupport::Concern
|
3
|
+
require 'abstract_controller'
|
3
4
|
|
4
5
|
included do
|
5
6
|
before_action :authenticate_github_request!, only: :create
|
6
7
|
before_action :check_github_event!, only: :create
|
7
8
|
end
|
8
9
|
|
9
|
-
class SignatureError < StandardError; end
|
10
|
-
class UnspecifiedWebhookSecretError < StandardError; end
|
11
|
-
class UnsupportedGithubEventError < StandardError; end
|
12
|
-
class UnsupportedContentTypeError < StandardError; end
|
13
|
-
|
14
10
|
# To fetch list from https://developer.github.com/v3/activity/events/types
|
15
11
|
# run this little JS code in the console:
|
16
|
-
#
|
12
|
+
# document.querySelectorAll('.list-style-none li.lh-condensed a').forEach(e => console.log(e.text))
|
17
13
|
GITHUB_EVENTS = %w(
|
18
14
|
check_run
|
19
15
|
check_suite
|
16
|
+
code_scanning_alert
|
20
17
|
commit_comment
|
18
|
+
content_reference
|
21
19
|
create
|
22
20
|
delete
|
21
|
+
deploy_key
|
23
22
|
deployment
|
24
23
|
deployment_status
|
25
|
-
|
26
|
-
|
24
|
+
discussion
|
25
|
+
discussion_comment
|
27
26
|
fork
|
28
|
-
fork_apply
|
29
27
|
github_app_authorization
|
30
|
-
gist
|
31
28
|
gollum
|
32
29
|
installation
|
33
30
|
installation_repositories
|
34
31
|
issue_comment
|
35
32
|
issues
|
36
33
|
label
|
34
|
+
marketplace_purchase
|
37
35
|
member
|
38
36
|
membership
|
37
|
+
meta
|
39
38
|
milestone
|
40
39
|
organization
|
41
40
|
org_block
|
41
|
+
package
|
42
42
|
page_build
|
43
43
|
ping
|
44
44
|
project_card
|
@@ -50,13 +50,20 @@ module GithubWebhook::Processor
|
|
50
50
|
pull_request_review_comment
|
51
51
|
push
|
52
52
|
release
|
53
|
+
repository_dispatch
|
53
54
|
repository
|
54
55
|
repository_import
|
55
56
|
repository_vulnerability_alert
|
57
|
+
secret_scanning_alert
|
58
|
+
security_advisory
|
59
|
+
sponsorship
|
60
|
+
star
|
56
61
|
status
|
57
62
|
team
|
58
63
|
team_add
|
59
64
|
watch
|
65
|
+
workflow_dispatch
|
66
|
+
workflow_run
|
60
67
|
)
|
61
68
|
|
62
69
|
def create
|
@@ -64,7 +71,7 @@ module GithubWebhook::Processor
|
|
64
71
|
self.send event_method, json_body
|
65
72
|
head(:ok)
|
66
73
|
else
|
67
|
-
raise
|
74
|
+
raise AbstractController::ActionNotFound.new("GithubWebhooksController##{event_method} not implemented")
|
68
75
|
end
|
69
76
|
end
|
70
77
|
|
@@ -75,23 +82,23 @@ module GithubWebhook::Processor
|
|
75
82
|
|
76
83
|
private
|
77
84
|
|
78
|
-
HMAC_DIGEST = OpenSSL::Digest.new('
|
85
|
+
HMAC_DIGEST = OpenSSL::Digest.new('sha256')
|
79
86
|
|
80
87
|
def authenticate_github_request!
|
81
|
-
raise
|
88
|
+
raise AbstractController::ActionNotFound.new unless respond_to?(:webhook_secret, true)
|
82
89
|
secret = webhook_secret(json_body)
|
83
90
|
|
84
|
-
expected_signature = "
|
85
|
-
|
91
|
+
expected_signature = "sha256=#{OpenSSL::HMAC.hexdigest(HMAC_DIGEST, secret, request_body)}"
|
92
|
+
unless ActiveSupport::SecurityUtils.secure_compare(signature_header, expected_signature)
|
86
93
|
GithubWebhook.logger && GithubWebhook.logger.warn("[GithubWebhook::Processor] signature "\
|
87
94
|
"invalid, actual: #{signature_header}, expected: #{expected_signature}")
|
88
|
-
raise
|
95
|
+
raise AbstractController::ActionNotFound
|
89
96
|
end
|
90
97
|
end
|
91
98
|
|
92
99
|
def check_github_event!
|
93
100
|
unless GITHUB_EVENTS.include?(request.headers['X-GitHub-Event'])
|
94
|
-
raise
|
101
|
+
raise AbstractController::ActionNotFound.new("#{request.headers['X-GitHub-Event']} is not a whitelisted GitHub event. See https://developer.github.com/v3/activity/events/types/")
|
95
102
|
end
|
96
103
|
end
|
97
104
|
|
@@ -112,7 +119,7 @@ module GithubWebhook::Processor
|
|
112
119
|
when 'application/json'
|
113
120
|
payload = request_body
|
114
121
|
else
|
115
|
-
raise
|
122
|
+
raise AbstractController::ActionNotFound.new(
|
116
123
|
"Content-Type #{content_type} is not supported. Use 'application/x-www-form-urlencoded' or 'application/json")
|
117
124
|
end
|
118
125
|
ActiveSupport::HashWithIndifferentAccess.new(JSON.load(payload))
|
@@ -120,7 +127,7 @@ module GithubWebhook::Processor
|
|
120
127
|
end
|
121
128
|
|
122
129
|
def signature_header
|
123
|
-
@signature_header ||= request.headers['X-Hub-Signature']
|
130
|
+
@signature_header ||= request.headers['X-Hub-Signature-256'] || ''
|
124
131
|
end
|
125
132
|
|
126
133
|
def event_method
|
@@ -53,9 +53,9 @@ module GithubWebhook
|
|
53
53
|
context 'when #webhook_secret is not defined' do
|
54
54
|
let(:controller_class) { ControllerWithoutSecret }
|
55
55
|
|
56
|
-
it "raises a
|
56
|
+
it "raises a AbstractController::ActionNotFound" do
|
57
57
|
expect { controller.send :authenticate_github_request! }
|
58
|
-
.to raise_error(
|
58
|
+
.to raise_error(AbstractController::ActionNotFound)
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
@@ -65,7 +65,7 @@ module GithubWebhook
|
|
65
65
|
it "calls the #push method in controller" do
|
66
66
|
expect(controller).to receive(:github_push)
|
67
67
|
controller.request.body = StringIO.new({ :foo => "bar" }.to_json.to_s)
|
68
|
-
controller.request.headers['X-Hub-Signature'] = "
|
68
|
+
controller.request.headers['X-Hub-Signature-256'] = "sha256=3f3ab3986b656abb17af3eb1443ed6c08ef8fff9fea83915909d1b421aec89be"
|
69
69
|
controller.request.headers['X-GitHub-Event'] = 'push'
|
70
70
|
controller.request.headers['Content-Type'] = 'application/json'
|
71
71
|
controller.send :authenticate_github_request! # Manually as we don't have the before_filter logic in our Mock object
|
@@ -75,7 +75,7 @@ module GithubWebhook
|
|
75
75
|
|
76
76
|
it "calls the #push method in controller (json)" do
|
77
77
|
controller.request.body = StringIO.new({ :foo => "bar" }.to_json.to_s)
|
78
|
-
controller.request.headers['X-Hub-Signature'] = "
|
78
|
+
controller.request.headers['X-Hub-Signature-256'] = "sha256=3f3ab3986b656abb17af3eb1443ed6c08ef8fff9fea83915909d1b421aec89be"
|
79
79
|
controller.request.headers['X-GitHub-Event'] = 'push'
|
80
80
|
controller.request.headers['Content-Type'] = 'application/json'
|
81
81
|
controller.send :authenticate_github_request! # Manually as we don't have the before_action logic in our Mock object
|
@@ -86,7 +86,7 @@ module GithubWebhook
|
|
86
86
|
it "calls the #push method (x-www-form-urlencoded encoded)" do
|
87
87
|
body = "payload=" + CGI::escape({ :foo => "bar" }.to_json.to_s)
|
88
88
|
controller.request.body = StringIO.new(body)
|
89
|
-
controller.request.headers['X-Hub-Signature'] = "
|
89
|
+
controller.request.headers['X-Hub-Signature-256'] = "sha256=cefe60b775fcb22483ceece8f20be4869868a20fb4aa79829e53c1de61b99d01"
|
90
90
|
controller.request.headers['X-GitHub-Event'] = 'push'
|
91
91
|
controller.request.headers['Content-Type'] = 'application/x-www-form-urlencoded'
|
92
92
|
controller.send :authenticate_github_request! # Manually as we don't have the before_action logic in our Mock object
|
@@ -96,30 +96,46 @@ module GithubWebhook
|
|
96
96
|
|
97
97
|
it "raises an error when signature does not match" do
|
98
98
|
controller.request.body = StringIO.new({ :foo => "bar" }.to_json.to_s)
|
99
|
-
controller.request.headers['X-Hub-Signature'] = "
|
99
|
+
controller.request.headers['X-Hub-Signature-256'] = "sha256=FOOBAR"
|
100
100
|
controller.request.headers['X-GitHub-Event'] = 'push'
|
101
101
|
controller.request.headers['Content-Type'] = 'application/json'
|
102
|
-
expect { controller.send :authenticate_github_request! }.to raise_error(
|
102
|
+
expect { controller.send :authenticate_github_request! }.to raise_error(AbstractController::ActionNotFound)
|
103
103
|
end
|
104
104
|
|
105
105
|
it "raises an error when the github event method is not implemented" do
|
106
106
|
controller.request.headers['X-GitHub-Event'] = 'deployment'
|
107
107
|
controller.request.headers['Content-Type'] = 'application/json'
|
108
|
-
expect { controller.create }.to raise_error(
|
108
|
+
expect { controller.create }.to raise_error(
|
109
|
+
AbstractController::ActionNotFound,
|
110
|
+
"GithubWebhooksController#github_deployment not implemented",
|
111
|
+
)
|
109
112
|
end
|
110
113
|
|
111
114
|
it "raises an error when the github event is not in the whitelist" do
|
112
115
|
controller.request.headers['X-GitHub-Event'] = 'fake_event'
|
113
116
|
controller.request.headers['Content-Type'] = 'application/json'
|
114
|
-
expect { controller.send :check_github_event! }.to raise_error(
|
117
|
+
expect { controller.send :check_github_event! }.to raise_error(
|
118
|
+
AbstractController::ActionNotFound,
|
119
|
+
"fake_event is not a whitelisted GitHub event. See https://developer.github.com/v3/activity/events/types/",
|
120
|
+
)
|
115
121
|
end
|
116
122
|
|
117
123
|
it "raises an error when the content type is not correct" do
|
118
124
|
controller.request.body = StringIO.new({ :foo => "bar" }.to_json.to_s)
|
119
|
-
controller.request.headers['X-Hub-Signature'] = "
|
125
|
+
controller.request.headers['X-Hub-Signature-256'] = "sha256=3f3ab3986b656abb17af3eb1443ed6c08ef8fff9fea83915909d1b421aec89be"
|
120
126
|
controller.request.headers['X-GitHub-Event'] = 'ping'
|
121
127
|
controller.request.headers['Content-Type'] = 'application/xml'
|
122
|
-
expect { controller.send :authenticate_github_request! }.to raise_error(
|
128
|
+
expect { controller.send :authenticate_github_request! }.to raise_error(
|
129
|
+
AbstractController::ActionNotFound,
|
130
|
+
"Content-Type application/xml is not supported. Use 'application/x-www-form-urlencoded' or 'application/json",
|
131
|
+
)
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'raises SignatureError when the X-Hub-Signature header is missing' do
|
135
|
+
controller.request.body = StringIO.new('{}')
|
136
|
+
controller.request.headers['Content-Type'] = 'application/json'
|
137
|
+
controller.request.headers['X-GitHub-Event'] = 'ping'
|
138
|
+
expect { controller.send :authenticate_github_request! }.to raise_error(AbstractController::ActionNotFound)
|
123
139
|
end
|
124
140
|
end
|
125
141
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: github_webhook
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sebastien Saunier
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-12-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -52,62 +52,34 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '4'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: bundler
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '1.5'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '1.5'
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
56
|
name: rake
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
72
58
|
requirements:
|
73
59
|
- - "~>"
|
74
60
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
61
|
+
version: '12.3'
|
76
62
|
type: :development
|
77
63
|
prerelease: false
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
79
65
|
requirements:
|
80
66
|
- - "~>"
|
81
67
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
68
|
+
version: '12.3'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
70
|
name: rspec
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
86
72
|
requirements:
|
87
73
|
- - "~>"
|
88
74
|
- !ruby/object:Gem::Version
|
89
|
-
version: '
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - "~>"
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '2.14'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: codeclimate-test-reporter
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - "~>"
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '1.0'
|
75
|
+
version: '3.9'
|
104
76
|
type: :development
|
105
77
|
prerelease: false
|
106
78
|
version_requirements: !ruby/object:Gem::Requirement
|
107
79
|
requirements:
|
108
80
|
- - "~>"
|
109
81
|
- !ruby/object:Gem::Version
|
110
|
-
version: '
|
82
|
+
version: '3.9'
|
111
83
|
- !ruby/object:Gem::Dependency
|
112
84
|
name: appraisal
|
113
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -129,9 +101,9 @@ executables: []
|
|
129
101
|
extensions: []
|
130
102
|
extra_rdoc_files: []
|
131
103
|
files:
|
104
|
+
- ".github/workflows/ruby.yml"
|
132
105
|
- ".gitignore"
|
133
106
|
- ".ruby-version"
|
134
|
-
- ".travis.yml"
|
135
107
|
- Appraisals
|
136
108
|
- Gemfile
|
137
109
|
- LICENSE.txt
|
@@ -151,7 +123,7 @@ homepage: https://github.com/ssaunier/github_webhook
|
|
151
123
|
licenses:
|
152
124
|
- MIT
|
153
125
|
metadata: {}
|
154
|
-
post_install_message:
|
126
|
+
post_install_message:
|
155
127
|
rdoc_options: []
|
156
128
|
require_paths:
|
157
129
|
- lib
|
@@ -166,9 +138,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
166
138
|
- !ruby/object:Gem::Version
|
167
139
|
version: '0'
|
168
140
|
requirements: []
|
169
|
-
|
170
|
-
|
171
|
-
signing_key:
|
141
|
+
rubygems_version: 3.1.6
|
142
|
+
signing_key:
|
172
143
|
specification_version: 4
|
173
144
|
summary: Process GitHub Webhooks in your Rails app (Controller mixin)
|
174
145
|
test_files:
|
data/.travis.yml
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
rvm:
|
3
|
-
- 2.4.2
|
4
|
-
- 2.3.5
|
5
|
-
- 2.2.8
|
6
|
-
gemfile:
|
7
|
-
- gemfiles/rails_4.2.gemfile
|
8
|
-
- gemfiles/rails_5.0.gemfile
|
9
|
-
- gemfiles/rails_5.1.gemfile
|
10
|
-
addons:
|
11
|
-
code_climate:
|
12
|
-
repo_token: 50425d682162d68af0b65bd9e5160da8337d2159fc3ebc00d2a5b14386548ac5
|
13
|
-
after_success:
|
14
|
-
- bundle exec codeclimate-test-reporter
|