diff --git a/src/Bootstrappers/QueueTenancyBootstrapper.php b/src/Bootstrappers/QueueTenancyBootstrapper.php index a9d13c23..018a80ae 100644 --- a/src/Bootstrappers/QueueTenancyBootstrapper.php +++ b/src/Bootstrappers/QueueTenancyBootstrapper.php @@ -46,7 +46,7 @@ class QueueTenancyBootstrapper implements TenancyBootstrapper } // Tenancy is already initialized for the tenant (e.g. dispatchNow was used) - if (tenancy()->initialized && tenant('id') === $tenantId) { + if (tenancy()->initialized && tenant()->getTenantKey() === $tenantId) { return; } @@ -87,7 +87,7 @@ class QueueTenancyBootstrapper implements TenancyBootstrapper return []; } - $id = tenant('id'); + $id = tenant()->getTenantKey(); return [ 'tenant_id' => $id, diff --git a/src/CacheManager.php b/src/CacheManager.php index 29610371..f7190842 100644 --- a/src/CacheManager.php +++ b/src/CacheManager.php @@ -17,7 +17,7 @@ class CacheManager extends BaseCacheManager */ public function __call($method, $parameters) { - $tags = [config('tenancy.cache.tag_base') . tenant('id')]; + $tags = [config('tenancy.cache.tag_base') . tenant()->getTenantKey()]; if ($method === 'tags') { if (count($parameters) !== 1) { diff --git a/src/Exceptions/TenancyNotInitializedException.php b/src/Exceptions/TenancyNotInitializedException.php new file mode 100644 index 00000000..f5c0c3f5 --- /dev/null +++ b/src/Exceptions/TenancyNotInitializedException.php @@ -0,0 +1,13 @@ +tenant_id) !== ((string) tenant('id'))) { + if (((string) $token->tenant_id) !== ((string) tenant()->getTenantKey())) { abort(403); } diff --git a/src/Middleware/ScopeSessions.php b/src/Middleware/ScopeSessions.php new file mode 100644 index 00000000..136bc43b --- /dev/null +++ b/src/Middleware/ScopeSessions.php @@ -0,0 +1,29 @@ +initialized) { + throw new TenancyNotInitializedException('Tenancy needs to be initialized before the session scoping middleware is executed'); + } + + if (! $request->session()->has(static::$tenantIdKey)) { + $request->session()->put(static::$tenantIdKey, tenant()->getTenantKey()); + } else { + if ($request->session()->get(static::$tenantIdKey) !== tenant()->getTenantKey()) { + abort(403); + } + } + + return $next($request); + } +} \ No newline at end of file diff --git a/tests/ScopeSessionsTest.php b/tests/ScopeSessionsTest.php new file mode 100644 index 00000000..25bcc2eb --- /dev/null +++ b/tests/ScopeSessionsTest.php @@ -0,0 +1,79 @@ + [StartSession::class, InitializeTenancyBySubdomain::class, ScopeSessions::class], + ], function () { + Route::get('/foo', function () { + return true; + }); + }); + + Event::listen(TenantCreated::class, function (TenantCreated $event) { + $tenant = $event->tenant; + + /** @var Tenant $tenant */ + $tenant->domains()->create([ + 'domain' => $tenant->id, + ]); + }); + } + + /** @test */ + public function tenant_id_is_auto_added_to_session_if_its_missing() + { + $tenant = Tenant::create([ + 'id' => 'acme', + ]); + + $this->get('http://acme.localhost/foo') + ->assertSessionHas(ScopeSessions::$tenantIdKey, 'acme'); + } + + /** @test */ + public function changing_tenant_id_in_session_will_abort_the_request() + { + $tenant = Tenant::create([ + 'id' => 'acme', + ]); + + $this->get('http://acme.localhost/foo') + ->assertSuccessful(); + + session()->put(ScopeSessions::$tenantIdKey, 'foobar'); + + $this->get('http://acme.localhost/foo') + ->assertStatus(403); + } + + /** @test */ + public function an_exception_is_thrown_when_the_middleware_is_executed_before_tenancy_is_initialized() + { + Route::get('/bar', function () { + return true; + })->middleware([StartSession::class, ScopeSessions::class]); + + $tenant = Tenant::create([ + 'id' => 'acme', + ]); + + $this->expectException(TenancyNotInitializedException::class); + $this->withoutExceptionHandling()->get('http://acme.localhost/bar'); + } +} \ No newline at end of file