11<?php
2+ declare (strict_types=1 );
23
34namespace Flownative \OAuth2 \Client ;
45
@@ -247,6 +248,18 @@ public function requestAccessToken(string $serviceName, string $clientId, string
247248 $ this ->entityManager ->flush ();
248249 }
249250
251+ /**
252+ * Returns an authorization id taking the service type and service name into account.
253+ *
254+ * @param string $clientId
255+ * @return string
256+ * @throws OAuthClientException
257+ */
258+ public function generateAuthorizationIdForAuthorizationCodeGrant (string $ clientId ): string
259+ {
260+ return Authorization::generateAuthorizationIdForAuthorizationCodeGrant ($ this ->getServiceType (), $ this ->getServiceName (), $ clientId );
261+ }
262+
250263 /**
251264 * Start OAuth authorization with the Authorization Code flow
252265 *
@@ -259,7 +272,30 @@ public function requestAccessToken(string $serviceName, string $clientId, string
259272 */
260273 public function startAuthorization (string $ clientId , string $ clientSecret , UriInterface $ returnToUri , string $ scope ): UriInterface
261274 {
262- $ authorizationId = Authorization::generateAuthorizationIdForAuthorizationCodeGrant ($ this ->getServiceType (), $ this ->getServiceName (), $ clientId );
275+ $ authorizationId = $ this ->generateAuthorizationIdForAuthorizationCodeGrant ($ clientId );
276+ return $ this ->startAuthorizationWithId ($ authorizationId , $ clientId , $ clientSecret , $ returnToUri , $ scope );
277+ }
278+
279+ /**
280+ * Start OAuth authorization with the Authorization Code flow
281+ * based on a specified authorization identifier.
282+ *
283+ * Note that, if you use this method, it is your responsibility to provide a
284+ * meaningful authorization id. You might weaken the security of your
285+ * application if you use an id which is deterministic or can be guessed by
286+ * an attacker.
287+ *
288+ * If in doubt, always use startAuthorization() instead.
289+ *
290+ * @param string $clientId The client id, as provided by the OAuth server
291+ * @param string $clientSecret The client secret, provided by the OAuth server
292+ * @param UriInterface $returnToUri URI to return to when authorization is finished
293+ * @param string $scope Scope to request for authorization. Must be scope ids separated by space, e.g. "openid profile email"
294+ * @return UriInterface The URL the browser should redirect to, asking the user to authorize
295+ * @throws OAuthClientException
296+ */
297+ public function startAuthorizationWithId (string $ authorizationId , string $ clientId , string $ clientSecret , UriInterface $ returnToUri , string $ scope ): UriInterface
298+ {
263299 $ authorization = new Authorization ($ authorizationId , $ this ->getServiceType (), $ clientId , Authorization::GRANT_AUTHORIZATION_CODE , $ scope );
264300 $ this ->logger ->info (sprintf ('OAuth (%s): Starting authorization %s using client id "%s", a %s bytes long secret and scope "%s". ' , $ this ->getServiceType (), $ authorization ->getAuthorizationId (), $ clientId , strlen ($ clientSecret ), $ scope ));
265301
@@ -472,16 +508,36 @@ public function renderFinishAuthorizationUri(): string
472508 $ this ->uriBuilder ->setCreateAbsoluteUri (true );
473509
474510 try {
475- $ uri = $ this ->uriBuilder ->
476- reset ()->
477- setCreateAbsoluteUri (true )->
478- uriFor ('finishAuthorization ' , ['serviceType ' => $ this ->getServiceType (), 'serviceName ' => $ this ->getServiceName ()], 'OAuth ' , 'Flownative.OAuth2.Client ' );
511+ $ uri = $ this ->uriBuilder
512+ -> reset ()
513+ -> setCreateAbsoluteUri (true )
514+ -> uriFor ('finishAuthorization ' , ['serviceType ' => $ this ->getServiceType (), 'serviceName ' => $ this ->getServiceName ()], 'OAuth ' , 'Flownative.OAuth2.Client ' );
479515 return $ uri ;
480516 } catch (MissingActionNameException $ e ) {
481517 return '' ;
482518 }
483519 }
484520
521+ /**
522+ * Helper method to set metadata on an Authorization instance. Changes are
523+ * persisted immediately.
524+ *
525+ * @param string $authorizationId
526+ * @param string $metadata
527+ * @return void
528+ */
529+ public function setAuthorizationMetadata (string $ authorizationId , string $ metadata ): void
530+ {
531+ $ authorization = $ this ->getAuthorization ($ authorizationId );
532+ if ($ authorization === null ) {
533+ throw new \RuntimeException (sprintf ('Failed setting authorization metadata: authorization %s was not found ' , $ authorizationId ), 1631821719 );
534+ }
535+ $ authorization ->setMetadata ($ metadata );
536+
537+ $ this ->entityManager ->persist ($ authorization );
538+ $ this ->entityManager ->flush ();
539+ }
540+
485541 /**
486542 * @param string $clientId
487543 * @param string $clientSecret
@@ -527,13 +583,13 @@ protected function removeExpiredAuthorizations(): void
527583 */
528584 public function shutdownObject (): void
529585 {
530- $ decimals = (integer )strlen (strrchr ($ this ->garbageCollectionProbability , '. ' )) - 1 ;
586+ $ garbageCollectionProbability = (string )$ this ->garbageCollectionProbability ;
587+ $ decimals = strlen (strrchr ($ garbageCollectionProbability , '. ' ) ?: '' ) - 1 ;
531588 $ factor = ($ decimals > -1 ) ? $ decimals * 10 : 1 ;
532589 try {
533590 if (random_int (1 , 100 * $ factor ) <= ($ this ->garbageCollectionProbability * $ factor )) {
534591 $ this ->removeExpiredAuthorizations ();
535592 }
536- } catch (InvalidQueryException $ e ) {
537593 } catch (\Exception $ e ) {
538594 }
539595 }
0 commit comments