126
common/Core/Policies/BasePolicy.php
Executable file
126
common/Core/Policies/BasePolicy.php
Executable file
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
namespace Common\Core\Policies;
|
||||
|
||||
use App\Models\User;
|
||||
use Common\Core\Exceptions\AccessResponseWithAction;
|
||||
use Common\Core\Exceptions\AccessResponseWithPermission;
|
||||
use Common\Settings\Settings;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
use Illuminate\Auth\Access\Response;
|
||||
use Illuminate\Http\Request;
|
||||
use Str;
|
||||
|
||||
abstract class BasePolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function __construct(
|
||||
protected Request $request,
|
||||
protected Settings $settings,
|
||||
) {
|
||||
}
|
||||
|
||||
protected function denyWithAction(
|
||||
$message,
|
||||
array|null $action = null,
|
||||
): AccessResponseWithAction {
|
||||
/** @var AccessResponseWithAction $response */
|
||||
$response = AccessResponseWithAction::deny($message);
|
||||
$response->action = $action;
|
||||
return $response;
|
||||
}
|
||||
|
||||
protected function storeWithCountRestriction(
|
||||
User $user,
|
||||
string $namespace,
|
||||
): Response {
|
||||
[
|
||||
$relationName,
|
||||
$permission,
|
||||
$singularName,
|
||||
$pluralName,
|
||||
] = $this->parseNamespace($namespace);
|
||||
|
||||
// user can't create resource at all
|
||||
if (!$this->hasPermission($user, $permission)) {
|
||||
return Response::deny();
|
||||
}
|
||||
|
||||
// user is admin, can ignore count restriction
|
||||
if ($user->hasPermission('admin')) {
|
||||
return Response::allow();
|
||||
}
|
||||
|
||||
// user does not have any restriction on maximum resource count
|
||||
$maxCount = $user->getRestrictionValue($permission, 'count');
|
||||
if (!$maxCount) {
|
||||
return Response::allow();
|
||||
}
|
||||
|
||||
// check if user did not go over their max quota
|
||||
if ($user->$relationName->count() >= $maxCount) {
|
||||
$message = __('policies.quota_exceeded', [
|
||||
'resources' => $pluralName,
|
||||
'resource' => $singularName,
|
||||
]);
|
||||
return $this->denyWithAction($message, $this->upgradeAction());
|
||||
}
|
||||
|
||||
return Response::allow();
|
||||
}
|
||||
|
||||
protected function hasPermission(?User $user, string $permission): bool
|
||||
{
|
||||
$model = $user ?: app('guestRole');
|
||||
return $model?->hasPermission($permission) ?? false;
|
||||
}
|
||||
|
||||
protected function authorizePermission(
|
||||
?User $user,
|
||||
string $permission,
|
||||
): AccessResponseWithPermission {
|
||||
return new AccessResponseWithPermission(
|
||||
$this->hasPermission($user, $permission),
|
||||
$permission,
|
||||
'',
|
||||
403,
|
||||
);
|
||||
}
|
||||
|
||||
protected function parseNamespace(
|
||||
string $namespace,
|
||||
string $ability = 'create',
|
||||
): array {
|
||||
// 'App\SomeModel' => 'Some_Model'
|
||||
$resourceName = Str::snake(class_basename($namespace));
|
||||
|
||||
// 'Some_Model' => 'someModels'
|
||||
$relationName = Str::camel(Str::plural($resourceName));
|
||||
|
||||
// 'Some_Model' => 'Some Model'
|
||||
$singularName = str_replace('_', ' ', $resourceName);
|
||||
|
||||
// 'Some Model' => 'Some Models'
|
||||
$pluralName = Str::plural($singularName);
|
||||
|
||||
// parent might need to override permission name. custom_domains instead of links_domains for example.
|
||||
$permissionName = $this->permissionName ?? Str::snake($relationName);
|
||||
|
||||
return [
|
||||
$relationName,
|
||||
"$permissionName.$ability",
|
||||
$singularName,
|
||||
$pluralName,
|
||||
];
|
||||
}
|
||||
|
||||
protected function upgradeAction(): ?array
|
||||
{
|
||||
if ($this->settings->get('billing.enable')) {
|
||||
return ['label' => __('Upgrade'), 'action' => '/pricing'];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user