GitHub.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. <?php
  2. namespace OAuth\OAuth2\Service;
  3. use OAuth\OAuth2\Token\StdOAuth2Token;
  4. use OAuth\Common\Http\Exception\TokenResponseException;
  5. use OAuth\Common\Http\Uri\Uri;
  6. use OAuth\Common\Consumer\CredentialsInterface;
  7. use OAuth\Common\Http\Client\ClientInterface;
  8. use OAuth\Common\Storage\TokenStorageInterface;
  9. use OAuth\Common\Http\Uri\UriInterface;
  10. class GitHub extends AbstractService
  11. {
  12. /**
  13. * Defined scopes, see http://developer.github.com/v3/oauth/ for definitions.
  14. */
  15. /**
  16. * Public read-only access (includes public user profile info, public repo info, and gists)
  17. */
  18. const SCOPE_READONLY = '';
  19. /**
  20. * Read/write access to profile info only.
  21. *
  22. * Includes SCOPE_USER_EMAIL and SCOPE_USER_FOLLOW.
  23. */
  24. const SCOPE_USER = 'user';
  25. /**
  26. * Read access to a user’s email addresses.
  27. */
  28. const SCOPE_USER_EMAIL = 'user:email';
  29. /**
  30. * Access to follow or unfollow other users.
  31. */
  32. const SCOPE_USER_FOLLOW = 'user:follow';
  33. /**
  34. * Read/write access to public repos and organizations.
  35. */
  36. const SCOPE_PUBLIC_REPO = 'public_repo';
  37. /**
  38. * Read/write access to public and private repos and organizations.
  39. *
  40. * Includes SCOPE_REPO_STATUS.
  41. */
  42. const SCOPE_REPO = 'repo';
  43. /**
  44. * Grants access to deployment statuses for public and private repositories.
  45. * This scope is only necessary to grant other users or services access to deployment statuses,
  46. * without granting access to the code.
  47. */
  48. const SCOPE_REPO_DEPLOYMENT = 'repo_deployment';
  49. /**
  50. * Read/write access to public and private repository commit statuses. This scope is only necessary to grant other
  51. * users or services access to private repository commit statuses without granting access to the code. The repo and
  52. * public_repo scopes already include access to commit status for private and public repositories, respectively.
  53. */
  54. const SCOPE_REPO_STATUS = 'repo:status';
  55. /**
  56. * Delete access to adminable repositories.
  57. */
  58. const SCOPE_DELETE_REPO = 'delete_repo';
  59. /**
  60. * Read access to a user’s notifications. repo is accepted too.
  61. */
  62. const SCOPE_NOTIFICATIONS = 'notifications';
  63. /**
  64. * Write access to gists.
  65. */
  66. const SCOPE_GIST = 'gist';
  67. /**
  68. * Grants read and ping access to hooks in public or private repositories.
  69. */
  70. const SCOPE_HOOKS_READ = 'read:repo_hook';
  71. /**
  72. * Grants read, write, and ping access to hooks in public or private repositories.
  73. */
  74. const SCOPE_HOOKS_WRITE = 'write:repo_hook';
  75. /**
  76. * Grants read, write, ping, and delete access to hooks in public or private repositories.
  77. */
  78. const SCOPE_HOOKS_ADMIN = 'admin:repo_hook';
  79. /**
  80. * Read-only access to organization, teams, and membership.
  81. */
  82. const SCOPE_ORG_READ = 'read:org';
  83. /**
  84. * Publicize and unpublicize organization membership.
  85. */
  86. const SCOPE_ORG_WRITE = 'write:org';
  87. /**
  88. * Fully manage organization, teams, and memberships.
  89. */
  90. const SCOPE_ORG_ADMIN = 'admin:org';
  91. /**
  92. * List and view details for public keys.
  93. */
  94. const SCOPE_PUBLIC_KEY_READ = 'read:public_key';
  95. /**
  96. * Create, list, and view details for public keys.
  97. */
  98. const SCOPE_PUBLIC_KEY_WRITE = 'write:public_key';
  99. /**
  100. * Fully manage public keys.
  101. */
  102. const SCOPE_PUBLIC_KEY_ADMIN = 'admin:public_key';
  103. public function __construct(
  104. CredentialsInterface $credentials,
  105. ClientInterface $httpClient,
  106. TokenStorageInterface $storage,
  107. $scopes = array(),
  108. UriInterface $baseApiUri = null
  109. ) {
  110. parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);
  111. if (null === $baseApiUri) {
  112. $this->baseApiUri = new Uri('https://api.github.com/');
  113. }
  114. }
  115. /**
  116. * {@inheritdoc}
  117. */
  118. public function getAuthorizationEndpoint()
  119. {
  120. return new Uri('https://github.com/login/oauth/authorize');
  121. }
  122. /**
  123. * {@inheritdoc}
  124. */
  125. public function getAccessTokenEndpoint()
  126. {
  127. return new Uri('https://github.com/login/oauth/access_token');
  128. }
  129. /**
  130. * {@inheritdoc}
  131. */
  132. protected function getAuthorizationMethod()
  133. {
  134. return static::AUTHORIZATION_METHOD_QUERY_STRING;
  135. }
  136. /**
  137. * {@inheritdoc}
  138. */
  139. protected function parseAccessTokenResponse($responseBody)
  140. {
  141. $data = json_decode($responseBody, true);
  142. if (null === $data || !is_array($data)) {
  143. throw new TokenResponseException('Unable to parse response.');
  144. } elseif (isset($data['error'])) {
  145. throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
  146. }
  147. $token = new StdOAuth2Token();
  148. $token->setAccessToken($data['access_token']);
  149. // Github tokens evidently never expire...
  150. $token->setEndOfLife(StdOAuth2Token::EOL_NEVER_EXPIRES);
  151. unset($data['access_token']);
  152. $token->setExtraParams($data);
  153. return $token;
  154. }
  155. /**
  156. * Used to configure response type -- we want JSON from github, default is query string format
  157. *
  158. * @return array
  159. */
  160. protected function getExtraOAuthHeaders()
  161. {
  162. return array('Accept' => 'application/json');
  163. }
  164. /**
  165. * Required for GitHub API calls.
  166. *
  167. * @return array
  168. */
  169. protected function getExtraApiHeaders()
  170. {
  171. return array('Accept' => 'application/vnd.github.beta+json');
  172. }
  173. /**
  174. * {@inheritdoc}
  175. */
  176. protected function getScopesDelimiter()
  177. {
  178. return ',';
  179. }
  180. }