11<?php
2+ declare (strict_types=1 );
23
34namespace Flownative \OAuth2 \Client ;
45
@@ -253,6 +254,18 @@ public function requestAccessToken(string $serviceName, string $clientId, string
253254 $ this ->entityManager ->flush ();
254255 }
255256
257+ /**
258+ * Returns an authorization id taking the service type and service name into account.
259+ *
260+ * @param string $clientId
261+ * @return string
262+ * @throws OAuthClientException
263+ */
264+ public function generateAuthorizationIdForAuthorizationCodeGrant (string $ clientId ): string
265+ {
266+ return Authorization::generateAuthorizationIdForAuthorizationCodeGrant ($ this ->getServiceType (), $ this ->getServiceName (), $ clientId );
267+ }
268+
256269 /**
257270 * Start OAuth authorization with the Authorization Code flow
258271 *
@@ -265,7 +278,30 @@ public function requestAccessToken(string $serviceName, string $clientId, string
265278 */
266279 public function startAuthorization (string $ clientId , string $ clientSecret , UriInterface $ returnToUri , string $ scope ): UriInterface
267280 {
268- $ authorizationId = Authorization::generateAuthorizationIdForAuthorizationCodeGrant ($ this ->getServiceType (), $ this ->getServiceName (), $ clientId );
281+ $ authorizationId = $ this ->generateAuthorizationIdForAuthorizationCodeGrant ($ clientId );
282+ return $ this ->startAuthorizationWithId ($ authorizationId , $ clientId , $ clientSecret , $ returnToUri , $ scope );
283+ }
284+
285+ /**
286+ * Start OAuth authorization with the Authorization Code flow
287+ * based on a specified authorization identifier.
288+ *
289+ * Note that, if you use this method, it is your responsibility to provide a
290+ * meaningful authorization id. You might weaken the security of your
291+ * application if you use an id which is deterministic or can be guessed by
292+ * an attacker.
293+ *
294+ * If in doubt, always use startAuthorization() instead.
295+ *
296+ * @param string $clientId The client id, as provided by the OAuth server
297+ * @param string $clientSecret The client secret, provided by the OAuth server
298+ * @param UriInterface $returnToUri URI to return to when authorization is finished
299+ * @param string $scope Scope to request for authorization. Must be scope ids separated by space, e.g. "openid profile email"
300+ * @return UriInterface The URL the browser should redirect to, asking the user to authorize
301+ * @throws OAuthClientException
302+ */
303+ public function startAuthorizationWithId (string $ authorizationId , string $ clientId , string $ clientSecret , UriInterface $ returnToUri , string $ scope ): UriInterface
304+ {
269305 $ authorization = new Authorization ($ authorizationId , $ this ->getServiceType (), $ clientId , Authorization::GRANT_AUTHORIZATION_CODE , $ scope );
270306 if ($ this ->defaultTokenLifetime !== null ) {
271307 $ authorization ->setExpires (new \DateTimeImmutable ('+ ' . $ this ->defaultTokenLifetime . ' seconds ' ));
@@ -502,16 +538,36 @@ public function renderFinishAuthorizationUri(): string
502538 $ this ->uriBuilder ->setCreateAbsoluteUri (true );
503539
504540 try {
505- $ uri = $ this ->uriBuilder ->
506- reset ()->
507- setCreateAbsoluteUri (true )->
508- uriFor ('finishAuthorization ' , ['serviceType ' => $ this ->getServiceType (), 'serviceName ' => $ this ->getServiceName ()], 'OAuth ' , 'Flownative.OAuth2.Client ' );
541+ $ uri = $ this ->uriBuilder
542+ -> reset ()
543+ -> setCreateAbsoluteUri (true )
544+ -> uriFor ('finishAuthorization ' , ['serviceType ' => $ this ->getServiceType (), 'serviceName ' => $ this ->getServiceName ()], 'OAuth ' , 'Flownative.OAuth2.Client ' );
509545 return $ uri ;
510546 } catch (MissingActionNameException $ e ) {
511547 return '' ;
512548 }
513549 }
514550
551+ /**
552+ * Helper method to set metadata on an Authorization instance. Changes are
553+ * persisted immediately.
554+ *
555+ * @param string $authorizationId
556+ * @param string $metadata
557+ * @return void
558+ */
559+ public function setAuthorizationMetadata (string $ authorizationId , string $ metadata ): void
560+ {
561+ $ authorization = $ this ->getAuthorization ($ authorizationId );
562+ if ($ authorization === null ) {
563+ throw new \RuntimeException (sprintf ('Failed setting authorization metadata: authorization %s was not found ' , $ authorizationId ), 1631821719 );
564+ }
565+ $ authorization ->setMetadata ($ metadata );
566+
567+ $ this ->entityManager ->persist ($ authorization );
568+ $ this ->entityManager ->flush ();
569+ }
570+
515571 /**
516572 * @param string $clientId
517573 * @param string $clientSecret
@@ -557,13 +613,13 @@ protected function removeExpiredAuthorizations(): void
557613 */
558614 public function shutdownObject (): void
559615 {
560- $ decimals = (integer )strlen (strrchr ($ this ->garbageCollectionProbability , '. ' )) - 1 ;
616+ $ garbageCollectionProbability = (string )$ this ->garbageCollectionProbability ;
617+ $ decimals = strlen (strrchr ($ garbageCollectionProbability , '. ' ) ?: '' ) - 1 ;
561618 $ factor = ($ decimals > -1 ) ? $ decimals * 10 : 1 ;
562619 try {
563620 if (random_int (1 , 100 * $ factor ) <= ($ this ->garbageCollectionProbability * $ factor )) {
564621 $ this ->removeExpiredAuthorizations ();
565622 }
566- } catch (InvalidQueryException $ e ) {
567623 } catch (\Exception $ e ) {
568624 }
569625 }
0 commit comments