add OCS api call to set expire date for link shares

This commit is contained in:
Bjoern Schiessle 2014-07-23 16:42:33 +02:00
parent 9834e38542
commit ecc1f92bb6
8 changed files with 225 additions and 34 deletions

View File

@ -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) {
@ -420,6 +422,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, 404, "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
@ -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);

View File

@ -938,6 +938,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
@ -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

View File

@ -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':

View File

@ -924,20 +924,70 @@ class Share extends \OC\Share\Constants {
throw new \Exception($message_t);
}
/**
* 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;
}
return true;
}
/**
* Checks whether a share has expired, calls unshareItem() if yes.
* @param array $item Share data (usually database row)

View File

@ -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
@ -170,6 +170,21 @@ class OC_Util {
return false;
}
/**
* 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

View File

@ -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);
}
/**

View File

@ -518,6 +518,15 @@ class Util {
return \OC_Util::isPublicLinkPasswordRequired();
}
/**
* 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.
*

View File

@ -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.'