Skip to content

Commit 37348cb

Browse files
committed
feat: improve VerifyMountPointEvent event
Signed-off-by: Robin Appelman <robin@icewind.nl>
1 parent eaaefda commit 37348cb

File tree

3 files changed

+101
-19
lines changed

3 files changed

+101
-19
lines changed

apps/files_sharing/lib/ShareTargetValidator.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public function verifyMountPoint(
6161
$parent = dirname($share->getTarget());
6262

6363
$recipientView = $this->getViewForUser($user);
64-
$event = new VerifyMountPointEvent($share, $recipientView, $parent);
64+
$event = new VerifyMountPointEvent($share, $recipientView, $parent, $user);
6565
$this->eventDispatcher->dispatchTyped($event);
6666
$parent = $event->getParent();
6767

@@ -79,9 +79,15 @@ public function verifyMountPoint(
7979
$this->folderExistsCache->set($parent, $parentExists);
8080
}
8181
if (!$parentExists) {
82-
$parent = Helper::getShareFolder($recipientView, $user->getUID());
83-
/** @psalm-suppress InternalMethod */
84-
$absoluteParent = $recipientView->getAbsolutePath($parent);
82+
if ($event->createParent()) {
83+
$internalPath = $parentMount->getInternalPath($absoluteParent);
84+
$parentMount->getStorage()->mkdir($internalPath);
85+
$parentMount->getStorage()->getUpdater()->update($internalPath);
86+
} else {
87+
$parent = Helper::getShareFolder($recipientView, $user->getUID());
88+
/** @psalm-suppress InternalMethod */
89+
$absoluteParent = $recipientView->getAbsolutePath($parent);
90+
}
8591
}
8692

8793
$newAbsoluteMountPoint = $this->generateUniqueTarget(

apps/files_sharing/tests/ShareTargetValidatorTest.php

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,25 @@
88

99
namespace OCA\Files_Sharing\Tests;
1010

11+
use OC\EventDispatcher\EventDispatcher;
12+
use OC\Files\SetupManager;
1113
use OCA\Files_Sharing\ShareTargetValidator;
1214
use OCP\Constants;
15+
use OCP\EventDispatcher\IEventDispatcher;
1316
use OCP\Files\Config\ICachedMountInfo;
14-
use OCP\Files\Folder;
17+
use OCP\Files\Mount\IMountManager;
1518
use OCP\IUser;
1619
use OCP\Server;
20+
use OCP\Share\Events\VerifyMountPointEvent;
21+
use OCP\Share\IManager;
1722
use OCP\Share\IShare;
23+
use Psr\Container\ContainerInterface;
24+
use Psr\Log\LoggerInterface;
25+
use Symfony\Component\EventDispatcher\EventDispatcher as SymfonyEventDispatcher;
1826

1927
#[\PHPUnit\Framework\Attributes\Group('DB')]
2028
class ShareTargetValidatorTest extends TestCase {
29+
private IEventDispatcher $eventDispatcher;
2130
private ShareTargetValidator $targetValidator;
2231

2332
private IUser $user2;
@@ -40,7 +49,17 @@ protected function setUp(): void {
4049
$this->view->file_put_contents($this->folder . $this->filename, 'file in subfolder');
4150
$this->view->file_put_contents($this->folder2 . $this->filename, 'file in subfolder2');
4251

43-
$this->targetValidator = Server::get(ShareTargetValidator::class);
52+
$this->eventDispatcher = new EventDispatcher(
53+
new SymfonyEventDispatcher(),
54+
Server::get(ContainerInterface::class),
55+
$this->createMock(LoggerInterface::class),
56+
);
57+
$this->targetValidator = new ShareTargetValidator(
58+
Server::get(IManager::class),
59+
$this->eventDispatcher,
60+
Server::get(SetupManager::class),
61+
Server::get(IMountManager::class),
62+
);
4463
$this->user2 = $this->createMock(IUser::class);
4564
$this->user2->method('getUID')
4665
->willReturn(self::TEST_FILES_SHARING_API_USER2);
@@ -138,4 +157,38 @@ public function testShareMountOverShare(): void {
138157
$this->shareManager->deleteShare($share2);
139158
$this->view->unlink($this->folder);
140159
}
160+
/**
161+
* test if the parent folder is created if asked for
162+
*/
163+
public function testShareMountCreateParentFolder(): void {
164+
// share to user
165+
$share = $this->share(
166+
IShare::TYPE_USER,
167+
$this->folder,
168+
self::TEST_FILES_SHARING_API_USER1,
169+
self::TEST_FILES_SHARING_API_USER2,
170+
Constants::PERMISSION_ALL);
171+
$this->shareManager->acceptShare($share, self::TEST_FILES_SHARING_API_USER2);
172+
173+
$share->setTarget('/foo/bar' . $this->folder);
174+
$this->shareManager->moveShare($share, self::TEST_FILES_SHARING_API_USER2);
175+
176+
$share = $this->shareManager->getShareById($share->getFullId());
177+
$this->assertSame('/foo/bar' . $this->folder, $share->getTarget());
178+
179+
$this->eventDispatcher->addListener(VerifyMountPointEvent::class, function (VerifyMountPointEvent $event) {
180+
$event->setCreateParent(true);
181+
});
182+
$this->targetValidator->verifyMountPoint($this->user2, $share, [], [$share]);
183+
184+
$share = $this->shareManager->getShareById($share->getFullId());
185+
$this->assertSame('/foo/bar' . $this->folder, $share->getTarget());
186+
$userFolder = $this->rootFolder->getUserFolder(self::TEST_FILES_SHARING_API_USER2);
187+
$this->assertTrue($userFolder->nodeExists('/foo/bar'));
188+
189+
//cleanup
190+
self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
191+
$this->shareManager->deleteShare($share);
192+
$this->view->unlink($this->folder);
193+
}
141194
}

lib/public/Share/Events/VerifyMountPointEvent.php

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,25 @@
1010

1111
use OC\Files\View;
1212
use OCP\EventDispatcher\Event;
13+
use OCP\IUser;
1314
use OCP\Share\IShare;
1415

1516
/**
1617
* @since 19.0.0
1718
*/
1819
class VerifyMountPointEvent extends Event {
19-
/** @var IShare */
20-
private $share;
21-
/** @var View */
22-
private $view;
23-
/** @var string */
24-
private $parent;
20+
private bool $createParent = false;
2521

2622
/**
2723
* @since 19.0.0
2824
*/
29-
public function __construct(IShare $share,
30-
View $view,
31-
string $parent) {
25+
public function __construct(
26+
private readonly IShare $share,
27+
private readonly View $view,
28+
private string $parent,
29+
private readonly IUser $user,
30+
) {
3231
parent::__construct();
33-
34-
$this->share = $share;
35-
$this->view = $view;
36-
$this->parent = $parent;
3732
}
3833

3934
/**
@@ -51,6 +46,8 @@ public function getView(): View {
5146
}
5247

5348
/**
49+
* The parent folder where the share is placed, as relative path to the users home directory.
50+
*
5451
* @since 19.0.0
5552
*/
5653
public function getParent(): string {
@@ -63,4 +60,30 @@ public function getParent(): string {
6360
public function setParent(string $parent): void {
6461
$this->parent = $parent;
6562
}
63+
64+
/**
65+
* @since 33.0.3
66+
*/
67+
public function setCreateParent(bool $create): void {
68+
$this->createParent = $create;
69+
}
70+
71+
/**
72+
* Whether the parent folder should be created if missing.
73+
*
74+
* If set for `false` (the default), and the parent folder doesn't exist already,
75+
* the share will be moved to the default share folder instead.
76+
*
77+
* @since 33.0.3
78+
*/
79+
public function createParent(): bool {
80+
return $this->createParent;
81+
}
82+
83+
/**
84+
* @since 33.0.3
85+
*/
86+
public function getUser(): IUser {
87+
return $this->user;
88+
}
6689
}

0 commit comments

Comments
 (0)