diff --git a/src/Models/Permission.php b/src/Models/Permission.php index 9bbf367e4..d0ea85122 100644 --- a/src/Models/Permission.php +++ b/src/Models/Permission.php @@ -104,13 +104,13 @@ public static function findByName(string $name, $guardName = null): PermissionCo /** * Find a permission by its id (and optionally guardName). * - * @param int $id + * @param int|string $id * @param string|null $guardName * @return \Spatie\Permission\Contracts\Permission * * @throws \Spatie\Permission\Exceptions\PermissionDoesNotExist */ - public static function findById(int $id, $guardName = null): PermissionContract + public static function findById($id, $guardName = null): PermissionContract { $guardName = $guardName ?? Guard::getDefaultName(static::class); $permission = static::getPermission([(new static())->getKeyName() => $id, 'guard_name' => $guardName]); diff --git a/src/Models/Role.php b/src/Models/Role.php index 9c6de4771..cc029761b 100644 --- a/src/Models/Role.php +++ b/src/Models/Role.php @@ -112,11 +112,11 @@ public static function findByName(string $name, $guardName = null): RoleContract /** * Find a role by its id (and optionally guardName). * - * @param int $id + * @param int|string $id * @param string|null $guardName * @return \Spatie\Permission\Contracts\Role|\Spatie\Permission\Models\Role */ - public static function findById(int $id, $guardName = null): RoleContract + public static function findById($id, $guardName = null): RoleContract { $guardName = $guardName ?? Guard::getDefaultName(static::class); diff --git a/src/Traits/HasPermissions.php b/src/Traits/HasPermissions.php index 0d85b998f..217ea526e 100644 --- a/src/Traits/HasPermissions.php +++ b/src/Traits/HasPermissions.php @@ -134,7 +134,7 @@ protected function convertToPermissionModels($permissions): array if ($permission instanceof Permission) { return $permission; } - $method = is_string($permission) ? 'findByName' : 'findById'; + $method = is_string($permission) && ! \Str::isUuid($permission) ? 'findByName' : 'findById'; return $this->getPermissionClass()->{$method}($permission, $this->getDefaultGuardName()); }, Arr::wrap($permissions)); @@ -152,14 +152,14 @@ public function filterPermission($permission, $guardName = null) { $permissionClass = $this->getPermissionClass(); - if (is_string($permission)) { + if (is_string($permission) && ! \Str::isUuid($permission)) { $permission = $permissionClass->findByName( $permission, $guardName ?? $this->getDefaultGuardName() ); } - if (is_int($permission)) { + if (is_int($permission) || is_string($permission)) { $permission = $permissionClass->findById( $permission, $guardName ?? $this->getDefaultGuardName() @@ -204,7 +204,7 @@ protected function hasWildcardPermission($permission, $guardName = null): bool { $guardName = $guardName ?? $this->getDefaultGuardName(); - if (is_int($permission)) { + if (is_int($permission) || \Str::isUuid($permission)) { $permission = $this->getPermissionClass()->findById($permission, $guardName); } @@ -449,7 +449,7 @@ protected function getStoredPermission($permissions) { $permissionClass = $this->getPermissionClass(); - if (is_numeric($permissions)) { + if (is_numeric($permissions) || \Str::isUuid($permissions)) { return $permissionClass->findById($permissions, $this->getDefaultGuardName()); } diff --git a/src/Traits/HasRoles.php b/src/Traits/HasRoles.php index 8ab3732ad..35d008aa4 100644 --- a/src/Traits/HasRoles.php +++ b/src/Traits/HasRoles.php @@ -83,7 +83,7 @@ public function scopeRole(Builder $query, $roles, $guard = null): Builder return $role; } - $method = is_numeric($role) ? 'findById' : 'findByName'; + $method = is_numeric($role) || \Str::isUuid($role) ? 'findById' : 'findByName'; return $this->getRoleClass()->{$method}($role, $guard ?: $this->getDefaultGuardName()); }, Arr::wrap($roles)); @@ -195,13 +195,13 @@ public function hasRole($roles, string $guard = null): bool $roles = $this->convertPipeToArray($roles); } - if (is_string($roles)) { + if (is_string($roles) && ! \Str::isUuid($roles)) { return $guard ? $this->roles->where('guard_name', $guard)->contains('name', $roles) : $this->roles->contains('name', $roles); } - if (is_int($roles)) { + if (is_int($roles) || is_string($roles)) { $roleClass = $this->getRoleClass(); $key = (new $roleClass())->getKeyName(); @@ -325,7 +325,7 @@ protected function getStoredRole($role): Role { $roleClass = $this->getRoleClass(); - if (is_numeric($role)) { + if (is_numeric($role) || \Str::isUuid($role)) { return $roleClass->findById($role, $this->getDefaultGuardName()); } diff --git a/tests/HasPermissionsWithCustomModelsTest.php b/tests/HasPermissionsWithCustomModelsTest.php index 6b9fa34ca..b491c8e05 100644 --- a/tests/HasPermissionsWithCustomModelsTest.php +++ b/tests/HasPermissionsWithCustomModelsTest.php @@ -36,4 +36,31 @@ public function it_can_use_custom_fields_from_cache() $this->assertSame(0, count(DB::getQueryLog())); } + + /** @test */ + public function it_can_scope_users_using_a_int() + { + // Skipped because custom model uses uuid, + // replacement "it_can_scope_users_using_a_uuid" + $this->assertTrue(true); + } + + /** @test */ + public function it_can_scope_users_using_a_uuid() + { + $uuid1 = $this->testUserPermission->getKey(); + $uuid2 = app(Permission::class)::where('name', 'edit-news')->first()->getKey(); + + $user1 = User::create(['email' => 'user1@test.com']); + $user2 = User::create(['email' => 'user2@test.com']); + $user1->givePermissionTo([$uuid1, $uuid2]); + $this->testUserRole->givePermissionTo($uuid1); + $user2->assignRole('testRole'); + + $scopedUsers1 = User::permission($uuid1)->get(); + $scopedUsers2 = User::permission([$uuid2])->get(); + + $this->assertEquals(2, $scopedUsers1->count()); + $this->assertEquals(1, $scopedUsers2->count()); + } } diff --git a/tests/Permission.php b/tests/Permission.php index 24d4938b8..9d8f2cd91 100644 --- a/tests/Permission.php +++ b/tests/Permission.php @@ -10,4 +10,24 @@ class Permission extends \Spatie\Permission\Models\Permission 'permission_test_id', 'name', ]; + + protected static function boot() + { + parent::boot(); + static::creating(function ($model) { + if (empty($model->{$model->getKeyName()})) { + $model->{$model->getKeyName()} = \Str::uuid()->toString(); + } + }); + } + + public function getIncrementing() + { + return false; + } + + public function getKeyType() + { + return 'string'; + } } diff --git a/tests/Role.php b/tests/Role.php index ee2862f82..79f8cdbfd 100644 --- a/tests/Role.php +++ b/tests/Role.php @@ -10,4 +10,24 @@ class Role extends \Spatie\Permission\Models\Role 'role_test_id', 'name', ]; + + protected static function boot() + { + parent::boot(); + static::creating(function ($model) { + if (empty($model->{$model->getKeyName()})) { + $model->{$model->getKeyName()} = \Str::uuid()->toString(); + } + }); + } + + public function getIncrementing() + { + return false; + } + + public function getKeyType() + { + return 'string'; + } } diff --git a/tests/TestCase.php b/tests/TestCase.php index 7fd2ebb57..9481feb84 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -159,6 +159,9 @@ private function prepareMigration() '(\'id\'); // role id', 'references(\'id\') // permission id', 'references(\'id\') // role id', + 'bigIncrements', + 'unsignedBigInteger(PermissionRegistrar::$pivotRole)', + 'unsignedBigInteger(PermissionRegistrar::$pivotPermission)', ], [ 'CreatePermissionCustomTables', @@ -166,6 +169,9 @@ private function prepareMigration() '(\'role_test_id\');', 'references(\'permission_test_id\')', 'references(\'role_test_id\')', + 'uuid', + 'uuid(PermissionRegistrar::$pivotRole)->nullable(false)', + 'uuid(PermissionRegistrar::$pivotPermission)->nullable(false)', ], file_get_contents(__DIR__.'/../database/migrations/create_permission_tables.php.stub') );