]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/NetReader.pm
net_reader: don't approve/reject credentials w/o "fill"
[public-inbox.git] / lib / PublicInbox / NetReader.pm
index 058f431398a6a8bcf5579e668db30ef6c1660bd5..08166415cfcb0c6519bd6dd749934a81d54b98a3 100644 (file)
@@ -96,8 +96,8 @@ sub mic_for ($$$$) { # mic = Mail::IMAPClient
                $cred = undef;
        }
        if ($cred) {
-               $cred->check_netrc unless defined $cred->{password};
-               $cred->fill($lei); # may prompt user here
+               my $p = $cred->{password} // $cred->check_netrc;
+               $cred->fill($lei) unless defined($p); # may prompt user here
                $mic->User($mic_arg->{User} = $cred->{username});
                $mic->Password($mic_arg->{Password} = $cred->{password});
        } else { # AUTH=ANONYMOUS
@@ -121,7 +121,7 @@ sub mic_for ($$$$) { # mic = Mail::IMAPClient
                }
                $mic = undef;
        }
-       $cred->run($mic ? 'approve' : 'reject') if $cred;
+       $cred->run($mic ? 'approve' : 'reject') if $cred && $cred->{filled};
        if ($err) {
                $lei ? $lei->fail($err) : warn($err);
        }
@@ -191,7 +191,7 @@ sub nn_for ($$$$) { # nn = Net::NNTP
                }, 'PublicInbox::GitCredential';
                ($u, $p) = split(/:/, $ui, 2);
                ($cred->{username}, $cred->{password}) = ($u, $p);
