From 21d7383d957cd814ae9f126a7585027af2124e6a Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Mon, 28 Oct 2019 19:22:05 +0100 Subject: [PATCH] Allow internal shares to have a default expiration date * Needs admin UI * Needs more checks * Basics seem to work Signed-off-by: Roeland Jago Douma --- lib/private/Share20/DefaultShareProvider.php | 10 ++ lib/private/Share20/Manager.php | 136 ++++++++++++++++++- 2 files changed, 141 insertions(+), 5 deletions(-) diff --git a/lib/private/Share20/DefaultShareProvider.php b/lib/private/Share20/DefaultShareProvider.php index c25a7b03d5..152e5d5539 100644 --- a/lib/private/Share20/DefaultShareProvider.php +++ b/lib/private/Share20/DefaultShareProvider.php @@ -144,9 +144,19 @@ class DefaultShareProvider implements IShareProvider { //Set the UID of the user we share with $qb->setValue('share_with', $qb->createNamedParameter($share->getSharedWith())); $qb->setValue('accepted', $qb->createNamedParameter(IShare::STATUS_PENDING)); + + //If an expiration date is set store it + if ($share->getExpirationDate() !== null) { + $qb->setValue('expiration', $qb->createNamedParameter($share->getExpirationDate(), 'datetime')); + } } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) { //Set the GID of the group we share with $qb->setValue('share_with', $qb->createNamedParameter($share->getSharedWith())); + + //If an expiration date is set store it + if ($share->getExpirationDate() !== null) { + $qb->setValue('expiration', $qb->createNamedParameter($share->getExpirationDate(), 'datetime')); + } } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) { //set label for public link $qb->setValue('label', $qb->createNamedParameter($share->getLabel())); diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php index 210dc7772c..3a9176e9eb 100644 --- a/lib/private/Share20/Manager.php +++ b/lib/private/Share20/Manager.php @@ -351,6 +351,77 @@ class Manager implements IManager { } } + /** + * Validate if the expiration date fits the system settings + * + * @param \OCP\Share\IShare $share The share to validate the expiration date of + * @return \OCP\Share\IShare The modified share object + * @throws GenericShareException + * @throws \InvalidArgumentException + * @throws \Exception + */ + protected function validateExpirationDateInternal(\OCP\Share\IShare $share) { + $expirationDate = $share->getExpirationDate(); + + if ($expirationDate !== null) { + //Make sure the expiration date is a date + $expirationDate->setTime(0, 0, 0); + + $date = new \DateTime(); + $date->setTime(0, 0, 0); + if ($date >= $expirationDate) { + $message = $this->l->t('Expiration date is in the past'); + throw new GenericShareException($message, $message, 404); + } + } + + // If expiredate is empty set a default one if there is a default + $fullId = null; + try { + $fullId = $share->getFullId(); + } catch (\UnexpectedValueException $e) { + // This is a new share + } + + if ($fullId === null && $expirationDate === null && $this->shareApiInternalDefaultExpireDate()) { + $expirationDate = new \DateTime(); + $expirationDate->setTime(0,0,0); + $expirationDate->add(new \DateInterval('P'.$this->shareApiInternalDefaultExpireDays().'D')); + } + + // If we enforce the expiration date check that is does not exceed + if ($this->shareApiInternalDefaultExpireDateEnforced()) { + if ($expirationDate === null) { + throw new \InvalidArgumentException('Expiration date is enforced'); + } + + $date = new \DateTime(); + $date->setTime(0, 0, 0); + $date->add(new \DateInterval('P' . $this->shareApiInternalDefaultExpireDays() . 'D')); + if ($date < $expirationDate) { + $message = $this->l->t('Can’t set expiration date more than %s days in the future', [$this->shareApiInternalDefaultExpireDays()]); + throw new GenericShareException($message, $message, 404); + } + } + + $accepted = true; + $message = ''; + \OCP\Util::emitHook('\OC\Share', 'verifyExpirationDate', [ + 'expirationDate' => &$expirationDate, + 'accepted' => &$accepted, + 'message' => &$message, + 'passwordSet' => $share->getPassword() !== null, + ]); + + if (!$accepted) { + throw new \Exception($message); + } + + $share->setExpirationDate($expirationDate); + + return $share; + } + /** * Validate if the expiration date fits the system settings * @@ -636,8 +707,16 @@ class Manager implements IManager { //Verify share type if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) { $this->userCreateChecks($share); + + //Verify the expiration date + $share = $this->validateExpirationDateInternal($share); + } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) { $this->groupCreateChecks($share); + + //Verify the expiration date + $share = $this->validateExpirationDateInternal($share); + } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) { $this->linkCreateChecks($share); $this->setLinkParent($share); @@ -653,7 +732,7 @@ class Manager implements IManager { ); //Verify the expiration date - $this->validateExpirationDate($share); + $share = $this->validateExpirationDate($share); //Verify the password $this->verifyPassword($share->getPassword()); @@ -850,8 +929,20 @@ class Manager implements IManager { if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) { $this->userCreateChecks($share); + + if ($share->getExpirationDate() != $originalShare->getExpirationDate()) { + //Verify the expiration date + $this->validateExpirationDate($share); + $expirationDateUpdated = true; + } } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) { $this->groupCreateChecks($share); + + if ($share->getExpirationDate() != $originalShare->getExpirationDate()) { + //Verify the expiration date + $this->validateExpirationDate($share); + $expirationDateUpdated = true; + } } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) { $this->linkCreateChecks($share); @@ -1575,7 +1666,7 @@ class Manager implements IManager { } /** - * Is default expire date enabled + * Is default link expire date enabled * * @return bool */ @@ -1584,7 +1675,7 @@ class Manager implements IManager { } /** - * Is default expire date enforced + * Is default link expire date enforced *` * @return bool */ @@ -1593,15 +1684,50 @@ class Manager implements IManager { $this->config->getAppValue('core', 'shareapi_enforce_expire_date', 'no') === 'yes'; } + /** - * Number of default expire days - *shareApiLinkAllowPublicUpload + * Number of default link expire days * @return int */ public function shareApiLinkDefaultExpireDays() { return (int)$this->config->getAppValue('core', 'shareapi_expire_after_n_days', '7'); } + /** + * Is default internal expire date enabled + * + * @return bool + */ + public function shareApiInternalDefaultExpireDate(): bool { + //FIXME: mage configurable + return true; + return $this->config->getAppValue('core', 'shareapi_default_internal_expire_date', 'no') === 'yes'; + } + + /** + * Is default expire date enforced + *` + * @return bool + */ + public function shareApiInternalDefaultExpireDateEnforced(): bool { + //FIXME: mage configurable + return true; + return $this->shareApiLinkDefaultExpireDate() && + $this->config->getAppValue('core', 'shareapi_enforce_internal_expire_date', 'no') === 'yes'; + } + + + /** + * Number of default expire days + * @return int + */ + public function shareApiInternalDefaultExpireDays(): int { + + //FIXME: mage configurable + return 6; + return (int)$this->config->getAppValue('core', 'shareapi_internal_expire_after_n_days', '7'); + } + /** * Allow public upload on link shares *