mirror of
https://github.com/archtechx/tenancy.git
synced 2025-12-12 14:34:04 +00:00
merge
This commit is contained in:
commit
e98db460ec
9 changed files with 68 additions and 25 deletions
|
|
@ -11,7 +11,6 @@
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"illuminate/support": "^6.0",
|
"illuminate/support": "^6.0",
|
||||||
"facade/ignition-contracts": "^1.0",
|
|
||||||
"ramsey/uuid": "^3.7"
|
"ramsey/uuid": "^3.7"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
|
@ -20,6 +19,7 @@
|
||||||
"laravel/framework": "^6.0",
|
"laravel/framework": "^6.0",
|
||||||
"orchestra/testbench-browser-kit": "^4.0",
|
"orchestra/testbench-browser-kit": "^4.0",
|
||||||
"league/flysystem-aws-s3-v3": "~1.0",
|
"league/flysystem-aws-s3-v3": "~1.0",
|
||||||
|
"facade/ignition-contracts": "^1.0",
|
||||||
"phpunit/phpcov": "^6.0"
|
"phpunit/phpcov": "^6.0"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,9 @@ class Install extends Command
|
||||||
$newKernel = str_replace("'web' => [", "'web' => [
|
$newKernel = str_replace("'web' => [", "'web' => [
|
||||||
\Stancl\Tenancy\Middleware\PreventAccessFromTenantDomains::class,", $newKernel);
|
\Stancl\Tenancy\Middleware\PreventAccessFromTenantDomains::class,", $newKernel);
|
||||||
|
|
||||||
|
$newKernel = str_replace("'api' => [", "'api' => [
|
||||||
|
\Stancl\Tenancy\Middleware\PreventAccessFromTenantDomains::class,", $newKernel);
|
||||||
|
|
||||||
file_put_contents(app_path('Http/Kernel.php'), $newKernel);
|
file_put_contents(app_path('Http/Kernel.php'), $newKernel);
|
||||||
$this->info('✔️ Set middleware priority');
|
$this->info('✔️ Set middleware priority');
|
||||||
|
|
||||||
|
|
@ -59,9 +62,9 @@ class Install extends Command
|
||||||
| Tenant Routes
|
| Tenant Routes
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| Here is where you can register tenant routes for your application. These
|
| Here you can register the tenant routes for your application.
|
||||||
| routes are loaded by the TenantRouteServiceProvider within a group
|
| These routes are loaded by the TenantRouteServiceProvider
|
||||||
| which contains the \"InitializeTenancy\" middleware. Good luck!
|
| with the tenancy and web middleware groups. Good luck!
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -73,8 +76,8 @@ Route::get('/app', function () {
|
||||||
$this->info('✔️ Created routes/tenant.php');
|
$this->info('✔️ Created routes/tenant.php');
|
||||||
|
|
||||||
$this->line('');
|
$this->line('');
|
||||||
$this->line("This package lets you store data about tenants either in Redis or in a relational database like MySQL. If you're going to use the database storage, you need to create tables for tenants and domains.");
|
$this->line('This package lets you store data about tenants either in Redis or in a relational database like MySQL. To store data about tenants in a relational database, you need a few database tables.');
|
||||||
if ($this->confirm('Do you want to publish the default database migrations?', true)) {
|
if ($this->confirm('Do you wish to publish the migrations that create these tables?', true)) {
|
||||||
$this->callSilent('vendor:publish', [
|
$this->callSilent('vendor:publish', [
|
||||||
'--provider' => 'Stancl\Tenancy\TenancyServiceProvider',
|
'--provider' => 'Stancl\Tenancy\TenancyServiceProvider',
|
||||||
'--tag' => 'migrations',
|
'--tag' => 'migrations',
|
||||||
|
|
|
||||||
|
|
@ -28,11 +28,17 @@ class InitializeTenancy
|
||||||
*/
|
*/
|
||||||
public function handle($request, Closure $next)
|
public function handle($request, Closure $next)
|
||||||
{
|
{
|
||||||
|
if (tenancy()->initialized) {
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! in_array($request->getHost(), config('tenancy.exempt_domains', []), true)) {
|
||||||
try {
|
try {
|
||||||
tenancy()->init($request->getHost());
|
tenancy()->init($request->getHost());
|
||||||
} catch (TenantCouldNotBeIdentifiedException $e) {
|
} catch (TenantCouldNotBeIdentifiedException $e) {
|
||||||
($this->onFail)($e);
|
($this->onFail)($e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,11 @@ declare(strict_types=1);
|
||||||
namespace Stancl\Tenancy\Middleware;
|
namespace Stancl\Tenancy\Middleware;
|
||||||
|
|
||||||
use Closure;
|
use Closure;
|
||||||
|
use Illuminate\Routing\Route;
|
||||||
|
use Illuminate\Support\Facades\Route as Router;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevent access to non-tenant routes from domains that are not exempt from tenancy.
|
* Prevent access from tenant domains to central routes and vice versa.
|
||||||
* = allow access to central routes only from routes listed in tenancy.exempt_routes.
|
|
||||||
*/
|
*/
|
||||||
class PreventAccessFromTenantDomains
|
class PreventAccessFromTenantDomains
|
||||||
{
|
{
|
||||||
|
|
@ -26,7 +27,7 @@ class PreventAccessFromTenantDomains
|
||||||
$isExemptDomain = in_array($request->getHost(), config('tenancy.exempt_domains'));
|
$isExemptDomain = in_array($request->getHost(), config('tenancy.exempt_domains'));
|
||||||
$isTenantDomain = ! $isExemptDomain;
|
$isTenantDomain = ! $isExemptDomain;
|
||||||
|
|
||||||
$isTenantRoute = in_array('tenancy', $request->route()->middleware());
|
$isTenantRoute = $this->isTenantRoute($request->route());
|
||||||
|
|
||||||
if ($isTenantDomain && ! $isTenantRoute) { // accessing web routes from tenant domains
|
if ($isTenantDomain && ! $isTenantRoute) { // accessing web routes from tenant domains
|
||||||
return redirect(config('tenancy.home_url'));
|
return redirect(config('tenancy.home_url'));
|
||||||
|
|
@ -38,4 +39,22 @@ class PreventAccessFromTenantDomains
|
||||||
|
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isTenantRoute(Route $route): bool
|
||||||
|
{
|
||||||
|
if (in_array('tenancy', $route->middleware(), true)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop one level deep and check if the route's middleware
|
||||||
|
// groups have a `tenancy` middleware group inside them
|
||||||
|
$middlewareGroups = Router::getMiddlewareGroups();
|
||||||
|
foreach ($route->gatherMiddleware() as $middleware) {
|
||||||
|
if (isset($middlewareGroups[$middleware]) && in_array('tenancy', $middlewareGroups[$middleware], true)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||||
namespace Stancl\Tenancy;
|
namespace Stancl\Tenancy;
|
||||||
|
|
||||||
use Illuminate\Cache\CacheManager;
|
use Illuminate\Cache\CacheManager;
|
||||||
|
use Illuminate\Contracts\Http\Kernel;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
use Stancl\Tenancy\TenancyBootstrappers\FilesystemTenancyBootstrapper;
|
use Stancl\Tenancy\TenancyBootstrappers\FilesystemTenancyBootstrapper;
|
||||||
|
|
@ -77,15 +78,27 @@ class TenancyServiceProvider extends ServiceProvider
|
||||||
__DIR__ . '/../assets/migrations/' => database_path('migrations'),
|
__DIR__ . '/../assets/migrations/' => database_path('migrations'),
|
||||||
], 'migrations');
|
], 'migrations');
|
||||||
|
|
||||||
$this->loadRoutesFrom(__DIR__ . '/routes.php');
|
$this->app->make(Kernel::class)->prependMiddleware(Middleware\InitializeTenancy::class);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since tenancy is initialized in the global middleware stack, this
|
||||||
|
* middleware group acts mostly as a 'flag' for the PreventAccess
|
||||||
|
* middleware to decide whether the request should be aborted.
|
||||||
|
*/
|
||||||
Route::middlewareGroup('tenancy', [
|
Route::middlewareGroup('tenancy', [
|
||||||
\Stancl\Tenancy\Middleware\InitializeTenancy::class,
|
/* Prevent access from tenant domains to central routes and vice versa. */
|
||||||
|
Middleware\PreventAccessFromTenantDomains::class,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$this->loadRoutesFrom(__DIR__ . '/routes.php');
|
||||||
|
|
||||||
$this->app->singleton('globalUrl', function ($app) {
|
$this->app->singleton('globalUrl', function ($app) {
|
||||||
|
if ($app->bound(FilesystemTenancyBootstrapper::class)) {
|
||||||
$instance = clone $app['url'];
|
$instance = clone $app['url'];
|
||||||
$instance->setAssetRoot($app[FilesystemTenancyBootstrapper::class]->originalPaths['asset_url']);
|
$instance->setAssetRoot($app[FilesystemTenancyBootstrapper::class]->originalPaths['asset_url']);
|
||||||
|
} else {
|
||||||
|
$instance = $app['url'];
|
||||||
|
}
|
||||||
|
|
||||||
return $instance;
|
return $instance;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,7 @@ class TenantRouteServiceProvider extends RouteServiceProvider
|
||||||
{
|
{
|
||||||
public function map()
|
public function map()
|
||||||
{
|
{
|
||||||
if (! in_array(request()->getHost(), $this->app['config']['tenancy.exempt_domains'] ?? [])
|
if (file_exists(base_path('routes/tenant.php'))) {
|
||||||
&& file_exists(base_path('routes/tenant.php'))) {
|
|
||||||
Route::middleware(['web', 'tenancy'])
|
Route::middleware(['web', 'tenancy'])
|
||||||
->namespace($this->app['config']['tenancy.tenant_route_namespace'] ?? 'App\Http\Controllers')
|
->namespace($this->app['config']['tenancy.tenant_route_namespace'] ?? 'App\Http\Controllers')
|
||||||
->group(base_path('routes/tenant.php'));
|
->group(base_path('routes/tenant.php'));
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
Route::middleware(['tenancy'])->group(function () {
|
||||||
Route::get('/tenancy/assets/{path}', 'Stancl\Tenancy\Controllers\TenantAssetsController@asset')
|
Route::get('/tenancy/assets/{path}', 'Stancl\Tenancy\Controllers\TenantAssetsController@asset')
|
||||||
->where('path', '(.*)')
|
->where('path', '(.*)')
|
||||||
->name('stancl.tenancy.asset');
|
->name('stancl.tenancy.asset');
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,7 @@ class CommandsTest extends TestCase
|
||||||
file_put_contents(app_path('Http/Kernel.php'), file_get_contents(__DIR__ . '/Etc/defaultHttpKernel.stub'));
|
file_put_contents(app_path('Http/Kernel.php'), file_get_contents(__DIR__ . '/Etc/defaultHttpKernel.stub'));
|
||||||
|
|
||||||
$this->artisan('tenancy:install')
|
$this->artisan('tenancy:install')
|
||||||
->expectsQuestion('Do you want to publish the default database migrations?', 'yes');
|
->expectsQuestion('Do you wish to publish the migrations that create these tables?', 'yes');
|
||||||
$this->assertFileExists(base_path('routes/tenant.php'));
|
$this->assertFileExists(base_path('routes/tenant.php'));
|
||||||
$this->assertFileExists(base_path('config/tenancy.php'));
|
$this->assertFileExists(base_path('config/tenancy.php'));
|
||||||
$this->assertFileExists(database_path('migrations/2019_09_15_000010_create_tenants_table.php'));
|
$this->assertFileExists(database_path('migrations/2019_09_15_000010_create_tenants_table.php'));
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ class Kernel extends HttpKernel
|
||||||
],
|
],
|
||||||
|
|
||||||
'api' => [
|
'api' => [
|
||||||
|
\Stancl\Tenancy\Middleware\PreventAccessFromTenantDomains::class,
|
||||||
'throttle:60,1',
|
'throttle:60,1',
|
||||||
'bindings',
|
'bindings',
|
||||||
],
|
],
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue