From 97d6fa4beac019b53f03736e568de485c7a2e9da Mon Sep 17 00:00:00 2001 From: Louis Chemineau Date: Thu, 23 May 2024 16:51:38 +0200 Subject: [PATCH] fix: Backport adaptation Signed-off-by: Louis Chemineau --- .../lib/Controller/ShareAPIController.php | 64 ++++++++++++------- .../features/bootstrap/Sharing.php | 16 ++--- lib/private/Share20/Manager.php | 29 ++++----- lib/private/Share20/Share.php | 4 +- 4 files changed, 66 insertions(+), 47 deletions(-) diff --git a/apps/files_sharing/lib/Controller/ShareAPIController.php b/apps/files_sharing/lib/Controller/ShareAPIController.php index eb60a3a85f10b..0362360cb9c50 100644 --- a/apps/files_sharing/lib/Controller/ShareAPIController.php +++ b/apps/files_sharing/lib/Controller/ShareAPIController.php @@ -233,7 +233,7 @@ protected function formatShare(IShare $share, Node $recipientNode = null): array $result['share_with'] = $share->getSharedWith(); $result['share_with_displayname'] = $sharedWith !== null ? $sharedWith->getDisplayName() : $share->getSharedWith(); $result['share_with_displayname_unique'] = $sharedWith !== null ? ( - !empty($sharedWith->getSystemEMailAddress()) ? $sharedWith->getSystemEMailAddress() : $sharedWith->getUID() + !empty($sharedWith->getSystemEMailAddress()) ? $sharedWith->getSystemEMailAddress() : $sharedWith->getUID() ) : $share->getSharedWith(); $result['status'] = []; @@ -332,7 +332,7 @@ protected function formatShare(IShare $share, Node $recipientNode = null): array $result['attributes'] = null; if ($attributes = $share->getAttributes()) { - $result['attributes'] = \json_encode($attributes->toArray()); + $result['attributes'] = \json_encode($attributes->toArray()); } return $result; @@ -579,7 +579,7 @@ public function createShare( string $publicUpload = 'false', string $password = '', string $sendPasswordByTalk = null, - string $expireDate = '', + ?string $expireDate = null, string $note = '', string $label = '', string $attributes = null @@ -739,13 +739,19 @@ public function createShare( $share->setSharedWith($shareWith); $share->setPermissions($permissions); - if ($expireDate !== '') { - try { - $expireDate = $this->parseDate($expireDate); - $share->setExpirationDate($expireDate); - } catch (\Exception $e) { - throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD')); + if ($expireDate !== null) { + if ($expireDate !== '') { + try { + $expireDate = $this->parseDate($expireDate); + $share->setExpirationDate($expireDate); + } catch (\Exception $e) { + throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD')); + } } + } else { + // Client sent empty string for expire date. + // Set noExpirationDate to true so overwrite is prevented. + $share->setNoExpirationDate(true); } $share->setSharedWithDisplayName($this->getCachedFederatedDisplayName($shareWith, false)); @@ -760,13 +766,19 @@ public function createShare( $share->setSharedWith($shareWith); $share->setPermissions($permissions); - if ($expireDate !== '') { - try { - $expireDate = $this->parseDate($expireDate); - $share->setExpirationDate($expireDate); - } catch (\Exception $e) { - throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD')); + if ($expireDate !== null) { + if ($expireDate !== '') { + try { + $expireDate = $this->parseDate($expireDate); + $share->setExpirationDate($expireDate); + } catch (\Exception $e) { + throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD')); + } } + } else { + // Client sent empty string for expire date. + // Set noExpirationDate to true so overwrite is prevented. + $share->setNoExpirationDate(true); } } elseif ($shareType === IShare::TYPE_CIRCLE) { if (!\OC::$server->getAppManager()->isEnabledForUser('circles') || !class_exists('\OCA\Circles\ShareByCircleProvider')) { @@ -804,13 +816,19 @@ public function createShare( } //Expire date - if ($expireDate !== '') { - try { - $expireDate = $this->parseDate($expireDate); - $share->setExpirationDate($expireDate); - } catch (\Exception $e) { - throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD')); + if ($expireDate !== null) { + if ($expireDate !== '') { + try { + $expireDate = $this->parseDate($expireDate); + $share->setExpirationDate($expireDate); + } catch (\Exception $e) { + throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD')); + } } + } else { + // Client sent empty string for expire date. + // Set noExpirationDate to true so overwrite is prevented. + $share->setNoExpirationDate(true); } $share->setShareType($shareType); @@ -1285,8 +1303,8 @@ public function updateShare( } if (!$this->hasPermission($newPermissions, Constants::PERMISSION_READ) && ( - $this->hasPermission($newPermissions, Constants::PERMISSION_UPDATE) || $this->hasPermission($newPermissions, Constants::PERMISSION_DELETE) - )) { + $this->hasPermission($newPermissions, Constants::PERMISSION_UPDATE) || $this->hasPermission($newPermissions, Constants::PERMISSION_DELETE) + )) { throw new OCSBadRequestException($this->l->t('Share must have READ permission if UPDATE or DELETE permission is set')); } } diff --git a/build/integration/features/bootstrap/Sharing.php b/build/integration/features/bootstrap/Sharing.php index f56ac3daf9db3..0f1b221563952 100644 --- a/build/integration/features/bootstrap/Sharing.php +++ b/build/integration/features/bootstrap/Sharing.php @@ -272,13 +272,13 @@ public function updatingLastShare($body) { } public function createShare($user, - $path = null, - $shareType = null, - $shareWith = null, - $publicUpload = null, - $password = null, - $permissions = null, - $viewOnly = false) { + $path = null, + $shareType = null, + $shareWith = null, + $publicUpload = null, + $password = null, + $permissions = null, + $viewOnly = false) { $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/apps/files_sharing/api/v{$this->sharingApiVersion}/shares"; $client = new Client(); $options = [ @@ -330,7 +330,7 @@ public function createShare($user, public function isFieldInResponse($field, $contentExpected) { $data = simplexml_load_string($this->response->getBody())->data[0]; if ((string)$field == 'expiration') { - if(!empty($contentExpected)) { + if (!empty($contentExpected)) { $contentExpected = date('Y-m-d', strtotime($contentExpected)) . " 00:00:00"; } } diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php index d3ba1549c6183..1bb4657ef79cf 100644 --- a/lib/private/Share20/Manager.php +++ b/lib/private/Share20/Manager.php @@ -298,7 +298,7 @@ protected function generalCreateChecks(IShare $share, bool $isUpdate = false) { $isFederatedShare = $share->getNode()->getStorage()->instanceOfStorage('\OCA\Files_Sharing\External\Storage'); $permissions = 0; - + $isReshare = $share->getNode()->getOwner() && $share->getNode()->getOwner()->getUID() !== $share->getSharedBy(); if (!$isReshare && $isUpdate) { // in case of update on owner-less filesystem, we use share owner to improve reshare detection @@ -406,7 +406,7 @@ protected function validateExpirationDateInternal(IShare $share) { // If $expirationDate is falsy, noExpirationDate is true and expiration not enforced // Then skip expiration date validation as null is accepted - if(!($share->getNoExpirationDate() && !$isEnforced)) { + if (!($share->getNoExpirationDate() && !$isEnforced)) { if ($expirationDate != null) { $expirationDate->setTimezone($this->dateTimeZone->getTimeZone()); $expirationDate->setTime(0, 0, 0); @@ -486,11 +486,11 @@ protected function validateExpirationDateLink(IShare $share) { // If $expirationDate is falsy, noExpirationDate is true and expiration not enforced // Then skip expiration date validation as null is accepted - if(!($share->getNoExpirationDate() && !$isEnforced)) { + if (!($share->getNoExpirationDate() && !$isEnforced)) { if ($expirationDate !== null) { $expirationDate->setTimezone($this->dateTimeZone->getTimeZone()); $expirationDate->setTime(0, 0, 0); - + $date = new \DateTime('now', $this->dateTimeZone->getTimeZone()); $date->setTime(0, 0, 0); if ($date >= $expirationDate) { @@ -506,24 +506,24 @@ protected function validateExpirationDateLink(IShare $share) { } catch (\UnexpectedValueException $e) { // This is a new share } - + if ($fullId === null && $expirationDate === null && $this->shareApiLinkDefaultExpireDate()) { $expirationDate = new \DateTime('now', $this->dateTimeZone->getTimeZone()); $expirationDate->setTime(0, 0, 0); - + $days = (int)$this->config->getAppValue('core', 'link_defaultExpDays', (string)$this->shareApiLinkDefaultExpireDays()); if ($days > $this->shareApiLinkDefaultExpireDays()) { $days = $this->shareApiLinkDefaultExpireDays(); } $expirationDate->add(new \DateInterval('P' . $days . 'D')); } - + // If we enforce the expiration date check that is does not exceed if ($isEnforced) { if (empty($expirationDate)) { throw new \InvalidArgumentException('Expiration date is enforced'); } - + $date = new \DateTime('now', $this->dateTimeZone->getTimeZone()); $date->setTime(0, 0, 0); $date->add(new \DateInterval('P' . $this->shareApiLinkDefaultExpireDays() . 'D')); @@ -532,7 +532,6 @@ protected function validateExpirationDateLink(IShare $share) { throw new GenericShareException($message, $message, 404); } } - } $accepted = true; @@ -907,12 +906,12 @@ public function createShare(IShare $share) { * @param \DateTime|null $expiration */ protected function sendMailNotification(IL10N $l, - $filename, - $link, - $initiator, - $shareWith, - \DateTime $expiration = null, - $note = '') { + $filename, + $link, + $initiator, + $shareWith, + \DateTime $expiration = null, + $note = '') { $initiatorUser = $this->userManager->get($initiator); $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator; diff --git a/lib/private/Share20/Share.php b/lib/private/Share20/Share.php index 8523557a5b47b..b911a3b462357 100644 --- a/lib/private/Share20/Share.php +++ b/lib/private/Share20/Share.php @@ -29,8 +29,8 @@ */ namespace OC\Share20; -use OCP\Files\File; use OCP\Files\Cache\ICacheEntry; +use OCP\Files\File; use OCP\Files\FileInfo; use OCP\Files\IRootFolder; use OCP\Files\Node; @@ -102,6 +102,8 @@ class Share implements IShare { /** @var bool */ private $hideDownload = false; + private bool $noExpirationDate = false; + public function __construct(IRootFolder $rootFolder, IUserManager $userManager) { $this->rootFolder = $rootFolder; $this->userManager = $userManager;