🚀 Enhance authorization and exception handling across Livewire components and SecurityMonitor

- **SecurityMonitor:** Added logic to record and prevent logging of locked-property exceptions, while ensuring non-security exceptions are properly forwarded.
- **Livewire `Members/Admin`:** Centralized authorization logic in private methods, enforced access control on actions, and moved allowed pubkeys to class constant for maintainability.
- **Livewire `News`:** Enforced authorization for editing and deleting news with guard methods and ensured unauthorized users can't access data.
- **Bootstrap exceptions:** Implemented custom exception handling to record Livewire-related security issues while preventing redundant logs.
- Updated tests with new behavior verification covering access control and exception responses.
This commit is contained in:
HolgerHatGarKeineNode
2026-06-02 19:23:51 +02:00
parent 59bc440a59
commit 5f28bfedd4
6 changed files with 251 additions and 34 deletions
@@ -4,6 +4,8 @@ use App\Models\EinundzwanzigPleb;
use App\Support\NostrAuth;
use Livewire\Livewire;
const ALLOWED_ADMIN_PUBKEY = '0adf67475ccc5ca456fd3022e46f5d526eb0af6284bf85494c0dd7847f3e5033';
it('denies access to unauthorized users', function () {
$pleb = EinundzwanzigPleb::factory()->create();
@@ -73,3 +75,60 @@ it('displays einundzwanzig pleb table when authorized', function () {
->assertSet('isAllowed', true)
->assertSee('einundzwanzig-pleb-table');
});
it('does not load the member list for unauthorized visitors', function () {
EinundzwanzigPleb::factory()->count(3)->create();
Livewire::test('association.members.admin')
->assertSet('isAllowed', false)
->assertSet('plebs', []);
});
it('forbids guests from exporting the member CSV', function () {
Livewire::test('association.members.admin')
->call('exportCsv')
->assertForbidden();
});
it('forbids unauthorized members from exporting the member CSV', function () {
$pleb = EinundzwanzigPleb::factory()->create();
NostrAuth::login($pleb->pubkey);
Livewire::test('association.members.admin')
->call('exportCsv')
->assertForbidden();
});
it('forbids unauthorized members from accepting an application', function () {
$pleb = EinundzwanzigPleb::factory()->create();
NostrAuth::login($pleb->pubkey);
Livewire::test('association.members.admin')
->call('acceptPleb')
->assertForbidden();
});
it('forbids unauthorized members from rejecting an application', function () {
$pleb = EinundzwanzigPleb::factory()->create();
NostrAuth::login($pleb->pubkey);
Livewire::test('association.members.admin')
->call('deletePleb')
->assertForbidden();
});
it('lets an authorized member pass the authorization guard', function () {
$pleb = EinundzwanzigPleb::factory()->create([
'pubkey' => ALLOWED_ADMIN_PUBKEY,
]);
NostrAuth::login($pleb->pubkey);
Livewire::test('association.members.admin')
->call('acceptPleb')
->assertStatus(200)
->assertHasNoErrors();
});