From 3b4a3d63bf7ccc2189d6a81228c453fcc358c732 Mon Sep 17 00:00:00 2001 From: Stephan Vock Date: Thu, 21 Apr 2022 09:37:55 +0100 Subject: [PATCH 1/3] GitLab: prevent invalid loop during composer install with invalid credentials --- src/Composer/Util/AuthHelper.php | 7 ++++ tests/Composer/Test/Util/AuthHelperTest.php | 36 +++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/src/Composer/Util/AuthHelper.php b/src/Composer/Util/AuthHelper.php index 28c4aba68..c208a1018 100644 --- a/src/Composer/Util/AuthHelper.php +++ b/src/Composer/Util/AuthHelper.php @@ -137,6 +137,7 @@ class AuthHelper $message = "\n".'Could not fetch '.$url.', enter your ' . $origin . ' credentials ' .($statusCode === 401 ? 'to access private repos' : 'to go over the API rate limit'); $gitLabUtil = new GitLab($this->io, $this->config, null); + $auth = null; if ($this->io->hasAuthentication($origin)) { $auth = $this->io->getAuthentication($origin); if (in_array($auth['password'], array('gitlab-ci-token', 'private-token', 'oauth2'), true)) { @@ -149,6 +150,12 @@ class AuthHelper ) { throw new TransportException('Could not authenticate against '.$origin, 401); } + + if ($auth !== null && $this->io->hasAuthentication($origin)) { + if ($auth === $this->io->getAuthentication($origin)) { + throw new TransportException("Invalid credentials for '" . $url . "', aborting.", $statusCode); + } + } } elseif ($origin === 'bitbucket.org' || $origin === 'api.bitbucket.org') { $askForOAuthToken = true; $origin = 'bitbucket.org'; diff --git a/tests/Composer/Test/Util/AuthHelperTest.php b/tests/Composer/Test/Util/AuthHelperTest.php index d7018cd1c..9372e691f 100644 --- a/tests/Composer/Test/Util/AuthHelperTest.php +++ b/tests/Composer/Test/Util/AuthHelperTest.php @@ -12,6 +12,7 @@ namespace Composer\Test\Util; +use Composer\Downloader\TransportException; use Composer\IO\IOInterface; use Composer\Test\TestCase; use Composer\Util\AuthHelper; @@ -513,6 +514,41 @@ class AuthHelperTest extends TestCase $this->authHelper->storeAuth($origin, $storeAuth); } + public function testPromptAuthIfNeededGitLabNoAuthChange() + { + $this->setExpectedException('Composer\Downloader\TransportException'); + + $origin = 'gitlab.com'; + + $this->io + ->method('hasAuthentication') + ->with($origin) + ->willReturn(true); + + $this->io + ->method('getAuthentication') + ->with($origin) + ->willReturn(array( + 'username' => 'gitlab-user', + 'password' => 'gitlab-password', + )); + + $this->io + ->expects($this->once()) + ->method('setAuthentication') + ->with('gitlab.com', 'gitlab-user', 'gitlab-password'); + + $this->config + ->method('get') + ->willReturnMap(array( + array('github-domains', 0, array()), + array('gitlab-domains', 0, array('gitlab.com')), + array('gitlab-token', 0, array('gitlab.com' => array('username' => 'gitlab-user', 'token' => 'gitlab-password'))), + )); + + $this->authHelper->promptAuthIfNeeded('https://gitlab.com/acme/archive.zip', $origin, 404, 'GitLab requires authentication and it was not provided'); + } + /** * @param string $origin * @param array $auth From 89721ab32203c41a9904e83921e543c550aae89f Mon Sep 17 00:00:00 2001 From: Stephan Vock Date: Thu, 21 Apr 2022 09:47:23 +0100 Subject: [PATCH 2/3] GitLab: detect invalid token setup and attempt to automatically resolve the issue for the user --- src/Composer/Util/GitLab.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Composer/Util/GitLab.php b/src/Composer/Util/GitLab.php index 4c1376ad4..57b87c576 100644 --- a/src/Composer/Util/GitLab.php +++ b/src/Composer/Util/GitLab.php @@ -92,7 +92,14 @@ class GitLab if (isset($token)) { $username = is_array($token) && array_key_exists("username", $token) ? $token["username"] : $token; $password = is_array($token) && array_key_exists("token", $token) ? $token["token"] : 'private-token'; - $this->io->setAuthentication($originUrl, $username, $password); + + // Composer expects the GitLab token to be stored as username and 'private-token' or 'gitlab-ci-token' to be stored as password + // Detect cases where this is reversed and resolve automatically resolve it + if (in_array($username, array('private-token', 'gitlab-ci-token', 'oauth2'), true)) { + $this->io->setAuthentication($originUrl, $password, $username); + } else { + $this->io->setAuthentication($originUrl, $username, $password); + } return true; } From d40c3a89c010b7ed1123de6a6e6b25f98138ea82 Mon Sep 17 00:00:00 2001 From: Stephan Vock Date: Thu, 28 Apr 2022 21:27:16 +0100 Subject: [PATCH 3/3] GitLab: add warning in case GitLab authentication is misconfigured --- tests/Composer/Test/Util/AuthHelperTest.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/Composer/Test/Util/AuthHelperTest.php b/tests/Composer/Test/Util/AuthHelperTest.php index 9372e691f..9dd4bacf4 100644 --- a/tests/Composer/Test/Util/AuthHelperTest.php +++ b/tests/Composer/Test/Util/AuthHelperTest.php @@ -474,6 +474,9 @@ class AuthHelperTest extends TestCase $this->authHelper->storeAuth($origin, $storeAuth); } + /** + * @return void + */ public function testStoreAuthWithPromptInvalidAnswer() { $this->setExpectedException('RuntimeException'); @@ -514,6 +517,9 @@ class AuthHelperTest extends TestCase $this->authHelper->storeAuth($origin, $storeAuth); } + /** + * @return void + */ public function testPromptAuthIfNeededGitLabNoAuthChange() { $this->setExpectedException('Composer\Downloader\TransportException');