create(['permissions' => null]); $actor = User::factory()->superuser()->create(); $existingLogIds = Actionlog::where('item_type', User::class) ->where('item_id', $user->id) ->pluck('id'); $this->actingAsForApi($actor) ->patchJson(route('api.users.update', $user), [ 'first_name' => $user->first_name, 'last_name' => $user->last_name, 'username' => $user->username, 'permissions' => ['assets.view' => '0', 'assets.create' => '0'], ]) ->assertOk(); $newUpdateLogs = Actionlog::where('item_type', User::class) ->where('item_id', $user->id) ->where('action_type', 'update') ->whereNotIn('id', $existingLogIds) ->count(); $this->assertEquals(0, $newUpdateLogs, 'Saving null permissions as "0" (inherit) should not create a log entry'); } /** * Same as above but starting from an empty JSON object rather than null — * the other common state for imported users. */ public function test_empty_permissions_saved_as_zero_does_not_create_log_entry() { $user = User::factory()->create(['permissions' => '{}']); $actor = User::factory()->superuser()->create(); $existingLogIds = Actionlog::where('item_type', User::class) ->where('item_id', $user->id) ->pluck('id'); $this->actingAsForApi($actor) ->patchJson(route('api.users.update', $user), [ 'first_name' => $user->first_name, 'last_name' => $user->last_name, 'username' => $user->username, 'permissions' => ['assets.view' => '0'], ]) ->assertOk(); $newUpdateLogs = Actionlog::where('item_type', User::class) ->where('item_id', $user->id) ->where('action_type', 'update') ->whereNotIn('id', $existingLogIds) ->count(); $this->assertEquals(0, $newUpdateLogs, 'Saving empty permissions as "0" (inherit) should not create a log entry'); } /** * Changing a permission from null/inherit to an explicit grant SHOULD be logged. */ public function test_changing_permission_from_null_to_one_creates_log_entry() { $user = User::factory()->create(['permissions' => null]); $actor = User::factory()->superuser()->create(); $existingLogIds = Actionlog::where('item_type', User::class) ->where('item_id', $user->id) ->pluck('id'); $this->actingAsForApi($actor) ->patchJson(route('api.users.update', $user), [ 'first_name' => $user->first_name, 'last_name' => $user->last_name, 'username' => $user->username, 'permissions' => ['assets.view' => '1'], ]) ->assertOk(); $newUpdateLogs = Actionlog::where('item_type', User::class) ->where('item_id', $user->id) ->where('action_type', 'update') ->whereNotIn('id', $existingLogIds) ->get(); $this->assertCount(1, $newUpdateLogs, 'Granting a permission should create a log entry'); $meta = json_decode($newUpdateLogs->first()->log_meta, true); $this->assertArrayHasKey('permissions', $meta); $this->assertStringContainsString('assets.view', $meta['permissions']['new']); } /** * Changing a permission from "0" (explicit inherit) to "1" (grant) SHOULD be logged. */ public function test_changing_permission_from_zero_to_one_creates_log_entry() { $user = User::factory()->create(['permissions' => json_encode(['assets.view' => '0'])]); $actor = User::factory()->superuser()->create(); $existingLogIds = Actionlog::where('item_type', User::class) ->where('item_id', $user->id) ->pluck('id'); $this->actingAsForApi($actor) ->patchJson(route('api.users.update', $user), [ 'first_name' => $user->first_name, 'last_name' => $user->last_name, 'username' => $user->username, 'permissions' => ['assets.view' => '1'], ]) ->assertOk(); $newUpdateLogs = Actionlog::where('item_type', User::class) ->where('item_id', $user->id) ->where('action_type', 'update') ->whereNotIn('id', $existingLogIds) ->get(); $this->assertCount(1, $newUpdateLogs, 'Changing from "0" to "1" should create a log entry'); } /** * Revoking a permission (going back to inherit) from an explicit grant SHOULD be logged. */ public function test_revoking_permission_from_one_to_zero_creates_log_entry() { $user = User::factory()->create(['permissions' => json_encode(['assets.view' => '1'])]); $actor = User::factory()->superuser()->create(); $existingLogIds = Actionlog::where('item_type', User::class) ->where('item_id', $user->id) ->pluck('id'); $this->actingAsForApi($actor) ->patchJson(route('api.users.update', $user), [ 'first_name' => $user->first_name, 'last_name' => $user->last_name, 'username' => $user->username, 'permissions' => ['assets.view' => '0'], ]) ->assertOk(); $newUpdateLogs = Actionlog::where('item_type', User::class) ->where('item_id', $user->id) ->where('action_type', 'update') ->whereNotIn('id', $existingLogIds) ->count(); $this->assertGreaterThan(0, $newUpdateLogs, 'Revoking a permission should create a log entry'); } }