line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Plack::App::GitHub::WebHook; |
2
|
7
|
|
|
7
|
|
368000
|
use strict; |
|
7
|
|
|
|
|
14
|
|
|
7
|
|
|
|
|
188
|
|
3
|
7
|
|
|
7
|
|
44
|
use warnings; |
|
7
|
|
|
|
|
9
|
|
|
7
|
|
|
|
|
154
|
|
4
|
7
|
|
|
7
|
|
60
|
use v5.10; |
|
7
|
|
|
|
|
18
|
|
|
7
|
|
|
|
|
223
|
|
5
|
|
|
|
|
|
|
|
6
|
7
|
|
|
7
|
|
25
|
use parent 'Plack::Component'; |
|
7
|
|
|
|
|
9
|
|
|
7
|
|
|
|
|
36
|
|
7
|
7
|
|
|
7
|
|
32347
|
use Plack::Util::Accessor qw(hook events secret access safe); |
|
7
|
|
|
|
|
1378
|
|
|
7
|
|
|
|
|
45
|
|
8
|
7
|
|
|
7
|
|
3367
|
use Plack::Request; |
|
7
|
|
|
|
|
186407
|
|
|
7
|
|
|
|
|
199
|
|
9
|
7
|
|
|
7
|
|
3327
|
use Plack::Middleware::HTTPExceptions; |
|
7
|
|
|
|
|
26032
|
|
|
7
|
|
|
|
|
191
|
|
10
|
7
|
|
|
7
|
|
2996
|
use Plack::Middleware::Access; |
|
7
|
|
|
|
|
232084
|
|
|
7
|
|
|
|
|
246
|
|
11
|
7
|
|
|
7
|
|
64
|
use Carp qw(croak); |
|
7
|
|
|
|
|
14
|
|
|
7
|
|
|
|
|
384
|
|
12
|
7
|
|
|
7
|
|
4812
|
use JSON qw(decode_json); |
|
7
|
|
|
|
|
59138
|
|
|
7
|
|
|
|
|
32
|
|
13
|
7
|
|
|
7
|
|
971
|
use Scalar::Util qw(blessed); |
|
7
|
|
|
|
|
15
|
|
|
7
|
|
|
|
|
6087
|
|
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
our $VERSION = '0.8'; |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
our @GITHUB_IPS = ( |
18
|
|
|
|
|
|
|
allow => "204.232.175.64/27", |
19
|
|
|
|
|
|
|
allow => "192.30.252.0/22", |
20
|
|
|
|
|
|
|
); |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
sub github_webhook { |
23
|
16
|
|
|
16
|
0
|
21
|
my $hook = shift; |
24
|
16
|
100
|
66
|
|
|
138
|
if ( !ref $hook ) { |
|
|
100
|
50
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
25
|
4
|
|
|
|
|
16
|
my $class = Plack::Util::load_class($hook, 'GitHub::WebHook'); |
26
|
3
|
|
|
|
|
404
|
$class = $class->new; |
27
|
3
|
|
|
3
|
|
30
|
return sub { $class->call(@_) }; |
|
3
|
|
|
|
|
8
|
|
28
|
|
|
|
|
|
|
} elsif ( ref $hook eq 'HASH' ) { |
29
|
2
|
|
|
|
|
6
|
my ($class, $args) = each %$hook; |
30
|
2
|
|
|
|
|
7
|
$class = Plack::Util::load_class($class, 'GitHub::WebHook'); |
31
|
2
|
50
|
|
|
|
36
|
$class = $class->new( ref $args eq 'HASH' ? %$args : @$args ); |
32
|
2
|
|
|
2
|
|
18
|
return sub { $class->call(@_) }; |
|
2
|
|
|
|
|
5
|
|
33
|
|
|
|
|
|
|
} elsif ( blessed $hook and $hook->can('call') ) { |
34
|
1
|
|
|
2
|
|
5
|
return sub { $hook->call(@_) }; |
|
2
|
|
|
|
|
5
|
|
35
|
|
|
|
|
|
|
} elsif ( (ref $hook // '') ne 'CODE') { |
36
|
0
|
|
|
|
|
0
|
croak "hook must be a CODE or ARRAY of CODEs"; |
37
|
|
|
|
|
|
|
} |
38
|
9
|
|
|
|
|
36
|
$hook; |
39
|
|
|
|
|
|
|
} |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
sub to_app { |
42
|
29
|
|
|
29
|
1
|
69962
|
my $self = shift; |
43
|
|
|
|
|
|
|
|
44
|
29
|
100
|
50
|
|
|
94
|
my $hook = (ref $self->hook // '') eq 'ARRAY' |
|
|
|
100
|
|
|
|
|
45
|
|
|
|
|
|
|
? $self->hook : [ $self->hook // () ]; |
46
|
29
|
|
|
|
|
494
|
$self->hook([ map { github_webhook($_) } @$hook ]); |
|
16
|
|
|
|
|
33
|
|
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
my $app = Plack::Middleware::HTTPExceptions->wrap( |
49
|
25
|
|
|
25
|
|
17904
|
sub { $self->call_granted($_[0]) } |
50
|
28
|
|
|
|
|
464
|
); |
51
|
|
|
|
|
|
|
|
52
|
28
|
50
|
|
|
|
780
|
if ($self->secret) { |
53
|
0
|
|
|
|
|
0
|
require Plack::Middleware::HubSignature; |
54
|
0
|
|
|
|
|
0
|
$app = Plack::Middleware::HubSignature->wrap($app, |
55
|
|
|
|
|
|
|
secret => $self->secret |
56
|
|
|
|
|
|
|
); |
57
|
|
|
|
|
|
|
} |
58
|
|
|
|
|
|
|
|
59
|
28
|
100
|
|
|
|
158
|
$self->access('github') unless $self->access; |
60
|
28
|
100
|
|
|
|
128
|
$self->access([]) if $self->access eq 'all'; |
61
|
28
|
|
|
|
|
180
|
my @rules = (@GITHUB_IPS, 'deny' => 'all'); |
62
|
28
|
100
|
|
|
|
54
|
if ( $self->access !~ /^github$/i ) { |
63
|
24
|
|
|
|
|
185
|
@rules = (); |
64
|
24
|
|
|
|
|
19
|
foreach (@{$self->access}) { |
|
24
|
|
|
|
|
45
|
|
65
|
26
|
100
|
100
|
|
|
137
|
if (@rules and $rules[0] eq 'allow' and $_ =~ /^github$/i) { |
|
|
|
100
|
|
|
|
|
66
|
3
|
|
|
|
|
7
|
push @rules, @GITHUB_IPS[1 .. $#GITHUB_IPS]; |
67
|
|
|
|
|
|
|
} else { |
68
|
23
|
|
|
|
|
33
|
push @rules, $_; |
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
} |
72
|
28
|
|
|
|
|
203
|
$app = Plack::Middleware::Access->wrap( $app, rules => \@rules ); |
73
|
|
|
|
|
|
|
|
74
|
28
|
|
|
|
|
13208
|
$app; |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
sub call_granted { |
78
|
25
|
|
|
25
|
0
|
30
|
my ($self, $env) = @_; |
79
|
|
|
|
|
|
|
|
80
|
25
|
100
|
|
|
|
72
|
if ( $env->{REQUEST_METHOD} ne 'POST' ) { |
81
|
1
|
|
|
|
|
10
|
return [405,['Content-Type'=>'text/plain','Content-Length'=>18],['Method Not Allowed']]; |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
|
84
|
24
|
|
|
|
|
104
|
my $req = Plack::Request->new($env); |
85
|
24
|
|
100
|
|
|
220
|
my $event = $env->{'HTTP_X_GITHUB_EVENT'} // ''; |
86
|
24
|
|
100
|
|
|
78
|
my $delivery = $env->{'HTTP_X_GITHUB_DELIVERY'} // ''; |
87
|
24
|
|
|
|
|
21
|
my $payload; |
88
|
24
|
|
|
|
|
23
|
my ($status, $message); |
89
|
|
|
|
|
|
|
|
90
|
24
|
100
|
100
|
|
|
54
|
if ( !$self->events or grep { $event eq $_ } @{$self->events} ) { |
|
2
|
|
|
|
|
10
|
|
|
2
|
|
|
|
|
10
|
|
91
|
23
|
|
100
|
|
|
143
|
$payload = $req->param('payload') || $req->content; |
92
|
23
|
|
|
|
|
8081
|
$payload = eval { decode_json $payload }; |
|
23
|
|
|
|
|
158
|
|
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
|
95
|
24
|
100
|
|
|
|
48
|
if (!$payload) { |
96
|
2
|
|
|
|
|
18
|
return [400,['Content-Type'=>'text/plain','Content-Length'=>11],['Bad Request']]; |
97
|
|
|
|
|
|
|
} |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
my $logger = Plack::App::GitHub::WebHook::Logger->new( |
100
|
11
|
|
|
11
|
|
6
|
$env->{'psgix.logger'} || sub { } |
101
|
22
|
|
100
|
|
|
219
|
); |
102
|
|
|
|
|
|
|
|
103
|
22
|
100
|
|
|
|
82
|
if ( $self->receive( [ $payload, $event, $delivery, $logger ], $env->{'psgi.errors'} ) ) { |
104
|
9
|
|
|
|
|
19
|
($status, $message) = (200,"OK"); |
105
|
|
|
|
|
|
|
} else { |
106
|
12
|
|
|
|
|
18
|
($status, $message) = (202,"Accepted"); |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
|
109
|
21
|
100
|
|
|
|
54
|
$message = ucfirst($event)." $message" if $self->events; |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
return [ |
112
|
21
|
|
|
|
|
193
|
$status, |
113
|
|
|
|
|
|
|
[ 'Content-Type' => 'text/plain', 'Content-Length' => length $message ], |
114
|
|
|
|
|
|
|
[ $message ] |
115
|
|
|
|
|
|
|
]; |
116
|
|
|
|
|
|
|
} |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
sub receive { |
119
|
22
|
|
|
22
|
0
|
54
|
my ($self, $args, $error) = @_; |
120
|
|
|
|
|
|
|
|
121
|
22
|
|
|
|
|
27
|
foreach my $hook (@{$self->{hook}}) { |
|
22
|
|
|
|
|
52
|
|
122
|
14
|
100
|
66
|
|
|
14
|
if ( !eval { $hook->(@$args) } || $@ ) { |
|
14
|
|
|
|
|
32
|
|
123
|
5
|
100
|
|
|
|
37
|
if ( $@ ) { |
124
|
2
|
100
|
|
|
|
4
|
if ($self->safe) { |
125
|
1
|
|
|
|
|
9
|
$error->print($@); |
126
|
|
|
|
|
|
|
} else { |
127
|
1
|
|
|
|
|
7
|
die Plack::App::GitHub::WebHook::Exception->new( 500, $@ ); |
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
} |
130
|
4
|
|
|
|
|
17
|
return; |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
} |
133
|
|
|
|
|
|
|
|
134
|
17
|
|
|
|
|
59
|
return scalar @{$self->{hook}}; |
|
17
|
|
|
|
|
49
|
|
135
|
|
|
|
|
|
|
} |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
{ |
138
|
|
|
|
|
|
|
package Plack::App::GitHub::WebHook::Logger; |
139
|
|
|
|
|
|
|
sub new { |
140
|
22
|
|
|
22
|
|
71
|
my $self = bless { logger => $_[1] }, $_[0]; |
141
|
22
|
|
|
|
|
49
|
foreach my $level (qw(debug info warn error fatal)) { |
142
|
10
|
|
|
10
|
|
31
|
$self->{$level} = sub { $self->log( $level => $_[0] ) } |
143
|
110
|
|
|
|
|
335
|
} |
144
|
22
|
|
|
|
|
39
|
$self; |
145
|
|
|
|
|
|
|
} |
146
|
|
|
|
|
|
|
sub log { |
147
|
22
|
|
|
22
|
|
29
|
my ($self, $level, $message) = @_; |
148
|
22
|
|
|
|
|
13
|
chomp $message; |
149
|
22
|
|
|
|
|
37
|
$self->{logger}->({ level => $level, message => $message }); |
150
|
22
|
|
|
|
|
55
|
1; |
151
|
|
|
|
|
|
|
} |
152
|
0
|
|
|
0
|
|
0
|
sub debug { $_[0]->log(debug => $_[1]) } |
153
|
0
|
|
|
0
|
|
0
|
sub info { $_[0]->log(info => $_[1]) } |
154
|
0
|
|
|
0
|
|
0
|
sub warn { $_[0]->log(warn => $_[1]) } |
155
|
0
|
|
|
0
|
|
0
|
sub error { $_[0]->log(error => $_[1]) } |
156
|
2
|
|
|
2
|
|
10
|
sub fatal { $_[0]->log(fatal => $_[1]) } |
157
|
|
|
|
|
|
|
} |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
{ |
160
|
|
|
|
|
|
|
package Plack::App::GitHub::WebHook::Exception; |
161
|
7
|
|
|
7
|
|
36
|
use overload '""' => sub { $_[0]->{message} }; |
|
7
|
|
|
1
|
|
9
|
|
|
7
|
|
|
|
|
59
|
|
|
1
|
|
|
|
|
792
|
|
162
|
1
|
|
|
1
|
|
7
|
sub new { bless { code => $_[1], message => $_[2] }, $_[0]; } |
163
|
1
|
|
|
1
|
|
43
|
sub code { $_[0]->{code} } |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
1; |
167
|
|
|
|
|
|
|
__END__ |