-               $cred->check_netrc unless defined $p;
+               $p //= $cred->check_netrc;
        }
        my $common = $nn_args->{$sec} // {};
        my $nn_arg = {
@@ -204,7 +204,7 @@ sub nn_for ($$$$) { # nn = Net::NNTP
        %$nn_arg = (%$nn_arg, %$sa) if $sa;
        my $nn = nn_new($nn_arg, $nntp_opt, $uri);
        if ($cred) {
-               $cred->fill($lei); # may prompt user here
+               $cred->fill($lei) unless defined($p); # may prompt user here
                if ($nn->authinfo($u, $p)) {
                        push @{$nntp_opt->{-postconn}}, [ 'authinfo', $u, $p ];
                } else {
@@ -231,23 +231,24 @@ W: see https://rt.cpan.org/Ticket/Display.html?id=129967 for updates
        }
 
        $self->{nn_arg}->{$sec} = $nn_arg;
-       $cred->run($nn ? 'approve' : 'reject') if $cred;
+       $cred->run($nn ? 'approve' : 'reject') if $cred && $cred->{filled};
        $nn;
 }
 
 sub imap_uri {
-       my ($url) = @_;
+       my ($url, $ls_ok) = @_;
        require PublicInbox::URIimap;
        my $uri = PublicInbox::URIimap->new($url);
-       $uri ? $uri->canonical : undef;
+       $uri && ($ls_ok || $uri->mailbox) ? $uri->canonical : undef;
 }
 
 my %IS_NNTP = (news => 1, snews => 1, nntp => 1, nntps => 1);
 sub nntp_uri {
-       my ($url) = @_;
+       my ($url, $ls_ok) = @_;
        require PublicInbox::URInntps;
        my $uri = PublicInbox::URInntps->new($url);
-       $uri && $IS_NNTP{$uri->scheme} && $uri->group ? $uri->canonical : undef;
+       $uri && $IS_NNTP{$uri->scheme} && ($ls_ok || $uri->group) ?
+               $uri->canonical : undef;
 }
 
 sub cfg_intvl ($$$) {
@@ -367,11 +368,13 @@ sub nntp_common_init ($;$) {
 }
 
 sub add_url {
-       my ($self, $arg) = @_;
+       my ($self, $arg, $ls_ok) = @_;
        my $uri;
-       if ($uri = imap_uri($arg)) {
+       if ($uri = imap_uri($arg, $ls_ok)) {
+               $_[1] = $$uri; # canonicalized
                push @{$self->{imap_order}}, $uri;
-       } elsif ($uri = nntp_uri($arg)) {
+       } elsif ($uri = nntp_uri($arg, $ls_ok)) {
+               $_[1] = $$uri; # canonicalized
                push @{$self->{nntp_order}}, $uri;
        } else {
                push @{$self->{unsupported_url}}, $arg;
@@ -417,7 +420,8 @@ sub _imap_do_msg ($$$$$) {
        my ($self, $uri, $uid, $raw, $flags) = @_;
        # our target audience expects LF-only, save storage
        $$raw =~ s/\r\n/\n/sg;
-       my $kw = flags2kw($self, $uri, $uid, $flags) // return;
+       my $kw = defined($flags) ?
+               (flags2kw($self, $uri, $uid, $flags) // return) : undef;
        my ($eml_cb, @args) = @{$self->{eml_each}};
        $eml_cb->($uri, $uid, $kw, PublicInbox::Eml->new($raw), @args);
 }
@@ -458,8 +462,9 @@ sub each_old_flags ($$$$) {
        my ($self, $mic, $uri, $l_uid) = @_;
        $l_uid ||= 1;
        my $sec = uri_section($uri);
-       my $bs = $self->{imap_opt}->{$sec}->{batch_size} // 10000;
+       my $bs = ($self->{imap_opt}->{$sec}->{batch_size} // 1) * 10000;
        my ($eml_cb, @args) = @{$self->{eml_each}};
+       $self->{quiet} or warn "# $uri syncing flags 1:$l_uid\n";
        for (my $n = 1; $n <= $l_uid; $n += $bs) {
                my $end = $n + $bs;
                $end = $l_uid if $end > $l_uid;
@@ -488,6 +493,9 @@ sub perm_fl_ok ($) {
        undef;
 }
 
+# may be overridden in NetWriter or Watch
+sub folder_select { $_[0]->{each_old} ? 'select' : 'examine' }
+
 sub _imap_fetch_all ($$$) {
        my ($self, $mic, $orig_uri) = @_;
        my $sec = uri_section($orig_uri);
@@ -496,7 +504,7 @@ sub _imap_fetch_all ($$$) {
 
        # we need to check for mailbox writability to see if we care about
        # FLAGS from already-imported messages.
-       my $cmd = $self->{each_old} ? 'select' : 'examine';
+       my $cmd = $self->folder_select;
        $mic->$cmd($mbx) or return "E: \U$cmd\E $mbx ($sec) failed: $!";
 
        my ($r_uidval, $r_uidnext, $perm_fl);
@@ -534,8 +542,8 @@ E: $uri strangely, UIDVALIDLITY matches ($l_uidval)
 EOF
        $mic->Uid(1); # the default, we hope
        my $err;
-       if (!defined($single_uid) && $self->{each_old} &&
-                               perm_fl_ok($perm_fl)) {
+       my $use_fl = perm_fl_ok($perm_fl);
+       if (!defined($single_uid) && $self->{each_old} && $use_fl) {
                $err = each_old_flags($self, $mic, $uri, $l_uid);
                return $err if $err;
        }
@@ -590,8 +598,8 @@ EOF
                                # messages get deleted, so holes appear
                                my $per_uid = delete $r->{$uid} // next;
                                my $raw = delete($per_uid->{$key}) // next;
-                               _imap_do_msg($self, $uri, $uid, \$raw,
-                                               $per_uid->{FLAGS});
+                               my $fl = $use_fl ? $per_uid->{FLAGS} : undef;
+                               _imap_do_msg($self, $uri, $uid, \$raw, $fl);
                                $last_uid = $uid;
                                last if $self->{quit};
                        }
@@ -747,4 +755,23 @@ sub nntp_each {
 
 sub new { bless {}, shift };
 
+# updates $uri with UIDVALIDITY
+sub mic_for_folder {
+       my ($self, $uri) = @_;
+       my $mic = $self->mic_get($uri) or die "E: not connected: $@";
+       my $m = $self->isa('PublicInbox::NetWriter') ? 'select' : 'examine';
+       $mic->$m($uri->mailbox) or return;
+       my $uidval;
+       for ($mic->Results) {
+               /^\* OK \[UIDVALIDITY ([0-9]+)\].*/ or next;
+               $uidval = $1;
+               last;
+       }
+       $uidval //= $mic->uidvalidity($uri->mailbox) or
+               die "E: failed to get uidvalidity from <$uri>: $@";
+       $uri->uidvalidity($uidval);
+       $mic;
+}
+
+
 1;