From d85f1ef3232e80d7562ccd60627fc5145c4bf8bc Mon Sep 17 00:00:00 2001 From: Dawid Miklas Date: Mon, 25 Sep 2023 12:02:46 +0200 Subject: [PATCH] revoked permission to unauthenticated role --- ...e_permission_from_unauthenticated_user.php | 20 ++ tests/Feature/AuthTest.php | 281 ++++++++++-------- 2 files changed, 176 insertions(+), 125 deletions(-) create mode 100644 database/migrations/2023_09_25_102109_remove_password_change_permission_from_unauthenticated_user.php diff --git a/database/migrations/2023_09_25_102109_remove_password_change_permission_from_unauthenticated_user.php b/database/migrations/2023_09_25_102109_remove_password_change_permission_from_unauthenticated_user.php new file mode 100644 index 000000000..f919f9c90 --- /dev/null +++ b/database/migrations/2023_09_25_102109_remove_password_change_permission_from_unauthenticated_user.php @@ -0,0 +1,20 @@ +where('name', 'Unauthenticated')->first()->revokePermissionTo( + 'auth.password_change', + ); + } + + public function down(): void + { + Role::query()->where('name', 'Unauthenticated')->first()->givePermissionTo( + 'auth.password_change', + ); + } +}; diff --git a/tests/Feature/AuthTest.php b/tests/Feature/AuthTest.php index cd1a701d3..95b27749d 100644 --- a/tests/Feature/AuthTest.php +++ b/tests/Feature/AuthTest.php @@ -55,14 +55,24 @@ class AuthTest extends TestCase private string $cipher; private string $webhookKey; + public static function tfaMethodProvider(): array + { + return [ + 'as app 2fa' => [TFAType::APP, 'secret'], + 'as email 2fa' => [TFAType::EMAIL, null], + ]; + } + public function setUp(): void { parent::setUp(); - $this->user->preferences()->associate(UserPreference::create([ - 'failed_login_attempt_alert' => false, - 'new_localization_login_alert' => false, - 'recovery_code_changed_alert' => false, - ])); + $this->user->preferences()->associate( + UserPreference::create([ + 'failed_login_attempt_alert' => false, + 'new_localization_login_alert' => false, + 'recovery_code_changed_alert' => false, + ]), + ); $this->user->save(); $this->expectedLog = 'ClientException(code: 422): Invalid credentials at'; @@ -713,17 +723,18 @@ public function testRefreshTokenUser(): void $response ->assertOk() - ->assertJsonStructure(['data' => [ - 'token', - 'identity_token', - 'refresh_token', - 'user' => [ - 'id', - 'email', - 'name', - 'avatar', + ->assertJsonStructure([ + 'data' => [ + 'token', + 'identity_token', + 'refresh_token', + 'user' => [ + 'id', + 'email', + 'name', + 'avatar', + ], ], - ], ]); } @@ -740,23 +751,24 @@ public function testRefreshTokenApp(): void $response ->assertOk() - ->assertJsonStructure(['data' => [ - 'token', - 'identity_token', - 'refresh_token', - 'user' => [ - 'id', - 'url', - 'microfrontend_url', - 'name', - 'slug', - 'version', - 'description', - 'icon', - 'author', - 'permissions', + ->assertJsonStructure([ + 'data' => [ + 'token', + 'identity_token', + 'refresh_token', + 'user' => [ + 'id', + 'url', + 'microfrontend_url', + 'name', + 'slug', + 'version', + 'description', + 'icon', + 'author', + 'permissions', + ], ], - ], ])->assertJsonFragment([ 'identity_token' => null, ]); @@ -1100,6 +1112,14 @@ public function testChangePasswordUnauthorized(): void $response->assertForbidden(); } + public function testChangePasswordNoUser(): void + { + $this->putJson('/users/password', [ + 'password' => 'test', + 'password_new' => 'Test1@3456', + ])->assertForbidden(); + } + public function testChangePassword(): void { $user = User::factory()->create([ @@ -1129,7 +1149,12 @@ public function testChangePasswordInvalidPassword(): void Log::shouldReceive('error') ->once() - ->withArgs(fn ($message) => str_contains($message, 'App\Exceptions\ClientException(code: 422): Invalid password at')); + ->withArgs( + fn ($message) => str_contains( + $message, + 'App\Exceptions\ClientException(code: 422): Invalid password at', + ), + ); $response = $this->actingAs($user)->json('PUT', '/users/password', [ 'password' => 'tests', @@ -1163,26 +1188,28 @@ public function testProfileUser(): void $this->actingAs($user)->getJson('/auth/profile') ->assertOk() - ->assertJson(['data' => [ - 'id' => $user->getKey(), - 'email' => $user->email, - 'name' => $user->name, - 'avatar' => $user->avatar, - 'roles' => [[ - $role1->getKeyName() => $role1->getKey(), - 'name' => $role1->name, - 'description' => $role1->description, - 'assignable' => true, - ], - ], - 'permissions' => [ - 'permission.1', - 'permission.2', + ->assertJson([ + 'data' => [ + 'id' => $user->getKey(), + 'email' => $user->email, + 'name' => $user->name, + 'avatar' => $user->avatar, + 'roles' => [ + [ + $role1->getKeyName() => $role1->getKey(), + 'name' => $role1->name, + 'description' => $role1->description, + 'assignable' => true, + ], + ], + 'permissions' => [ + 'permission.1', + 'permission.2', + ], + 'metadata' => [], + 'metadata_personal' => [], + 'created_at' => $user->created_at, ], - 'metadata' => [], - 'metadata_personal' => [], - 'created_at' => $user->created_at, - ], ]); } @@ -1197,21 +1224,22 @@ public function testProfileApp(): void $this->actingAs($app)->getJson('/auth/profile') ->assertOk() - ->assertJson(['data' => [ - 'id' => $app->getKey(), - 'url' => $app->url, - 'microfrontend_url' => $app->microfrontend_url, - 'name' => $app->name, - 'slug' => $app->slug, - 'version' => $app->version, - 'description' => $app->description, - 'icon' => $app->icon, - 'author' => $app->author, - 'permissions' => [ - 'permission.1', - 'permission.2', + ->assertJson([ + 'data' => [ + 'id' => $app->getKey(), + 'url' => $app->url, + 'microfrontend_url' => $app->microfrontend_url, + 'name' => $app->name, + 'slug' => $app->slug, + 'version' => $app->version, + 'description' => $app->description, + 'icon' => $app->icon, + 'author' => $app->author, + 'permissions' => [ + 'permission.1', + 'permission.2', + ], ], - ], ]); } @@ -1338,15 +1366,16 @@ public function testCheckIdentity($user): void $this->actingAs($this->{$user})->getJson("/auth/check/{$token}") ->assertOk() - ->assertJson(['data' => [ - 'id' => $otherUser->getKey(), - 'name' => $otherUser->name, - 'avatar' => $otherUser->avatar, - 'permissions' => [ - 'permission.1', - 'permission.2', + ->assertJson([ + 'data' => [ + 'id' => $otherUser->getKey(), + 'name' => $otherUser->name, + 'avatar' => $otherUser->avatar, + 'permissions' => [ + 'permission.1', + 'permission.2', + ], ], - ], ]); } @@ -1378,16 +1407,17 @@ public function testCheckIdentityNoAppMapping($user): void $this->actingAs($this->{$user})->getJson("/auth/check/{$token}") ->assertOk() - ->assertJson(['data' => [ - 'id' => $otherUser->getKey(), - 'name' => $otherUser->name, - 'avatar' => $otherUser->avatar, - 'permissions' => [ - 'app.app_slug.raw_name', - 'permission.1', - 'permission.2', + ->assertJson([ + 'data' => [ + 'id' => $otherUser->getKey(), + 'name' => $otherUser->name, + 'avatar' => $otherUser->avatar, + 'permissions' => [ + 'app.app_slug.raw_name', + 'permission.1', + 'permission.2', + ], ], - ], ]); } @@ -1416,16 +1446,17 @@ public function testCheckIdentityAppMapping(): void $this->actingAs($app)->getJson("/auth/check/{$token}") ->assertOk() - ->assertJson(['data' => [ - 'id' => $user->getKey(), - 'name' => $user->name, - 'avatar' => $user->avatar, - 'permissions' => [ - 'permission.1', - 'permission.2', - 'raw_name', + ->assertJson([ + 'data' => [ + 'id' => $user->getKey(), + 'name' => $user->name, + 'avatar' => $user->avatar, + 'permissions' => [ + 'permission.1', + 'permission.2', + 'raw_name', + ], ], - ], ]); } @@ -1443,14 +1474,6 @@ public function testConfirmTfaUnauthorized(): void ])->assertForbidden(); } - public static function tfaMethodProvider(): array - { - return [ - 'as app 2fa' => [TFAType::APP, 'secret'], - 'as email 2fa' => [TFAType::EMAIL, null], - ]; - } - /** * @dataProvider tfaMethodProvider */ @@ -1549,11 +1572,12 @@ public function testSetupAppTfa(): void $response ->assertOk() - ->assertJsonStructure(['data' => [ - 'type', - 'secret', - 'qr_code_url', - ], + ->assertJsonStructure([ + 'data' => [ + 'type', + 'secret', + 'qr_code_url', + ], ]); Event::assertNotDispatched(TfaInit::class); @@ -1578,9 +1602,10 @@ public function testConfirmAppTfa(): void $this->actingAs($this->user)->json('POST', '/auth/2fa/confirm', [ 'code' => $code, - ])->assertOk()->assertJsonStructure(['data' => [ - 'recovery_codes', - ], + ])->assertOk()->assertJsonStructure([ + 'data' => [ + 'recovery_codes', + ], ]); Notification::assertSentTo( @@ -1640,9 +1665,10 @@ public function testConfirmAppTfaNoPreferences(): void $this->actingAs($this->user)->json('POST', '/auth/2fa/confirm', [ 'code' => $code, - ])->assertOk()->assertJsonStructure(['data' => [ - 'recovery_codes', - ], + ])->assertOk()->assertJsonStructure([ + 'data' => [ + 'recovery_codes', + ], ]); Notification::assertNotSentTo( @@ -1681,9 +1707,10 @@ public function testSetupEmailTfa(): void $response ->assertOk() - ->assertJsonStructure(['data' => [ - 'type', - ], + ->assertJsonStructure([ + 'data' => [ + 'type', + ], ]); } @@ -1763,9 +1790,10 @@ public function testConfirmEmailTfa(): void $this->actingAs($this->user)->json('POST', '/auth/2fa/confirm', [ 'code' => $code, - ])->assertOk()->assertJsonStructure(['data' => [ - 'recovery_codes', - ], + ])->assertOk()->assertJsonStructure([ + 'data' => [ + 'recovery_codes', + ], ]); Notification::assertSentTo( @@ -1821,9 +1849,10 @@ public function testConfirmEmailTfaNoPreferences(): void $this->actingAs($this->user)->json('POST', '/auth/2fa/confirm', [ 'code' => $code, - ])->assertOk()->assertJsonStructure(['data' => [ - 'recovery_codes', - ], + ])->assertOk()->assertJsonStructure([ + 'data' => [ + 'recovery_codes', + ], ]); Notification::assertNotSentTo( @@ -1898,9 +1927,10 @@ public function testRecoveryCodesCreate($method, $secret): void ->whereNull('expires_at') ->get(); - $response->assertJsonStructure(['data' => [ - 'recovery_codes', - ], + $response->assertJsonStructure([ + 'data' => [ + 'recovery_codes', + ], ]); $this->assertDatabaseCount('one_time_security_codes', count($recovery_codes)); @@ -1934,9 +1964,10 @@ public function testRecoveryCodesCreateNoPreferences($method, $secret): void ->whereNull('expires_at') ->get(); - $response->assertJsonStructure(['data' => [ - 'recovery_codes', - ], + $response->assertJsonStructure([ + 'data' => [ + 'recovery_codes', + ], ]); $this->assertDatabaseCount('one_time_security_codes', count($recovery_codes));