Skip to content

Navigation Menu

Sign in
Appearance settings
Sign up
Appearance settings
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[AccessToken] allow user to set a default token lifetime via credenti…
…als url
  • Loading branch information
pounard committed Sep 30, 2024
commit d8b333ee5419949adb2bb85f4688e9b0cc82ba9a
13 changes: 11 additions & 2 deletions 13 src/Symfony/Component/AccessToken/AccessToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,25 @@ class AccessToken implements AccessTokenInterface
*/
public const IN_MEMORY = 'in_memory';

/**
* Default lifetime in use when the remote service does not expose the
* token lifetime.
*
* @see CredentialsInterface::getDefaultLifetime() for overriding this value.
*/
public const DEFAULT_LIFETIME = 600;

protected ?\DateTimeImmutable $expiresAt;
protected ?bool $hasExpired = null;

/**
* @param string $id Identifier of credentials used for generating it
* @param string $id Identifier of credentials used for generating it
* @param int $expiresIn Access token lifetime in seconds
*/
public function __construct(
protected readonly string $value,
protected readonly string $type = 'Bearer',
protected readonly int $expiresIn = 600,
protected readonly int $expiresIn = self::DEFAULT_LIFETIME,
protected readonly \DateTimeImmutable $issuedAt = new \DateTimeImmutable(),
protected readonly string $id = self::IN_MEMORY,
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ abstract class AbstractOAuthCredentials extends AbstractCredentials
public function __construct(
#[\SensitiveParameter] protected readonly ?string $tenant = null,
protected readonly ?string $endpoint = null,
?int $defaultLifetime = null,
) {
parent::__construct($defaultLifetime);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ public function __construct(
#[\SensitiveParameter] ?string $tenant = null,
string|array|null $scope = null,
?string $endpoint = null,
?int $defaultLifetime = null,
) {
parent::__construct($tenant, $endpoint);
parent::__construct($tenant, $endpoint, $defaultLifetime);

$this->scope = \is_string($scope) ? array_filter(explode(' ', $scope)) : $scope;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ protected function parseResponse(ClientCredentials $credentials, string $body):
return new AccessToken(
value: $data['access_token'],
type: $data['token_type'] ?? 'Bearer',
expiresIn: (int) ($data['expires_in'] ?? 600),
expiresIn: (int) ($data['expires_in'] ?? $credentials->getDefaultLifetime()),
id: $credentials->getId(),
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ public function createCredentials(Dsn $dsn): CredentialsInterface
clientSecret: $clientSecret,
tenant: $dsn->getOption('tenant'),
scope: $dsn->getOption('scope'),
endpoint: $dsn->toEndpointUrl(['grant_type', 'client_id', 'client_secret', 'tenant', 'scope']),
endpoint: $dsn->toEndpointUrl(['grant_type', 'client_id', 'client_secret', 'tenant', 'scope', 'default_lifetime']),
defaultLifetime: (int) $dsn->getOption('default_lifetime'),
);
}

Expand All @@ -61,7 +62,8 @@ public function createCredentials(Dsn $dsn): CredentialsInterface
clientSecret: $clientSecret,
tenant: $dsn->getOption('tenant'),
scope: $dsn->getOption('scope'),
endpoint: $dsn->toEndpointUrl(['grant_type', 'refresh_token', 'client_id', 'client_secret', 'tenant', 'scope']),
endpoint: $dsn->toEndpointUrl(['grant_type', 'refresh_token', 'client_id', 'client_secret', 'tenant', 'scope', 'default_lifetime']),
defaultLifetime: (int) $dsn->getOption('default_lifetime'),
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ public function __construct(
#[\SensitiveParameter] ?string $tenant = null,
string|array|null $scope = null,
?string $endpoint = null,
?int $defaultLifetime = null,
) {
parent::__construct($tenant, $endpoint);
parent::__construct($tenant, $endpoint, $defaultLifetime);

$this->scope = \is_string($scope) ? array_filter(explode(' ', $scope)) : $scope;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ protected function parseResponse(RefreshTokenCredentials $credentials, string $b
return new AccessToken(
value: $data['access_token'],
type: $data['token_type'] ?? 'Bearer',
expiresIn: (int) ($data['expires_in'] ?? 600),
expiresIn: (int) ($data['expires_in'] ?? $credentials->getDefaultLifetime()),
id: $credentials->getId(),
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Symfony\Component\AccessToken\Credentials;

use Symfony\Component\AccessToken\AccessToken;
use Symfony\Component\AccessToken\CredentialsInterface;

/**
Expand All @@ -25,8 +26,18 @@ abstract class AbstractCredentials implements CredentialsInterface
*/
protected abstract function computeId(): string;

public function __construct(
private ?int $defaultLifetime = null
) {
}

public function getId(): string
{
return $this->id ??= $this->computeId();
}

public function getDefaultLifetime(): int
{
return $this->defaultLifetime ?? AccessToken::DEFAULT_LIFETIME;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ class BasicAuthCredentials extends AbstractCredentials
public function __construct(
private readonly string $username,
private readonly ?string $password = null,
) {}
?int $defaultLifetime = null,
) {
parent::__construct($defaultLifetime);
}

public function getUsername(): string
{
Expand Down
8 changes: 8 additions & 0 deletions 8 src/Symfony/Component/AccessToken/CredentialsInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,12 @@ interface CredentialsInterface
* order to avoid cache pollution.
*/
public function getId(): string;

/**
* Get default lifetime for this credentials.
*
* When the remote service does not give any information about token
* lifetime, the value here will be used.
*/
public function getDefaultLifetime(): int;
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public function testClientCredentials(): void
{
$factory = new OAuthFactory();

$uri = 'oauth://example.tld/oauth?grant_type=client_credentials&client_id=fooId&client_secret=fooSecret&tenant=fooTenant&scope=fooScope%20barScope';
$uri = 'oauth://example.tld/oauth?grant_type=client_credentials&client_id=fooId&client_secret=fooSecret&tenant=fooTenant&scope=fooScope%20barScope&default_lifetime=12';
$credentials = $factory->createCredentials(Dsn::fromString($uri));
\assert($credentials instanceof ClientCredentials);

Expand All @@ -67,6 +67,7 @@ public function testClientCredentials(): void
self::assertSame('fooSecret', $credentials->getClientSecret());
self::assertSame('fooTenant', $credentials->getTenant());
self::assertSame(['fooScope', 'barScope'], $credentials->getScope());
self::assertSame(12, $credentials->getDefaultLifetime());
}

public function testClientCredentialsUserPassFallbackOnBasicAuth(): void
Expand Down Expand Up @@ -105,7 +106,7 @@ public function testRefreshTokenCredentials(): void
{
$factory = new OAuthFactory();

$uri = 'oauth://example.tld/oauth?grant_type=refresh_token&refresh_token=the_token&client_id=fooId&client_secret=fooSecret&tenant=fooTenant&scope=fooScope%20barScope';
$uri = 'oauth://example.tld/oauth?grant_type=refresh_token&refresh_token=the_token&client_id=fooId&client_secret=fooSecret&tenant=fooTenant&scope=fooScope%20barScope&default_lifetime=12';
$credentials = $factory->createCredentials(Dsn::fromString($uri));
\assert($credentials instanceof RefreshTokenCredentials);

Expand All @@ -115,6 +116,7 @@ public function testRefreshTokenCredentials(): void
self::assertSame('fooId', $credentials->getClientId());
self::assertSame('fooSecret', $credentials->getClientSecret());
self::assertSame('fooTenant', $credentials->getTenant());
self::assertSame(12, $credentials->getDefaultLifetime());
}

public function testRefreshTokenCredentialsBareMinimum(): void
Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.