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
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,6 @@ private function confirmSignedOrigin(?IIncomingSignedRequest $signedRequest, str
*
* @param IIncomingSignedRequest|null $signedRequest
* @param string $resourceType
* @param string $sharedSecret
*
* @throws IncomingRequestException
* @throws BadRequestException
Expand All @@ -524,7 +523,7 @@ private function confirmNotificationIdentity(
return;
}
} catch (\Exception $e) {
throw new IncomingRequestException($e->getMessage());
throw new IncomingRequestException($e->getMessage(), previous: $e);
}

$this->confirmNotificationEntry($signedRequest, $identity);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@
use NCU\Federation\ISignedCloudFederationProvider;
use OC\AppFramework\Http;
use OC\Files\Filesystem;
use OC\Files\SetupManager;
use OCA\FederatedFileSharing\AddressHandler;
use OCA\FederatedFileSharing\FederatedShareProvider;
use OCA\Federation\TrustedServers;
use OCA\Files_Sharing\Activity\Providers\RemoteShares;
use OCA\Files_Sharing\External\ExternalShare;
use OCA\Files_Sharing\External\Manager;
use OCA\GlobalSiteSelector\Service\SlaveService;
use OCA\Polls\Db\Share;
use OCP\Activity\IManager as IActivityManager;
use OCP\App\IAppManager;
use OCP\AppFramework\QueryException;
Expand All @@ -32,15 +35,18 @@
use OCP\HintException;
use OCP\IConfig;
use OCP\IDBConnection;
use OCP\IGroup;
use OCP\IGroupManager;
use OCP\IURLGenerator;
use OCP\IUser;
use OCP\IUserManager;
use OCP\Notification\IManager as INotificationManager;
use OCP\Server;
use OCP\Share\Exceptions\ShareNotFound;
use OCP\Share\IManager;
use OCP\Share\IProviderFactory;
use OCP\Share\IShare;
use OCP\Snowflake\IGenerator;
use OCP\Util;
use Psr\Log\LoggerInterface;
use SensitiveParameter;
Expand Down Expand Up @@ -68,13 +74,12 @@ public function __construct(
private LoggerInterface $logger,
private IFilenameValidator $filenameValidator,
private readonly IProviderFactory $shareProviderFactory,
private readonly SetupManager $setupManager,
private readonly IGenerator $snowflakeGenerator,
) {
}

