Harvest.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. <?php
  2. namespace OAuth\OAuth2\Service;
  3. use OAuth\Common\Consumer\CredentialsInterface;
  4. use OAuth\Common\Http\Client\ClientInterface;
  5. use OAuth\Common\Http\Exception\TokenResponseException;
  6. use OAuth\Common\Http\Uri\Uri;
  7. use OAuth\Common\Http\Uri\UriInterface;
  8. use OAuth\Common\Storage\TokenStorageInterface;
  9. use OAuth\Common\Token\TokenInterface;
  10. use OAuth\OAuth2\Token\StdOAuth2Token;
  11. class Harvest extends AbstractService
  12. {
  13. public function __construct(
  14. CredentialsInterface $credentials,
  15. ClientInterface $httpClient,
  16. TokenStorageInterface $storage,
  17. $scopes = array(),
  18. UriInterface $baseApiUri = null
  19. ) {
  20. parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri);
  21. if (null === $baseApiUri) {
  22. $this->baseApiUri = new Uri('https://api.harvestapp.com/');
  23. }
  24. }
  25. /**
  26. * {@inheritdoc}
  27. */
  28. public function getAuthorizationUri(array $additionalParameters = array())
  29. {
  30. $parameters = array_merge(
  31. $additionalParameters,
  32. array(
  33. 'client_id' => $this->credentials->getConsumerId(),
  34. 'redirect_uri' => $this->credentials->getCallbackUrl(),
  35. 'state' => 'optional-csrf-token',
  36. 'response_type' => 'code',
  37. )
  38. );
  39. // Build the url
  40. $url = clone $this->getAuthorizationEndpoint();
  41. foreach ($parameters as $key => $val) {
  42. $url->addToQuery($key, $val);
  43. }
  44. return $url;
  45. }
  46. /**
  47. * {@inheritdoc}
  48. */
  49. public function getAuthorizationEndpoint()
  50. {
  51. return new Uri('https://api.harvestapp.com/oauth2/authorize');
  52. }
  53. /**
  54. * {@inheritdoc}
  55. */
  56. public function getAccessTokenEndpoint()
  57. {
  58. return new Uri('https://api.harvestapp.com/oauth2/token');
  59. }
  60. /**
  61. * {@inheritdoc}
  62. */
  63. protected function getAuthorizationMethod()
  64. {
  65. return static::AUTHORIZATION_METHOD_QUERY_STRING;
  66. }
  67. /**
  68. * {@inheritdoc}
  69. */
  70. protected function parseAccessTokenResponse($responseBody)
  71. {
  72. $data = json_decode($responseBody, true);
  73. if (null === $data || ! is_array($data)) {
  74. throw new TokenResponseException('Unable to parse response.');
  75. } elseif (isset($data['error'])) {
  76. throw new TokenResponseException('Error in retrieving token: "' . $data['error'] . '"');
  77. }
  78. $token = new StdOAuth2Token();
  79. $token->setAccessToken($data['access_token']);
  80. $token->setLifetime($data['expires_in']);
  81. $token->setRefreshToken($data['refresh_token']);
  82. unset($data['access_token']);
  83. $token->setExtraParams($data);
  84. return $token;
  85. }
  86. /**
  87. * Refreshes an OAuth2 access token.
  88. *
  89. * @param TokenInterface $token
  90. *
  91. * @return TokenInterface $token
  92. *
  93. * @throws MissingRefreshTokenException
  94. */
  95. public function refreshAccessToken(TokenInterface $token)
  96. {
  97. $refreshToken = $token->getRefreshToken();
  98. if (empty($refreshToken)) {
  99. throw new MissingRefreshTokenException();
  100. }
  101. $parameters = array(
  102. 'grant_type' => 'refresh_token',
  103. 'type' => 'web_server',
  104. 'client_id' => $this->credentials->getConsumerId(),
  105. 'client_secret' => $this->credentials->getConsumerSecret(),
  106. 'refresh_token' => $refreshToken,
  107. );
  108. $responseBody = $this->httpClient->retrieveResponse(
  109. $this->getAccessTokenEndpoint(),
  110. $parameters,
  111. $this->getExtraOAuthHeaders()
  112. );
  113. $token = $this->parseAccessTokenResponse($responseBody);
  114. $this->storage->storeAccessToken($this->service(), $token);
  115. return $token;
  116. }
  117. /**
  118. * @return array
  119. */
  120. protected function getExtraOAuthHeaders()
  121. {
  122. return array('Accept' => 'application/json');
  123. }
  124. /**
  125. * Return any additional headers always needed for this service implementation's API calls.
  126. *
  127. * @return array
  128. */
  129. protected function getExtraApiHeaders()
  130. {
  131. return array('Accept' => 'application/json');
  132. }
  133. }