73
common/Auth/Permissions/Permission.php
Executable file
73
common/Auth/Permissions/Permission.php
Executable file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace Common\Auth\Permissions;
|
||||
|
||||
use Arr;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class Permission extends Model
|
||||
{
|
||||
protected $guarded = ['id'];
|
||||
|
||||
protected $casts = [
|
||||
'id' => 'integer',
|
||||
'advanced' => 'integer',
|
||||
];
|
||||
|
||||
protected $hidden = ['pivot', 'permissionable_type'];
|
||||
|
||||
const MODEL_TYPE = 'permission';
|
||||
|
||||
public static function getModelTypeAttribute(): string
|
||||
{
|
||||
return self::MODEL_TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|array $value
|
||||
* @return Collection
|
||||
*/
|
||||
public function getRestrictionsAttribute($value)
|
||||
{
|
||||
// if loading permissions via parent (user, role, plan) return restrictions
|
||||
// stored on pivot table, otherwise return restrictions stored on permission itself
|
||||
$value = $this->pivot ? $this->pivot->restrictions : $value;
|
||||
if ( ! $value) $value = [];
|
||||
return collect(is_string($value) ? json_decode($value, true) : $value)->values();
|
||||
}
|
||||
|
||||
public function setRestrictionsAttribute($value)
|
||||
{
|
||||
if ($value && is_array($value)) {
|
||||
$this->attributes['restrictions'] = json_encode(array_values($value));
|
||||
}
|
||||
}
|
||||
|
||||
public function getRestrictionValue(string $name): int | bool | null
|
||||
{
|
||||
$restriction = $this->restrictions->first(function($restriction) use($name) {
|
||||
return $restriction['name'] === $name;
|
||||
});
|
||||
|
||||
return Arr::get($restriction, 'value') ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge restrictions from specified permission into this permission.
|
||||
*/
|
||||
public function mergeRestrictions(Permission $permission = null): self
|
||||
{
|
||||
if ($permission) {
|
||||
$permission->restrictions->each(function($restriction) {
|
||||
$exists = $this->restrictions->first(function($r) use($restriction) {
|
||||
return $r['name'] === $restriction['name'];
|
||||
});
|
||||
if ( ! $exists) {
|
||||
$this->restrictions->push($restriction);
|
||||
}
|
||||
});
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
48
common/Auth/Permissions/Policies/PermissionPolicy.php
Executable file
48
common/Auth/Permissions/Policies/PermissionPolicy.php
Executable file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Common\Auth\Permissions\Policies;
|
||||
|
||||
use Common\Auth\Permissions\Permission;
|
||||
use Common\Auth\BaseUser;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class PermissionPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* @var Request
|
||||
*/
|
||||
private $request;
|
||||
|
||||
public function __construct(Request $request)
|
||||
{
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
public function index(BaseUser $user)
|
||||
{
|
||||
return $user->hasPermission('permission.view');
|
||||
}
|
||||
|
||||
public function show(BaseUser $user, Permission $permission)
|
||||
{
|
||||
return $user->hasPermission('permission.view');
|
||||
}
|
||||
|
||||
public function store(BaseUser $user)
|
||||
{
|
||||
return $user->hasPermission('permission.create');
|
||||
}
|
||||
|
||||
public function update(BaseUser $user)
|
||||
{
|
||||
return $user->hasPermission('permission.update');
|
||||
}
|
||||
|
||||
public function destroy(BaseUser $user)
|
||||
{
|
||||
return $user->hasPermission('permission.delete');
|
||||
}
|
||||
}
|
||||
50
common/Auth/Permissions/Traits/HasPermissionsRelation.php
Executable file
50
common/Auth/Permissions/Traits/HasPermissionsRelation.php
Executable file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace Common\Auth\Permissions\Traits;
|
||||
|
||||
use Common\Auth\Permissions\Permission;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphToMany;
|
||||
|
||||
trait HasPermissionsRelation
|
||||
{
|
||||
public function permissions(): MorphToMany
|
||||
{
|
||||
return $this->morphToMany(Permission::class, 'permissionable')
|
||||
->withPivot('restrictions')
|
||||
->select('name', 'permissions.id', 'permissions.restrictions');
|
||||
}
|
||||
|
||||
public function hasPermission(string $name): bool
|
||||
{
|
||||
return !is_null($this->getPermission($name)) ||
|
||||
!is_null($this->getPermission('admin'));
|
||||
}
|
||||
|
||||
public function hasExactPermission(string $name): bool
|
||||
{
|
||||
return !is_null($this->getPermission($name));
|
||||
}
|
||||
|
||||
public function getPermission(string $name): Permission|null
|
||||
{
|
||||
if (method_exists($this, 'loadPermissions')) {
|
||||
$this->loadPermissions();
|
||||
}
|
||||
|
||||
foreach ($this->permissions as $permission) {
|
||||
if ($permission->name === $name) {
|
||||
return $permission;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getRestrictionValue(
|
||||
string $permissionName,
|
||||
string $restriction,
|
||||
): int|bool|null {
|
||||
$permission = $this->getPermission($permissionName);
|
||||
return $permission?->getRestrictionValue($restriction);
|
||||
}
|
||||
}
|
||||
36
common/Auth/Permissions/Traits/SyncsPermissions.php
Executable file
36
common/Auth/Permissions/Traits/SyncsPermissions.php
Executable file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Common\Auth\Permissions\Traits;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
trait SyncsPermissions
|
||||
{
|
||||
public function syncPermissions(
|
||||
Model $model,
|
||||
array|Collection $permissions
|
||||
): void {
|
||||
$permissionIds = collect($permissions)->mapWithKeys(function (
|
||||
$permission
|
||||
) {
|
||||
$restrictions = Arr::get($permission, 'restrictions', []);
|
||||
return [
|
||||
$permission['id'] => [
|
||||
'restrictions' => collect($restrictions)
|
||||
->filter(function ($restriction) {
|
||||
return isset($restriction['value']);
|
||||
})
|
||||
->map(function ($restriction) {
|
||||
return [
|
||||
'name' => $restriction['name'],
|
||||
'value' => $restriction['value'],
|
||||
];
|
||||
}),
|
||||
],
|
||||
];
|
||||
});
|
||||
$model->permissions()->sync($permissionIds);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user