Skip to content

Commit

Permalink
Add cache to client repository
Browse files Browse the repository at this point in the history
  • Loading branch information
cicnavi committed Jan 21, 2025
1 parent 9b04454 commit 6ab312e
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 33 deletions.
56 changes: 30 additions & 26 deletions config-templates/module_oidc.php
Original file line number Diff line number Diff line change
Expand Up @@ -258,42 +258,46 @@
// also give proper adapter arguments for its instantiation below.
// @see https://symfony.com/doc/current/components/cache.html#available-cache-adapters
ModuleConfig::OPTION_PROTOCOL_CACHE_ADAPTER => null,
//ModuleConfig::OPTION_PROTOCOL_CACHE_ADAPTER => \Symfony\Component\Cache\Adapter\FilesystemAdapter::class,
//ModuleConfig::OPTION_PROTOCOL_CACHE_ADAPTER => \Symfony\Component\Cache\Adapter\MemcachedAdapter::class,
// ModuleConfig::OPTION_PROTOCOL_CACHE_ADAPTER => \Symfony\Component\Cache\Adapter\FilesystemAdapter::class,
// ModuleConfig::OPTION_PROTOCOL_CACHE_ADAPTER => \Symfony\Component\Cache\Adapter\MemcachedAdapter::class,

// Federation cache adapter arguments used for adapter instantiation. Refer to documentation for particular
// Protocol cache adapter arguments used for adapter instantiation. Refer to documentation for particular
// adapter on which arguments are needed to create its instance, in the order of constructor arguments.
// See examples below.
ModuleConfig::OPTION_PROTOCOL_CACHE_ADAPTER_ARGUMENTS => [
// Adapter arguments here...
],
// Example for FileSystemAdapter:
//ModuleConfig::OPTION_FEDERATION_CACHE_ADAPTER_ARGUMENTS => [
// 'openidFederation', // Namespace, subdirectory of main cache directory
// 60 * 60 * 6, // Default lifetime in seconds (used when particular cache item doesn't define its own lifetime)
// '/path/to/main/cache/directory' // Must be writable. Can be set to null to use system temporary directory.
//],
// Example for MemcachedAdapter:
//ModuleConfig::OPTION_FEDERATION_CACHE_ADAPTER_ARGUMENTS => [
// // First argument is a connection instance, so we can use the helper method to create it. In this example a
// // single server is used. Refer to documentation on how to use multiple servers, and / or to provide other
// // options.
// \Symfony\Component\Cache\Adapter\MemcachedAdapter::createConnection(
// 'memcached://localhost'
// // the DSN can include config options (pass them as a query string):
// // 'memcached://localhost:11222?retry_timeout=10'
// // 'memcached://localhost:11222?socket_recv_size=1&socket_send_size=2'
// ),
// 'openidFederation', // Namespace, key prefix.
// 60 * 60 * 6, // Default lifetime in seconds (used when particular cache item doesn't define its own lifetime)
//],
// ModuleConfig::OPTION_PROTOCOL_CACHE_ADAPTER_ARGUMENTS => [
// 'openidFederation', // Namespace, subdirectory of main cache directory
// 60 * 60 * 6, // Default lifetime in seconds (used when particular cache item doesn't define its own lifetime)
// '/path/to/main/cache/directory' // Must be writable. Can be set to null to use system temporary directory.
// ],
// Example for MemcachedAdapter:
// ModuleConfig::OPTION_PROTOCOL_CACHE_ADAPTER_ARGUMENTS => [
// // First argument is a connection instance, so we can use the helper method to create it. In this example a
// // single server is used. Refer to documentation on how to use multiple servers, and / or to provide other
// // options.
// \Symfony\Component\Cache\Adapter\MemcachedAdapter::createConnection(
// 'memcached://localhost'
// // the DSN can include config options (pass them as a query string):
// // 'memcached://localhost:11222?retry_timeout=10'
// // 'memcached://localhost:11222?socket_recv_size=1&socket_send_size=2'
// ),
// 'openidProtocol', // Namespace, key prefix.
// 60 * 60 * 6, // Default lifetime in seconds (used when particular cache item doesn't define its own lifetime)
// ],

/**
* Protocol cache duration for particular entities. This is only relevant if protocol cache adapter is set up.
* For duration format info, check https://www.php.net/manual/en/dateinterval.construct.php.
*/
// Cache duration for user entities (authenticated users data). If not set, cache duration will be the same as
// session duration. This is used to avoid fetching user data from database on every authentication event.
// This is only relevant if protocol cache adapter is set up. For duration format info, check
// https://www.php.net/manual/en/dateinterval.construct.php.
// session duration.
// ModuleConfig::OPTION_PROTOCOL_USER_ENTITY_CACHE_DURATION => 'PT1H', // 1 hour
ModuleConfig::OPTION_PROTOCOL_USER_ENTITY_CACHE_DURATION => null, // fallback to session duration
ModuleConfig::OPTION_PROTOCOL_USER_ENTITY_CACHE_DURATION => null, // Fallback to session duration
// Cache duration for client entities, with given default.
ModuleConfig::OPTION_PROTOCOL_CLIENT_ENTITY_CACHE_DURATION => 'PT10M', // 10 minutes

