Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. GitLabDriver.php

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\Vcs

Code

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;
        }
    }
}
RSS feed
Powered by Drupal