diff --git a/apps/files_sharing/api/local.php b/apps/files_sharing/api/local.php index eeb31899830118cc15999838394b6b9aea82bdf0..87025998b3dbdcd44194f567a8faee0169824c16 100644 --- a/apps/files_sharing/api/local.php +++ b/apps/files_sharing/api/local.php @@ -292,7 +292,7 @@ class Local { try { $expirationDate = isset($_POST['expireDate']) ? self::parseDate($_POST['expireDate']) : null; } catch (\Exception $e) { - return new \OC_OCS_Result(null, 404, 'Invalid Date'); + return new \OC_OCS_Result(null, 404, 'Invalid Date. Format must be YYYY-MM-DD.'); } break; @@ -315,7 +315,11 @@ class Local { $expirationDate ); } catch (HintException $e) { - return new \OC_OCS_Result(null, 400, $e->getHint()); + if ($e->getCode() === 0) { + return new \OC_OCS_Result(null, 400, $e->getHint()); + } else { + return new \OC_OCS_Result(null, $e->getCode(), $e->getHint()); + } } catch (\Exception $e) { return new \OC_OCS_Result(null, 403, $e->getMessage()); } @@ -559,13 +563,13 @@ class Local { */ private static function parseDate($expireDate) { if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $expireDate) === 0) { - throw new \Exception(); + throw new \Exception('Invalid date. Format must be YYYY-MM-DD'); } $date = new \DateTime($expireDate); if ($date === false) { - throw new \Exception(); + throw new \Exception('Invalid date. Format must be YYYY-MM-DD'); } return $date; diff --git a/apps/files_sharing/tests/api.php b/apps/files_sharing/tests/api.php index a9b6ee9f64e78045d7bfe5755dba333df5134778..d0ee71cec5a28334d6fa688b1edae72fd67a054b 100644 --- a/apps/files_sharing/tests/api.php +++ b/apps/files_sharing/tests/api.php @@ -1518,7 +1518,7 @@ class Test_Files_Sharing_Api extends TestCase { if ($valid === false) { $this->assertFalse($result->succeeded()); $this->assertEquals(404, $result->getStatusCode()); - $this->assertEquals('Invalid Date', $result->getMeta()['message']); + $this->assertEquals('Invalid Date. Format must be YYYY-MM-DD.', $result->getMeta()['message']); return; } @@ -1543,4 +1543,90 @@ class Test_Files_Sharing_Api extends TestCase { $fileinfo = $this->view->getFileInfo($this->folder); \OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_LINK, null); } + + public function testCreatePublicLinkExpireDateValid() { + $config = \OC::$server->getConfig(); + + // enforce expire date, by default 7 days after the file was shared + $config->setAppValue('core', 'shareapi_default_expire_date', 'yes'); + $config->setAppValue('core', 'shareapi_enforce_expire_date', 'yes'); + + $date = new \DateTime(); + $date->add(new \DateInterval('P5D')); + + $_POST['path'] = $this->folder; + $_POST['shareType'] = \OCP\Share::SHARE_TYPE_LINK; + $_POST['expireDate'] = $date->format('Y-m-d'); + + $result = \OCA\Files_Sharing\API\Local::createShare([]); + + $this->assertTrue($result->succeeded()); + + $data = $result->getData(); + $this->assertTrue(is_string($data['token'])); + + // check for correct link + $url = \OC::$server->getURLGenerator()->getAbsoluteURL('/index.php/s/' . $data['token']); + $this->assertEquals($url, $data['url']); + + + $share = $this->getShareFromId($data['id']); + $items = \OCP\Share::getItemShared('file', $share['item_source']); + $this->assertTrue(!empty($items)); + + $item = reset($items); + $this->assertTrue(is_array($item)); + $this->assertEquals($date->format('Y-m-d'), substr($item['expiration'], 0, 10)); + + $fileinfo = $this->view->getFileInfo($this->folder); + \OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_LINK, null); + + $config->setAppValue('core', 'shareapi_default_expire_date', 'no'); + $config->setAppValue('core', 'shareapi_enforce_expire_date', 'no'); + } + + public function testCreatePublicLinkExpireDateInvalidFuture() { + $config = \OC::$server->getConfig(); + + // enforce expire date, by default 7 days after the file was shared + $config->setAppValue('core', 'shareapi_default_expire_date', 'yes'); + $config->setAppValue('core', 'shareapi_enforce_expire_date', 'yes'); + + $date = new \DateTime(); + $date->add(new \DateInterval('P8D')); + + $_POST['path'] = $this->folder; + $_POST['shareType'] = \OCP\Share::SHARE_TYPE_LINK; + $_POST['expireDate'] = $date->format('Y-m-d'); + + $result = \OCA\Files_Sharing\API\Local::createShare([]); + + $this->assertFalse($result->succeeded()); + $this->assertEquals(404, $result->getStatusCode()); + $this->assertEquals('Cannot set expiration date. Shares cannot expire later than 7 after they have been shared', $result->getMeta()['message']); + + $config->setAppValue('core', 'shareapi_default_expire_date', 'no'); + $config->setAppValue('core', 'shareapi_enforce_expire_date', 'no'); + } + + public function testCreatePublicLinkExpireDateInvalidPast() { + $config = \OC::$server->getConfig(); + + $date = new \DateTime(); + $date->sub(new \DateInterval('P8D')); + + $_POST['path'] = $this->folder; + $_POST['shareType'] = \OCP\Share::SHARE_TYPE_LINK; + $_POST['expireDate'] = $date->format('Y-m-d'); + + $result = \OCA\Files_Sharing\API\Local::createShare([]); + + $this->assertFalse($result->succeeded()); + $this->assertEquals(404, $result->getStatusCode()); + $this->assertEquals('Cannot set expiration date. Expiration date is in the past', $result->getMeta()['message']); + + $config->setAppValue('core', 'shareapi_default_expire_date', 'no'); + $config->setAppValue('core', 'shareapi_enforce_expire_date', 'no'); + } + } diff --git a/lib/private/share/share.php b/lib/private/share/share.php index 9aea4677b5b0738002acabc0ade6bbdeab4ec003..7b052483ac3df78435c330d6b130a4cf38e9e5c1 100644 --- a/lib/private/share/share.php +++ b/lib/private/share/share.php @@ -649,6 +649,21 @@ class Share extends Constants { $permissions = (int)$permissions & ~\OCP\Constants::PERMISSION_DELETE; } + //Validate expirationDate + if ($expirationDate !== null) { + try { + /* + * Reuse the validateExpireDate. + * We have to pass time() since the second arg is the time + * the file was shared, since it is not shared yet we just use + * the current time. + */ + $expirationDate = self::validateExpireDate($expirationDate->format('Y-m-d'), time(), $itemType, $itemSource); + } catch (\Exception $e) { + throw new \OC\HintException($e->getMessage(), $e->getMessage(), 404); + } + } + // Verify share type and sharing conditions are met if ($shareType === self::SHARE_TYPE_USER) { if ($shareWith == $uidOwner) {