App-KGB
view release on metacpan or search on metacpan
script/kgb-bot view on Meta::CPAN
my $fh = IO::File->new(">> $KGB::simulate")
or die "Error opening $KGB::simulate for writing: $!\n";
$fh->autoflush(1);
$fh->binmode(':utf8');
$fh->print("$chanid $line\n");
$fh->close;
}
else {
my ( $net, $chan ) = KGB->get_net_chan($chanid);
$kernel->yield(
irc_notify => $net, $chan, [$line],
$opts->{use_irc_notices} ? 'notice' : 'privmsg'
);
}
}
}
}
return 'OK';
}
package KGB::WebHook;
use strict;
use warnings;
use File::Basename;
use HTTP::Status;
use JSON;
use App::KGB::Painter;
use List::MoreUtils qw(any);
use List::Util qw(max);
use Net::IP;
use POE;
use Text::Glob qw(match_glob);
sub colorize { KGB::SOAP::colorize( @_ ) };
sub colorize_change { KGB::SOAP::colorize_change( @_ ) };
sub webhook_error(\@$;$$) {
my $env = shift;
my $message = shift;
my $code = shift // HTTP::Status::HTTP_BAD_REQUEST;
my $content = shift // $message;
KGB->debug("Webhook error: $message");
my $response = $env->[ARG1];
$response->code($code);
$response->message($message);
$response->content($content);
return $env->[KERNEL]->post( $env->[SENDER], DONE => $response);
}
=head2 webhook_request I<request> I<response> I<dirmatch>
Handler for webhook HTTP request.
This handler only processes the HTTP part, parsing URI parameters and POST
contents.
The actual processing and IRC notification is done via an appropriate
C<gitlab_webhook_*> event, asynchronously.
=cut
my @array_webhook_params =
qw( channel pipeline_only_status always_squash_branch only_branch
only_tag always_squash_outside_dir );
my %array_webhook_params = map( ( $_ => 1 ), @array_webhook_params );
sub webhook_request {
my ( $kernel, $request, $response, $dirmatch ) = @_[ KERNEL, ARG0 .. ARG2 ];
unless ( $KGB::config->{webhook}{enabled} ) {
return webhook_error(@_, 'WebHook support not enabled',
HTTP::Status::HTTP_PRECONDITION_FAILED);
}
my $client_ip = $response->connection->remote_ip;
# fix ipv4-as-ipv6 represenation
$client_ip =~ s/^::ffff:(\d+\.\d+\.\d+\.\d+)$/$1/;
$client_ip = Net::IP->new($client_ip);
my $allowed = 0;
my $allowed_nets = $KGB::config->{webhook}{allowed_networks};
if ($allowed_nets) {
for my $net (@$allowed_nets) {
next unless $net->version == $client_ip->version;
$allowed = 1, last
if $net->overlaps($client_ip) != $Net::IP::IP_NO_OVERLAP;
}
}
unless ($allowed) {
return webhook_error(@_, 'Client IP ' . $client_ip->ip . ' is not whitelisted',
HTTP::Status::HTTP_FORBIDDEN);
}
KGB->debug( "got a webhook request from " . $client_ip->ip );
unless( $request->method eq 'POST' ) {
return webhook_error(@_, 'Request method must be "POST"');
}
KGB->debug('DEBUG: method check passed');
my $json;
my $ok = eval {
$json = JSON::from_json( $request->content, { utf8 => 1 } );
1;
};
unless ($ok) {
return webhook_error(@_, 'Error decoding JSON body', undef, $@);
}
KGB->debug('Body decoded');
unless (
$json
( run in 0.801 second using v1.01-cache-2.11-cpan-5b529ec07f3 )