/**
* @return string
*/
public function getShareType() {
public function getShareType(): string {
return 'file';
}

Expand All @@ -89,7 +94,7 @@ public function getShareType() {
* @throws HintException
* @since 14.0.0
*/
public function shareReceived(ICloudFederationShare $share) {
public function shareReceived(ICloudFederationShare $share): string {
if (!$this->isS2SEnabled(true)) {
throw new ProviderCouldNotAddShareException('Server does not support federated cloud sharing', '', Http::STATUS_SERVICE_UNAVAILABLE);
}
Expand All @@ -99,7 +104,8 @@ public function shareReceived(ICloudFederationShare $share) {
throw new ProviderCouldNotAddShareException('Unsupported protocol for data exchange.', '', Http::STATUS_NOT_IMPLEMENTED);
}

[$ownerUid, $remote] = $this->addressHandler->splitUserRemote($share->getOwner());
[, $remote] = $this->addressHandler->splitUserRemote($share->getOwner());

// for backward compatibility make sure that the remote url stored in the
// database ends with a trailing slash
if (!str_ends_with($remote, '/')) {
Expand All @@ -109,17 +115,15 @@ public function shareReceived(ICloudFederationShare $share) {
$token = $share->getShareSecret();
$name = $share->getResourceName();
$owner = $share->getOwnerDisplayName() ?: $share->getOwner();
$sharedBy = $share->getSharedByDisplayName();
$shareWith = $share->getShareWith();
$remoteId = $share->getProviderId();
$sharedByFederatedId = $share->getSharedBy();
$ownerFederatedId = $share->getOwner();
$shareType = $this->mapShareTypeToNextcloud($share->getShareType());

// if no explicit information about the person who created the share was send
// if no explicit information about the person who created the share was sent
// we assume that the share comes from the owner
if ($sharedByFederatedId === null) {
$sharedBy = $owner;
$sharedByFederatedId = $ownerFederatedId;
}

Expand All @@ -128,6 +132,8 @@ public function shareReceived(ICloudFederationShare $share) {
throw new ProviderCouldNotAddShareException('The mountpoint name contains invalid characters.', '', Http::STATUS_BAD_REQUEST);
}

$userOrGroup = null;

// FIXME this should be a method in the user management instead
if ($shareType === IShare::TYPE_USER) {
$this->logger->debug('shareWith before, ' . $shareWith, ['app' => 'files_sharing']);
Expand All @@ -138,20 +144,34 @@ public function shareReceived(ICloudFederationShare $share) {
);
$this->logger->debug('shareWith after, ' . $shareWith, ['app' => 'files_sharing']);

if (!$this->userManager->userExists($shareWith)) {
$userOrGroup = $this->userManager->get($shareWith);
if ($userOrGroup === null) {
throw new ProviderCouldNotAddShareException('User does not exists', '', Http::STATUS_BAD_REQUEST);
}

\OC_Util::setupFS($shareWith);
$this->setupManager->setupForUser($userOrGroup);
}

if ($shareType === IShare::TYPE_GROUP && !$this->groupManager->groupExists($shareWith)) {
throw new ProviderCouldNotAddShareException('Group does not exists', '', Http::STATUS_BAD_REQUEST);
if ($shareType === IShare::TYPE_GROUP) {
$userOrGroup = $this->groupManager->get($shareWith);
if ($userOrGroup === null) {
throw new ProviderCouldNotAddShareException('Group does not exists', '', Http::STATUS_BAD_REQUEST);
}
}

$externalShare = new ExternalShare();
$externalShare->setId($this->snowflakeGenerator->nextId());
$externalShare->setRemote($remote);
$externalShare->setRemoteId($remoteId);
$externalShare->setShareToken($token);
$externalShare->setPassword('');
$externalShare->setName($name);
$externalShare->setOwner($owner);
$externalShare->setShareType($shareType);
$externalShare->setAccepted(IShare::STATUS_PENDING);

try {
$this->externalShareManager->addShare($remote, $token, '', $name, $owner, $shareType, false, $shareWith, $remoteId);
$shareId = Server::get(IDBConnection::class)->lastInsertId('*PREFIX*share_external');
$this->externalShareManager->addShare($externalShare, $userOrGroup);

// get DisplayName about the owner of the share
$ownerDisplayName = $this->getUserDisplayName($ownerFederatedId);
Expand All @@ -168,39 +188,42 @@ public function shareReceived(ICloudFederationShare $share) {


if ($shareType === IShare::TYPE_USER) {
/** @var IUser $userOrGroup */
$event = $this->activityManager->generateEvent();
$event->setApp('files_sharing')
->setType('remote_share')
->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_RECEIVED, [$ownerFederatedId, trim($name, '/'), $ownerDisplayName])
->setAffectedUser($shareWith)
->setObject('remote_share', $shareId, $name);
->setObject('remote_share', $externalShare->getId(), $name);
Server::get(IActivityManager::class)->publish($event);
$this->notifyAboutNewShare($shareWith, $shareId, $ownerFederatedId, $sharedByFederatedId, $name, $ownerDisplayName);
$this->notifyAboutNewShare($shareWith, $externalShare->getId(), $ownerFederatedId, $sharedByFederatedId, $name, $ownerDisplayName);

// If auto-accept is enabled, accept the share
if ($this->federatedShareProvider->isFederatedTrustedShareAutoAccept() && $trustedServers?->isTrustedServer($remote) === true) {
$this->externalShareManager->acceptShare($shareId, $shareWith);
/** @var IUser $userOrGroup */
$this->externalShareManager->acceptShare($externalShare, $userOrGroup);
}
} else {
$groupMembers = $this->groupManager->get($shareWith)->getUsers();
/** @var IGroup $userOrGroup */
$groupMembers = $userOrGroup->getUsers();
foreach ($groupMembers as $user) {
$event = $this->activityManager->generateEvent();
$event->setApp('files_sharing')
->setType('remote_share')
->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_RECEIVED, [$ownerFederatedId, trim($name, '/'), $ownerDisplayName])
->setAffectedUser($user->getUID())
->setObject('remote_share', $shareId, $name);
->setObject('remote_share', $externalShare->getId(), $name);
Server::get(IActivityManager::class)->publish($event);
$this->notifyAboutNewShare($user->getUID(), $shareId, $ownerFederatedId, $sharedByFederatedId, $name, $ownerDisplayName);
$this->notifyAboutNewShare($user->getUID(), $externalShare->getId(), $ownerFederatedId, $sharedByFederatedId, $name, $ownerDisplayName);

// If auto-accept is enabled, accept the share
if ($this->federatedShareProvider->isFederatedTrustedShareAutoAccept() && $trustedServers?->isTrustedServer($remote) === true) {
$this->externalShareManager->acceptShare($shareId, $user->getUID());
$this->externalShareManager->acceptShare($externalShare, $user);
}
}
}

return $shareId;
return $externalShare->getId();
} catch (\Exception $e) {
$this->logger->error('Server can not add remote share.', [
'app' => 'files_sharing',
Expand Down Expand Up @@ -262,7 +285,7 @@ private function mapShareTypeToNextcloud($shareType) {
return $result;
}

private function notifyAboutNewShare($shareWith, $shareId, $ownerFederatedId, $sharedByFederatedId, $name, $displayName): void {
private function notifyAboutNewShare($shareWith, string $shareId, $ownerFederatedId, $sharedByFederatedId, string $name, string $displayName): void {
$notification = $this->notificationManager->createNotification();
$notification->setApp('files_sharing')
->setUser($shareWith)
Expand Down Expand Up @@ -768,7 +791,7 @@ public function getUserDisplayName(string $userId): string {
try {
$slaveService = Server::get(SlaveService::class);
} catch (\Throwable $e) {
Server::get(LoggerInterface::class)->error(
$this->logger->error(
$e->getMessage(),
['exception' => $e]
);
Expand Down Expand Up @@ -800,7 +823,7 @@ public function getFederationIdFromSharedSecret(
return '';
}

return $share['user'] . '@' . $share['remote'];
return $share->getUser() . '@' . $share->getRemote();
}

// if uid_owner is a local account, the request comes from the recipient
Expand Down
3 changes: 3 additions & 0 deletions apps/files_sharing/composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
'OCA\\Files_Sharing\\Exceptions\\SharingRightsException' => $baseDir . '/../lib/Exceptions/SharingRightsException.php',
'OCA\\Files_Sharing\\ExpireSharesJob' => $baseDir . '/../lib/ExpireSharesJob.php',
'OCA\\Files_Sharing\\External\\Cache' => $baseDir . '/../lib/External/Cache.php',
'OCA\\Files_Sharing\\External\\ExternalShare' => $baseDir . '/../lib/External/ExternalShare.php',
'OCA\\Files_Sharing\\External\\ExternalShareMapper' => $baseDir . '/../lib/External/ExternalShareMapper.php',
'OCA\\Files_Sharing\\External\\Manager' => $baseDir . '/../lib/External/Manager.php',
'OCA\\Files_Sharing\\External\\Mount' => $baseDir . '/../lib/External/Mount.php',
'OCA\\Files_Sharing\\External\\MountProvider' => $baseDir . '/../lib/External/MountProvider.php',
Expand Down Expand Up @@ -82,6 +84,7 @@
'OCA\\Files_Sharing\\Migration\\Version24000Date20220404142216' => $baseDir . '/../lib/Migration/Version24000Date20220404142216.php',
'OCA\\Files_Sharing\\Migration\\Version31000Date20240821142813' => $baseDir . '/../lib/Migration/Version31000Date20240821142813.php',
'OCA\\Files_Sharing\\Migration\\Version32000Date20251017081948' => $baseDir . '/../lib/Migration/Version32000Date20251017081948.php',
'OCA\\Files_Sharing\\Migration\\Version33000Date20251030081948' => $baseDir . '/../lib/Migration/Version33000Date20251030081948.php',
'OCA\\Files_Sharing\\MountProvider' => $baseDir . '/../lib/MountProvider.php',
'OCA\\Files_Sharing\\Notification\\Listener' => $baseDir . '/../lib/Notification/Listener.php',
'OCA\\Files_Sharing\\Notification\\Notifier' => $baseDir . '/../lib/Notification/Notifier.php',
Expand Down
3 changes: 3 additions & 0 deletions apps/files_sharing/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ class ComposerStaticInitFiles_Sharing
'OCA\\Files_Sharing\\Exceptions\\SharingRightsException' => __DIR__ . '/..' . '/../lib/Exceptions/SharingRightsException.php',
'OCA\\Files_Sharing\\ExpireSharesJob' => __DIR__ . '/..' . '/../lib/ExpireSharesJob.php',
'OCA\\Files_Sharing\\External\\Cache' => __DIR__ . '/..' . '/../lib/External/Cache.php',
'OCA\\Files_Sharing\\External\\ExternalShare' => __DIR__ . '/..' . '/../lib/External/ExternalShare.php',
'OCA\\Files_Sharing\\External\\ExternalShareMapper' => __DIR__ . '/..' . '/../lib/External/ExternalShareMapper.php',
'OCA\\Files_Sharing\\External\\Manager' => __DIR__ . '/..' . '/../lib/External/Manager.php',
'OCA\\Files_Sharing\\External\\Mount' => __DIR__ . '/..' . '/../lib/External/Mount.php',
'OCA\\Files_Sharing\\External\\MountProvider' => __DIR__ . '/..' . '/../lib/External/MountProvider.php',
Expand Down Expand Up @@ -97,6 +99,7 @@ class ComposerStaticInitFiles_Sharing
'OCA\\Files_Sharing\\Migration\\Version24000Date20220404142216' => __DIR__ . '/..' . '/../lib/Migration/Version24000Date20220404142216.php',
'OCA\\Files_Sharing\\Migration\\Version31000Date20240821142813' => __DIR__ . '/..' . '/../lib/Migration/Version31000Date20240821142813.php',
'OCA\\Files_Sharing\\Migration\\Version32000Date20251017081948' => __DIR__ . '/..' . '/../lib/Migration/Version32000Date20251017081948.php',
'OCA\\Files_Sharing\\Migration\\Version33000Date20251030081948' => __DIR__ . '/..' . '/../lib/Migration/Version33000Date20251030081948.php',
'OCA\\Files_Sharing\\MountProvider' => __DIR__ . '/..' . '/../lib/MountProvider.php',
'OCA\\Files_Sharing\\Notification\\Listener' => __DIR__ . '/..' . '/../lib/Notification/Listener.php',
'OCA\\Files_Sharing\\Notification\\Notifier' => __DIR__ . '/..' . '/../lib/Notification/Notifier.php',
Expand Down
27 changes: 13 additions & 14 deletions apps/files_sharing/lib/Controller/ExternalSharesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/
namespace OCA\Files_Sharing\Controller;

use OCA\Files_Sharing\External\Manager;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\JSONResponse;
Expand All @@ -21,42 +22,40 @@ class ExternalSharesController extends Controller {
public function __construct(
string $appName,
IRequest $request,
private \OCA\Files_Sharing\External\Manager $externalManager,
private readonly Manager $externalManager,
) {
parent::__construct($appName, $request);
}

/**
* @NoOutgoingFederatedSharingRequired
*
* @return JSONResponse
*/
#[NoAdminRequired]
public function index() {
public function index(): JSONResponse {
return new JSONResponse($this->externalManager->getOpenShares());
}

/**
* @NoOutgoingFederatedSharingRequired
*
* @param int $id
* @return JSONResponse
*/
#[NoAdminRequired]
public function create($id) {
$this->externalManager->acceptShare($id);
public function create(string $id): JSONResponse {
$externalShare = $this->externalManager->getShare($id);
if ($externalShare !== false) {
$this->externalManager->acceptShare($externalShare);
}
return new JSONResponse();
}

/**
* @NoOutgoingFederatedSharingRequired
*
* @param integer $id
* @return JSONResponse
*/
#[NoAdminRequired]
public function destroy($id) {
$this->externalManager->declineShare($id);
public function destroy(string $id): JSONResponse {
$externalShare = $this->externalManager->getShare($id);
if ($externalShare !== false) {
$this->externalManager->declineShare($externalShare);
}
return new JSONResponse();
}
}
Loading
Loading