From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 05AC01F94C for ; Sat, 27 Jun 2020 10:04:06 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 31/34] watch: use our own "git credential" wrapper Date: Sat, 27 Jun 2020 10:03:57 +0000 Message-Id: <20200627100400.9871-32-e@yhbt.net> In-Reply-To: <20200627100400.9871-1-e@yhbt.net> References: <20200627100400.9871-1-e@yhbt.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: Git.pm may not be installed on some systems; or some users have multiple Perl installations and Git.pm is not available to the Perl running -watch. Accomodate both those types of users by providing our own "git credential" wrapper. --- MANIFEST | 1 + lib/PublicInbox/GitCredential.pm | 40 ++++++++++++++++++++++++++++++++ lib/PublicInbox/WatchMaildir.pm | 22 ++++++++---------- 3 files changed, 51 insertions(+), 12 deletions(-) create mode 100644 lib/PublicInbox/GitCredential.pm diff --git a/MANIFEST b/MANIFEST index f9d1eea5bd9..6de2c72581b 100644 --- a/MANIFEST +++ b/MANIFEST @@ -123,6 +123,7 @@ lib/PublicInbox/Filter/Vger.pm lib/PublicInbox/GetlineBody.pm lib/PublicInbox/Git.pm lib/PublicInbox/GitAsyncCat.pm +lib/PublicInbox/GitCredential.pm lib/PublicInbox/GitHTTPBackend.pm lib/PublicInbox/GzipFilter.pm lib/PublicInbox/HTTP.pm diff --git a/lib/PublicInbox/GitCredential.pm b/lib/PublicInbox/GitCredential.pm new file mode 100644 index 00000000000..826e7a55e8b --- /dev/null +++ b/lib/PublicInbox/GitCredential.pm @@ -0,0 +1,40 @@ +# Copyright (C) 2020 all contributors +# License: AGPL-3.0+ +package PublicInbox::GitCredential; +use strict; +use PublicInbox::Spawn qw(popen_rd); + +sub run ($$) { + my ($self, $op) = @_; + my ($in_r, $in_w); + pipe($in_r, $in_w) or die "pipe: $!"; + my $out_r = popen_rd([qw(git credential), $op], undef, { 0 => $in_r }); + close $in_r or die "close in_r: $!"; + + my $out = ''; + for my $k (qw(url protocol host username password)) { + defined(my $v = $self->{$k}) or next; + die "`$k' contains `\\n' or `\\0'\n" if $v =~ /[\n\0]/; + $out .= "$k=$v\n"; + } + $out .= "\n"; + print $in_w $out or die "print (git credential $op): $!"; + close $in_w or die "close (git credential $op): $!"; + return $out_r if $op eq 'fill'; + <$out_r> and die "unexpected output from `git credential $op'\n"; + close $out_r or die "`git credential $op' failed: \$!=$! \$?=$?\n"; +} + +sub fill { + my ($self) = @_; + my $out_r = run($self, 'fill'); + while (<$out_r>) { + chomp; + return if $_ eq ''; + /\A([^=]+)=(.*)\z/ or die "bad line: $_\n"; + $self->{$1} = $2; + } + close $out_r or die "git credential fill failed: \$!=$! \$?=$?\n"; +} + +1; diff --git a/lib/PublicInbox/WatchMaildir.pm b/lib/PublicInbox/WatchMaildir.pm index 43c8395c79b..19f894d4315 100644 --- a/lib/PublicInbox/WatchMaildir.pm +++ b/lib/PublicInbox/WatchMaildir.pm @@ -308,13 +308,14 @@ sub auth_anon_cb { '' }; # for Mail::IMAPClient::Authcallback sub mic_for ($$$) { # mic = Mail::IMAPClient my ($self, $url, $mic_args) = @_; my $uri = PublicInbox::URIimap->new($url); - my $cred = { + require PublicInbox::GitCredential; + my $cred = bless { url => $url, protocol => $uri->scheme, host => $uri->host, username => $uri->user, password => $uri->password, - }; + }, 'PublicInbox::GitCredential'; my $common = $mic_args->{uri_section($uri)} // {}; my $host = $cred->{host}; my $mic_arg = { @@ -342,7 +343,7 @@ sub mic_for ($$$) { # mic = Mail::IMAPClient $cred = undef; } if ($cred) { - Git::credential($cred, 'fill'); # may prompt user here + $cred->fill; # may prompt user here $mic->User($mic_arg->{User} = $cred->{username}); $mic->Password($mic_arg->{Password} = $cred->{password}); } else { # AUTH=ANONYMOUS @@ -356,7 +357,7 @@ sub mic_for ($$$) { # mic = Mail::IMAPClient warn "E: <$url> LOGIN: $@\n"; $mic = undef; } - Git::credential($cred, $mic ? 'approve' : 'reject') if $cred; + $cred->run($mic ? 'approve' : 'reject') if $cred; $mic; } @@ -653,8 +654,6 @@ sub watch_imap_init ($) { my ($self) = @_; eval { require PublicInbox::IMAPClient } or die "Mail::IMAPClient is required for IMAP:\n$@\n"; - eval { require Git } or - die "Git (Perl module) is required for IMAP:\n$@\n"; eval { require PublicInbox::IMAPTracker } or die "DBD::SQLite is required for IMAP\n:$@\n"; @@ -772,11 +771,12 @@ sub nn_for ($$$) { # nn = Net::NNTP my $cred; my ($u, $p); if (defined(my $ui = $uri->userinfo)) { - $cred = { + require PublicInbox::GitCredential; + $cred = bless { url => $sec, protocol => uri_scheme($uri), host => $uri->host, - }; + }, 'PublicInbox::GitCredential'; ($u, $p) = split(/:/, $ui, 2); ($cred->{username}, $cred->{password}) = ($u, $p); } @@ -791,7 +791,7 @@ sub nn_for ($$$) { # nn = Net::NNTP my $nn = nn_new($nn_arg, $nntp_opt, $url); if ($cred) { - Git::credential($cred, 'fill'); # may prompt user here + $cred->fill; # may prompt user here if ($nn->authinfo($u, $p)) { push @{$nntp_opt->{-postconn}}, [ 'authinfo', $u, $p ]; } else { @@ -818,7 +818,7 @@ W: see https://rt.cpan.org/Ticket/Display.html?id=129967 for updates } $self->{nn_arg}->{$sec} = $nn_arg; - Git::credential($cred, $nn ? 'approve' : 'reject') if $cred; + $cred->run($nn ? 'approve' : 'reject') if $cred; $nn; } @@ -896,8 +896,6 @@ sub watch_nntp_init ($) { my ($self) = @_; eval { require Net::NNTP } or die "Net::NNTP is required for NNTP:\n$@\n"; - eval { require Git } or - die "Git (Perl module) is required for NNTP:\n$@\n"; eval { require PublicInbox::IMAPTracker } or die "DBD::SQLite is required for NNTP\n:$@\n";