PageRenderTime 46ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/drush/composer/vendor/composer/composer/src/Composer/Util/GitLab.php

https://bitbucket.org/kbasarab/kbasarab_vim
PHP | 153 lines | 85 code | 26 blank | 42 comment | 7 complexity | 0997243dd4f9d63a455519c8d0188f53 MD5 | raw file
Possible License(s): MIT
  1. <?php
  2. /*
  3. * This file is part of Composer.
  4. *
  5. * (c) Nils Adermann <naderman@naderman.de>
  6. * Jordi Boggiano <j.boggiano@seld.be>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11. namespace Composer\Util;
  12. use Composer\IO\IOInterface;
  13. use Composer\Config;
  14. use Composer\Factory;
  15. use Composer\Downloader\TransportException;
  16. use Composer\Json\JsonFile;
  17. /**
  18. * @author Roshan Gautam <roshan.gautam@hotmail.com>
  19. */
  20. class GitLab
  21. {
  22. protected $io;
  23. protected $config;
  24. protected $process;
  25. protected $remoteFilesystem;
  26. /**
  27. * Constructor.
  28. *
  29. * @param IOInterface $io The IO instance
  30. * @param Config $config The composer configuration
  31. * @param ProcessExecutor $process Process instance, injectable for mocking
  32. * @param RemoteFilesystem $remoteFilesystem Remote Filesystem, injectable for mocking
  33. */
  34. public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, RemoteFilesystem $remoteFilesystem = null)
  35. {
  36. $this->io = $io;
  37. $this->config = $config;
  38. $this->process = $process ?: new ProcessExecutor();
  39. $this->remoteFilesystem = $remoteFilesystem ?: Factory::createRemoteFilesystem($this->io, $config);
  40. }
  41. /**
  42. * Attempts to authorize a GitLab domain via OAuth.
  43. *
  44. * @param string $originUrl The host this GitLab instance is located at
  45. *
  46. * @return bool true on success
  47. */
  48. public function authorizeOAuth($originUrl)
  49. {
  50. if (!in_array($originUrl, $this->config->get('gitlab-domains'), true)) {
  51. return false;
  52. }
  53. // if available use token from git config
  54. if (0 === $this->process->execute('git config gitlab.accesstoken', $output)) {
  55. $this->io->setAuthentication($originUrl, trim($output), 'oauth2');
  56. return true;
  57. }
  58. return false;
  59. }
  60. /**
  61. * Authorizes a GitLab domain interactively via OAuth.
  62. *
  63. * @param string $originUrl The host this GitLab instance is located at
  64. * @param string $message The reason this authorization is required
  65. *
  66. * @throws \RuntimeException
  67. * @throws TransportException|\Exception
  68. *
  69. * @return bool true on success
  70. */
  71. public function authorizeOAuthInteractively($scheme, $originUrl, $message = null)
  72. {
  73. if ($message) {
  74. $this->io->writeError($message);
  75. }
  76. $this->io->writeError(sprintf('A token will be created and stored in "%s", your password will never be stored', $this->config->getAuthConfigSource()->getName()));
  77. $this->io->writeError('To revoke access to this token you can visit '.$originUrl.'/profile/applications');
  78. $attemptCounter = 0;
  79. while ($attemptCounter++ < 5) {
  80. try {
  81. $response = $this->createToken($scheme, $originUrl);
  82. } catch (TransportException $e) {
  83. // 401 is bad credentials,
  84. // 403 is max login attempts exceeded
  85. if (in_array($e->getCode(), array(403, 401))) {
  86. if (401 === $e->getCode()) {
  87. $this->io->writeError('Bad credentials.');
  88. } else {
  89. $this->io->writeError('Maximum number of login attempts exceeded. Please try again later.');
  90. }
  91. $this->io->writeError('You can also manually create a personal token at '.$scheme.'://'.$originUrl.'/profile/applications');
  92. $this->io->writeError('Add it using "composer config gitlab-oauth.'.$originUrl.' <token>"');
  93. continue;
  94. }
  95. throw $e;
  96. }
  97. $this->io->setAuthentication($originUrl, $response['access_token'], 'oauth2');
  98. // store value in user config in auth file
  99. $this->config->getAuthConfigSource()->addConfigSetting('gitlab-oauth.'.$originUrl, $response['access_token']);
  100. return true;
  101. }
  102. throw new \RuntimeException('Invalid GitLab credentials 5 times in a row, aborting.');
  103. }
  104. private function createToken($scheme, $originUrl)
  105. {
  106. $username = $this->io->ask('Username: ');
  107. $password = $this->io->askAndHideAnswer('Password: ');
  108. $headers = array('Content-Type: application/x-www-form-urlencoded');
  109. $apiUrl = $originUrl;
  110. $data = http_build_query(array(
  111. 'username' => $username,
  112. 'password' => $password,
  113. 'grant_type' => 'password',
  114. ));
  115. $options = array(
  116. 'retry-auth-failure' => false,
  117. 'http' => array(
  118. 'method' => 'POST',
  119. 'header' => $headers,
  120. 'content' => $data,
  121. ),
  122. );
  123. $json = $this->remoteFilesystem->getContents($originUrl, $scheme.'://'.$apiUrl.'/oauth/token', false, $options);
  124. $this->io->writeError('Token successfully created');
  125. return JsonFile::parseJson($json);
  126. }
  127. }