From 50623380798dccafa03a68e3acc9c6620b43e9b8 Mon Sep 17 00:00:00 2001 From: Stephan Date: Sun, 13 Nov 2022 20:24:28 +0000 Subject: [PATCH] Audit: ignores configured repository options (#11173) * Audit: ignores configured repository options * ComposerRepository: add test case to assert that repo http options are used to make security advisory POST request --- .../Repository/ComposerRepository.php | 17 ++++--- .../Composer/Test/Mock/HttpDownloaderMock.php | 6 ++- .../Repository/ComposerRepositoryTest.php | 50 +++++++++++++++++++ 3 files changed, 63 insertions(+), 10 deletions(-) diff --git a/src/Composer/Repository/ComposerRepository.php b/src/Composer/Repository/ComposerRepository.php index f06fcf5c2..1dcf991aa 100644 --- a/src/Composer/Repository/ComposerRepository.php +++ b/src/Composer/Repository/ComposerRepository.php @@ -690,14 +690,15 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito } if ($apiUrl !== null && count($packageConstraintMap) > 0) { - $options = [ - 'http' => [ - 'method' => 'POST', - 'header' => ['Content-type: application/x-www-form-urlencoded'], - 'timeout' => 10, - 'content' => http_build_query(['packages' => array_keys($packageConstraintMap)]), - ], - ]; + $options = $this->options; + $options['http']['method'] = 'POST'; + if (isset($options['http']['header'])) { + $options['http']['header'] = (array) $options['http']['header']; + } + $options['http']['header'][] = 'Content-type: application/x-www-form-urlencoded'; + $options['http']['timeout'] = 10; + $options['http']['content'] = http_build_query(['packages' => array_keys($packageConstraintMap)]); + $response = $this->httpDownloader->get($apiUrl, $options); /** @var string $name */ foreach ($response->decodeJson()['advisories'] as $name => $list) { diff --git a/tests/Composer/Test/Mock/HttpDownloaderMock.php b/tests/Composer/Test/Mock/HttpDownloaderMock.php index 538124a1d..0005a5d87 100644 --- a/tests/Composer/Test/Mock/HttpDownloaderMock.php +++ b/tests/Composer/Test/Mock/HttpDownloaderMock.php @@ -112,8 +112,10 @@ class HttpDownloaderMock extends HttpDownloader } throw new AssertionFailedError( - 'Received unexpected request for "'.$fileUrl.'"'.PHP_EOL. - (is_array($this->expectations) && count($this->expectations) > 0 ? 'Expected "'.$this->expectations[0]['url'].'" at this point.' : 'Expected no more calls at this point.').PHP_EOL. + 'Received unexpected request for "'.$fileUrl.'" with options "'.json_encode($options).'"'.PHP_EOL. + (is_array($this->expectations) && count($this->expectations) > 0 + ? 'Expected "'.$this->expectations[0]['url'].($this->expectations[0]['options'] !== null ? '" with options "'.json_encode($this->expectations[0]['options']) : '').'" at this point.' + : 'Expected no more calls at this point.').PHP_EOL. 'Received calls:'.PHP_EOL.implode(PHP_EOL, array_slice($this->log, 0, -1)) ); } diff --git a/tests/Composer/Test/Repository/ComposerRepositoryTest.php b/tests/Composer/Test/Repository/ComposerRepositoryTest.php index 19192ffda..0806bb108 100644 --- a/tests/Composer/Test/Repository/ComposerRepositoryTest.php +++ b/tests/Composer/Test/Repository/ComposerRepositoryTest.php @@ -16,6 +16,7 @@ use Composer\IO\NullIO; use Composer\Json\JsonFile; use Composer\Repository\ComposerRepository; use Composer\Repository\RepositoryInterface; +use Composer\Semver\Constraint\Constraint; use Composer\Test\Mock\FactoryMock; use Composer\Test\TestCase; use Composer\Package\Loader\ArrayLoader; @@ -380,4 +381,53 @@ class ComposerRepositoryTest extends TestCase $this->assertEquals(['foo/bar'], $repository->getPackageNames()); } + + public function testGetSecurityAdvisoriesAssertRepositoryHttpOptionsAreUsed(): void + { + $httpDownloader = $this->getHttpDownloaderMock(); + $httpDownloader->expects( + [ + [ + 'url' => 'https://example.org/packages.json', + 'body' => JsonFile::encode([ + 'packages' => ['foo/bar' => [ + 'dev-branch' => ['name' => 'foo/bar'], + 'v1.0.0' => ['name' => 'foo/bar'], + ]], + 'metadata-url' => 'https://example.org/p2/%package%.json', + 'security-advisories' => [ + 'api-url' => 'https://example.org/security-advisories', + ], + ]), + 'options' => ['http' => ['verify_peer' => false]], + ], + [ + 'url' => 'https://example.org/security-advisories', + 'body' => JsonFile::encode(['advisories' => []]), + 'options' => ['http' => [ + 'verify_peer' => false, + 'method' => 'POST', + 'header' => [ + 'Content-type: application/x-www-form-urlencoded', + ], + 'timeout' => 10, + 'content' => http_build_query(['packages' => ['foo/bar']]), + ]], + ] + ], + true + ); + + $repository = new ComposerRepository( + ['url' => 'https://example.org/packages.json', 'options' => ['http' => ['verify_peer' => false]]], + new NullIO(), + FactoryMock::createConfig(), + $httpDownloader + ); + + $this->assertSame([ + 'namesFound' => [], + 'advisories' => [], + ], $repository->getSecurityAdvisories(['foo/bar' => new Constraint('=', '1.0.0.0')])); + } }