/**
* Cron related options.
Expand Down
16 changes: 16 additions & 0 deletions src/ModuleConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class ModuleConfig
final public const OPTION_PROTOCOL_CACHE_ADAPTER = 'protocol_cache_adapter';
final public const OPTION_PROTOCOL_CACHE_ADAPTER_ARGUMENTS = 'protocol_cache_adapter_arguments';
final public const OPTION_PROTOCOL_USER_ENTITY_CACHE_DURATION = 'protocol_user_entity_cache_duration';
final public const OPTION_PROTOCOL_CLIENT_ENTITY_CACHE_DURATION = 'protocol_client_entity_cache_duration';
final public const OPTION_FEDERATION_PARTICIPATION_LIMIT_BY_TRUST_MARKS =
'federation_participation_limit_by_trust_marks';

Expand Down Expand Up @@ -464,6 +465,21 @@ public function getProtocolUserEntityCacheDuration(): DateInterval
);
}

/**
* Get cache duration for client entities (user data), with given default
*
* @throws \Exception
*/
public function getProtocolClientEntityCacheDuration(): DateInterval
{
return new DateInterval(
$this->config()->getOptionalString(
self::OPTION_PROTOCOL_CLIENT_ENTITY_CACHE_DURATION,
null,
) ?? 'PT10M',
);
}


/*****************************************************************************************************************
* OpenID Federation related config.
Expand Down
7 changes: 7 additions & 0 deletions src/Repositories/AbstractDatabaseRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,12 @@ public function __construct(
) {
}

public function getCacheKey(string $identifier): string
{
return is_string($tableName = $this->getTableName()) ?
$tableName . '_' . $identifier :
$identifier;
}

abstract public function getTableName(): ?string;
}
65 changes: 63 additions & 2 deletions src/Repositories/ClientRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,13 @@ public function validateClient($clientIdentifier, $clientSecret, $grantType): bo
*/
public function findById(string $clientIdentifier, ?string $owner = null): ?ClientEntityInterface
{
/** @var ?array $cachedState */
$cachedState = $this->protocolCache?->get(null, $this->getCacheKey($clientIdentifier));

if (is_array($cachedState)) {
return $this->clientEntityFactory->fromState($cachedState);
}

/**
* @var string $query
* @var array $params
Expand All @@ -116,11 +123,26 @@ public function findById(string $clientIdentifier, ?string $owner = null): ?Clie
return null;
}

return $this->clientEntityFactory->fromState($row);
$clientEntity = $this->clientEntityFactory->fromState($row);

$this->protocolCache?->set(
$clientEntity->getState(),
$this->moduleConfig->getProtocolClientEntityCacheDuration(),
$this->getCacheKey($clientEntity->getIdentifier()),
);

return $clientEntity;
}

public function findByEntityIdentifier(string $entityIdentifier, ?string $owner = null): ?ClientEntityInterface
{
/** @var ?array $cachedState */
$cachedState = $this->protocolCache?->get(null, $this->getCacheKey($entityIdentifier));

if (is_array($cachedState)) {
return $this->clientEntityFactory->fromState($cachedState);
}

/**
* @var string $query
* @var array $params
Expand Down Expand Up @@ -153,7 +175,15 @@ public function findByEntityIdentifier(string $entityIdentifier, ?string $owner
return null;
}

return $this->clientEntityFactory->fromState($row);
$clientEntity = $this->clientEntityFactory->fromState($row);

$this->protocolCache?->set(
$clientEntity->getState(),
$this->moduleConfig->getProtocolClientEntityCacheDuration(),
$this->getCacheKey($entityIdentifier),
);

return $clientEntity;
}

private function addOwnerWhereClause(string $query, array $params, ?string $owner = null): array
Expand Down Expand Up @@ -302,6 +332,19 @@ public function add(ClientEntityInterface $client): void
$stmt,
$client->getState(),
);

$this->protocolCache?->set(
$client->getState(),
$this->moduleConfig->getProtocolClientEntityCacheDuration(),
$this->getCacheKey($client->getIdentifier()),
);
if (($entityIdentifier = $client->getEntityIdentifier()) !== null) {
$this->protocolCache?->set(
$client->getState(),
$this->moduleConfig->getProtocolClientEntityCacheDuration(),
$this->getCacheKey($entityIdentifier),
);
}
}

public function delete(ClientEntityInterface $client, ?string $owner = null): void
Expand All @@ -318,6 +361,11 @@ public function delete(ClientEntityInterface $client, ?string $owner = null): vo
$owner,
);
$this->database->write($sqlQuery, $params);

$this->protocolCache?->delete($this->getCacheKey($client->getIdentifier()));
if (($entityIdentifier = $client->getEntityIdentifier()) !== null) {
$this->protocolCache?->delete($this->getCacheKey($entityIdentifier));
}
}

public function update(ClientEntityInterface $client, ?string $owner = null): void
Expand Down Expand Up @@ -366,6 +414,19 @@ public function update(ClientEntityInterface $client, ?string $owner = null): vo
$sqlQuery,
$params,
);

$this->protocolCache?->set(
$client->getState(),
$this->moduleConfig->getProtocolClientEntityCacheDuration(),
$this->getCacheKey($client->getIdentifier()),
);
if (($entityIdentifier = $client->getEntityIdentifier()) !== null) {
$this->protocolCache?->set(
$client->getState(),
$this->moduleConfig->getProtocolClientEntityCacheDuration(),
$this->getCacheKey($entityIdentifier),
);
}
}

private function count(string $query, ?string $owner): int
Expand Down
5 changes: 0 additions & 5 deletions src/Repositories/UserRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,6 @@ public function getTableName(): string
return $this->database->applyPrefix(self::TABLE_NAME);
}

public function getCacheKey(string $identifier): string
{
return $this->getTableName() . '_' . $identifier;
}

/**
* @param string $identifier
*
Expand Down

0 comments on commit 6ab312e

Please sign in to comment.