Verzeichnisstruktur phpBB-3.3.15
- Veröffentlicht
- 28.08.2024
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
AbstractService.php
001 <?php
002
003 namespace OAuth\OAuth2\Service;
004
005 use OAuth\Common\Consumer\CredentialsInterface;
006 use OAuth\Common\Http\Client\ClientInterface;
007 use OAuth\Common\Http\Uri\UriInterface;
008 use OAuth\Common\Service\AbstractService as BaseAbstractService;
009 use OAuth\Common\Storage\TokenStorageInterface;
010 use OAuth\Common\Token\Exception\ExpiredTokenException;
011 use OAuth\Common\Token\TokenInterface;
012 use OAuth\OAuth2\Service\Exception\InvalidAuthorizationStateException;
013 use OAuth\OAuth2\Service\Exception\InvalidScopeException;
014 use OAuth\OAuth2\Service\Exception\MissingRefreshTokenException;
015 use ReflectionClass;
016
017 abstract class AbstractService extends BaseAbstractService implements ServiceInterface
018 {
019 /** @const OAUTH_VERSION */
020 const OAUTH_VERSION = 2;
021
022 /** @var array */
023 protected $scopes;
024
025 /** @var null|UriInterface */
026 protected $baseApiUri;
027
028 /** @var bool */
029 protected $stateParameterInAuthUrl;
030
031 /** @var string */
032 protected $apiVersion;
033
034 /**
035 * @param array $scopes
036 * @param bool $stateParameterInAutUrl
037 * @param string $apiVersion
038 */
039 public function __construct(
040 CredentialsInterface $credentials,
041 ClientInterface $httpClient,
042 TokenStorageInterface $storage,
043 $scopes = [],
044 ?UriInterface $baseApiUri = null,
045 $stateParameterInAutUrl = false,
046 $apiVersion = ''
047 ) {
048 parent::__construct($credentials, $httpClient, $storage);
049 $this->stateParameterInAuthUrl = $stateParameterInAutUrl;
050
051 foreach ($scopes as $scope) {
052 if (!$this->isValidScope($scope)) {
053 throw new InvalidScopeException('Scope ' . $scope . ' is not valid for service ' . get_class($this));
054 }
055 }
056
057 $this->scopes = $scopes;
058
059 $this->baseApiUri = $baseApiUri;
060
061 $this->apiVersion = $apiVersion;
062 }
063
064 /**
065 * {@inheritdoc}
066 */
067 public function getAuthorizationUri(array $additionalParameters = [])
068 {
069 $parameters = array_merge(
070 $additionalParameters,
071 [
072 'type' => 'web_server',
073 'client_id' => $this->credentials->getConsumerId(),
074 'redirect_uri' => $this->credentials->getCallbackUrl(),
075 'response_type' => 'code',
076 ]
077 );
078
079 $parameters['scope'] = implode($this->getScopesDelimiter(), $this->scopes);
080
081 if ($this->needsStateParameterInAuthUrl()) {
082 if (!isset($parameters['state'])) {
083 $parameters['state'] = $this->generateAuthorizationState();
084 }
085 $this->storeAuthorizationState($parameters['state']);
086 }
087
088 // Build the url
089 $url = clone $this->getAuthorizationEndpoint();
090 foreach ($parameters as $key => $val) {
091 $url->addToQuery($key, $val);
092 }
093
094 return $url;
095 }
096
097 /**
098 * {@inheritdoc}
099 */
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 }
350