Skip to content

Commit 3d9dac1

Browse files
Merge pull request #55860 from nextcloud/backport/55628/stable32
[stable32] fix(dav): dav:remove-invalid-shares removing federated calendar shares
2 parents 56a79b9 + cbec7c6 commit 3d9dac1

File tree

2 files changed

+105
-13
lines changed

2 files changed

+105
-13
lines changed

apps/dav/lib/Command/RemoveInvalidShares.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
namespace OCA\DAV\Command;
1212

1313
use OCA\DAV\Connector\Sabre\Principal;
14+
use OCA\DAV\DAV\RemoteUserPrincipalBackend;
1415
use OCP\IDBConnection;
1516
use Symfony\Component\Console\Command\Command;
1617
use Symfony\Component\Console\Input\InputInterface;
@@ -24,6 +25,7 @@ class RemoveInvalidShares extends Command {
2425
public function __construct(
2526
private IDBConnection $connection,
2627
private Principal $principalBackend,
28+
private RemoteUserPrincipalBackend $remoteUserPrincipalBackend,
2729
) {
2830
parent::__construct();
2931
}
@@ -42,7 +44,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int
4244

4345
while ($row = $result->fetch()) {
4446
$principaluri = $row['principaluri'];
45-
$p = $this->principalBackend->getPrincipalByPath($principaluri);
47+
$p = $this->principalBackend->getPrincipalByPath($principaluri)
48+
?? $this->remoteUserPrincipalBackend->getPrincipalByPath($principaluri);
4649
if ($p === null) {
4750
$this->deleteSharesForPrincipal($principaluri);
4851
}

apps/dav/tests/unit/Command/RemoveInvalidSharesTest.php

Lines changed: 101 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,11 @@
1010

1111
use OCA\DAV\Command\RemoveInvalidShares;
1212
use OCA\DAV\Connector\Sabre\Principal;
13+
use OCA\DAV\DAV\RemoteUserPrincipalBackend;
14+
use OCP\DB\QueryBuilder\IQueryBuilder;
1315
use OCP\IDBConnection;
1416
use OCP\Server;
17+
use PHPUnit\Framework\MockObject\MockObject;
1518
use Symfony\Component\Console\Input\InputInterface;
1619
use Symfony\Component\Console\Output\OutputInterface;
1720
use Test\TestCase;
@@ -23,32 +26,118 @@
2326
* @group DB
2427
*/
2528
class RemoveInvalidSharesTest extends TestCase {
29+
private RemoveInvalidShares $command;
30+
31+
private IDBConnection $db;
32+
private Principal&MockObject $principalBackend;
33+
private RemoteUserPrincipalBackend&MockObject $remoteUserPrincipalBackend;
34+
2635
protected function setUp(): void {
2736
parent::setUp();
28-
$db = Server::get(IDBConnection::class);
2937

30-
$db->insertIfNotExist('*PREFIX*dav_shares', [
38+
$this->db = Server::get(IDBConnection::class);
39+
$this->principalBackend = $this->createMock(Principal::class);
40+
$this->remoteUserPrincipalBackend = $this->createMock(RemoteUserPrincipalBackend::class);
41+
42+
$this->db->insertIfNotExist('*PREFIX*dav_shares', [
3143
'principaluri' => 'principal:unknown',
3244
'type' => 'calendar',
3345
'access' => 2,
3446
'resourceid' => 666,
3547
]);
36-
}
37-
38-
public function test(): void {
39-
$db = Server::get(IDBConnection::class);
40-
$principal = $this->createMock(Principal::class);
48+
$this->db->insertIfNotExist('*PREFIX*dav_shares', [
49+
'principaluri' => 'principals/remote-users/foobar',
50+
'type' => 'calendar',
51+
'access' => 2,
52+
'resourceid' => 666,
53+
]);
4154

42-
$repair = new RemoveInvalidShares($db, $principal);
43-
$this->invokePrivate($repair, 'run', [$this->createMock(InputInterface::class), $this->createMock(OutputInterface::class)]);
55+
$this->command = new RemoveInvalidShares(
56+
$this->db,
57+
$this->principalBackend,
58+
$this->remoteUserPrincipalBackend,
59+
);
60+
}
4461

45-
$query = $db->getQueryBuilder();
62+
private function selectShares(): array {
63+
$query = $this->db->getQueryBuilder();
4664
$query->select('*')
4765
->from('dav_shares')
48-
->where($query->expr()->eq('principaluri', $query->createNamedParameter('principal:unknown')));
66+
->where($query->expr()->in(
67+
'principaluri',
68+
$query->createNamedParameter(
69+
['principal:unknown', 'principals/remote-users/foobar'],
70+
IQueryBuilder::PARAM_STR_ARRAY,
71+
),
72+
));
4973
$result = $query->executeQuery();
5074
$data = $result->fetchAll();
5175
$result->closeCursor();
52-
$this->assertEquals(0, count($data));
76+
77+
return $data;
78+
}
79+
80+
public function testWithoutPrincipals(): void {
81+
$this->principalBackend->method('getPrincipalByPath')
82+
->willReturnMap([
83+
['principal:unknown', null],
84+
['principals/remote-users/foobar', null],
85+
]);
86+
$this->remoteUserPrincipalBackend->method('getPrincipalByPath')
87+
->willReturnMap([
88+
['principal:unknown', null],
89+
['principals/remote-users/foobar', null],
90+
]);
91+
92+
$this->command->run(
93+
$this->createMock(InputInterface::class),
94+
$this->createMock(OutputInterface::class),
95+
);
96+
97+
$data = $this->selectShares();
98+
$this->assertCount(0, $data);
99+
}
100+
101+
public function testWithLocalPrincipal(): void {
102+
$this->principalBackend->method('getPrincipalByPath')
103+
->willReturnMap([
104+
['principal:unknown', ['uri' => 'principal:unknown']],
105+
['principals/remote-users/foobar', null],
106+
]);
107+
$this->remoteUserPrincipalBackend->method('getPrincipalByPath')
108+
->willReturnMap([
109+
['principals/remote-users/foobar', null],
110+
]);
111+
112+
$this->command->run(
113+
$this->createMock(InputInterface::class),
114+
$this->createMock(OutputInterface::class),
115+
);
116+
117+
$data = $this->selectShares();
118+
$this->assertCount(1, $data);
119+
$this->assertEquals('principal:unknown', $data[0]['principaluri']);
120+
}
121+
122+
public function testWithRemotePrincipal() {
123+
$this->principalBackend->method('getPrincipalByPath')
124+
->willReturnMap([
125+
['principal:unknown', null],
126+
['principals/remote-users/foobar', null],
127+
]);
128+
$this->remoteUserPrincipalBackend->method('getPrincipalByPath')
129+
->willReturnMap([
130+
['principal:unknown', null],
131+
['principals/remote-users/foobar', ['uri' => 'principals/remote-users/foobar']],
132+
]);
133+
134+
$this->command->run(
135+
$this->createMock(InputInterface::class),
136+
$this->createMock(OutputInterface::class),
137+
);
138+
139+
$data = $this->selectShares();
140+
$this->assertCount(1, $data);
141+
$this->assertEquals('principals/remote-users/foobar', $data[0]['principaluri']);
53142
}
54143
}

0 commit comments

Comments
 (0)