1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2026-02-06 01:34:02 +00:00

Cache prefixing logic rewrite, session scoping improvements, tests refactor (#43)

* Run cache tests on all supported drivers

* update ci healthcheck for memcached

* remove memcached healthcheck

* fix typos in test comments, expand internal.md [ci skip]

* add empty line [ci skip]

* switch to using $store->setPrefix()

* add dynamodb

* refactor try-finally to try-catch

* remove unnecessary clearResolvedInstances() call

* add dual Cache:: and cache() assertions

* add apc

* Flush APCu cache in test setup

* Revert "add dual Cache:: and cache() assertions"

This reverts commit a0bab162fbe2dd0d25e7056ceca4fb7ce54efc77.

* phpstan fix

* Add logic for scoping 'file' disks to FilesystemTenancyBootstrapper

* minor changes, add todos

* refactor how the session.connection is used in the DB session bootstrapper

* add session forgery prevention logic to the db session bootstrapper

* only use the fs bootstrapper for file disk in 'cache data is separated' dataset

* minor session scoping test changes

* Add session scoping logic to FilesystemTenancyBootstrapper, correctly update disk roots even with storage_path_tenancy disabled

* Fix code style (php-cs-fixer)

* update docblock

* make not-null check more explicit

* separate bootstrapper tests, fix swapped test names for two tests

* refactor cache bootstrapper tests

* resolve global cache todo

* expand tests: session separation tests, more filesystem separation assertions; change prefix_base-type config keys to templates/formats

* add apc session scoping test, various session separation bugfixes

* phpstan + minor logic fixes

* prefix_format -> prefix

* fix database session separation test

* revert composer.json changes, update laravel dependencies to expected next release

* only run session scoping logic in cache bootstrapper for redis, memcached, dynamodb, apc; update gitattributes

* tenancy.central_domains -> tenancy.identification.central_domains

* db session separation test: add datasets

---------

Co-authored-by: PHP CS Fixer <phpcsfixer@example.com>
This commit is contained in:
Samuel Štancl 2024-04-09 20:40:27 +02:00 committed by GitHub
parent 943b960718
commit eecf6f21c8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
40 changed files with 1856 additions and 1177 deletions

View file

@ -14,6 +14,8 @@ use Stancl\Tenancy\Contracts\Tenant;
/**
* This resets the database connection used by the database session driver.
*
* It also includes a mechanism to prevent session forgery when SESSION_CONNECTION is specified.
*
* It runs each time tenancy is initialized or ended.
* That way the session driver always uses the current DB connection.
*/
@ -25,23 +27,37 @@ class DatabaseSessionBootstrapper implements TenancyBootstrapper
protected SessionManager $session,
) {}
protected string|null $originalConnection = null;
public function bootstrap(Tenant $tenant): void
{
$this->originalConnection = $this->config->get('session.connection');
if ($this->config->get('session.driver') === 'database') {
$this->resetDatabaseHandler();
// At first, this bootstrapper runs before the StartSession middleware, so
// changing the session.connection here will affect what connection the session
// driver will use. This is helpful to override the SESSION_CONNECTION that might
// otherwise allow for session forgery in the tenant context.
$this->config->set('session.connection', 'tenant');
$this->resetDatabaseHandler('tenant');
}
}
public function revert(): void
{
if ($this->config->get('session.driver') === 'database') {
$connection = $this->originalConnection ?? config('tenancy.database.central_connection');
// When ending tenancy, this runs *before* the DatabaseTenancyBootstrapper, so DB tenancy
// is still bootstrapped. For that reason, we have to explicitly use the central connection
$this->resetDatabaseHandler(config('tenancy.database.central_connection'));
// instead of null for the default connection.
$this->config->set('session.connection', $connection);
$this->resetDatabaseHandler($connection);
}
}
protected function resetDatabaseHandler(string $defaultConnection = null): void
protected function resetDatabaseHandler(string $connection): void
{
$sessionDrivers = $this->session->getDrivers();
@ -49,15 +65,12 @@ class DatabaseSessionBootstrapper implements TenancyBootstrapper
/** @var \Illuminate\Session\Store $databaseDriver */
$databaseDriver = $sessionDrivers['database'];
$databaseDriver->setHandler($this->createDatabaseHandler($defaultConnection));
$databaseDriver->setHandler($this->createDatabaseHandler($connection));
}
}
protected function createDatabaseHandler(string $defaultConnection = null): DatabaseSessionHandler
protected function createDatabaseHandler(string $connection): DatabaseSessionHandler
{
// Typically returns null, so this falls back to the default DB connection
$connection = $this->config->get('session.connection') ?? $defaultConnection;
// Based on SessionManager::createDatabaseDriver
return new DatabaseSessionHandler(
$this->container->make('db')->connection($connection),