mirror of
https://github.com/nextcloud/server.git
synced 2026-04-14 13:38:10 -04:00
fix(shareManager): Respect empty expireDate in server
If `expireDate` is an empty string and not `null` then the server should not set a default. Signed-off-by: fenn-cs <fenn25.fn@gmail.com>
This commit is contained in:
parent
2fa099a6e1
commit
59a5b4e0bd
5 changed files with 146 additions and 95 deletions
|
|
@ -549,7 +549,8 @@ class ShareAPIController extends OCSController {
|
|||
* @param string $publicUpload If public uploading is allowed
|
||||
* @param string $password Password for the share
|
||||
* @param string|null $sendPasswordByTalk Send the password for the share over Talk
|
||||
* @param string $expireDate Expiry date of the share using user timezone at 00:00. It means date in UTC timezone will be used.
|
||||
* @param ?string $expireDate The expiry date of the share in the user's timezone (UTC) at 00:00.
|
||||
* If $expireDate is not supplied or set to `null`, the system default will be used.
|
||||
* @param string $note Note for the share
|
||||
* @param string $label Label for the share (only used in link and email)
|
||||
* @param string|null $attributes Additional attributes for the share
|
||||
|
|
@ -571,7 +572,7 @@ class ShareAPIController extends OCSController {
|
|||
string $publicUpload = 'false',
|
||||
string $password = '',
|
||||
?string $sendPasswordByTalk = null,
|
||||
string $expireDate = '',
|
||||
?string $expireDate = null,
|
||||
string $note = '',
|
||||
string $label = '',
|
||||
?string $attributes = null
|
||||
|
|
@ -646,12 +647,18 @@ class ShareAPIController extends OCSController {
|
|||
}
|
||||
|
||||
//Expire date
|
||||
if ($expireDate !== '') {
|
||||
try {
|
||||
$expireDateTime = $this->parseDate($expireDate);
|
||||
$share->setExpirationDate($expireDateTime);
|
||||
} catch (\Exception $e) {
|
||||
throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD'));
|
||||
if ($expireDate !== null) {
|
||||
if ($expireDate !== '') {
|
||||
try {
|
||||
$expireDateTime = $this->parseDate($expireDate);
|
||||
$share->setExpirationDate($expireDateTime);
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1781,10 +1781,10 @@
|
|||
{
|
||||
"name": "expireDate",
|
||||
"in": "query",
|
||||
"description": "Expiry date of the share using user timezone at 00:00. It means date in UTC timezone will be used.",
|
||||
"description": "The expiry date of the share in the user's timezone (UTC) at 00:00. If $expireDate is not supplied or set to `null`, the system default will be used.",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -348,26 +348,6 @@ class Manager implements IManager {
|
|||
|
||||
$expirationDate = $share->getExpirationDate();
|
||||
|
||||
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) {
|
||||
$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 ($isRemote) {
|
||||
$defaultExpireDate = $this->shareApiRemoteDefaultExpireDate();
|
||||
$defaultExpireDays = $this->shareApiRemoteDefaultExpireDays();
|
||||
|
|
@ -379,28 +359,53 @@ class Manager implements IManager {
|
|||
$configProp = 'internal_defaultExpDays';
|
||||
$isEnforced = $this->shareApiInternalDefaultExpireDateEnforced();
|
||||
}
|
||||
if ($fullId === null && $expirationDate === null && $defaultExpireDate) {
|
||||
$expirationDate = new \DateTime('now', $this->dateTimeZone->getTimeZone());
|
||||
$expirationDate->setTime(0, 0, 0);
|
||||
$days = (int)$this->config->getAppValue('core', $configProp, (string)$defaultExpireDays);
|
||||
if ($days > $defaultExpireDays) {
|
||||
$days = $defaultExpireDays;
|
||||
}
|
||||
$expirationDate->add(new \DateInterval('P' . $days . 'D'));
|
||||
}
|
||||
|
||||
// If we enforce the expiration date check that is does not exceed
|
||||
if ($isEnforced) {
|
||||
if ($expirationDate === null) {
|
||||
throw new \InvalidArgumentException('Expiration date is enforced');
|
||||
// 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 ($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) {
|
||||
$message = $this->l->t('Expiration date is in the past');
|
||||
throw new GenericShareException($message, $message, 404);
|
||||
}
|
||||
}
|
||||
|
||||
$date = new \DateTime('now', $this->dateTimeZone->getTimeZone());
|
||||
$date->setTime(0, 0, 0);
|
||||
$date->add(new \DateInterval('P' . $defaultExpireDays . 'D'));
|
||||
if ($date < $expirationDate) {
|
||||
$message = $this->l->n('Cannot set expiration date more than %n day in the future', 'Cannot set expiration date more than %n days in the future', $defaultExpireDays);
|
||||
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 && $defaultExpireDate) {
|
||||
$expirationDate = new \DateTime('now', $this->dateTimeZone->getTimeZone());
|
||||
$expirationDate->setTime(0, 0, 0);
|
||||
$days = (int)$this->config->getAppValue('core', $configProp, (string)$defaultExpireDays);
|
||||
if ($days > $defaultExpireDays) {
|
||||
$days = $defaultExpireDays;
|
||||
}
|
||||
$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' . $defaultExpireDays . 'D'));
|
||||
if ($date < $expirationDate) {
|
||||
$message = $this->l->n('Cannot set expiration date more than %n day in the future', 'Cannot set expiration date more than %n days in the future', $defaultExpireDays);
|
||||
throw new GenericShareException($message, $message, 404);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -433,51 +438,57 @@ class Manager implements IManager {
|
|||
*/
|
||||
protected function validateExpirationDateLink(IShare $share) {
|
||||
$expirationDate = $share->getExpirationDate();
|
||||
$isEnforced = $this->shareApiLinkDefaultExpireDateEnforced();
|
||||
|
||||
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) {
|
||||
$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->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 ($this->shareApiLinkDefaultExpireDateEnforced()) {
|
||||
if ($expirationDate === null) {
|
||||
throw new \InvalidArgumentException('Expiration date is enforced');
|
||||
// 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 ($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) {
|
||||
$message = $this->l->t('Expiration date is in the past');
|
||||
throw new GenericShareException($message, $message, 404);
|
||||
}
|
||||
}
|
||||
|
||||
$date = new \DateTime('now', $this->dateTimeZone->getTimeZone());
|
||||
$date->setTime(0, 0, 0);
|
||||
$date->add(new \DateInterval('P' . $this->shareApiLinkDefaultExpireDays() . 'D'));
|
||||
if ($date < $expirationDate) {
|
||||
$message = $this->l->n('Cannot set expiration date more than %n day in the future', 'Cannot set expiration date more than %n days in the future', $this->shareApiLinkDefaultExpireDays());
|
||||
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->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'));
|
||||
if ($date < $expirationDate) {
|
||||
$message = $this->l->n('Cannot set expiration date more than %n day in the future', 'Cannot set expiration date more than %n days in the future', $this->shareApiLinkDefaultExpireDays());
|
||||
throw new GenericShareException($message, $message, 404);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$accepted = true;
|
||||
|
|
|
|||
|
|
@ -90,13 +90,13 @@ class Share implements IShare {
|
|||
private $mailSend;
|
||||
/** @var string */
|
||||
private $label = '';
|
||||
|
||||
/** @var ICacheEntry|null */
|
||||
private $nodeCacheEntry;
|
||||
|
||||
/** @var bool */
|
||||
private $hideDownload = false;
|
||||
|
||||
private bool $noExpirationDate = false;
|
||||
|
||||
public function __construct(
|
||||
private IRootFolder $rootFolder,
|
||||
private IUserManager $userManager,
|
||||
|
|
@ -421,6 +421,21 @@ class Share implements IShare {
|
|||
return $this->expireDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function setNoExpirationDate(bool $noExpirationDate) {
|
||||
$this->noExpirationDate = $noExpirationDate;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function getNoExpirationDate(): bool {
|
||||
return $this->noExpirationDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -385,20 +385,38 @@ interface IShare {
|
|||
/**
|
||||
* Set the expiration date
|
||||
*
|
||||
* @param null|\DateTime $expireDate
|
||||
* @param \DateTime|null $expireDate
|
||||
* @return \OCP\Share\IShare The modified object
|
||||
* @since 9.0.0
|
||||
*/
|
||||
public function setExpirationDate($expireDate);
|
||||
public function setExpirationDate(\DateTime|null $expireDate);
|
||||
|
||||
/**
|
||||
* Get the expiration date
|
||||
*
|
||||
* @return null|\DateTime
|
||||
* @return \DateTime|null
|
||||
* @since 9.0.0
|
||||
*/
|
||||
public function getExpirationDate();
|
||||
|
||||
/**
|
||||
* Set overwrite flag for falsy expiry date vavlues
|
||||
*
|
||||
* @param bool $noExpirationDate
|
||||
* @return \OCP\Share\IShare The modified object
|
||||
* @since 30.0.0
|
||||
*/
|
||||
public function setNoExpirationDate(bool $noExpirationDate);
|
||||
|
||||
|
||||
/**
|
||||
* Get value of overwrite falsy expiry date flag
|
||||
*
|
||||
* @return bool
|
||||
* @since 30.0.0
|
||||
*/
|
||||
public function getNoExpirationDate();
|
||||
|
||||
/**
|
||||
* Is the share expired ?
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in a new issue