1
0
Fork 0

Prompt users in interactive mode for where to store the credentials if a local auth config file exists (#11188)

pull/11230/head
PrinsFrank 2022-12-16 14:31:28 +01:00 committed by GitHub
parent 8ff237afb6
commit b1f3f8b8fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 44 additions and 11 deletions

View File

@ -102,6 +102,8 @@ class Config
private $configSource;
/** @var ConfigSourceInterface */
private $authConfigSource;
/** @var ConfigSourceInterface|null */
private $localAuthConfigSource = null;
/** @var bool */
private $useEnvironment;
/** @var array<string, true> */
@ -153,6 +155,16 @@ class Config
return $this->authConfigSource;
}
public function setLocalAuthConfigSource(ConfigSourceInterface $source): void
{
$this->localAuthConfigSource = $source;
}
public function getLocalAuthConfigSource(): ?ConfigSourceInterface
{
return $this->localAuthConfigSource;
}
/**
* Merges new config values with the existing ones (overriding)
*

View File

@ -336,7 +336,7 @@ class Factory
$io->writeError('Loading config file ' . $localAuthFile->getPath(), true, IOInterface::DEBUG);
self::validateJsonSchema($io, $localAuthFile, JsonFile::AUTH_SCHEMA);
$config->merge(['config' => $localAuthFile->read()], $localAuthFile->getPath());
$config->setAuthConfigSource(new JsonConfigSource($localAuthFile, true));
$config->setLocalAuthConfigSource(new JsonConfigSource($localAuthFile, true));
}
}

View File

@ -141,11 +141,17 @@ class Bitbucket
$this->io->writeError($message);
}
$localAuthConfig = $this->config->getLocalAuthConfigSource();
$url = 'https://support.atlassian.com/bitbucket-cloud/docs/use-oauth-on-bitbucket-cloud/';
$this->io->writeError(sprintf('Follow the instructions on %s', $url));
$this->io->writeError(sprintf('to create a consumer. It will be stored in "%s" for future use by Composer.', $this->config->getAuthConfigSource()->getName()));
$this->io->writeError(sprintf('to create a consumer. It will be stored in "%s" for future use by Composer.', ($localAuthConfig !== null ? $localAuthConfig->getName() . ' OR ' : '') . $this->config->getAuthConfigSource()->getName()));
$this->io->writeError('Ensure you enter a "Callback URL" (http://example.com is fine) or it will not be possible to create an Access Token (this callback url will not be used by composer)');
$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);
}
$consumerKey = trim((string) $this->io->askAndHideAnswer('Consumer Key (hidden): '));
if (!$consumerKey) {
@ -171,7 +177,8 @@ class Bitbucket
}
// store value in user config
$this->storeInAuthConfig($originUrl, $consumerKey, $consumerSecret);
$authConfigSource = $storeInLocalAuthConfig && $localAuthConfig !== null ? $localAuthConfig : $this->config->getAuthConfigSource();
$this->storeInAuthConfig($authConfigSource, $originUrl, $consumerKey, $consumerSecret);
// Remove conflicting basic auth credentials (if available)
$this->config->getAuthConfigSource()->removeConfigSetting('http-basic.' . $originUrl);
@ -195,7 +202,7 @@ class Bitbucket
return '';
}
$this->storeInAuthConfig($originUrl, $consumerKey, $consumerSecret);
$this->storeInAuthConfig($this->config->getLocalAuthConfigSource() ?? $this->config->getAuthConfigSource(), $originUrl, $consumerKey, $consumerSecret);
if (!isset($this->token['access_token'])) {
throw new \LogicException('Failed to initialize token above');
@ -207,7 +214,7 @@ class Bitbucket
/**
* Store the new/updated credentials to the configuration
*/
private function storeInAuthConfig(string $originUrl, string $consumerKey, string $consumerSecret): void
private function storeInAuthConfig(Config\ConfigSourceInterface $authConfigSource, string $originUrl, string $consumerKey, string $consumerSecret): void
{
$this->config->getConfigSource()->removeConfigSetting('bitbucket-oauth.'.$originUrl);

View File

@ -95,12 +95,18 @@ class GitHub
$this->io->writeError(sprintf('When working with _public_ GitHub repositories only, head to %s to retrieve a token.', $url));
$this->io->writeError('This token will have read-only permission for public information only.');
$localAuthConfig = $this->config->getLocalAuthConfigSource();
$url = 'https://'.$originUrl.'/settings/tokens/new?scopes=repo&description=' . str_replace('%20', '+', rawurlencode($note));
$this->io->writeError(sprintf('When you need to access _private_ GitHub repositories as well, go to %s', $url));
$this->io->writeError('Note that such tokens have broad read/write permissions on your behalf, even if not needed by Composer.');
$this->io->writeError(sprintf('Tokens will be stored in plain text in "%s" for future use by Composer.', $this->config->getAuthConfigSource()->getName()));
$this->io->writeError(sprintf('Tokens will be stored in plain text in "%s" for future use by Composer.', ($localAuthConfig !== null ? $localAuthConfig->getName() . ' OR ' : '') . $this->config->getAuthConfigSource()->getName()));
$this->io->writeError('For additional information, check https://getcomposer.org/doc/articles/authentication-for-private-packages.md#github-oauth');
$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);
}
$token = trim((string) $this->io->askAndHideAnswer('Token (hidden): '));
if ($token === '') {
@ -129,9 +135,10 @@ class GitHub
throw $e;
}
// store value in user config
// store value in local/user config
$authConfigSource = $storeInLocalAuthConfig && $localAuthConfig !== null ? $localAuthConfig : $this->config->getAuthConfigSource();
$this->config->getConfigSource()->removeConfigSetting('github-oauth.'.$originUrl);
$this->config->getAuthConfigSource()->addConfigSetting('github-oauth.'.$originUrl, $token);
$authConfigSource->addConfigSetting('github-oauth.'.$originUrl, $token);
$this->io->writeError('<info>Token stored successfully.</info>');

View File

@ -125,10 +125,16 @@ class GitLab
$this->io->writeError($message);
}
$this->io->writeError(sprintf('A token will be created and stored in "%s", your password will never be stored', $this->config->getAuthConfigSource()->getName()));
$localAuthConfig = $this->config->getLocalAuthConfigSource();
$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 '.$scheme.'://'.$originUrl.'/-/profile/applications');
$this->io->writeError('Alternatively you can setup an personal access token on '.$scheme.'://'.$originUrl.'/-/profile/personal_access_tokens and store it under "gitlab-token" see https://getcomposer.org/doc/articles/authentication-for-private-packages.md#gitlab-token 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) {
@ -160,9 +166,10 @@ class GitLab
$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'])) {
$this->config->getAuthConfigSource()->addConfigSetting(
$authConfigSource->addConfigSetting(
'gitlab-oauth.'.$originUrl,
[
'expires-at' => intval($response['created_at']) + intval($response['expires_in']),
@ -171,7 +178,7 @@ class GitLab
]
);
} else {
$this->config->getAuthConfigSource()->addConfigSetting('gitlab-oauth.'.$originUrl, $response['access_token']);
$authConfigSource->addConfigSetting('gitlab-oauth.'.$originUrl, $response['access_token']);
}
return true;