From: Matthieu Moy <Matthieu.Moy@imag.fr>
To: git@vger.kernel.org, gitster@pobox.com
Cc: Javier.Roucher-Iglesias@ensimag.imag.fr,
Matthieu Moy <Matthieu.Moy@imag.fr>
Subject: [PATCH 3/3] git-remote-mediawiki: add credential support
Date: Fri, 22 Jun 2012 18:07:11 +0200 [thread overview]
Message-ID: <1340381231-9522-4-git-send-email-Matthieu.Moy@imag.fr> (raw)
In-Reply-To: <1340381231-9522-1-git-send-email-Matthieu.Moy@imag.fr>
The previous version implemented the possibility to log in a wiki, but
the username and password had to be provided as configuration variables.
We add the possibility to use the Git credential system to prompt
the password.
The support if implemented with generic functions that mimic the C API,
designed to be usable from other contexts in the future (i.e. they may
migrate to Git.pm if someone is interested).
While we're there, do a bit of refactoring in mw_connect_maybe.
Based on patch by: Javier Roucher Iglesias <Javier.Roucher-Iglesias@ensimag.imag.fr>
---
contrib/mw-to-git/git-remote-mediawiki | 106 +++++++++++++++++++++++++++++----
1 file changed, 94 insertions(+), 12 deletions(-)
diff --git a/contrib/mw-to-git/git-remote-mediawiki b/contrib/mw-to-git/git-remote-mediawiki
index c18bfa1..a34f53f 100755
--- a/contrib/mw-to-git/git-remote-mediawiki
+++ b/contrib/mw-to-git/git-remote-mediawiki
@@ -43,6 +43,8 @@ use encoding 'utf8';
binmode STDERR, ":utf8";
use URI::Escape;
+use IPC::Open2;
+
use warnings;
# Mediawiki filenames can contain forward slashes. This variable decides by which pattern they should be replaced
@@ -151,28 +153,108 @@ while (<STDIN>) {
########################## Functions ##############################
+## credential API management (generic functions)
+
+sub credential_from_url {
+ my $url = shift;
+ my $parsed = URI->new($url);
+ my %credential;
+
+ if ($parsed->scheme) {
+ $credential{protocol} = $parsed->scheme;
+ }
+ if ($parsed->host) {
+ $credential{host} = $parsed->host;
+ }
+ if ($parsed->path) {
+ $credential{path} = $parsed->path;
+ }
+ if ($parsed->userinfo) {
+ if ($parsed->userinfo =~ /([^:]*):(.*)/) {
+ $credential{username} = $1;
+ $credential{password} = $2;
+ } else {
+ $credential{username} = $parsed->userinfo;
+ }
+ }
+
+ return %credential;
+}
+
+sub credential_read {
+ my %credential;
+ my $reader = shift;
+ my $op = shift;
+ while (<$reader>) {
+ my ($key, $value) = /([^=]*)=(.*)/;
+ if (not defined $key) {
+ die "ERROR receiving response from git credential $op:\n$_\n";
+ }
+ $credential{$key} = $value;
+ }
+ return %credential;
+}
+
+sub credential_write {
+ my $credential = shift;
+ my $writer = shift;
+ while (my ($key, $value) = each(%$credential) ) {
+ if ($value) {
+ print $writer "$key=$value\n";
+ }
+ }
+}
+
+sub credential_run {
+ my $op = shift;
+ my $credential = shift;
+ my $pid = open2(my $reader, my $writer, "git credential $op");
+ credential_write($credential, $writer);
+ print $writer "\n";
+ close($writer);
+
+ if ($op eq "fill") {
+ %$credential = credential_read($reader, $op);
+ } else {
+ if (<$reader>) {
+ die "ERROR while running git credential $op:\n$_";
+ }
+ }
+ close($reader);
+ waitpid($pid, 0);
+ my $child_exit_status = $? >> 8;
+ if ($child_exit_status != 0) {
+ die "'git credential $op' failed with code $child_exit_status.";
+ }
+}
+
# MediaWiki API instance, created lazily.
my $mediawiki;
sub mw_connect_maybe {
if ($mediawiki) {
- return;
+ return;
}
$mediawiki = MediaWiki::API->new;
$mediawiki->{config}->{api_url} = "$url/api.php";
if ($wiki_login) {
- if (!$mediawiki->login({
- lgname => $wiki_login,
- lgpassword => $wiki_passwd,
- lgdomain => $wiki_domain,
- })) {
- print STDERR "Failed to log in mediawiki user \"$wiki_login\" on $url\n";
- print STDERR "(error " .
- $mediawiki->{error}->{code} . ': ' .
- $mediawiki->{error}->{details} . ")\n";
- exit 1;
+ my %credential = credential_from_url($url);
+ $credential{username} = $wiki_login;
+ $credential{password} = $wiki_passwd;
+ credential_run("fill", \%credential);
+ my $request = {lgname => $credential{username},
+ lgpassword => $credential{password},
+ lgdomain => $wiki_domain};
+ if ($mediawiki->login($request)) {
+ credential_run("approve", \%credential);
+ print STDERR "Logged in mediawiki user \"$credential{username}\".\n";
} else {
- print STDERR "Logged in with user \"$wiki_login\".\n";
+ print STDERR "Failed to log in mediawiki user \"$credential{username}\" on $url\n";
+ print STDERR " (error " .
+ $mediawiki->{error}->{code} . ': ' .
+ $mediawiki->{error}->{details} . ")\n";
+ credential_run("reject", \%credential);
+ exit 1;
}
}
}
--
1.7.11.5.g0c7e058.dirty
prev parent reply other threads:[~2012-06-22 16:07 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-06-22 16:07 [PATCH 0/3] git credential plumbing command: implementation and use Matthieu Moy
2012-06-22 16:07 ` [PATCH 1/3] add 'git credential' plumbing command Matthieu Moy
2012-06-22 20:24 ` Junio C Hamano
2012-06-24 11:37 ` Matthieu Moy
2012-06-24 11:39 ` Matthieu Moy
2012-06-24 11:40 ` [PATCH 2/3] git credential fill: output the whole 'struct credential' Matthieu Moy
2012-06-24 11:40 ` [PATCH 3/3] git-remote-mediawiki: add credential support Matthieu Moy
2012-06-26 21:58 ` [PATCH 1/3] add 'git credential' plumbing command Junio C Hamano
2012-06-22 16:07 ` [PATCH 2/3] git credential fill: output the whole 'struct credential' Matthieu Moy
2012-06-22 20:26 ` Junio C Hamano
2012-06-22 16:07 ` Matthieu Moy [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1340381231-9522-4-git-send-email-Matthieu.Moy@imag.fr \
--to=matthieu.moy@imag.fr \
--cc=Javier.Roucher-Iglesias@ensimag.imag.fr \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).