From 1fb57141bcfc6be846a38ace9a74aecff99e6e44 Mon Sep 17 00:00:00 2001 From: a6a2f5842 Date: Sun, 15 Jun 2025 18:29:50 +0200 Subject: [PATCH] I basic structure --- config/permissions.php | 8 ++-- .../migrations/create_blax_role_tables.php | 43 +++++++++++++++---- src/Models/Assignment.php | 7 --- src/Models/Permission.php | 25 ++++++++++- src/Models/PermissionUsage.php | 24 +++++++++++ src/Models/Role.php | 32 +++++++++++++- src/Models/RoleMember.php | 29 +++++++++++++ src/Models/RolePermission.php | 27 ++++++++++++ src/Traits/HasRoles.php | 21 +++++---- 9 files changed, 185 insertions(+), 31 deletions(-) delete mode 100644 src/Models/Assignment.php create mode 100644 src/Models/PermissionUsage.php create mode 100644 src/Models/RoleMember.php create mode 100644 src/Models/RolePermission.php diff --git a/config/permissions.php b/config/permissions.php index 18ebe4a..e0c3f79 100644 --- a/config/permissions.php +++ b/config/permissions.php @@ -4,15 +4,17 @@ return [ 'models' => [ 'role' => \Blax\Roles\Models\Role::class, + 'role_member' => \Blax\Roles\Models\RoleMember::class, + 'role_permission' => \Blax\Roles\Models\RolePermission::class, 'permission' => \Blax\Roles\Models\Permission::class, + 'permission_usage' => \Blax\Roles\Models\PermissionUsage::class, + ], 'table_names' => [ 'roles' => 'roles', 'permissions' => 'permissions', - 'model_has_roles' => 'model_has_roles', - 'model_has_permissions' => 'model_has_permissions', - 'role_has_permissions' => 'role_has_permissions', + 'permission_usage' => 'permission_usage', ], ]; diff --git a/database/migrations/create_blax_role_tables.php b/database/migrations/create_blax_role_tables.php index 9a4919f..a13f796 100644 --- a/database/migrations/create_blax_role_tables.php +++ b/database/migrations/create_blax_role_tables.php @@ -13,25 +13,52 @@ return new class extends Migration */ public function up(): void { - // TODO finish the migration - - Schema::create('roles', function (Blueprint $table) { + // Permission + Schema::create(config('permissions.table_names.permissions'), function (Blueprint $table) { $table->id(); $table->string('name')->unique(); $table->string('description')->nullable(); $table->timestamps(); }); - Schema::create('permissions', function (Blueprint $table) { + // PermissionUsage + Schema::create(config('permissions.table_names.permission_usage'), function (Blueprint $table) { $table->id(); - $table->string('name')->unique(); + $table->foreignId('permission_id')->constrained('permissions')->onDelete('cascade'); + $table->morphs('user'); + $table->json('context')->nullable(); + $table->timestamps(); + }); + + // Role + Schema::create(config('permissions.table_names.roles'), function (Blueprint $table) { + $table->id(); + $table->foreignId('parent_id') + ->nullable() + ->constrained('roles') + ->onDelete('set null'); + $table->string('name'); + $table->string('slug',32)->unique(); $table->string('description')->nullable(); $table->timestamps(); }); - Schema::create('assignments', function (Blueprint $table) { - $table->morphs('affected'); - $table->morphs('assignment'); + // RoleMember + Schema::create(config('permissions.table_names.role_members'), function (Blueprint $table) { + $table->id(); + $table->foreignId('role_id')->constrained('roles')->onDelete('cascade'); + $table->morphs('member'); + $table->json('context')->nullable(); + $table->timestamp('expires_at')->nullable(); + $table->timestamps(); + }); + + // RolePermission + Schema::create(config('permissions.table_names.role_permission'), function (Blueprint $table) { + $table->id(); + $table->foreignId('role_id')->constrained('roles')->onDelete('cascade'); + $table->foreignId('permission_id')->constrained('permissions')->onDelete('cascade'); + $table->json('context')->nullable(); $table->timestamp('expires_at')->nullable(); $table->timestamps(); }); diff --git a/src/Models/Assignment.php b/src/Models/Assignment.php deleted file mode 100644 index e3375aa..0000000 --- a/src/Models/Assignment.php +++ /dev/null @@ -1,7 +0,0 @@ -table = config('permissions.table_names.permissions') ?: parent::getTable(); + } + + public function usages() + { + return $this->hasMany(PermissionUsage::class); + } + + public function roles() + { + return $this->belongsToMany(RolePermission::class); + } +} diff --git a/src/Models/PermissionUsage.php b/src/Models/PermissionUsage.php new file mode 100644 index 0000000..71ca8d6 --- /dev/null +++ b/src/Models/PermissionUsage.php @@ -0,0 +1,24 @@ +table = config('permissions.table_names.permission_usages') ?: parent::getTable(); + } + + public function permission() + { + return $this->belongsTo(Permission::class); + } +} diff --git a/src/Models/Role.php b/src/Models/Role.php index 781d55a..7a9ea7c 100644 --- a/src/Models/Role.php +++ b/src/Models/Role.php @@ -4,4 +4,34 @@ namespace Blax\Roles\Models; use Illuminate\Database\Eloquent\Model; -class Role extends Model {} +class Role extends Model { + protected $fillable = [ + 'parent_id', + 'name', + 'slug', + 'description', + ]; + + public function __construct(array $attributes = []) + { + parent::__construct($attributes); + + $this->table = config('permissions.table_names.roles') ?: parent::getTable(); + } + + public function members() { + return $this->belongsToMany(RoleMember::class); + } + + public function permissions() { + return $this->belongsToMany(RolePermission::class); + } + + public function parent() { + return $this->belongsTo(Role::class, 'parent_id'); + } + + public function children() { + return $this->hasMany(Role::class, 'parent_id'); + } +} diff --git a/src/Models/RoleMember.php b/src/Models/RoleMember.php new file mode 100644 index 0000000..d98b4ac --- /dev/null +++ b/src/Models/RoleMember.php @@ -0,0 +1,29 @@ +table = config('permissions.table_names.role_members') ?: parent::getTable(); + } + + public function role() { + return $this->belongsTo(Role::class); + } + + public function member() { + return $this->morphTo(); + } +} diff --git a/src/Models/RolePermission.php b/src/Models/RolePermission.php new file mode 100644 index 0000000..3b265b7 --- /dev/null +++ b/src/Models/RolePermission.php @@ -0,0 +1,27 @@ +table = config('permissions.table_names.role_permission') ?: parent::getTable(); + } + + public function role() { + return $this->belongsTo(Role::class); + } + + public function permission() { + return $this->belongsTo(Permission::class); + } +} diff --git a/src/Traits/HasRoles.php b/src/Traits/HasRoles.php index bad7918..7db27f3 100644 --- a/src/Traits/HasRoles.php +++ b/src/Traits/HasRoles.php @@ -5,28 +5,27 @@ namespace Blax\Roles; trait HasRoles { /** - * The roles that belong to the model. + * Get all roles for the user. * - * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany + * @return \Illuminate\Database\Eloquent\Relations\MorphToMany */ public function roles() { - return $this->belongsToMany( - config('permissions.models.role'), - config('permissions.table_names.model_has_roles'), - 'model_id', - 'role_id' + return $this->morphToMany( + config('permissions.models.role', \Blax\Roles\Models\Role::class), + 'member', + config('permissions.table_names.role_members', 'role_members') ); } /** - * Check if the model has a specific role. + * Check if the user has a specific role. * - * @param string $role + * @param string $roleSlug * @return bool */ - public function hasRole($role) + public function hasRole(string $roleSlug): bool { - return $this->roles()->where('name', $role)->exists(); + return $this->roles()->where('slug', $roleSlug)->exists(); } }