mirror of
https://github.com/archtechx/tenancy.git
synced 2026-06-20 22:54:05 +00:00
The PreventAcessFromUnwantedDomains MW had the `tenancy()->routeIsUniversal($route)` check either for returning early, or it was a leftover from some older implementation, so I removed it. The middleware aborts if the `$this->accessingTenantRouteFromCentralDomain($request, $route) || $this->accessingCentralRouteFromTenantDomain($request, $route)` check passes. Meaning, **for the middleware to abort, the route has to be either in central or tenant mode**. When the route is in universal mode, the middleware will never reach `return $abortRequest()`. `return $next($request)` will always get reached, even when the `|| tenancy()->routeIsUniversal($route)` check is deleted from the previous condition, so that check was basically useless. Since the docblock for the class does mention the behavior for universal routes explicitly, we've instead added a comment documenting that things work this way. That's probably the most reasonable way to have this explicit behavior for universal routes easily understandable in this fairly complex logic without redundant code. Resolves #1418 --------- Co-authored-by: Samuel Štancl <samuel@archte.ch>
78 lines
2.9 KiB
PHP
78 lines
2.9 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace Stancl\Tenancy\Middleware;
|
||
|
||
use Closure;
|
||
use Illuminate\Http\Request;
|
||
use Illuminate\Routing\Route;
|
||
use Stancl\Tenancy\Concerns\UsableWithEarlyIdentification;
|
||
use Stancl\Tenancy\Enums\RouteMode;
|
||
|
||
/**
|
||
* Prevents accessing central domains in the tenant context/tenant domains in the central context.
|
||
* The access isn't prevented if the request is trying to access a route flagged as 'universal',
|
||
* or if this middleware should be skipped.
|
||
*
|
||
* @see UsableWithEarlyIdentification – more info about the skipping part
|
||
*/
|
||
class PreventAccessFromUnwantedDomains
|
||
{
|
||
use UsableWithEarlyIdentification;
|
||
|
||
/**
|
||
* 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
|
||
{
|
||
$route = tenancy()->getRoute($request);
|
||
|
||
if ($this->shouldBeSkipped($route)) {
|
||
return $next($request);
|
||
}
|
||
|
||
// If the route is universal, neither of these checks will pass and the logic will
|
||
// fall through to the $next($request) call at the end.
|
||
if ($this->accessingTenantRouteFromCentralDomain($request, $route) || $this->accessingCentralRouteFromTenantDomain($request, $route)) {
|
||
$abortRequest = static::$abortRequest ?? function () {
|
||
abort(404);
|
||
};
|
||
|
||
return $abortRequest($request, $next);
|
||
}
|
||
|
||
return $next($request);
|
||
}
|
||
|
||
protected function accessingTenantRouteFromCentralDomain(Request $request, Route $route): bool
|
||
{
|
||
return tenancy()->getRouteMode($route) === RouteMode::TENANT // Current route's middleware context is tenant
|
||
&& $this->isCentralDomain($request); // The request comes from a domain that IS present in the configured `tenancy.identification.central_domains`
|
||
}
|
||
|
||
protected function accessingCentralRouteFromTenantDomain(Request $request, Route $route): bool
|
||
{
|
||
return tenancy()->getRouteMode($route) === RouteMode::CENTRAL // Current route's middleware context is central
|
||
&& ! $this->isCentralDomain($request); // The request comes from a domain that ISN'T present in the configured `tenancy.identification.central_domains`
|
||
}
|
||
|
||
/**
|
||
* Check if the request's host name is present in the configured `tenancy.identification.central_domains`.
|
||
*/
|
||
protected function isCentralDomain(Request $request): bool
|
||
{
|
||
return in_array($request->getHost(), config('tenancy.identification.central_domains'), true);
|
||
}
|
||
|
||
public function requestHasTenant(Request $request): bool
|
||
{
|
||
// This middleware is special in that it's not an identification middleware
|
||
// but still uses some logic from UsableWithEarlyIdentification, so we just
|
||
// need to implement this method here. It doesn't matter what it returns.
|
||
return false;
|
||
}
|
||
}
|