OAuthOAuth2ServiceAbstractService

The Gravity Forms Salesforce Add-On OAuth OAuth2 Service AbstractService class.

Defined (1)

The class is defined in the following location(s).

/lib/PHPoAuthLib/src/OAuth/OAuth2/Service/AbstractService.php  
  1. abstract class AbstractService extends BaseAbstractService implements ServiceInterface 
  2. /** @const OAUTH_VERSION */ 
  3. const OAUTH_VERSION = 2; 
  4.  
  5. /** @var array */ 
  6. protected $scopes; 
  7.  
  8. /** @var UriInterface|null */ 
  9. protected $baseApiUri; 
  10.  
  11. /** @var bool */ 
  12. protected $stateParameterInAuthUrl; 
  13.  
  14. /** 
  15. * @param CredentialsInterface $credentials 
  16. * @param ClientInterface $httpClient 
  17. * @param TokenStorageInterface $storage 
  18. * @param array $scopes 
  19. * @param UriInterface|null $baseApiUri 
  20. * @param bool $stateParameterInAutUrl 
  21. * @throws InvalidScopeException 
  22. */ 
  23. public function __construct( 
  24. CredentialsInterface $credentials,  
  25. ClientInterface $httpClient,  
  26. TokenStorageInterface $storage,  
  27. $scopes = array(),  
  28. UriInterface $baseApiUri = null,  
  29. $stateParameterInAutUrl = false 
  30. ) { 
  31. parent::__construct($credentials, $httpClient, $storage); 
  32. $this->stateParameterInAuthUrl = $stateParameterInAutUrl; 
  33.  
  34. foreach ($scopes as $scope) { 
  35. if (!$this->isValidScope($scope)) { 
  36. throw new InvalidScopeException('Scope ' . $scope . ' is not valid for service ' . get_class($this)); 
  37.  
  38. $this->scopes = $scopes; 
  39.  
  40. $this->baseApiUri = $baseApiUri; 
  41.  
  42. /** 
  43. * {@inheritdoc} 
  44. */ 
  45. public function getAuthorizationUri(array $additionalParameters = array()) 
  46. $parameters = array_merge( 
  47. $additionalParameters,  
  48. array( 
  49. 'type' => 'web_server',  
  50. 'client_id' => $this->credentials->getConsumerId(),  
  51. 'redirect_uri' => $this->credentials->getCallbackUrl(),  
  52. 'response_type' => 'code',  
  53. ); 
  54.  
  55. $parameters['scope'] = implode(' ', $this->scopes); 
  56.  
  57. if ($this->needsStateParameterInAuthUrl()) { 
  58. if (!isset($parameters['state'])) { 
  59. $parameters['state'] = $this->generateAuthorizationState(); 
  60. $this->storeAuthorizationState($parameters['state']); 
  61.  
  62. // Build the url 
  63. $url = clone $this->getAuthorizationEndpoint(); 
  64. foreach ($parameters as $key => $val) { 
  65. $url->addToQuery($key, $val); 
  66.  
  67. return $url; 
  68.  
  69. /** 
  70. * {@inheritdoc} 
  71. */ 
  72. public function requestAccessToken($code, $state = null) 
  73. if (null !== $state) { 
  74. $this->validateAuthorizationState($state); 
  75.  
  76. $bodyParams = array( 
  77. 'code' => $code,  
  78. 'client_id' => $this->credentials->getConsumerId(),  
  79. 'client_secret' => $this->credentials->getConsumerSecret(),  
  80. 'redirect_uri' => $this->credentials->getCallbackUrl(),  
  81. 'grant_type' => 'authorization_code',  
  82. ); 
  83.  
  84. $responseBody = $this->httpClient->retrieveResponse( 
  85. $this->getAccessTokenEndpoint(),  
  86. $bodyParams,  
  87. $this->getExtraOAuthHeaders() 
  88. ); 
  89.  
  90. $token = $this->parseAccessTokenResponse($responseBody); 
  91. $this->storage->storeAccessToken($this->service(), $token); 
  92.  
  93. return $token; 
  94.  
  95. /** 
  96. * Sends an authenticated API request to the path provided. 
  97. * If the path provided is not an absolute URI, the base API Uri (must be passed into constructor) will be used. 
  98. * @param string|UriInterface $path 
  99. * @param string $method HTTP method 
  100. * @param array $body Request body if applicable. 
  101. * @param array $extraHeaders Extra headers if applicable. These will override service-specific 
  102. * any defaults. 
  103. * @return string 
  104. * @throws ExpiredTokenException 
  105. * @throws Exception 
  106. */ 
  107. public function request($path, $method = 'GET', $body = null, array $extraHeaders = array()) 
  108. $uri = $this->determineRequestUriFromPath($path, $this->baseApiUri); 
  109. $token = $this->storage->retrieveAccessToken($this->service()); 
  110.  
  111. if ($token->getEndOfLife() !== TokenInterface::EOL_NEVER_EXPIRES 
  112. && $token->getEndOfLife() !== TokenInterface::EOL_UNKNOWN 
  113. && time() > $token->getEndOfLife() 
  114. ) { 
  115. throw new ExpiredTokenException( 
  116. sprintf( 
  117. 'Token expired on %s at %s',  
  118. date('m/d/Y', $token->getEndOfLife()),  
  119. date('h:i:s A', $token->getEndOfLife()) 
  120. ); 
  121.  
  122. // add the token where it may be needed 
  123. if (static::AUTHORIZATION_METHOD_HEADER_OAUTH === $this->getAuthorizationMethod()) { 
  124. $extraHeaders = array_merge(array('Authorization' => 'OAuth ' . $token->getAccessToken()), $extraHeaders); 
  125. } elseif (static::AUTHORIZATION_METHOD_QUERY_STRING === $this->getAuthorizationMethod()) { 
  126. $uri->addToQuery('access_token', $token->getAccessToken()); 
  127. } elseif (static::AUTHORIZATION_METHOD_QUERY_STRING_V2 === $this->getAuthorizationMethod()) { 
  128. $uri->addToQuery('oauth2_access_token', $token->getAccessToken()); 
  129. } elseif (static::AUTHORIZATION_METHOD_QUERY_STRING_V3 === $this->getAuthorizationMethod()) { 
  130. $uri->addToQuery('apikey', $token->getAccessToken()); 
  131. } elseif (static::AUTHORIZATION_METHOD_HEADER_BEARER === $this->getAuthorizationMethod()) { 
  132. $extraHeaders = array_merge(array('Authorization' => 'Bearer ' . $token->getAccessToken()), $extraHeaders); 
  133.  
  134. $extraHeaders = array_merge($this->getExtraApiHeaders(), $extraHeaders); 
  135.  
  136. return $this->httpClient->retrieveResponse($uri, $body, $extraHeaders, $method); 
  137.  
  138. /** 
  139. * Accessor to the storage adapter to be able to retrieve tokens 
  140. * @return TokenStorageInterface 
  141. */ 
  142. public function getStorage() 
  143. return $this->storage; 
  144.  
  145. /** 
  146. * Refreshes an OAuth2 access token. 
  147. * @param TokenInterface $token 
  148. * @return TokenInterface $token 
  149. * @throws MissingRefreshTokenException 
  150. */ 
  151. public function refreshAccessToken(TokenInterface $token) 
  152. $refreshToken = $token->getRefreshToken(); 
  153.  
  154. if (empty($refreshToken)) { 
  155. throw new MissingRefreshTokenException(); 
  156.  
  157. $parameters = array( 
  158. 'grant_type' => 'refresh_token',  
  159. 'type' => 'web_server',  
  160. 'client_id' => $this->credentials->getConsumerId(),  
  161. 'client_secret' => $this->credentials->getConsumerSecret(),  
  162. 'refresh_token' => $refreshToken,  
  163. ); 
  164.  
  165. $responseBody = $this->httpClient->retrieveResponse( 
  166. $this->getAccessTokenEndpoint(),  
  167. $parameters,  
  168. $this->getExtraOAuthHeaders() 
  169. ); 
  170. $token = $this->parseAccessTokenResponse($responseBody); 
  171. $this->storage->storeAccessToken($this->service(), $token); 
  172.  
  173. return $token; 
  174.  
  175. /** 
  176. * Return whether or not the passed scope value is valid. 
  177. * @param string $scope 
  178. * @return bool 
  179. */ 
  180. public function isValidScope($scope) 
  181. $reflectionClass = new \ReflectionClass(get_class($this)); 
  182.  
  183. return in_array($scope, $reflectionClass->getConstants(), true); 
  184.  
  185. /** 
  186. * Check if the given service need to generate a unique state token to build the authorization url 
  187. * @return bool 
  188. */ 
  189. public function needsStateParameterInAuthUrl() 
  190. return $this->stateParameterInAuthUrl; 
  191.  
  192. /** 
  193. * Validates the authorization state against a given one 
  194. * @param string $state 
  195. * @throws InvalidAuthorizationStateException 
  196. */ 
  197. protected function validateAuthorizationState($state) 
  198. if ($this->retrieveAuthorizationState() !== $state) { 
  199. throw new InvalidAuthorizationStateException(); 
  200.  
  201. /** 
  202. * Generates a random string to be used as state 
  203. * @return string 
  204. */ 
  205. protected function generateAuthorizationState() 
  206. return md5(rand()); 
  207.  
  208. /** 
  209. * Retrieves the authorization state for the current service 
  210. * @return string 
  211. */ 
  212. protected function retrieveAuthorizationState() 
  213. return $this->storage->retrieveAuthorizationState($this->service()); 
  214.  
  215. /** 
  216. * Stores a given authorization state into the storage 
  217. * @param string $state 
  218. */ 
  219. protected function storeAuthorizationState($state) 
  220. $this->storage->storeAuthorizationState($this->service(), $state); 
  221.  
  222. /** 
  223. * Return any additional headers always needed for this service implementation's OAuth calls. 
  224. * @return array 
  225. */ 
  226. protected function getExtraOAuthHeaders() 
  227. return array(); 
  228.  
  229. /** 
  230. * Return any additional headers always needed for this service implementation's API calls. 
  231. * @return array 
  232. */ 
  233. protected function getExtraApiHeaders() 
  234. return array(); 
  235.  
  236. /** 
  237. * Parses the access token response and returns a TokenInterface. 
  238. * @abstract 
  239. * @param string $responseBody 
  240. * @return TokenInterface 
  241. * @throws TokenResponseException 
  242. */ 
  243. abstract protected function parseAccessTokenResponse($responseBody); 
  244.  
  245. /** 
  246. * Returns a class constant from ServiceInterface defining the authorization method used for the API 
  247. * Header is the sane default. 
  248. * @return int 
  249. */ 
  250. protected function getAuthorizationMethod() 
  251. return static::AUTHORIZATION_METHOD_HEADER_OAUTH;