diff --git a/app/Filament/Helpers/Pages/LogPageAccess.php b/app/Filament/Helpers/Pages/LogPageAccess.php new file mode 100644 index 0000000000..facac8d53a --- /dev/null +++ b/app/Filament/Helpers/Pages/LogPageAccess.php @@ -0,0 +1,30 @@ + auth()->user()->id, + 'loggable_id' => $this->record->id, + 'loggable_type' => get_class($this->record), + 'action' => $this->getLogActionName(), + ]); + } +} diff --git a/app/Filament/Helpers/Pages/LogRelationAccess.php b/app/Filament/Helpers/Pages/LogRelationAccess.php new file mode 100644 index 0000000000..151a690754 --- /dev/null +++ b/app/Filament/Helpers/Pages/LogRelationAccess.php @@ -0,0 +1,30 @@ + auth()->user()->id, + 'loggable_id' => $this->ownerRecord->id, + 'loggable_type' => get_class($this->ownerRecord), + 'action' => $this->getLogActionName(), + ]); + } +} diff --git a/app/Filament/Resources/AccountResource/Pages/ViewAccount.php b/app/Filament/Resources/AccountResource/Pages/ViewAccount.php index b75efae0c5..8c89942a79 100644 --- a/app/Filament/Resources/AccountResource/Pages/ViewAccount.php +++ b/app/Filament/Resources/AccountResource/Pages/ViewAccount.php @@ -3,6 +3,7 @@ namespace App\Filament\Resources\AccountResource\Pages; use App\Filament\Helpers\Pages\BaseViewRecordPage; +use App\Filament\Helpers\Pages\LogPageAccess; use App\Filament\Resources\AccountResource; use App\Jobs\UpdateMember; use App\Models\Contact; @@ -18,8 +19,15 @@ class ViewAccount extends BaseViewRecordPage { + use LogPageAccess; + protected static string $resource = AccountResource::class; + protected function getLogActionName(): string + { + return 'ViewAccount'; + } + protected function getHeaderActions(): array { return [ diff --git a/app/Filament/Resources/AccountResource/RelationManagers/BansRelationManager.php b/app/Filament/Resources/AccountResource/RelationManagers/BansRelationManager.php index 85a893b1f1..3faf92fd95 100644 --- a/app/Filament/Resources/AccountResource/RelationManagers/BansRelationManager.php +++ b/app/Filament/Resources/AccountResource/RelationManagers/BansRelationManager.php @@ -2,6 +2,7 @@ namespace App\Filament\Resources\AccountResource\RelationManagers; +use App\Filament\Helpers\Pages\LogRelationAccess; use App\Filament\Resources\BanResource; use App\Models\Mship\Account\Ban; use App\Models\Mship\Ban\Reason; @@ -16,10 +17,17 @@ class BansRelationManager extends RelationManager { + use LogRelationAccess; + protected static string $relationship = 'bans'; protected static ?string $recordTitleAttribute = 'id'; + protected function getLogActionName(): string + { + return 'ViewBans'; + } + public function isReadOnly(): bool { return false; diff --git a/app/Filament/Resources/AccountResource/RelationManagers/NotesRelationManager.php b/app/Filament/Resources/AccountResource/RelationManagers/NotesRelationManager.php index ff4d55ba8f..d13d50edcf 100644 --- a/app/Filament/Resources/AccountResource/RelationManagers/NotesRelationManager.php +++ b/app/Filament/Resources/AccountResource/RelationManagers/NotesRelationManager.php @@ -2,6 +2,7 @@ namespace App\Filament\Resources\AccountResource\RelationManagers; +use App\Filament\Helpers\Pages\LogRelationAccess; use App\Models\Mship\Account; use App\Models\Mship\Account\Note; use App\Models\Mship\Note\Type; @@ -15,6 +16,13 @@ class NotesRelationManager extends RelationManager { + use LogRelationAccess; + + protected function getLogActionName(): string + { + return 'ViewNotes'; + } + protected static string $relationship = 'notes'; protected static ?string $recordTitleAttribute = 'id'; diff --git a/app/Models/AdminAccessLog.php b/app/Models/AdminAccessLog.php new file mode 100644 index 0000000000..6a774ab3e1 --- /dev/null +++ b/app/Models/AdminAccessLog.php @@ -0,0 +1,23 @@ +belongsTo(User::class, 'accessor_account_id'); + } + + public function loggable() + { + return $this->morphTo(); + } +} diff --git a/database/factories/AdminAccessLogFactory.php b/database/factories/AdminAccessLogFactory.php new file mode 100644 index 0000000000..74a25a6573 --- /dev/null +++ b/database/factories/AdminAccessLogFactory.php @@ -0,0 +1,26 @@ + + */ +class AdminAccessLogFactory extends Factory +{ + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'accessor_account_id' => 1, + 'loggable_id' => 1, + 'loggable_type' => 'App\Models\User', + 'action' => 'View', + ]; + } +} diff --git a/database/migrations/2023_11_15_184316_create_admin_access_logs_table.php b/database/migrations/2023_11_15_184316_create_admin_access_logs_table.php new file mode 100644 index 0000000000..433aed52aa --- /dev/null +++ b/database/migrations/2023_11_15_184316_create_admin_access_logs_table.php @@ -0,0 +1,30 @@ +id(); + $table->string('accessor_account_id'); + $table->morphs('loggable'); + $table->string('action')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('admin_access_logs'); + } +}; diff --git a/tests/Feature/Admin/Account/Pages/ViewAccountPageTest.php b/tests/Feature/Admin/Account/Pages/ViewAccountPageTest.php index eb181d267d..9bdc76beb4 100644 --- a/tests/Feature/Admin/Account/Pages/ViewAccountPageTest.php +++ b/tests/Feature/Admin/Account/Pages/ViewAccountPageTest.php @@ -100,4 +100,18 @@ public function test_can_request_update() Bus::assertDispatched(UpdateMember::class, fn (UpdateMember $job) => $job->accountID === $this->privacc->id); } + + public function test_records_page_visit_in_admin_log() + { + $this->user->givePermissionTo('account.view-insensitive.*'); + Livewire::actingAs($this->user); + + Livewire::test(ViewAccount::class, ['record' => $this->privacc->id]); + + $this->assertDatabaseHas('admin_access_logs', [ + 'accessor_account_id' => $this->user->id, + 'loggable_id' => $this->privacc->id, + 'loggable_type' => get_class($this->privacc), + ]); + } }