[ Index ] |
PHP Cross Reference of phpBB-3.3.14-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 3 namespace OAuth\OAuth2\Service; 4 5 use OAuth\Common\Consumer\CredentialsInterface; 6 use OAuth\Common\Http\Client\ClientInterface; 7 use OAuth\Common\Http\Uri\UriInterface; 8 use OAuth\Common\Service\AbstractService as BaseAbstractService; 9 use OAuth\Common\Storage\TokenStorageInterface; 10 use OAuth\Common\Token\Exception\ExpiredTokenException; 11 use OAuth\Common\Token\TokenInterface; 12 use OAuth\OAuth2\Service\Exception\InvalidAuthorizationStateException; 13 use OAuth\OAuth2\Service\Exception\InvalidScopeException; 14 use OAuth\OAuth2\Service\Exception\MissingRefreshTokenException; 15 use ReflectionClass; 16 17 abstract class AbstractService extends BaseAbstractService implements ServiceInterface 18 { 19 /** @const OAUTH_VERSION */ 20 const OAUTH_VERSION = 2; 21 22 /** @var array */ 23 protected $scopes; 24 25 /** @var null|UriInterface */ 26 protected $baseApiUri; 27 28 /** @var bool */ 29 protected $stateParameterInAuthUrl; 30 31 /** @var string */ 32 protected $apiVersion; 33 34 /** 35 * @param array $scopes 36 * @param bool $stateParameterInAutUrl 37 * @param string $apiVersion 38 */ 39 public function __construct( 40 CredentialsInterface $credentials, 41 ClientInterface $httpClient, 42 TokenStorageInterface $storage, 43 $scopes = [], 44 ?UriInterface $baseApiUri = null, 45 $stateParameterInAutUrl = false, 46 $apiVersion = '' 47 ) { 48 parent::__construct($credentials, $httpClient, $storage); 49 $this->stateParameterInAuthUrl = $stateParameterInAutUrl; 50 51 foreach ($scopes as $scope) { 52 if (!$this->isValidScope($scope)) { 53 throw new InvalidScopeException('Scope ' . $scope . ' is not valid for service ' . get_class($this)); 54 } 55 } 56 57 $this->scopes = $scopes; 58 59 $this->baseApiUri = $baseApiUri; 60 61 $this->apiVersion = $apiVersion; 62 } 63 64 /** 65 * {@inheritdoc} 66 */ 67 public function getAuthorizationUri(array $additionalParameters = []) 68 { 69 $parameters = array_merge( 70 $additionalParameters, 71 [ 72 'type' => 'web_server', 73 'client_id' => $this->credentials->getConsumerId(), 74 'redirect_uri' => $this->credentials->getCallbackUrl(), 75 'response_type' => 'code', 76 ] 77 ); 78 79 $parameters['scope'] = implode($this->getScopesDelimiter(), $this->scopes); 80 81 if ($this->needsStateParameterInAuthUrl()) { 82 if (!isset($parameters['state'])) { 83 $parameters['state'] = $this->generateAuthorizationState(); 84 } 85 $this->storeAuthorizationState($parameters['state']); 86 } 87 88 // Build the url 89 $url = clone $this->getAuthorizationEndpoint(); 90 foreach ($parameters as $key => $val) { 91 $url->addToQuery($key, $val); 92 } 93 94 return $url; 95 } 96 97 /** 98 * {@inheritdoc} 99 */ 100 public function requestAccessToken($code, $state = null) 101 { 102 if (null !== $state) { 103 $this->validateAuthorizationState($state); 104 } 105 106 $bodyParams = [ 107 'code' => $code, 108 'client_id' => $this->credentials->getConsumerId(), 109 'client_secret' => $this->credentials->getConsumerSecret(), 110 'redirect_uri' => $this->credentials->getCallbackUrl(), 111 'grant_type' => 'authorization_code', 112 ]; 113 114 $responseBody = $this->httpClient->retrieveResponse( 115 $this->getAccessTokenEndpoint(), 116 $bodyParams, 117 $this->getExtraOAuthHeaders() 118 ); 119 120 $token = $this->parseAccessTokenResponse($responseBody); 121 $this->storage->storeAccessToken($this->service(), $token); 122 123 return $token; 124 } 125 126 /** 127 * Sends an authenticated API request to the path provided. 128 * If the path provided is not an absolute URI, the base API Uri (must be passed into constructor) will be used. 129 * 130 * @param string|UriInterface $path 131 * @param string $method HTTP method 132 * @param array $body request body if applicable 133 * @param array $extraHeaders Extra headers if applicable. These will override service-specific 134 * any defaults. 135 * 136 * @return string 137 */ 138 public function request($path, $method = 'GET', $body = null, array $extraHeaders = []) 139 { 140 $uri = $this->determineRequestUriFromPath($path, $this->baseApiUri); 141 $token = $this->storage->retrieveAccessToken($this->service()); 142 143 if ($token->getEndOfLife() !== TokenInterface::EOL_NEVER_EXPIRES 144 && $token->getEndOfLife() !== TokenInterface::EOL_UNKNOWN 145 && time() > $token->getEndOfLife() 146 ) { 147 throw new ExpiredTokenException( 148 sprintf( 149 'Token expired on %s at %s', 150 date('m/d/Y', $token->getEndOfLife()), 151 date('h:i:s A', $token->getEndOfLife()) 152 ) 153 ); 154 } 155 // add the token where it may be needed 156 if (static::AUTHORIZATION_METHOD_HEADER_OAUTH === $this->getAuthorizationMethod()) { 157 $extraHeaders = array_merge(['Authorization' => 'OAuth ' . $token->getAccessToken()], $extraHeaders); 158 } elseif (static::AUTHORIZATION_METHOD_QUERY_STRING === $this->getAuthorizationMethod()) { 159 $uri->addToQuery('access_token', $token->getAccessToken()); 160 } elseif (static::AUTHORIZATION_METHOD_QUERY_STRING_V2 === $this->getAuthorizationMethod()) { 161 $uri->addToQuery('oauth2_access_token', $token->getAccessToken()); 162 } elseif (static::AUTHORIZATION_METHOD_QUERY_STRING_V3 === $this->getAuthorizationMethod()) { 163 $uri->addToQuery('apikey', $token->getAccessToken()); 164 } elseif (static::AUTHORIZATION_METHOD_QUERY_STRING_V4 === $this->getAuthorizationMethod()) { 165 $uri->addToQuery('auth', $token->getAccessToken()); 166 } elseif (static::AUTHORIZATION_METHOD_QUERY_STRING_V5 === $this->getAuthorizationMethod()) { 167 $uri->addToQuery('oauth_token', $token->getAccessToken()); 168 } elseif (static::AUTHORIZATION_METHOD_HEADER_BEARER === $this->getAuthorizationMethod()) { 169 $extraHeaders = array_merge(['Authorization' => 'Bearer ' . $token->getAccessToken()], $extraHeaders); 170 } elseif (static::AUTHORIZATION_METHOD_HEADER_TOKEN === $this->getAuthorizationMethod()) { 171 $extraHeaders = array_merge(['Authorization' => 'token ' . $token->getAccessToken()], $extraHeaders); 172 } 173 174 $extraHeaders = array_merge($this->getExtraApiHeaders(), $extraHeaders); 175 return $this->httpClient->retrieveResponse($uri, $body, $extraHeaders, $method); 176 } 177 178 /** 179 * Accessor to the storage adapter to be able to retrieve tokens. 180 * 181 * @return TokenStorageInterface 182 */ 183 public function getStorage() 184 { 185 return $this->storage; 186 } 187 188 /** 189 * Refreshes an OAuth2 access token. 190 * 191 * @return TokenInterface $token 192 */ 193 public function refreshAccessToken(TokenInterface $token) 194 { 195 $refreshToken = $token->getRefreshToken(); 196 197 if (empty($refreshToken)) { 198 throw new MissingRefreshTokenException(); 199 } 200 201 $parameters = [ 202 'grant_type' => 'refresh_token', 203 'type' => 'web_server', 204 'client_id' => $this->credentials->getConsumerId(), 205 'client_secret' => $this->credentials->getConsumerSecret(), 206 'refresh_token' => $refreshToken, 207 ]; 208 209 $responseBody = $this->httpClient->retrieveResponse( 210 $this->getAccessTokenEndpoint(), 211 $parameters, 212 $this->getExtraOAuthHeaders() 213 ); 214 $token = $this->parseAccessTokenResponse($responseBody); 215 $this->storage->storeAccessToken($this->service(), $token); 216 217 return $token; 218 } 219 220 /** 221 * Return whether or not the passed scope value is valid. 222 * 223 * @param string $scope 224 * 225 * @return bool 226 */ 227 public function isValidScope($scope) 228 { 229 $reflectionClass = new ReflectionClass(get_class($this)); 230 231 return in_array($scope, $reflectionClass->getConstants(), true); 232 } 233 234 /** 235 * Check if the given service need to generate a unique state token to build the authorization url. 236 * 237 * @return bool 238 */ 239 public function needsStateParameterInAuthUrl() 240 { 241 return $this->stateParameterInAuthUrl; 242 } 243 244 /** 245 * Validates the authorization state against a given one. 246 * 247 * @param string $state 248 */ 249 protected function validateAuthorizationState($state): void 250 { 251 if ($this->retrieveAuthorizationState() !== $state) { 252 throw new InvalidAuthorizationStateException(); 253 } 254 } 255 256 /** 257 * Generates a random string to be used as state. 258 * 259 * @return string 260 */ 261 protected function generateAuthorizationState() 262 { 263 return md5(mt_rand()); 264 } 265 266 /** 267 * Retrieves the authorization state for the current service. 268 * 269 * @return string 270 */ 271 protected function retrieveAuthorizationState() 272 { 273 return $this->storage->retrieveAuthorizationState($this->service()); 274 } 275 276 /** 277 * Stores a given authorization state into the storage. 278 * 279 * @param string $state 280 */ 281 protected function storeAuthorizationState($state): void 282 { 283 $this->storage->storeAuthorizationState($this->service(), $state); 284 } 285 286 /** 287 * Return any additional headers always needed for this service implementation's OAuth calls. 288 * 289 * @return array 290 */ 291 protected function getExtraOAuthHeaders() 292 { 293 return []; 294 } 295 296 /** 297 * Return any additional headers always needed for this service implementation's API calls. 298 * 299 * @return array 300 */ 301 protected function getExtraApiHeaders() 302 { 303 return []; 304 } 305 306 /** 307 * Parses the access token response and returns a TokenInterface. 308 * 309 * @abstract 310 * 311 * @param string $responseBody 312 * 313 * @return TokenInterface 314 */ 315 abstract protected function parseAccessTokenResponse($responseBody); 316 317 /** 318 * Returns a class constant from ServiceInterface defining the authorization method used for the API 319 * Header is the sane default. 320 * 321 * @return int 322 */ 323 protected function getAuthorizationMethod() 324 { 325 return static::AUTHORIZATION_METHOD_HEADER_OAUTH; 326 } 327 328 /** 329 * Returns api version string if is set else retrun empty string. 330 * 331 * @return string 332 */ 333 protected function getApiVersionString() 334 { 335 return !(empty($this->apiVersion)) ? '/' . $this->apiVersion : ''; 336 } 337 338 /** 339 * Returns delimiter to scopes in getAuthorizationUri 340 * For services that do not fully respect the Oauth's RFC, 341 * and use scopes with commas as delimiter. 342 * 343 * @return string 344 */ 345 protected function getScopesDelimiter() 346 { 347 return ' '; 348 } 349 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Nov 25 19:05:08 2024 | Cross-referenced by PHPXref 0.7.1 |