Author: Brett Wuth <wuth@castrov.cuug.ab.ca>
Last-Update: 2013-07-09
Bug-Debian: https://bugs.debian.org/715420
Description: support login with Basic HTTP Authentication

--- a/lib/WWW/Mediawiki/Client.pm
+++ b/lib/WWW/Mediawiki/Client.pm
@@ -271,6 +271,10 @@ use constant REMEMBER_NAME      => 'wpRe
 use constant LOGIN_SUBMIT_NAME  => 'wpLoginattempt';
 use constant LOGIN_SUBMIT_VALUE => 'Log In';
 use constant LOGIN_TOKEN        => 'wpLoginToken';
+use constant HTTP_AUTHORIZATION_NAME    => 'Authorization';
+use constant HTTP_AUTHORIZATION_NONE    => 'none';
+use constant HTTP_AUTHORIZATION_BASIC   => 'Basic';
+use constant HTTP_AUTHORIZATION_DEFAULT => HTTP_AUTHORIZATION_NONE;
 
 =head2 Files
 
@@ -292,7 +296,7 @@ use constant CONFIG_FILE => './.mediawik
 use constant COOKIE_FILE => '.mediawiki_cookies.dat';
 use constant SAVED_ATTRIBUTES => (
     qw(site_url host protocol language_code space_substitute username
-       password wiki_path watch encoding minor_edit escape_filenames)
+       password http_authorization_method wiki_path watch encoding minor_edit escape_filenames)
 );  # It's important that host goes first since it has side effects
 
 
@@ -314,12 +318,12 @@ sub new {
     my $pkg = shift;
     my %init = @_;
     my $self = bless {};
+    $self->{ua} = LWP::UserAgent->new();
     $self->load_state;
     foreach my $attr (SAVED_ATTRIBUTES) {
         next unless $init{$attr};
         $self->$attr($init{$attr});
     }
-    $self->{ua} = LWP::UserAgent->new();
     push @{ $self->{ua}->requests_redirectable }, 'POST';
     my $agent = 'WWW::Mediawiki::Client/' . $VERSION;
     $self->{ua}->agent($agent);
@@ -554,7 +558,10 @@ user.
 
 sub username {
     my ($self, $username) = @_;
-    $self->{username} = $username if $username;
+    if ($username) {
+      $self->{username} = $username;
+      $self->use_http_authorization_method;
+    }
     return $self->{username};
 }
 
@@ -570,10 +577,82 @@ good idea to use an important one.
 
 sub password {
     my ($self, $password) = @_;
-    $self->{password} = $password if $password;
+    if ($password) {
+      $self->{password} = $password;
+      $self->use_http_authorization_method;
+    }
     return $self->{password};
 }
 
+
+=head2 http_authorization_method
+
+  my $method = $mvs->http_authorization_method($method);
+
+The method used for HTTP access to the web server.
+
+= over
+= item 'none'
+
+(Default) Indicates that the server does not use HTTP Authorization.
+Most mediawiki's web servers use this value, which is to say that
+access to the mediawiki software is available to any client, even if
+the mediawiki software itself may further limit privileges.
+
+= item 'Basic'
+
+Use Basic HTTP Authorization.  A mediawiki web server which is set up
+to use this option, will not allow the client to talk to the mediawiki
+software unless the username and password is included in the request.
+The mediawiki software might require an additional log in using the
+same information, or it might take the credentials from the web server
+using, e.g. http://www.mediawiki.org/wiki/Extension:AutomaticREMOTE_USER
+
+Basic HTTP Authorization is considered insecure unless used over a
+secure channel such as https.
+
+=back
+
+B<Throws:>
+
+=over
+
+=item WWW::Mediawiki::Client::URLConstructionException
+
+=back
+
+=cut
+
+sub http_authorization_method {
+  my ($self, $method) = @_;
+  if ($method) {
+    WWW::Mediawiki::Client::AuthException->throw( "Unsupported method: $method" )
+	unless $method eq HTTP_AUTHORIZATION_NONE or $method eq HTTP_AUTHORIZATION_BASIC;
+    $self->{http_authorization_method} = $method;
+    $self->use_http_authorization_method;
+  }
+  $self->{http_authorization_method} = HTTP_AUTHORIZATION_DEFAULT
+    unless $self->{http_authorization_method};
+  return $self->{http_authorization_method};
+}
+
+sub use_http_authorization_method {
+  require MIME::Base64;
+  my $self = shift;
+
+  my $headers = $self->{ua}->default_headers;
+  my $header_name = HTTP_AUTHORIZATION_NAME;
+  my $method = $self->http_authorization_method;
+  if ($method eq HTTP_AUTHORIZATION_NONE) {
+    $headers->remove_header( $header_name );
+  } else {
+    $headers->header( $header_name =>
+		      "$method " .
+		      MIME::Base64::encode($self->username . ':' . $self->password, '') );
+  }
+}
+
+
 =head2 commit_message
 
   my $msg = $mvs->commit_message($msg);
--- a/bin/mvs
+++ b/bin/mvs
@@ -13,7 +13,7 @@ use Data::Dumper;
 # Options:
 our (
 	$opt_help, $opt_verbose, $opt_defaults,
-	$opt_host, $opt_lang, $opt_username, $opt_password, 
+	$opt_host, $opt_lang, $opt_username, $opt_password, $opt_basic_http_authorization,
         $opt_version, $opt_wiki_path, $opt_space_sub,
 	$opt_message, $opt_watch, $opt_minor, $opt_tls
 );
@@ -67,6 +67,7 @@ sub main {
     $wmc->language_code($opt_lang) if $opt_lang;
     $wmc->username($opt_username) if $opt_username;
     $wmc->password($opt_password) if $opt_password;
+    $wmc->http_authorization_method( 'Basic' ) if $opt_basic_http_authorization;
     $wmc->space_substitute($opt_space_sub) if $opt_space_sub;
     $wmc->wiki_path($opt_wiki_path) if $opt_wiki_path;
     $wmc->minor_edit($opt_minor) if defined($opt_minor);
@@ -190,6 +191,7 @@ sub parse_options {
 		'lang|l=s'	=> \$opt_lang,
 		'username|u=s'	=> \$opt_username,
 		'password|p=s'	=> \$opt_password,
+		'basic_http_authorization|b' => \$opt_basic_http_authorization,
 		'wikipath|w=s'	=> \$opt_wiki_path,
 		'spaces|S=s'	=> \$opt_space_sub,
 	) if $command eq 'login';
@@ -239,7 +241,7 @@ mvs - A command line Mediawiki client
   mkdir wikistuff
   cd wikistuff
 
-  mvs login [-q|-v] [-T] [-d <wikihost>] [-l language_code ] [-u <username>] [-p <password> ] [-w <wiki_path>] 
+  mvs login [-q|-v] [-T] [-d <wikihost>] [-l language_code ] [-u <username>] [-p <password> ] [-b] [-w <wiki_path>]
 
   mvs update [-q|-v] [<file> ..]
   mvs up [[-q|-v] <file> ..]
@@ -319,6 +321,8 @@ specify a C<language_code>:
 The code must match the one which your wiki host uses for a given language,
 and of course the language version must exist for the given host.
 
+If the wiki requires Basic HTTP Authentication, use -b.
+
 If your Mediawiki install uses a nonstandard path to the wiki script you
 can specify it on login.  The path to the wiki script is the part of the
 URL after the host name, and before the '?':
