Skip to content

Commit 1c86efc

Browse files
feat(share): add ShareReviewAccessCheckEvent to OCP public API
Introduces OCP\Share\Events\ShareReviewAccessCheckEvent as the canonical authorization gate event for ShareReview sources. The event carries the source name and share ID for listener context, implements deny-wins semantics, and stops propagation immediately on denial. Assisted-by: ClaudeCode:claude-sonnet-4-6 Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
1 parent 99640bc commit 1c86efc

1 file changed

Lines changed: 96 additions & 0 deletions

File tree

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
7+
* SPDX-License-Identifier: AGPL-3.0-or-later
8+
*/
9+
10+
namespace lib\Share20\Events;
11+
12+
use OCP\Share\Events\ShareReviewAccessCheckEvent;
13+
use PHPUnit\Framework\TestCase;
14+
15+
final class ShareReviewAccessCheckEventTest extends TestCase {
16+
17+
private function makeEvent(): ShareReviewAccessCheckEvent {
18+
return new ShareReviewAccessCheckEvent('MyApp', '42');
19+
}
20+
21+
public function testInitialState(): void {
22+
$event = $this->makeEvent();
23+
24+
$this->assertFalse($event->isHandled());
25+
$this->assertFalse($event->isGranted());
26+
$this->assertNull($event->getReason());
27+
}
28+
29+
public function testConstructorPayload(): void {
30+
$event = new ShareReviewAccessCheckEvent('Deck', '99');
31+
32+
$this->assertSame('Deck', $event->getSourceName());
33+
$this->assertSame('99', $event->getShareId());
34+
}
35+
36+
public function testGrantAccess(): void {
37+
$event = $this->makeEvent();
38+
$event->grantAccess();
39+
40+
$this->assertTrue($event->isHandled());
41+
$this->assertTrue($event->isGranted());
42+
$this->assertNull($event->getReason());
43+
$this->assertFalse($event->isPropagationStopped());
44+
}
45+
46+
public function testDenyAccess(): void {
47+
$event = $this->makeEvent();
48+
$event->denyAccess('not in group');
49+
50+
$this->assertTrue($event->isHandled());
51+
$this->assertFalse($event->isGranted());
52+
$this->assertSame('not in group', $event->getReason());
53+
}
54+
55+
public function testDenyStopsPropagation(): void {
56+
$event = $this->makeEvent();
57+
$event->denyAccess('no access');
58+
59+
$this->assertTrue($event->isPropagationStopped());
60+
}
61+
62+
public function testGrantDoesNotStopPropagation(): void {
63+
$event = $this->makeEvent();
64+
$event->grantAccess();
65+
66+
$this->assertFalse($event->isPropagationStopped());
67+
}
68+
69+
public function testGrantThenDenyIsDenied(): void {
70+
$event = $this->makeEvent();
71+
$event->grantAccess();
72+
$event->denyAccess('revoked');
73+
74+
$this->assertFalse($event->isGranted());
75+
$this->assertSame('revoked', $event->getReason());
76+
$this->assertTrue($event->isPropagationStopped());
77+
}
78+
79+
public function testDenyThenGrantRemainesDenied(): void {
80+
$event = $this->makeEvent();
81+
$event->denyAccess('not allowed');
82+
$event->grantAccess(); // must be ignored — deny wins
83+
84+
$this->assertFalse($event->isGranted());
85+
$this->assertSame('not allowed', $event->getReason());
86+
}
87+
88+
public function testMultipleGrantsAreIdempotent(): void {
89+
$event = $this->makeEvent();
90+
$event->grantAccess();
91+
$event->grantAccess();
92+
93+
$this->assertTrue($event->isGranted());
94+
$this->assertFalse($event->isPropagationStopped());
95+
}
96+
}

0 commit comments

Comments
 (0)