function GitLab::authorizeOAuthInteractively
Authorizes a GitLab domain interactively via OAuth.
Parameters
string $scheme Scheme used in the origin URL:
string $originUrl The host this GitLab instance is located at:
string $message The reason this authorization is required:
Return value
bool true on success
Throws
\RuntimeException
TransportException|\Exception
File
-
vendor/
composer/ composer/ src/ Composer/ Util/ GitLab.php, line 122
Class
- GitLab
- @author Roshan Gautam <roshan.gautam@hotmail.com>
Namespace
Composer\UtilCode
public function authorizeOAuthInteractively(string $scheme, string $originUrl, ?string $message = null) : bool {
if ($message) {
$this->io
->writeError($message);
}
$localAuthConfig = $this->config
->getLocalAuthConfigSource();
$personalAccessTokenLink = $scheme . '://' . $originUrl . '/-/profile/personal_access_tokens';
$revokeLink = $scheme . '://' . $originUrl . '/-/profile/applications';
$this->io
->writeError(sprintf('A token will be created and stored in "%s", your password will never be stored', ($localAuthConfig !== null ? $localAuthConfig->getName() . ' OR ' : '') . $this->config
->getAuthConfigSource()
->getName()));
$this->io
->writeError('To revoke access to this token you can visit:');
$this->io
->writeError($revokeLink);
$this->io
->writeError('Alternatively you can setup an personal access token on:');
$this->io
->writeError($personalAccessTokenLink);
$this->io
->writeError('and store it under "gitlab-token" see https://getcomposer.org/doc/articles/authentication-for-private-packages.md#gitlab-token for more details.');
$this->io
->writeError('https://getcomposer.org/doc/articles/authentication-for-private-packages.md#gitlab-token');
$this->io
->writeError('for more details.');
$storeInLocalAuthConfig = false;
if ($localAuthConfig !== null) {
$storeInLocalAuthConfig = $this->io
->askConfirmation('A local auth config source was found, do you want to store the token there?', true);
}
$attemptCounter = 0;
while ($attemptCounter++ < 5) {
try {
$response = $this->createToken($scheme, $originUrl);
} catch (TransportException $e) {
// 401 is bad credentials,
// 403 is max login attempts exceeded
if (in_array($e->getCode(), [
403,
401,
])) {
if (401 === $e->getCode()) {
$response = json_decode($e->getResponse(), true);
if (isset($response['error']) && $response['error'] === 'invalid_grant') {
$this->io
->writeError('Bad credentials. If you have two factor authentication enabled you will have to manually create a personal access token');
}
else {
$this->io
->writeError('Bad credentials.');
}
}
else {
$this->io
->writeError('Maximum number of login attempts exceeded. Please try again later.');
}
$this->io
->writeError('You can also manually create a personal access token enabling the "read_api" scope at:');
$this->io
->writeError($scheme . '://' . $originUrl . '/profile/personal_access_tokens');
$this->io
->writeError('Add it using "composer config --global --auth gitlab-token.' . $originUrl . ' <token>"');
continue;
}
throw $e;
}
$this->io
->setAuthentication($originUrl, $response['access_token'], 'oauth2');
$authConfigSource = $storeInLocalAuthConfig && $localAuthConfig !== null ? $localAuthConfig : $this->config
->getAuthConfigSource();
// store value in user config in auth file
if (isset($response['expires_in'])) {
$authConfigSource->addConfigSetting('gitlab-oauth.' . $originUrl, [
'expires-at' => intval($response['created_at']) + intval($response['expires_in']),
'refresh-token' => $response['refresh_token'],
'token' => $response['access_token'],
]);
}
else {
$authConfigSource->addConfigSetting('gitlab-oauth.' . $originUrl, $response['access_token']);
}
return true;
}
throw new \RuntimeException('Invalid GitLab credentials 5 times in a row, aborting.');
}