summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Schießle <schiessle@owncloud.com>2014-07-28 17:28:32 +0200
committerBjörn Schießle <schiessle@owncloud.com>2014-07-28 17:28:32 +0200
commitc53b56e3139e517af4bca2aca631f625f435f74e (patch)
treefaea592fb96f60e69036bb43e7ccba2d35a808f8
parent1fbbaed26149cd2261637e5a737b22089340345b (diff)
parentb7958f79c39b78304daa19ece96072acec50c2ba (diff)
downloadnextcloud-server-c53b56e3139e517af4bca2aca631f625f435f74e.tar.gz
nextcloud-server-c53b56e3139e517af4bca2aca631f625f435f74e.zip
Merge pull request #9798 from owncloud/ocs_share_api_add_expire_date
[share api] add OCS api call to set expire date for link shares
-rw-r--r--apps/files_sharing/lib/api.php29
-rw-r--r--apps/files_sharing/tests/api.php74
-rw-r--r--core/ajax/share.php16
-rw-r--r--lib/private/share/share.php59
-rwxr-xr-xlib/private/util.php19
-rw-r--r--lib/public/share.php5
-rw-r--r--lib/public/util.php9
-rw-r--r--tests/lib/share/share.php48
8 files changed, 225 insertions, 34 deletions
diff --git a/apps/files_sharing/lib/api.php b/apps/files_sharing/lib/api.php
index 50ba74f5beb..faf141db25f 100644
--- a/apps/files_sharing/lib/api.php
+++ b/apps/files_sharing/lib/api.php
@@ -339,6 +339,8 @@ class Api {
return self::updatePassword($share, $params);
} elseif (isset($params['_put']['publicUpload'])) {
return self::updatePublicUpload($share, $params);
+ } elseif (isset($params['_put']['expireDate'])) {
+ return self::updateExpireDate($share, $params);
}
} catch (\Exception $e) {
@@ -409,7 +411,7 @@ class Api {
if ($share['item_type'] !== 'folder' ||
(int)$share['share_type'] !== \OCP\Share::SHARE_TYPE_LINK ) {
- return new \OC_OCS_Result(null, 404, "public upload is only possible for public shared folders");
+ return new \OC_OCS_Result(null, 400, "public upload is only possible for public shared folders");
}
// read, create, update (7) if public upload is enabled or
@@ -421,6 +423,29 @@ class Api {
}
/**
+ * set expire date for public link share
+ * @param array $share information about the share
+ * @param array $params contains 'expireDate' which needs to be a well formated date string, e.g DD-MM-YYYY
+ * @return \OC_OCS_Result
+ */
+ private static function updateExpireDate($share, $params) {
+ // only public links can have a expire date
+ if ((int)$share['share_type'] !== \OCP\Share::SHARE_TYPE_LINK ) {
+ return new \OC_OCS_Result(null, 400, "expire date only exists for public link shares");
+ }
+
+ try {
+ $expireDateSet = \OCP\Share::setExpirationDate($share['item_type'], $share['item_source'], $params['_put']['expireDate'], (int)$share['stime']);
+ $result = ($expireDateSet) ? new \OC_OCS_Result() : new \OC_OCS_Result(null, 404, "couldn't set expire date");
+ } catch (\Exception $e) {
+ $result = new \OC_OCS_Result(null, 404, $e->getMessage());
+ }
+
+ return $result;
+
+ }
+
+ /**
* update password for public link share
* @param array $share information about the share
* @param array $params 'password'
@@ -555,7 +580,7 @@ class Api {
* @return array with: item_source, share_type, share_with, item_type, permissions
*/
private static function getShareFromId($shareID) {
- $sql = 'SELECT `file_source`, `item_source`, `share_type`, `share_with`, `item_type`, `permissions` FROM `*PREFIX*share` WHERE `id` = ?';
+ $sql = 'SELECT `file_source`, `item_source`, `share_type`, `share_with`, `item_type`, `permissions`, `stime` FROM `*PREFIX*share` WHERE `id` = ?';
$args = array($shareID);
$query = \OCP\DB::prepare($sql);
$result = $query->execute($args);
diff --git a/apps/files_sharing/tests/api.php b/apps/files_sharing/tests/api.php
index 72dd5816ea0..49571d4c3c2 100644
--- a/apps/files_sharing/tests/api.php
+++ b/apps/files_sharing/tests/api.php
@@ -940,6 +940,78 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base {
/**
* @medium
+ */
+ function testUpdateShareExpireDate() {
+
+ $fileInfo = $this->view->getFileInfo($this->folder);
+
+ // enforce expire date, by default 7 days after the file was shared
+ \OCP\Config::setAppValue('core', 'shareapi_default_expire_date', 'yes');
+ \OCP\Config::setAppValue('core', 'shareapi_enforce_expire_date', 'yes');
+
+ $dateWithinRange = new \DateTime();
+ $dateWithinRange->add(new \DateInterval('P5D'));
+ $dateOutOfRange = new \DateTime();
+ $dateOutOfRange->add(new \DateInterval('P8D'));
+
+ $result = \OCP\Share::shareItem('folder', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_LINK,
+ null, 1);
+
+ // share was successful?
+ $this->assertTrue(is_string($result));
+
+ $items = \OCP\Share::getItemShared('file', null);
+
+ // make sure that we found a link share
+ $this->assertEquals(1, count($items));
+
+ $linkShare = reset($items);
+
+ // update expire date to a valid value
+ $params = array();
+ $params['id'] = $linkShare['id'];
+ $params['_put'] = array();
+ $params['_put']['expireDate'] = $dateWithinRange->format('Y-m-d');
+
+ $result = Share\Api::updateShare($params);
+
+ $this->assertTrue($result->succeeded());
+
+ $items = \OCP\Share::getItemShared('file', $linkShare['file_source']);
+
+ $updatedLinkShare = reset($items);
+
+ // date should be changed
+ $this->assertTrue(is_array($updatedLinkShare));
+ $this->assertEquals($dateWithinRange->format('Y-m-d') . ' 00:00:00', $updatedLinkShare['expiration']);
+
+ // update expire date to a value out of range
+ $params = array();
+ $params['id'] = $linkShare['id'];
+ $params['_put'] = array();
+ $params['_put']['expireDate'] = $dateOutOfRange->format('Y-m-d');
+
+ $result = Share\Api::updateShare($params);
+
+ $this->assertFalse($result->succeeded());
+
+ $items = \OCP\Share::getItemShared('file', $linkShare['file_source']);
+
+ $updatedLinkShare = reset($items);
+
+ // date shouldn't be changed
+ $this->assertTrue(is_array($updatedLinkShare));
+ $this->assertEquals($dateWithinRange->format('Y-m-d') . ' 00:00:00', $updatedLinkShare['expiration']);
+
+ // cleanup
+ \OCP\Config::setAppValue('core', 'shareapi_default_expire_date', 'no');
+ \OCP\Config::setAppValue('core', 'shareapi_enforce_expire_date', 'no');
+ \OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_LINK, null);
+
+ }
+
+ /**
+ * @medium
* @depends testCreateShare
*/
function testDeleteShare() {
@@ -1158,7 +1230,7 @@ class Test_Files_Sharing_Api extends Test_Files_Sharing_Base {
$result = \OCP\Share::shareItem('file', $info->getId(), \OCP\Share::SHARE_TYPE_USER, \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, 31);
$this->assertTrue($result);
- $result = \OCP\Share::setExpirationDate('file', $info->getId() , $expireDate);
+ $result = \OCP\Share::setExpirationDate('file', $info->getId() , $expireDate, $now);
$this->assertTrue($result);
//manipulate stime so that both shares are older then the default expire date
diff --git a/core/ajax/share.php b/core/ajax/share.php
index be72e36541a..4b5a6cd664f 100644
--- a/core/ajax/share.php
+++ b/core/ajax/share.php
@@ -80,18 +80,12 @@ if (isset($_POST['action']) && isset($_POST['itemType']) && isset($_POST['itemSo
break;
case 'setExpirationDate':
if (isset($_POST['date'])) {
- $l = OC_L10N::get('core');
- $date = new \DateTime($_POST['date']);
- $today = new \DateTime('now');
-
-
-
- if ($date < $today) {
- OC_JSON::error(array('data' => array('message' => $l->t('Expiration date is in the past.'))));
- return;
+ try {
+ $return = OCP\Share::setExpirationDate($_POST['itemType'], $_POST['itemSource'], $_POST['date']);
+ ($return) ? OC_JSON::success() : OC_JSON::error();
+ } catch (\Exception $e) {
+ OC_JSON::error(array('data' => array('message' => $e->getMessage())));
}
- $return = OCP\Share::setExpirationDate($_POST['itemType'], $_POST['itemSource'], $_POST['date']);
- ($return) ? OC_JSON::success() : OC_JSON::error();
}
break;
case 'informRecipients':
diff --git a/lib/private/share/share.php b/lib/private/share/share.php
index 673c0dc383a..af286e7154e 100644
--- a/lib/private/share/share.php
+++ b/lib/private/share/share.php
@@ -925,19 +925,69 @@ class Share extends \OC\Share\Constants {
}
/**
+ * validate expire date if it meets all constraints
+ *
+ * @param string $expireDate well formate date string, e.g. "DD-MM-YYYY"
+ * @param string $shareTime timestamp when the file was shared
+ * @param string $itemType
+ * @param string $itemSource
+ * @return DateTime validated date
+ * @throws \Exception
+ */
+ private static function validateExpireDate($expireDate, $shareTime, $itemType, $itemSource) {
+ $l = \OC_L10N::get('lib');
+ $date = new \DateTime($expireDate);
+ $today = new \DateTime('now');
+
+ // if the user doesn't provide a share time we need to get it from the database
+ // fall-back mode to keep API stable, because the $shareTime parameter was added later
+ $defaultExpireDateEnforced = \OCP\Util::isDefaultExpireDateEnforced();
+ if ($defaultExpireDateEnforced && $shareTime === null) {
+ $items = self::getItemShared($itemType, $itemSource);
+ $firstItem = reset($items);
+ $shareTime = (int)$firstItem['stime'];
+ }
+
+ if ($defaultExpireDateEnforced) {
+ // initialize max date with share time
+ $maxDate = new \DateTime();
+ $maxDate->setTimestamp($shareTime);
+ $maxDays = \OCP\Config::getAppValue('core', 'shareapi_expire_after_n_days', '7');
+ $maxDate->add(new \DateInterval('P' . $maxDays . 'D'));
+ if ($date > $maxDate) {
+ $warning = 'Can not set expire date. Shares can not expire later then ' . $maxDays . ' after they where shared';
+ $warning_t = $l->t('Can not set expire date. Shares can not expire later then %s after they where shared', array($maxDays));
+ \OCP\Util::writeLog('OCP\Share', $warning, \OCP\Util::WARN);
+ throw new \Exception($warning_t);
+ }
+ }
+
+ if ($date < $today) {
+ $message = 'Can not set expire date. Expire date is in the past';
+ $message_t = $l->t('Can not set expire date. Expire date is in the past');
+ \OCP\Util::writeLog('OCP\Share', $message, \OCP\Util::WARN);
+ throw new \Exception($message_t);
+ }
+
+ return $date;
+ }
+
+ /**
* Set expiration date for a share
* @param string $itemType
* @param string $itemSource
* @param string $date expiration date
+ * @param int $shareTime timestamp from when the file was shared
+ * @throws \Exception
* @return boolean
*/
- public static function setExpirationDate($itemType, $itemSource, $date) {
+ public static function setExpirationDate($itemType, $itemSource, $date, $shareTime = null) {
$user = \OC_User::getUser();
if ($date == '') {
$date = null;
} else {
- $date = new \DateTime($date);
+ $date = self::validateExpireDate($date, $shareTime, $itemType, $itemSource);
}
$query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `expiration` = ? WHERE `item_type` = ? AND `item_source` = ? AND `uid_owner` = ? AND `share_type` = ?');
$query->bindValue(1, $date, 'datetime');
@@ -954,11 +1004,10 @@ class Share extends \OC\Share\Constants {
'date' => $date,
'uidOwner' => $user
));
-
+
return true;
+ }
- }
-
/**
* Checks whether a share has expired, calls unshareItem() if yes.
* @param array $item Share data (usually database row)
diff --git a/lib/private/util.php b/lib/private/util.php
index 67da7a2f63f..896b076afa6 100755
--- a/lib/private/util.php
+++ b/lib/private/util.php
@@ -22,7 +22,7 @@ class OC_Util {
self::$rootMounted = true;
}
}
-
+
/**
* mounting an object storage as the root fs will in essence remove the
* necessity of a data folder being present.
@@ -50,7 +50,7 @@ class OC_Util {
self::$rootMounted = true;
}
}
-
+
/**
* Can be set up
* @param string $user
@@ -171,6 +171,21 @@ class OC_Util {
}
/**
+ * check if share API enforces a default expire date
+ * @return boolean
+ */
+ public static function isDefaultExpireDateEnforced() {
+ $isDefaultExpireDateEnabled = \OCP\Config::getAppValue('core', 'shareapi_default_expire_date', 'no');
+ $enforceDefaultExpireDate = false;
+ if ($isDefaultExpireDateEnabled === 'yes') {
+ $value = \OCP\Config::getAppValue('core', 'shareapi_enforce_expire_date', 'no');
+ $enforceDefaultExpireDate = ($value === 'yes') ? true : false;
+ }
+
+ return $enforceDefaultExpireDate;
+ }
+
+ /**
* Get the quota of a user
* @param string $user
* @return int Quota bytes
diff --git a/lib/public/share.php b/lib/public/share.php
index 8566a38c61e..c0939dce53f 100644
--- a/lib/public/share.php
+++ b/lib/public/share.php
@@ -298,10 +298,11 @@ class Share extends \OC\Share\Constants {
* @param string $itemType
* @param string $itemSource
* @param string $date expiration date
+ * @param int $shareTime timestamp from when the file was shared
* @return boolean
*/
- public static function setExpirationDate($itemType, $itemSource, $date) {
- return \OC\Share\Share::setExpirationDate($itemType, $itemSource, $date);
+ public static function setExpirationDate($itemType, $itemSource, $date, $shareTime = null) {
+ return \OC\Share\Share::setExpirationDate($itemType, $itemSource, $date, $shareTime);
}
/**
diff --git a/lib/public/util.php b/lib/public/util.php
index ff8c743c0df..87b7a4f19db 100644
--- a/lib/public/util.php
+++ b/lib/public/util.php
@@ -519,6 +519,15 @@ class Util {
}
/**
+ * check if share API enforces a default expire date
+ * @return boolean
+ */
+ public static function isDefaultExpireDateEnforced() {
+ return \OC_Util::isDefaultExpireDateEnforced();
+ }
+
+
+ /**
* Checks whether the current version needs upgrade.
*
* @return bool true if upgrade is needed, false otherwise
diff --git a/tests/lib/share/share.php b/tests/lib/share/share.php
index 5920b44a8e0..0e3dfe8291d 100644
--- a/tests/lib/share/share.php
+++ b/tests/lib/share/share.php
@@ -326,10 +326,14 @@ class Test_Share extends PHPUnit_Framework_TestCase {
$this->shareUserOneTestFileWithUserTwo();
$this->shareUserTestFileAsLink();
- $this->assertTrue(
- OCP\Share::setExpirationDate('test', 'test.txt', $this->dateInPast),
- 'Failed asserting that user 1 successfully set an expiration date for the test.txt share.'
- );
+ // manipulate share table and set expire date to the past
+ $query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `expiration` = ? WHERE `item_type` = ? AND `item_source` = ? AND `uid_owner` = ? AND `share_type` = ?');
+ $query->bindValue(1, new \DateTime($this->dateInPast), 'datetime');
+ $query->bindValue(2, 'test');
+ $query->bindValue(3, 'test.txt');
+ $query->bindValue(4, $this->user1);
+ $query->bindValue(5, \OCP\Share::SHARE_TYPE_LINK);
+ $query->execute();
$shares = OCP\Share::getItemsShared('test');
$this->assertSame(1, count($shares));
@@ -337,6 +341,24 @@ class Test_Share extends PHPUnit_Framework_TestCase {
$this->assertSame(\OCP\Share::SHARE_TYPE_USER, $share['share_type']);
}
+ public function testSetExpireDateInPast() {
+ OC_User::setUserId($this->user1);
+ $this->shareUserOneTestFileWithUserTwo();
+ $this->shareUserTestFileAsLink();
+
+ $setExpireDateFailed = false;
+ try {
+ $this->assertTrue(
+ OCP\Share::setExpirationDate('test', 'test.txt', $this->dateInPast, ''),
+ 'Failed asserting that user 1 successfully set an expiration date for the test.txt share.'
+ );
+ } catch (\Exception $e) {
+ $setExpireDateFailed = true;
+ }
+
+ $this->assertTrue($setExpireDateFailed);
+ }
+
public function testShareWithUserExpirationValid() {
OC_User::setUserId($this->user1);
$this->shareUserOneTestFileWithUserTwo();
@@ -344,7 +366,7 @@ class Test_Share extends PHPUnit_Framework_TestCase {
$this->assertTrue(
- OCP\Share::setExpirationDate('test', 'test.txt', $this->dateInFuture),
+ OCP\Share::setExpirationDate('test', 'test.txt', $this->dateInFuture, ''),
'Failed asserting that user 1 successfully set an expiration date for the test.txt share.'
);
@@ -552,7 +574,7 @@ class Test_Share extends PHPUnit_Framework_TestCase {
// testGetShareByTokenExpirationValid
$this->assertTrue(
- OCP\Share::setExpirationDate('test', 'test.txt', $this->dateInFuture),
+ OCP\Share::setExpirationDate('test', 'test.txt', $this->dateInFuture, ''),
'Failed asserting that user 1 successfully set a future expiration date for the test.txt share.'
);
$row = $this->getShareByValidToken($token);
@@ -561,11 +583,15 @@ class Test_Share extends PHPUnit_Framework_TestCase {
'Failed asserting that the returned row has an expiration date.'
);
- // testGetShareByTokenExpirationExpired
- $this->assertTrue(
- OCP\Share::setExpirationDate('test', 'test.txt', $this->dateInPast),
- 'Failed asserting that user 1 successfully set a past expiration date for the test.txt share.'
- );
+ // manipulate share table and set expire date to the past
+ $query = \OC_DB::prepare('UPDATE `*PREFIX*share` SET `expiration` = ? WHERE `item_type` = ? AND `item_source` = ? AND `uid_owner` = ? AND `share_type` = ?');
+ $query->bindValue(1, new \DateTime($this->dateInPast), 'datetime');
+ $query->bindValue(2, 'test');
+ $query->bindValue(3, 'test.txt');
+ $query->bindValue(4, $this->user1);
+ $query->bindValue(5, \OCP\Share::SHARE_TYPE_LINK);
+ $query->execute();
+
$this->assertFalse(
OCP\Share::getShareByToken($token),
'Failed asserting that an expired share could not be found.'