function GitLabDriver::getContents
@inheritDoc
Overrides VcsDriver::getContents
1 call to GitLabDriver::getContents()
- GitLabDriver::getReferences in vendor/
composer/ composer/ src/ Composer/ Repository/ Vcs/ GitLabDriver.php
File
-
vendor/
composer/ composer/ src/ Composer/ Repository/ Vcs/ GitLabDriver.php, line 458
Class
- GitLabDriver
- Driver for GitLab API, use the Git driver for local checkouts.
Namespace
Composer\Repository\VcsCode
protected function getContents(string $url, bool $fetchingRepoData = false) : Response {
try {
$response = parent::getContents($url);
if ($fetchingRepoData) {
$json = $response->decodeJson();
// Accessing the API with a token with Guest (10) access will return
// more data than unauthenticated access but no default_branch data
// accessing files via the API will then also fail
if (!isset($json['default_branch']) && isset($json['permissions'])) {
$this->isPrivate = $json['visibility'] !== 'public';
$moreThanGuestAccess = false;
// Check both access levels (e.g. project, group)
// - value will be null if no access is set
// - value will be array with key access_level if set
foreach ($json['permissions'] as $permission) {
if ($permission && $permission['access_level'] > 10) {
$moreThanGuestAccess = true;
}
}
if (!$moreThanGuestAccess) {
$this->io
->writeError('<warning>GitLab token with Guest only access detected</warning>');
$this->attemptCloneFallback();
return new Response([
'url' => 'dummy',
], 200, [], 'null');
}
}
// force auth as the unauthenticated version of the API is broken
if (!isset($json['default_branch'])) {
// GitLab allows you to disable the repository inside a project to use a project only for issues and wiki
if (isset($json['repository_access_level']) && $json['repository_access_level'] === 'disabled') {
throw new TransportException('The GitLab repository is disabled in the project', 400);
}
if (!empty($json['id'])) {
$this->isPrivate = false;
}
throw new TransportException('GitLab API seems to not be authenticated as it did not return a default_branch', 401);
}
}
return $response;
} catch (TransportException $e) {
$gitLabUtil = new GitLab($this->io, $this->config, $this->process, $this->httpDownloader);
switch ($e->getCode()) {
case 401:
case 404:
// try to authorize only if we are fetching the main /repos/foo/bar data, otherwise it must be a real 404
if (!$fetchingRepoData) {
throw $e;
}
if ($gitLabUtil->authorizeOAuth($this->originUrl)) {
return parent::getContents($url);
}
if ($gitLabUtil->isOAuthExpired($this->originUrl) && $gitLabUtil->authorizeOAuthRefresh($this->scheme, $this->originUrl)) {
return parent::getContents($url);
}
if (!$this->io
->isInteractive()) {
$this->attemptCloneFallback();
return new Response([
'url' => 'dummy',
], 200, [], 'null');
}
$this->io
->writeError('<warning>Failed to download ' . $this->namespace . '/' . $this->repository . ':' . $e->getMessage() . '</warning>');
$gitLabUtil->authorizeOAuthInteractively($this->scheme, $this->originUrl, 'Your credentials are required to fetch private repository metadata (<info>' . $this->url . '</info>)');
return parent::getContents($url);
case 403:
if (!$this->io
->hasAuthentication($this->originUrl) && $gitLabUtil->authorizeOAuth($this->originUrl)) {
return parent::getContents($url);
}
if (!$this->io
->isInteractive() && $fetchingRepoData) {
$this->attemptCloneFallback();
return new Response([
'url' => 'dummy',
], 200, [], 'null');
}
throw $e;
default:
throw $e;
}
}
}