From 5814dee50f9e16b96bad8488b8a953599c2769bd Mon Sep 17 00:00:00 2001 From: "Kyle J. McKay" Date: Mon, 15 Feb 2021 08:04:25 -0700 Subject: [PATCH] Girocco/Notify.pm: refactor JSON code for easier reuse Separate out the parts likely to be reused in the future into their own little private functions. No externally visible changes. Signed-off-by: Kyle J. McKay --- Girocco/Notify.pm | 99 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 58 insertions(+), 41 deletions(-) diff --git a/Girocco/Notify.pm b/Girocco/Notify.pm index 1337f77..9d3b785 100644 --- a/Girocco/Notify.pm +++ b/Girocco/Notify.pm @@ -90,6 +90,60 @@ sub _jsonagent { ")"; } +sub _jsonrepo { + my $proj = shift; + return { + "name" => $proj->{name}, + # Girocco extension: full_name is full project name, + # equivalent to GitHub's "owner[name]/name". + "full_name" => $proj->{name}.".git", + + "url" => $Girocco::Config::gitweburl.'/'.$proj->{name}.".git", + # Girocco extension: Pull URL. + "pull_url" => $Girocco::Config::gitpullurl.'/'.$proj->{name}.".git", + + "owner" => { "name" => "", "email" => $proj->{email} } + }; +} + +sub _jsonpayload { + my ($proj, $payload) = @_; + my $ct = $proj->{jsontype}; + if (!defined($ct) || $ct ne 'application/json') { + { + use bytes; + # Spaces are expected to be encoded as '+' rather than %20 + # This is not part of any RFC, but matches the behavior + # of the specification that we're emulating here + $payload =~ s/([^ A-Za-z0-9_.~-])/sprintf("%%%02X",ord($1))/ge; + $payload =~ s/[ ]/+/g; # expected but NOT part of any RFC! + } + $payload = 'payload=' . $payload; + } + return $payload; +} + +sub _jsonsigheaders { + my ($proj, $payload) = @_; + my $hmackey = $proj->{jsonsecret}; + my @sigheaders = (); + if (defined($hmackey) && $hmackey ne "") { + my $sig = "sha1=".lc(unpack('H*',hmac_sha1($hmackey, $payload))); + push(@sigheaders, X_Hub_Signature => $sig); + if ($have_hmac_sha256) { + # Yes, the argument order is different! #%@#%^@! + # hmac_sha1 is provided by Girocco::HashUtil and it uses the + # sane order of "key" then "text" as that's the order they are + # mentioned in RFC 2104. The @#%^^@* Digest::SHA module, on the + # other hand, is the one providing hmac_sha256 and for some + # inscrutable reason uses the order of "text" then "key"! + my $sig256 = "sha256=".lc(unpack('H*',hmac_sha256($payload, $hmackey))); + push(@sigheaders, X_Hub_Signature_256 => $sig256); + } + } + return @sigheaders; +} + sub json { my ($url, $proj, $user, $ref, $oldrev, $newrev, $forced) = @_; @@ -120,20 +174,7 @@ sub json { "created" => json_bool($oldrev =~ /^0+$/ ? 1 : 0), "deleted" => json_bool($newrev =~ /^0+$/ ? 1 : 0), "forced" => json_bool($forced ? 1 : 0), - - "repository" => { - "name" => $proj->{name}, - # Girocco extension: full_name is full project name, - # equivalent to GitHub's "owner[name]/name". - "full_name" => $proj->{name}.".git", - - "url" => $Girocco::Config::gitweburl.'/'.$proj->{name}.".git", - # Girocco extension: Pull URL. - "pull_url" => $Girocco::Config::gitpullurl.'/'.$proj->{name}.".git", - - "owner" => { "name" => "", "email" => $proj->{email} } - }, - + "repository" => _jsonrepo($proj), "pusher" => $pusher, "sender" => $sender, "commits" => $commits @@ -143,35 +184,11 @@ sub json { my $ua = LWP::UserAgent->new(agent => _jsonagent($proj)); $ua->timeout(5); my $ct = $proj->{jsontype}; - if (!defined($ct) || $ct ne 'application/json') { + defined($ct) && $ct eq 'application/json' or $ct = 'application/x-www-form-urlencoded'; - { - use bytes; - # Spaces are expected to be encoded as '+' rather than %20 - # This is not part of any RFC, but matches the behavior - # of the specification that we're emulating here - $payload =~ s/([^ A-Za-z0-9_.~-])/sprintf("%%%02X",ord($1))/ge; - $payload =~ s/[ ]/+/g; # expected but NOT part of any RFC! - } - $payload = 'payload=' . $payload; - } + $payload = _jsonpayload($proj, $payload); my @headers = ( Content_Type => $ct, Content_Length => length($payload) ); - my $hmackey = $proj->{jsonsecret}; - if (defined($hmackey) && $hmackey ne "") { - my $sig = "sha1=".lc(unpack('H*',hmac_sha1($hmackey, $payload))); - push(@headers, X_Hub_Signature => $sig); - if ($have_hmac_sha256) { - # Yes, the argument order is different! #%@#%^@! - # hmac_sha1 is provided by Girocco::HashUtil and it uses the - # sane order of "key" then "text" as that's the order they are - # mentioned in RFC 2104. The @#%^^@* Digest::SHA module, on the - # other hand, is the one providing hmac_sha256 and for some - # inscrutable reason uses the order of "text" then "key"! - my $sig256 = "sha256=".lc(unpack('H*',hmac_sha256($payload, $hmackey))); - push(@headers, X_Hub_Signature_256 => $sig256); - } - } - $ua->post($url, @headers, Content => $payload); + $ua->post($url, @headers, _jsonsigheaders($proj, $payload), Content => $payload); } -- 2.11.4.GIT