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
28 changes: 2 additions & 26 deletions apps/dav/lib/Connector/Sabre/FilesPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
use OCP\IRequest;
use OCP\IUserSession;
use OCP\L10N\IFactory;
use OCP\OCM\Permissions;
use OCP\User\Exceptions\UserNotFoundException;
use Sabre\DAV\Exception\Forbidden;
use Sabre\DAV\Exception\NotFound;
Expand Down Expand Up @@ -348,7 +349,7 @@ public function handleGetProperties(PropFind $propFind, \Sabre\DAV\INode $node)
$ncPermissions = $node->getSharePermissions(
$user->getUID()
);
$ocmPermissions = $this->ncPermissions2ocmPermissions($ncPermissions);
$ocmPermissions = Permissions::fromNextcloud($ncPermissions);
return json_encode($ocmPermissions, JSON_THROW_ON_ERROR);
});

Expand Down Expand Up @@ -567,31 +568,6 @@ public function handleGetProperties(PropFind $propFind, \Sabre\DAV\INode $node)
}
}

/**
* translate Nextcloud permissions to OCM Permissions
*
* @param $ncPermissions
* @return array
*/
protected function ncPermissions2ocmPermissions($ncPermissions) {
$ocmPermissions = [];

if ($ncPermissions & Constants::PERMISSION_SHARE) {
$ocmPermissions[] = 'share';
}

if ($ncPermissions & Constants::PERMISSION_READ) {
$ocmPermissions[] = 'read';
}

if (($ncPermissions & Constants::PERMISSION_CREATE)
|| ($ncPermissions & Constants::PERMISSION_UPDATE)) {
$ocmPermissions[] = 'write';
}

return $ocmPermissions;
}

/**
* Update ownCloud-specific properties
*
Expand Down
8 changes: 7 additions & 1 deletion apps/dav/tests/unit/Connector/Sabre/FilesPluginTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use OCA\DAV\Connector\Sabre\FilesPlugin;
use OCA\DAV\Connector\Sabre\Node;
use OCP\Accounts\IAccountManager;
use OCP\Constants;
use OCP\Files\FileInfo;
use OCP\Files\IFilenameValidator;
use OCP\Files\InvalidPathException;
Expand Down Expand Up @@ -256,6 +257,7 @@ public function testGetDisplayNamePropertyWhenNotPublishedButLoggedIn(): void {
'/dummyPath',
[
FilesPlugin::OWNER_DISPLAY_NAME_PROPERTYNAME,
FilesPlugin::OCM_SHARE_PERMISSIONS_PROPERTYNAME,
],
0
);
Expand All @@ -267,7 +269,10 @@ public function testGetDisplayNamePropertyWhenNotPublishedButLoggedIn(): void {
->willReturn($user);

$loggedInUser = $this->createMock(User::class);
$this->userSession->expects($this->once())
$loggedInUser->expects($this->once())->method('getUID')->willReturn('recipient');
$node->expects($this->once())->method('getSharePermissions')
->with('recipient')->willReturn(Constants::PERMISSION_ALL);
$this->userSession->expects($this->exactly(2))
->method('getUser')
->willReturn($loggedInUser);

Expand All @@ -285,6 +290,7 @@ public function testGetDisplayNamePropertyWhenNotPublishedButLoggedIn(): void {
);

$this->assertEquals('M. Foo', $propFind->get(FilesPlugin::OWNER_DISPLAY_NAME_PROPERTYNAME));
$this->assertSame('["share","read","write"]', $propFind->get(FilesPlugin::OCM_SHARE_PERMISSIONS_PROPERTYNAME));
}

public function testGetPropertiesStorageNotAvailable(): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
use OCP\AppFramework\OCS\OCSBadRequestException;
use OCP\AppFramework\OCS\OCSException;
use OCP\AppFramework\OCSController;
use OCP\Constants;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Federation\Exceptions\ProviderCouldNotAddShareException;
use OCP\Federation\Exceptions\ProviderDoesNotExistsException;
Expand All @@ -30,6 +29,7 @@
use OCP\IDBConnection;
use OCP\IRequest;
use OCP\Log\Audit\CriticalActionPerformedEvent;
use OCP\OCM\Permissions;
use OCP\Server;
use OCP\Share\Exceptions\ShareNotFound;
use Psr\Log\LoggerInterface;
Expand Down Expand Up @@ -334,7 +334,7 @@ public function updatePermissions(string $id, ?string $token = null, ?int $permi

try {
$provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
$ocmPermissions = $this->ncPermissions2ocmPermissions((int)$ncPermissions);
$ocmPermissions = Permissions::fromNextcloud((int)$ncPermissions);
$notification = ['sharedSecret' => $token, 'permission' => $ocmPermissions];
$provider->notificationReceived('RESHARE_CHANGE_PERMISSION', $id, $notification);
$this->eventDispatcher->dispatchTyped(new CriticalActionPerformedEvent('Federated share with id "%s" has updated permissions "%s"', [$id, implode(', ', $ocmPermissions)]));
Expand All @@ -346,31 +346,6 @@ public function updatePermissions(string $id, ?string $token = null, ?int $permi
return new DataResponse();
}

/**
* translate Nextcloud permissions to OCM Permissions
*
* @param $ncPermissions
* @return array
*/
protected function ncPermissions2ocmPermissions($ncPermissions) {
$ocmPermissions = [];

if ($ncPermissions & Constants::PERMISSION_SHARE) {
$ocmPermissions[] = 'share';
}

if ($ncPermissions & Constants::PERMISSION_READ) {
$ocmPermissions[] = 'read';
}

if (($ncPermissions & Constants::PERMISSION_CREATE)
|| ($ncPermissions & Constants::PERMISSION_UPDATE)) {
$ocmPermissions[] = 'write';
}

return $ocmPermissions;
}

