>

Linedata Services (UK) Ltd
Registered Office: Bishopsgate Court, 4-12 Norton Folgate, London, E1 6DB
Registered in England and Wales No 3027851    VAT Reg No 778499447

-----Original Message-----


> From: Giulio Troccoli
> Sent: 08 December 2009 11:18
> To: us...@subversion.tigris.org; users@subversion.apache.org
> Subject: Authentication with Perl bindings
>
> I'm desperately trying to write something in Perl to authenticate.
>
> The functionality I want to reproduce is:
> - use the chached username and password if any
> - if not, ask for a password for the current username
> - if that fails, ask for a username and a password
>
> This is what the SVN client does, I think. But I'm not able
> to do it in Perl. I'm using the following code, which I found
> in the perldoc for SVN::Client
>
>            use SVN::Client;
>            my $ctx = new SVN::Client(
>                      auth => [
>                              SVN::Client::get_simple_provider(),
>
> SVN::Client::get_simple_prompt_provider(\&simple_prompt,2),
>                              SVN::Client::get_username_provider()
>                              ]
>                      );
>
>            sub simple_prompt {
>              my $cred = shift;
>              my $realm = shift;
>              my $default_username = shift;
>              my $may_save = shift;
>              my $pool = shift;
>
>              print "Enter authentication info for realm: $realm\n";
>              print "Username: ";
>              my $username = <>;
>              chomp($username);
>              $cred->username($username);
>              print "Password: ";
>              my $password = <>;
>              chomp($password);
>              $cred->password($password);
>            }
>
> (I know the password is in clear, but I can fix that later).
>
> If the username and password are cached this works perfectly
> well. When I comment out the get_simple_provider line (to
> simulate authentication data not being cached) I am asked for
> a username and password. If I enter the correct ones
> everything works. Otherwise I am asked two more times, and
> eventually the authentication fails.
>
> So, my questions are:
>
> 1) What is get_username_provider used for? When would I want
> to get the chached username only?
>
> 2) How can I implement my second point "ask for a password
> for the current username" ? I have tried changing
> simple_prompt as follows
>
>       print "Enter authentication info for realm: $realm\n";
> #      print "Username: ";
>       my $username = $default_username;
> #      chomp($username);
>       $cred->username($username);
>
> And it works if I enter the correct password the first time.
> But if the password is wrong, not only I'm not asked again
> but I get a "Memory fault" error. I wasn't really expecting
> to be asked for the username but at least for the password
> for two more times.
>
> Anyone has done what I'm trying to do already? Anyone has any
> hints or suggestions?
>
> Thanks in advance
> Giulio
>
> P.S. I post this email to both mailing list @tigris and
> @apache, just becuase the apache one doesn't seem to be very active.

Well, after some experimentation I ahve found the solution, so I'm posting it 
here for future reference.

The trick is to use two separate callback subroutines to 
get_simple_prompt_provider: one to use the default username (and to not retry) 
and one to ask for both username and password (with 1 retry, so a total of 3 
attempts).

I have also used the IO::Prompt package to mask the password.

my $ctx = SVN::Client->new(
                  auth => [
                           SVN::Client::get_simple_provider(),
                           
SVN::Client::get_simple_prompt_provider(\&ask_for_password,0),
                           
SVN::Client::get_simple_prompt_provider(\&ask_for_username_and_password,1),
                           ]
         );

sub ask_for_password {
   my ($cred, $realm, $default_username, $may_save, $pool) = @_;

   print "Enter authentication info for realm: $realm\n";
   $cred->username($default_username);
   my $password = IO::Prompt::prompt('Password: ', -le => '*');
   chomp($password);
   $cred->password($password);
}

sub ask_for_username_and_password {
   my ($cred, $realm, $default_username, $may_save, $pool) = @_;

   print "Enter authentication info for realm: $realm\n";
   print "Username: ";
   my $username = <>;
   chomp($username);
   $cred->username($username);
   my $password = IO::Prompt::prompt('Password: ', -le => '*');
   chomp($password);
   $cred->password($password);
}

Reply via email to