1
0
Fork 0
mirror of https://github.com/archtechx/tenancy.git synced 2025-12-12 16:24:04 +00:00

Early identification support (#1)

* wip

* Improve tests

* rename class

* wip

* improve tests

* introduce early identification middlewares

* Update PreventAccessFromCentralDomains.php

* method rename

* method rename

* Update UniversalRouteTest.php

* Update UniversalRouteTest.php

* Update EarlyIdentificationTest.php

* remove early classes and add check in existing classes

* MWs improvements

* Update UniversalRouteTest.php

* Fix code style (php-cs-fixer)

* trigger ci

* fix failing test after merge

* add test for universal route in early identification

* Update InitializeTenancyByDomain.php

* Update UniversalRouteTest.php

* remove `routeHasMiddleware` method from MW and use the UniversalRoutes class method

* helper dockblock

* add test

* handle universal routes in early identification

* remove UniversalRoute class because we are not using it anymore

* rename class from PreventAccessFromCentralDomains to PreventAccessFromUnwantedDomains

* improvements after self review

* Update PreventAccessFromUnwantedDomains.php

* remove inline class namespaces

* remove DomainTenant class and use the Tenant class

* update comment

* removed custom expection and add method

* Update tests/EarlyIdentificationTest.php

Co-authored-by: Samuel Štancl <samuel.stancl@gmail.com>

* use ltrim and simplify the comment

* remove comments and typhint

* dataset and keys rename

* rename $route parameter

* removed helper functions

* fix style

* Update InitializeTenancyByPath.php

* Update tests/EarlyIdentificationTest.php

* code style

* improve subdomain test

* use TenancyInitialized event and remove DomainTenant alias

* remove comment and move expectException below

* code style

* use TenancyInitialized event

* improve test

* improve datasets

* Initialized -> Initializing

* Update InitializeTenancyByPath.php

* remove todo

* Fix code style (php-cs-fixer)

* refactor helper method

* Update UniversalRouteTest.php

* add note above test

* remove after each hook

* renamed universal_middleware to global_middleware

* remove helper and improve url names

* change check position

* Revert "change check position"

This reverts commit e4371d2f3aa8ad7ae5e5b7d15781b72a5f1be03c.

* repositioned central check

* add comment

Co-authored-by: PHP CS Fixer <phpcsfixer@example.com>
Co-authored-by: Samuel Štancl <samuel.stancl@gmail.com>
This commit is contained in:
Abrar Ahmad 2022-11-20 06:31:37 +05:00 committed by GitHub
parent 9520cbc811
commit ff46bcfe20
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 330 additions and 163 deletions

View file

@ -22,6 +22,11 @@ class InitializeTenancyByDomain extends IdentificationMiddleware
/** @return \Illuminate\Http\Response|mixed */
public function handle(Request $request, Closure $next): mixed
{
if (in_array($request->getHost(), config('tenancy.central_domains', []), true)) {
// Always bypass tenancy initialization when host is in central domains
return $next($request);
}
return $this->initializeTenancy(
$request,
$next,

View file

@ -28,14 +28,13 @@ class InitializeTenancyByPath extends IdentificationMiddleware
/** @return \Illuminate\Http\Response|mixed */
public function handle(Request $request, Closure $next): mixed
{
/** @var Route $route */
$route = $request->route();
$route = $this->route($request);
// Only initialize tenancy if tenant is the first parameter
// We don't want to initialize tenancy if the tenant is
// simply injected into some route controller action.
if ($route->parameterNames()[0] === PathTenantResolver::tenantParameterName()) {
$this->setDefaultTenantForRouteParametersWhenTenancyIsInitialized();
$this->setDefaultTenantForRouteParametersWhenInitializingTenancy();
return $this->initializeTenancy(
$request,
@ -47,7 +46,26 @@ class InitializeTenancyByPath extends IdentificationMiddleware
}
}
protected function setDefaultTenantForRouteParametersWhenTenancyIsInitialized(): void
protected function route(Request $request): Route
{
/** @var Route $route */
$route = $request->route();
if (! $route) {
// Create a fake $route instance that has enough information for this middleware's needs
$route = new Route($request->method(), $request->getUri(), []);
/**
* getPathInfo() returns the path except the root domain.
* We fetch the first parameter because tenant parameter is *always* first.
*/
$route->parameters[PathTenantResolver::tenantParameterName()] = explode('/', ltrim($request->getPathInfo(), '/'))[0];
$route->parameterNames[] = PathTenantResolver::tenantParameterName();
}
return $route;
}
protected function setDefaultTenantForRouteParametersWhenInitializingTenancy(): void
{
Event::listen(InitializingTenancy::class, function (InitializingTenancy $event) {
/** @var Tenant $tenant */

View file

@ -27,6 +27,11 @@ class InitializeTenancyBySubdomain extends InitializeTenancyByDomain
/** @return Response|mixed */
public function handle(Request $request, Closure $next): mixed
{
if (in_array($request->getHost(), config('tenancy.central_domains', []), true)) {
// Always bypass tenancy initialization when host is in central domains
return $next($request);
}
$subdomain = $this->makeSubdomain($request->getHost());
if (is_object($subdomain) && $subdomain instanceof Exception) {

View file

@ -1,30 +0,0 @@
<?php
declare(strict_types=1);
namespace Stancl\Tenancy\Middleware;
use Closure;
use Illuminate\Http\Request;
class PreventAccessFromCentralDomains
{
/**
* Set this property if you want to customize the on-fail behavior.
*/
public static ?Closure $abortRequest;
/** @return \Illuminate\Http\Response|mixed */
public function handle(Request $request, Closure $next): mixed
{
if (in_array($request->getHost(), config('tenancy.central_domains'))) {
$abortRequest = static::$abortRequest ?? function () {
abort(404);
};
return $abortRequest($request, $next);
}
return $next($request);
}
}

View file

@ -0,0 +1,58 @@
<?php
declare(strict_types=1);
namespace Stancl\Tenancy\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Routing\Route;
use Illuminate\Support\Facades\Route as Router;
// todo come up with a better name
class PreventAccessFromUnwantedDomains
{
/**
* Set this property if you want to customize the on-fail behavior.
*/
public static ?Closure $abortRequest;
/** @return \Illuminate\Http\Response|mixed */
public function handle(Request $request, Closure $next): mixed
{
if ($this->routeHasMiddleware($request->route(), 'universal')) {
return $next($request);
}
if (in_array($request->getHost(), config('tenancy.central_domains'), true)) {
$abortRequest = static::$abortRequest ?? function () {
abort(404);
};
return $abortRequest($request, $next);
}
return $next($request);
}
protected function routeHasMiddleware(Route $route, string $middleware): bool
{
/** @var array $routeMiddleware */
$routeMiddleware = $route->middleware();
if (in_array($middleware, $routeMiddleware, true)) {
return true;
}
// Loop one level deep and check if the route's middleware
// groups have the searched middleware group inside them
$middlewareGroups = Router::getMiddlewareGroups();
foreach ($route->gatherMiddleware() as $inner) {
if (! $inner instanceof Closure && isset($middlewareGroups[$inner]) && in_array($middleware, $middlewareGroups[$inner], true)) {
return true;
}
}
return false;
}
}