Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions apps/federatedfilesharing/lib/FederatedShareProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

use OC\Share20\Exception\InvalidShare;
use OC\Share20\Share;
use OCA\Files_Sharing\External\Storage as ExternalStorage;
use OCP\Constants;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Federation\ICloudFederationProviderManager;
Expand Down Expand Up @@ -127,14 +128,10 @@ public function create(IShare $share): IShare {

$share->setSharedWith($cloudId->getId());

$mountPoint = $this->getFederatedMountPoint($share);
try {
$remoteShare = $this->getShareFromExternalShareTable($share->getShareOwner(), $share->getTarget());
// The target only carries the name of the node, make sure the node is the mounted federated share
$mountedShare = $this->rootFolder->getUserFolder($share->getShareOwner())->get($remoteShare['mountpoint']);
if ($mountedShare->getId() !== $itemSource) {
$remoteShare = null;
}
} catch (ShareNotFound|NotFoundException) {
$remoteShare = $mountPoint === null ? null : $this->getShareFromExternalShareTable($share->getShareOwner(), $mountPoint);
} catch (ShareNotFound) {
$remoteShare = null;
}

Expand Down Expand Up @@ -231,6 +228,25 @@ protected function createFederatedShare(IShare $share): string {
return $shareId;
}

/**
* Mount point of the federated share, relative to the home of the share owner,
* if the shared node is the root of a federated share mounted for the share owner
*/
private function getFederatedMountPoint(IShare $share): ?string {
$node = $share->getNode();
if ($node->getInternalPath() !== '' || !$node->getStorage()->instanceOfStorage(ExternalStorage::class)) {
return null;
}

$prefix = '/' . $share->getShareOwner() . '/files/';
$mountPoint = $node->getMountPoint()->getMountPoint();
if (!str_starts_with($mountPoint, $prefix)) {
return null;
}

return '/' . trim(substr($mountPoint, strlen($prefix)), '/');
}

/**
* get federated share from the share_external table but exclude mounted link shares
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use OCA\FederatedFileSharing\FederatedShareProvider;
use OCA\FederatedFileSharing\Notifications;
use OCA\FederatedFileSharing\TokenHandler;
use OCA\Files_Sharing\External\Storage as ExternalStorage;
use OCP\Constants;
use OCP\DB\IResult;
use OCP\DB\QueryBuilder\IExpressionBuilder;
Expand All @@ -23,7 +24,7 @@
use OCP\Federation\ICloudIdManager;
use OCP\Files\Folder;
use OCP\Files\IRootFolder;
use OCP\Files\IUserFolder;
use OCP\Files\Mount\IMountPoint;
use OCP\GlobalScale\IConfig as GlobalScaleConfig;
use OCP\IConfig;
use OCP\IDBConnection;
Expand Down Expand Up @@ -96,9 +97,20 @@ protected function setUp(): void {
public function testCreateRemoteOwner(): void {
$permissions = Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE;

// the shared node is the root of the federated share mounted for alice
$storage = $this->createMock(ExternalStorage::class);
$storage->method('instanceOfStorage')
->with(ExternalStorage::class)
->willReturn(true);
$mount = $this->createMock(IMountPoint::class);
$mount->method('getMountPoint')->willReturn('/alice/files/Share1/');

$node = $this->createMock(Folder::class);
$node->method('getId')->willReturn(1000);
$node->method('getName')->willReturn('Share 1');
$node->method('getInternalPath')->willReturn('');
$node->method('getStorage')->willReturn($storage);
$node->method('getMountPoint')->willReturn($mount);

/*
* Mocks getSharedWith ($alreadyShared and $alreadySharedGroup).
Expand Down Expand Up @@ -302,15 +314,6 @@ public function testCreateRemoteOwner(): void {
)
->willReturn(['share_token2', '20']);

// the shared node is the mount point of the federated share
$userFolder = $this->createMock(IUserFolder::class);
$userFolder->method('get')
->with('/Share1')
->willReturn($node);
$this->rootFolder->method('getUserFolder')
->with('alice')
->willReturn($userFolder);

$share = new Share($this->rootFolder, $this->userManager);
$share
->setSharedWith('bob@https://destination.test')
Expand Down
15 changes: 3 additions & 12 deletions apps/federatedfilesharing/tests/FederatedShareProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,8 @@
use OCP\Federation\ICloudFederationProviderManager;
use OCP\Federation\ICloudIdManager;
use OCP\Files\File;
use OCP\Files\Folder;
use OCP\Files\IRootFolder;
use OCP\Files\IUserFolder;
use OCP\Files\Storage\IStorage;
use OCP\ICacheFactory;
use OCP\IConfig;
use OCP\IDBConnection;
Expand Down Expand Up @@ -232,6 +231,8 @@ public function testCreateSameNameAsMountedFederatedShare(): void {
$node = $this->createMock(File::class);
$node->method('getId')->willReturn(42);
$node->method('getName')->willReturn('myFile');
$node->method('getInternalPath')->willReturn('myFile');
$node->method('getStorage')->willReturn($this->createMock(IStorage::class));

$share->setSharedWith('user@server.com')
->setSharedBy('sharedBy')
Expand All @@ -241,16 +242,6 @@ public function testCreateSameNameAsMountedFederatedShare(): void {
->setNode($node)
->setTarget('/myFile');

$mountedShare = $this->createMock(Folder::class);
$mountedShare->method('getId')->willReturn(43);
$userFolder = $this->createMock(IUserFolder::class);
$userFolder->method('get')
->with('/myFile')
->willReturn($mountedShare);
$this->rootFolder->method('getUserFolder')
->with('shareOwner')
->willReturn($userFolder);

$this->tokenHandler->method('generateToken')->willReturn('token');
$this->addressHandler->method('generateRemoteURL')
->willReturn('http://localhost/');
Expand Down
Loading