mirror of
https://github.com/AnimeThemes/animethemes-server.git
synced 2026-07-26 00:34:28 +02:00
105 lines
3.4 KiB
PHP
105 lines
3.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Http\Middleware\Models\Pivot;
|
|
|
|
use App\Models\Auth\User;
|
|
use Closure;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Gate;
|
|
use Illuminate\Support\Str;
|
|
|
|
class AuthorizesPivot
|
|
{
|
|
/**
|
|
* @param Closure(Request): mixed $next
|
|
* @param class-string $foreignClass
|
|
* @param class-string $relatedClass
|
|
*/
|
|
public function handle(Request $request, Closure $next, string $foreignClass, string $foreignParameter, string $relatedClass, string $relatedParameter): mixed
|
|
{
|
|
/** @var Model $foreignModel */
|
|
$foreignModel = $request->route($foreignParameter);
|
|
|
|
/** @var Model $relatedModel */
|
|
$relatedModel = $request->route($relatedParameter);
|
|
|
|
$isAuthorized = match ($request->route()->getActionMethod()) {
|
|
'index' => $this->forIndex($request->user(), $foreignClass, $relatedClass),
|
|
'show' => $this->forShow($request->user(), $foreignModel, $relatedModel),
|
|
'create', 'store' => $this->forStore($request->user(), $foreignModel, $relatedModel),
|
|
'destroy' => $this->forDestroy($request->user(), $foreignModel, $relatedModel),
|
|
'edit', 'update' => $this->forUpdate($request->user(), $foreignModel, $relatedModel),
|
|
default => false,
|
|
};
|
|
|
|
abort_unless($isAuthorized, 403);
|
|
|
|
return $next($request);
|
|
}
|
|
|
|
/**
|
|
* Get the authorization to index.
|
|
*
|
|
* @param class-string $foreignClass
|
|
* @param class-string $relatedClass
|
|
*/
|
|
protected function forIndex(?User $user, string $foreignClass, string $relatedClass): bool
|
|
{
|
|
return Gate::forUser($user)->check('viewAny', $foreignClass)
|
|
&& Gate::forUser($user)->check('viewAny', $relatedClass);
|
|
}
|
|
|
|
/**
|
|
* Get the authorization to show a pivot.
|
|
*/
|
|
protected function forShow(?User $user, Model $foreignModel, Model $relatedModel): bool
|
|
{
|
|
return Gate::forUser($user)->check('view', $foreignModel)
|
|
&& Gate::forUser($user)->check('view', $relatedModel);
|
|
}
|
|
|
|
/**
|
|
* Get the authorization to store a pivot.
|
|
*/
|
|
protected function forStore(User $user, Model $foreignModel, Model $relatedModel): bool
|
|
{
|
|
$attachAny = Str::of('attachAny')
|
|
->append(Str::studly(class_basename($relatedModel)))
|
|
->__toString();
|
|
|
|
$attach = Str::of('attach')
|
|
->append(Str::studly(class_basename($relatedModel)))
|
|
->__toString();
|
|
|
|
return Gate::forUser($user)->any([$attach, $attachAny], [$foreignModel, $relatedModel]);
|
|
}
|
|
|
|
/**
|
|
* Get the authorization to destroy a pivot.
|
|
*/
|
|
protected function forDestroy(User $user, Model $foreignModel, Model $relatedModel): bool
|
|
{
|
|
$detachAny = Str::of('detachAny')
|
|
->append(Str::studly(class_basename($relatedModel)))
|
|
->__toString();
|
|
|
|
$detach = Str::of('detach')
|
|
->append(Str::studly(class_basename($relatedModel)))
|
|
->__toString();
|
|
|
|
return Gate::forUser($user)->any([$detach, $detachAny], [$foreignModel, $relatedModel]);
|
|
}
|
|
|
|
/**
|
|
* Get the authorization to update a pivot.
|
|
*/
|
|
protected function forUpdate(User $user, Model $foreignModel, Model $relatedModel): bool
|
|
{
|
|
return Gate::forUser($user)->check('update', $foreignModel)
|
|
&& Gate::forUser($user)->check('update', $relatedModel);
|
|
}
|
|
}
|