From cfd255b60eca9d110362ddcf9112551ebc6eabfb Mon Sep 17 00:00:00 2001 From: Nico Hoffmann Date: Sun, 22 Sep 2024 13:30:43 +0200 Subject: [PATCH] Validate roles when creating user --- src/Cms/UserRules.php | 14 ++++++++- tests/Cms/Users/UserRulesTest.php | 47 +++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/src/Cms/UserRules.php b/src/Cms/UserRules.php index 930b589ca9..0a302d3d45 100644 --- a/src/Cms/UserRules.php +++ b/src/Cms/UserRules.php @@ -198,13 +198,25 @@ public static function create(User $user, array $props = []): bool // check user permissions (if not on install) if ( $user->kirby()->users()->count() > 0 && - $user->permissions()->can('create') !== true + $user->permissions()->create() !== true ) { throw new PermissionException([ 'key' => 'user.create.permission' ]); } + $role = $props['role'] ?? null; + + // prevent creating a role that is not available for user + if ( + in_array($role, [null, 'default', 'nobody'], true) === false && + $user->kirby()->roles('create')->find($role) instanceof Role === false + ) { + throw new InvalidArgumentException([ + 'key' => 'user.role.invalid', + ]); + } + return true; } diff --git a/tests/Cms/Users/UserRulesTest.php b/tests/Cms/Users/UserRulesTest.php index 0562e6f1af..7f25d45c62 100644 --- a/tests/Cms/Users/UserRulesTest.php +++ b/tests/Cms/Users/UserRulesTest.php @@ -361,6 +361,53 @@ public function testCreatePermissions() ]); } + public function testCreateInvalidRole() + { + $app = $this->app()->clone([ + 'users' => [ + ['email' => 'editor@getkirby.com', 'role' => 'editor'] + ] + ]); + + $app->impersonate('editor@getkirby.com'); + + $permissions = $this->createMock(UserPermissions::class); + $permissions->method('__call')->with('create')->willReturn(true); + + $user = $this->createMock(User::class); + $user->method('kirby')->willReturn($app); + $user->method('permissions')->willReturn($permissions); + $user->method('id')->willReturn('test'); + $user->method('email')->willReturn('test@getkirby.com'); + $user->method('language')->willReturn('en'); + + // no role + $this->assertTrue(UserRules::create($user, [ + 'password' => 12345678 + ])); + + // role: nobody + $this->assertTrue(UserRules::create($user, [ + 'password' => 12345678, + 'role' => 'nobody' + ])); + + // role: default + $this->assertTrue(UserRules::create($user, [ + 'password' => 12345678, + 'role' => 'default' + ])); + + // invalid role + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Please enter a valid role'); + + UserRules::create($user, [ + 'password' => 12345678, + 'role' => 'foo' + ]); + } + public function testUpdate() { $app = $this->appWithAdmin();