/**
* change the owner of a server-to-server share
*
Expand Down
3 changes: 2 additions & 1 deletion apps/federatedfilesharing/lib/FederatedShareProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,8 @@ protected function createFederatedShare(IShare $share): string {
$ownerCloudId->getId(),
$share->getSharedBy(),
$sharedByFederatedId,
$share->getShareType()
$share->getShareType(),
$share->getPermissions()
);

if ($send === false) {
Expand Down
13 changes: 10 additions & 3 deletions apps/federatedfilesharing/lib/Notifications.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,12 @@ public function __construct(
* @param string $sharedBy
* @param string $sharedByFederatedId
* @param int $shareType (can be a remote user or group share)
* @param int $permissions Nextcloud permission bitmask
* @return bool
* @throws HintException
* @throws ServerNotAvailableException
*/
public function sendRemoteShare($token, $shareWith, $name, $remoteId, $owner, $ownerFederatedId, $sharedBy, $sharedByFederatedId, $shareType) {
public function sendRemoteShare($token, $shareWith, $name, $remoteId, $owner, $ownerFederatedId, $sharedBy, $sharedByFederatedId, $shareType, int $permissions) {
[$user, $remote] = $this->addressHandler->splitUserRemote($shareWith);

if ($user && $remote) {
Expand All @@ -67,7 +68,8 @@ public function sendRemoteShare($token, $shareWith, $name, $remoteId, $owner, $o
'sharedBy' => $sharedBy,
'sharedByFederatedId' => $sharedByFederatedId,
'remote' => $local,
'shareType' => $shareType
'shareType' => $shareType,
'permissions' => $permissions,
];

$result = $this->tryHttpPostToShareEndpoint($remote, '', $fields);
Expand Down Expand Up @@ -308,6 +310,10 @@ protected function tryHttpPostToShareEndpoint($remoteDomain, $urlSuffix, array $
return $result;
}

if ($action === 'share') {
unset($fields['permissions']);
}

return $this->tryLegacyEndPoint($remoteDomain, $urlSuffix, $fields);
}

Expand Down Expand Up @@ -373,7 +379,8 @@ protected function tryOCMEndPoint($remoteDomain, $fields, $action) {
$fields['sharedBy'],
$fields['token'],
$fields['shareType'],
'file'
'file',
$fields['permissions']
);
return $this->federationProviderManager->sendShare($share);
case 'reshare':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use OCA\FederatedFileSharing\Controller\RequestHandlerController;
use OCA\FederatedFileSharing\FederatedShareProvider;
use OCP\AppFramework\Http\DataResponse;
use OCP\Constants;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Federation\ICloudFederationFactory;
use OCP\Federation\ICloudFederationProvider;
Expand Down Expand Up @@ -115,6 +116,19 @@ public function testCreateShare(): void {
$this->assertInstanceOf(DataResponse::class, $result);
}

public function testUpdatePermissions(): void {
$this->cloudFederationProviderManager->expects($this->once())
->method('getCloudFederationProvider')->with('file')->willReturn($this->cloudFederationProvider);
$this->cloudFederationProvider->expects($this->once())
->method('notificationReceived')
->with('RESHARE_CHANGE_PERMISSION', '42', [
'sharedSecret' => 'token',
'permission' => ['share', 'read', 'write'],
]);

$this->assertInstanceOf(DataResponse::class, $this->requestHandler->updatePermissions('42', 'token', Constants::PERMISSION_ALL));
}

public function testDeclineShare(): void {
$id = '42';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,9 @@ public function testCreate(?\DateTime $expirationDate, ?string $expectedDataDate
'shareOwner',
'shareOwner@http://localhost',
'sharedBy',
'sharedBy@http://localhost'
'sharedBy@http://localhost',
IShare::TYPE_REMOTE,
19
)
->willReturn(true);

Expand Down
58 changes: 58 additions & 0 deletions apps/federatedfilesharing/tests/NotificationsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@
use OCA\FederatedFileSharing\BackgroundJob\RetryJob;
use OCA\FederatedFileSharing\Notifications;
use OCP\BackgroundJob\IJobList;
use OCP\Constants;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Federation\ICloudFederationFactory;
use OCP\Federation\ICloudFederationProviderManager;
use OCP\Federation\ICloudFederationShare;
use OCP\Http\Client\IClientService;
use OCP\OCS\IDiscoveryService;
use OCP\Share\IShare;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;

Expand Down Expand Up @@ -78,6 +81,61 @@ private function getInstance(array $mockedMethods = []) {
->getMock();
}

public function testSendRemoteSharePermissions(): void {
$permissions = Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE | Constants::PERMISSION_SHARE;
$this->addressHandler->method('splitUserRemote')->willReturn(['recipient', 'https://remote.example']);
$this->addressHandler->method('generateRemoteURL')->willReturn('https://local.example');
$this->addressHandler->method('urlContainProtocol')->willReturn(true);
$share = $this->createMock(ICloudFederationShare::class);
$this->cloudFederationFactory->expects($this->once())
->method('getCloudFederationShare')
->with(
'recipient@https://remote.example',
'document.odt',
'',
'123',
'owner@local.example',
'Owner',
'owner@local.example',
'Owner',
'share-secret',
IShare::TYPE_REMOTE,
'file',
$permissions,
)
->willReturn($share);
$this->cloudFederationProviderManager->expects($this->once())
->method('sendShare')->with($share)->willReturn([]);
$this->httpClientService->expects($this->never())->method('newClient');

$this->assertTrue($this->getInstance()->sendRemoteShare(
'share-secret', 'recipient@remote.example', 'document.odt', '123',
'Owner', 'owner@local.example', 'Owner', 'owner@local.example',
IShare::TYPE_REMOTE, $permissions,
));
}

public static function legacyPermissionsProvider(): array {
return [
'new share' => ['share', ['token' => 'share-secret']],
'permission update' => ['permissions', ['token' => 'share-secret', 'permissions' => Constants::PERMISSION_READ]],
];
}

#[\PHPUnit\Framework\Attributes\DataProvider('legacyPermissionsProvider')]
public function testLegacyPermissions(string $action, array $expectedFields): void {
$this->addressHandler->method('urlContainProtocol')->willReturn(true);
$fields = ['token' => 'share-secret', 'permissions' => Constants::PERMISSION_READ];
$result = ['success' => true, 'result' => ''];
$instance = $this->getInstance(['tryOCMEndPoint', 'tryLegacyEndPoint']);
$instance->expects($this->once())->method('tryOCMEndPoint')
->with('https://remote.example', $fields, $action)->willReturn(false);
$instance->expects($this->once())->method('tryLegacyEndPoint')
->with('https://remote.example', '', $expectedFields)->willReturn($result);

$this->assertSame($result, $this->invokePrivate($instance, 'tryHttpPostToShareEndpoint', ['https://remote.example', '', $fields, $action]));
}

#[\PHPUnit\Framework\Attributes\DataProvider(methodName: 'dataTestSendUpdateToRemote')]
public function testSendUpdateToRemote(int $try, array $httpRequestResult, bool $expected): void {
$remote = 'http://remote';
Expand Down
1 change: 1 addition & 0 deletions lib/composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,7 @@
'OCP\\OCM\\IOCMProvider' => $baseDir . '/lib/public/OCM/IOCMProvider.php',
'OCP\\OCM\\IOCMResource' => $baseDir . '/lib/public/OCM/IOCMResource.php',
'OCP\\OCM\\OCMCapabilities' => $baseDir . '/lib/public/OCM/OCMCapabilities.php',
'OCP\\OCM\\Permissions' => $baseDir . '/lib/public/OCM/Permissions.php',
'OCP\\OCS\\IDiscoveryService' => $baseDir . '/lib/public/OCS/IDiscoveryService.php',
'OCP\\OpenMetrics\\IMetricFamily' => $baseDir . '/lib/public/OpenMetrics/IMetricFamily.php',
'OCP\\OpenMetrics\\Metric' => $baseDir . '/lib/public/OpenMetrics/Metric.php',
Expand Down
1 change: 1 addition & 0 deletions lib/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -884,6 +884,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\OCM\\IOCMProvider' => __DIR__ . '/../../..' . '/lib/public/OCM/IOCMProvider.php',
'OCP\\OCM\\IOCMResource' => __DIR__ . '/../../..' . '/lib/public/OCM/IOCMResource.php',
'OCP\\OCM\\OCMCapabilities' => __DIR__ . '/../../..' . '/lib/public/OCM/OCMCapabilities.php',
'OCP\\OCM\\Permissions' => __DIR__ . '/../../..' . '/lib/public/OCM/Permissions.php',
'OCP\\OCS\\IDiscoveryService' => __DIR__ . '/../../..' . '/lib/public/OCS/IDiscoveryService.php',
'OCP\\OpenMetrics\\IMetricFamily' => __DIR__ . '/../../..' . '/lib/public/OpenMetrics/IMetricFamily.php',
'OCP\\OpenMetrics\\Metric' => __DIR__ . '/../../..' . '/lib/public/OpenMetrics/Metric.php',
Expand Down
Loading
Loading