From 9d03dc5a899a1e6f4c1215034a509c681f4aa023 Mon Sep 17 00:00:00 2001 From: Mark Achee Date: Sun, 30 Sep 2012 11:12:29 -0500 Subject: [PATCH 1/4] Attempt user/pass authentication for git repos not on github --- src/Composer/Downloader/GitDownloader.php | 30 +++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/Composer/Downloader/GitDownloader.php b/src/Composer/Downloader/GitDownloader.php index a882002ff..92b2e13c8 100644 --- a/src/Composer/Downloader/GitDownloader.php +++ b/src/Composer/Downloader/GitDownloader.php @@ -199,6 +199,36 @@ class GitDownloader extends VcsDownloader } $retrying = true; } while (--$retries); + } elseif ( + $this->io->isInteractive() && + preg_match('{(https?://)([^/]+/)(.*)$}i', $url, $match) && + strpos($this->process->getErrorOutput(), 'fatal: Authentication failed') === 0 + ) { + if ($saved = $this->io->hasAuthorization($match[1].$match[2])) { + $auth = $this->io->getAuthorization($match[1].$match[2]); + } else { + $this->io->write($match[1].$match[2].' ('.$match[3].') requires Authentication'); + $auth = array( + 'username' => $this->io->ask('Username: '), + 'password' => $this->io->askAndHideAnswer('Password: '), + ); + } + + $url = $match[1].urlencode($auth['username']).':'. + urlencode($auth['password']).'@'.$match[2].$match[3]; + + $command = call_user_func($commandCallable, $url); + if (0 === $this->process->execute($command, $handler)) { + if (!$saved) { + $saved = $this->io->ask('Save user/pass for other requests to '. + $match[1].$match[2].' ? [y]/n: '); + if (in_array($saved, array('y', 'Y', null), true)) { + $this->io->setAuthorization($match[1].$match[2], $auth['username'], $auth['password']); + $this->io->write('saved...'); + } + } + return; + } } if (null !== $path) { From ac2fed29a4aa13272b3915055e1bba039b64db8b Mon Sep 17 00:00:00 2001 From: Mark Achee Date: Mon, 1 Oct 2012 10:11:34 -0500 Subject: [PATCH 2/4] Store http auth creds by domain only --- src/Composer/Downloader/GitDownloader.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Composer/Downloader/GitDownloader.php b/src/Composer/Downloader/GitDownloader.php index 92b2e13c8..cd910c6f0 100644 --- a/src/Composer/Downloader/GitDownloader.php +++ b/src/Composer/Downloader/GitDownloader.php @@ -204,10 +204,10 @@ class GitDownloader extends VcsDownloader preg_match('{(https?://)([^/]+/)(.*)$}i', $url, $match) && strpos($this->process->getErrorOutput(), 'fatal: Authentication failed') === 0 ) { - if ($saved = $this->io->hasAuthorization($match[1].$match[2])) { - $auth = $this->io->getAuthorization($match[1].$match[2]); + if ($saved = $this->io->hasAuthorization($match[2])) { + $auth = $this->io->getAuthorization($match[2]); } else { - $this->io->write($match[1].$match[2].' ('.$match[3].') requires Authentication'); + $this->io->write($match[1].$match[2].$match[3].' requires Authentication'); $auth = array( 'username' => $this->io->ask('Username: '), 'password' => $this->io->askAndHideAnswer('Password: '), @@ -221,9 +221,9 @@ class GitDownloader extends VcsDownloader if (0 === $this->process->execute($command, $handler)) { if (!$saved) { $saved = $this->io->ask('Save user/pass for other requests to '. - $match[1].$match[2].' ? [y]/n: '); + $match[2].' ? [y]/n: '); if (in_array($saved, array('y', 'Y', null), true)) { - $this->io->setAuthorization($match[1].$match[2], $auth['username'], $auth['password']); + $this->io->setAuthorization($match[2], $auth['username'], $auth['password']); $this->io->write('saved...'); } } From 6f689f8926f6e59807cd7f73fb6c1a49f03eb821 Mon Sep 17 00:00:00 2001 From: Mark Achee Date: Mon, 1 Oct 2012 10:14:05 -0500 Subject: [PATCH 3/4] Look for Auth failed anywhere in errorOutput --- src/Composer/Downloader/GitDownloader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Composer/Downloader/GitDownloader.php b/src/Composer/Downloader/GitDownloader.php index cd910c6f0..dc6e4b173 100644 --- a/src/Composer/Downloader/GitDownloader.php +++ b/src/Composer/Downloader/GitDownloader.php @@ -202,7 +202,7 @@ class GitDownloader extends VcsDownloader } elseif ( $this->io->isInteractive() && preg_match('{(https?://)([^/]+/)(.*)$}i', $url, $match) && - strpos($this->process->getErrorOutput(), 'fatal: Authentication failed') === 0 + strpos($this->process->getErrorOutput(), 'fatal: Authentication failed') !== false ) { if ($saved = $this->io->hasAuthorization($match[2])) { $auth = $this->io->getAuthorization($match[2]); From 5ed5f1314b39335c2d43d1ad55fe204a5f191ba8 Mon Sep 17 00:00:00 2001 From: Mark Achee Date: Mon, 1 Oct 2012 12:56:41 -0500 Subject: [PATCH 4/4] Capture user/pass from 'git remote' when updating non github repo --- src/Composer/Downloader/GitDownloader.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Composer/Downloader/GitDownloader.php b/src/Composer/Downloader/GitDownloader.php index dc6e4b173..5cd89bdf5 100644 --- a/src/Composer/Downloader/GitDownloader.php +++ b/src/Composer/Downloader/GitDownloader.php @@ -49,12 +49,14 @@ class GitDownloader extends VcsDownloader $this->io->write(" Checking out ".$ref); $command = 'cd %s && git remote set-url composer %s && git fetch composer && git fetch --tags composer'; - // capture username/password from github URL if there is one + // capture username/password from URL if there is one $this->process->execute(sprintf('cd %s && git remote -v', escapeshellarg($path)), $output); - if (preg_match('{^composer\s+https://(.+):(.+)@github.com/}im', $output, $match)) { - $this->io->setAuthorization('github.com', $match[1], $match[2]); + if (preg_match('{^(?:composer|origin)\s+https?://(.+):(.+)@([^/]+)/}im', $output, $match)) { + $this->io->setAuthorization($match[3], urldecode($match[1]), urldecode($match[2])); } + // added in git 1.7.1, prevents prompting the user + putenv('GIT_ASKPASS=echo'); $commandCallable = function($url) use ($ref, $path, $command) { return sprintf($command, escapeshellarg($path), escapeshellarg($url), escapeshellarg($ref)); }; @@ -201,7 +203,7 @@ class GitDownloader extends VcsDownloader } while (--$retries); } elseif ( $this->io->isInteractive() && - preg_match('{(https?://)([^/]+/)(.*)$}i', $url, $match) && + preg_match('{(https?://)([^/]+)(.*)$}i', $url, $match) && strpos($this->process->getErrorOutput(), 'fatal: Authentication failed') !== false ) { if ($saved = $this->io->hasAuthorization($match[2])) {