Skip to content

Commit 172b61a

Browse files
committed
feat: improve VerifyMountPointEvent event
Signed-off-by: Robin Appelman <[email protected]>
1 parent 9cd337b commit 172b61a

File tree

3 files changed

+102
-19
lines changed

3 files changed

+102
-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: 57 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,40 @@ public function testShareMountOverShare(): void {
138157
$this->shareManager->deleteShare($share2);
139158
$this->view->unlink($this->folder);
140159
}
160+
161+
162+
/**
163+
* test if the parent folder is created if asked for
164+
*/
165+
public function testShareMountCreateParentFolder(): void {
166+
// share to user
167+
$share = $this->share(
168+
IShare::TYPE_USER,
169+
$this->folder,
170+
self::TEST_FILES_SHARING_API_USER1,
171+
self::TEST_FILES_SHARING_API_USER2,
172+
Constants::PERMISSION_ALL);
173+
$this->shareManager->acceptShare($share, self::TEST_FILES_SHARING_API_USER2);
174+
175+
$share->setTarget('/foo/bar' . $this->folder);
176+
$this->shareManager->moveShare($share, self::TEST_FILES_SHARING_API_USER2);
177+
178+
$share = $this->shareManager->getShareById($share->getFullId());
179+
$this->assertSame('/foo/bar' . $this->folder, $share->getTarget());
180+
181+
$this->eventDispatcher->addListener(VerifyMountPointEvent::class, function(VerifyMountPointEvent $event) {
182+
$event->setCreateParent(true);
183+
});
184+
$this->targetValidator->verifyMountPoint($this->user2, $share, [], [$share]);
185+
186+
$share = $this->shareManager->getShareById($share->getFullId());
187+
$this->assertSame('/foo/bar' . $this->folder, $share->getTarget());
188+
$userFolder = $this->rootFolder->getUserFolder(self::TEST_FILES_SHARING_API_USER2);
189+
$this->assertTrue($userFolder->nodeExists('/foo/bar'));
190+
191+
//cleanup
192+
self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
193+
$this->shareManager->deleteShare($share);
194+
$this->view->unlink($this->folder);
195+
}
141196
}

lib/public/Share/Events/VerifyMountPointEvent.php

Lines changed: 35 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
/**
@@ -45,6 +40,7 @@ public function getShare(): IShare {
4540

4641
/**
4742
* @since 19.0.0
43+
* @depecated 34.0.0 Get the user folder for `$this->getUser()` instead
4844
*/
4945
public function getView(): View {
5046
return $this->view;
@@ -63,4 +59,30 @@ public function getParent(): string {
6359
public function setParent(string $parent): void {
6460
$this->parent = $parent;
6561
}
62+
63+
/**
64+
* @since 34.0.0
65+
*/
66+
public function setCreateParent(bool $create): void {
67+
$this->createParent = $create;
68+
}
69+
70+
/**
71+
* Whether the parent folder should be created if missing.
72+
*
73+
* If set for `false` (the default), and the parent folder doesn't exist already,
74+
* the share will be moved to the default share folder instead.
75+
*
76+
* @since 34.0.0
77+
*/
78+
public function createParent(): bool {
79+
return $this->createParent;
80+
}
81+
82+
/**
83+
* @since 34.0.0
84+
*/
85+
public function getUser(): IUser {
86+
return $this->user;
87+
}
6688
}

0 commit comments

Comments
 (0)