Merge pull request #22028 from owncloud/share_hook_expirationdate

Share hook expirationdate
This commit is contained in:
Thomas Müller 2016-02-01 14:13:54 +01:00
commit 84d9704121
2 changed files with 134 additions and 28 deletions

View File

@ -217,7 +217,9 @@ class Manager implements IManager {
* @return \DateTime|null The expiration date or null if $expireDate was null and it is not required * @return \DateTime|null The expiration date or null if $expireDate was null and it is not required
* @throws \OC\HintException * @throws \OC\HintException
*/ */
protected function validateExpirationDate($expirationDate) { protected function validateExpirationDate(\OCP\Share\IShare $share) {
$expirationDate = $share->getExpirationDate();
if ($expirationDate !== null) { if ($expirationDate !== null) {
//Make sure the expiration date is a date //Make sure the expiration date is a date
@ -244,18 +246,30 @@ class Manager implements IManager {
$message = $this->l->t('Cannot set expiration date more than %s days in the future', [$this->shareApiLinkDefaultExpireDays()]); $message = $this->l->t('Cannot set expiration date more than %s days in the future', [$this->shareApiLinkDefaultExpireDays()]);
throw new \OC\HintException($message, $message, 404); throw new \OC\HintException($message, $message, 404);
} }
return $expirationDate;
} }
// If expiredate is empty set a default one if there is a default // If expiredate is empty set a default one if there is a default
if ($expirationDate === null && $this->shareApiLinkDefaultExpireDate()) { if ($expirationDate === null && $this->shareApiLinkDefaultExpireDate()) {
$date = new \DateTime(); $expirationDate = new \DateTime();
$date->setTime(0,0,0); $expirationDate->setTime(0,0,0);
$date->add(new \DateInterval('P'.$this->shareApiLinkDefaultExpireDays().'D')); $expirationDate->add(new \DateInterval('P'.$this->shareApiLinkDefaultExpireDays().'D'));
return $date;
} }
$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 $expirationDate; return $expirationDate;
} }
@ -436,7 +450,7 @@ class Manager implements IManager {
); );
//Verify the expiration date //Verify the expiration date
$share->setExpirationDate($this->validateExpirationDate($share->getExpirationDate())); $this->validateExpirationDate($share);
//Verify the password //Verify the password
$this->verifyPassword($share->getPassword()); $this->verifyPassword($share->getPassword());
@ -573,7 +587,7 @@ class Manager implements IManager {
if ($share->getExpirationDate() !== $originalShare->getExpirationDate()) { if ($share->getExpirationDate() !== $originalShare->getExpirationDate()) {
//Verify the expiration date //Verify the expiration date
$share->setExpirationDate($this->validateExpirationDate($share->getExpirationDate())); $this->validateExpirationDate($share);
$expirationDateUpdated = true; $expirationDateUpdated = true;
} }
} }

View File

@ -607,7 +607,10 @@ class ManagerTest extends \Test\TestCase {
$past = new \DateTime(); $past = new \DateTime();
$past->sub(new \DateInterval('P1D')); $past->sub(new \DateInterval('P1D'));
$this->invokePrivate($this->manager, 'validateExpirationDate', [$past]); $share = $this->manager->newShare();
$share->setExpirationDate($past);
$this->invokePrivate($this->manager, 'validateExpirationDate', [$share]);
} }
/** /**
@ -615,12 +618,14 @@ class ManagerTest extends \Test\TestCase {
* @expectedExceptionMessage Expiration date is enforced * @expectedExceptionMessage Expiration date is enforced
*/ */
public function testvalidateExpirationDateEnforceButNotSet() { public function testvalidateExpirationDateEnforceButNotSet() {
$share = $this->manager->newShare();
$this->config->method('getAppValue') $this->config->method('getAppValue')
->will($this->returnValueMap([ ->will($this->returnValueMap([
['core', 'shareapi_enforce_expire_date', 'no', 'yes'], ['core', 'shareapi_enforce_expire_date', 'no', 'yes'],
])); ]));
$this->invokePrivate($this->manager, 'validateExpirationDate', [null]); $this->invokePrivate($this->manager, 'validateExpirationDate', [$share]);
} }
public function testvalidateExpirationDateEnforceToFarIntoFuture() { public function testvalidateExpirationDateEnforceToFarIntoFuture() {
@ -628,6 +633,9 @@ class ManagerTest extends \Test\TestCase {
$future = new \DateTime(); $future = new \DateTime();
$future->add(new \DateInterval('P7D')); $future->add(new \DateInterval('P7D'));
$share = $this->manager->newShare();
$share->setExpirationDate($future);
$this->config->method('getAppValue') $this->config->method('getAppValue')
->will($this->returnValueMap([ ->will($this->returnValueMap([
['core', 'shareapi_enforce_expire_date', 'no', 'yes'], ['core', 'shareapi_enforce_expire_date', 'no', 'yes'],
@ -635,7 +643,7 @@ class ManagerTest extends \Test\TestCase {
])); ]));
try { try {
$this->invokePrivate($this->manager, 'validateExpirationDate', [$future]); $this->invokePrivate($this->manager, 'validateExpirationDate', [$share]);
} catch (\OC\HintException $e) { } catch (\OC\HintException $e) {
$this->assertEquals('Cannot set expiration date more than 3 days in the future', $e->getMessage()); $this->assertEquals('Cannot set expiration date more than 3 days in the future', $e->getMessage());
$this->assertEquals('Cannot set expiration date more than 3 days in the future', $e->getHint()); $this->assertEquals('Cannot set expiration date more than 3 days in the future', $e->getHint());
@ -648,31 +656,61 @@ class ManagerTest extends \Test\TestCase {
$future = new \DateTime(); $future = new \DateTime();
$future->add(new \DateInterval('P2D')); $future->add(new \DateInterval('P2D'));
$future->setTime(0,0,0); $future->setTime(0,0,0);
$expected = $future->format(\DateTime::ISO8601);
$expected = clone $future;
$future->setTime(1,2,3); $future->setTime(1,2,3);
$share = $this->manager->newShare();
$share->setExpirationDate($future);
$this->config->method('getAppValue') $this->config->method('getAppValue')
->will($this->returnValueMap([ ->will($this->returnValueMap([
['core', 'shareapi_enforce_expire_date', 'no', 'yes'], ['core', 'shareapi_enforce_expire_date', 'no', 'yes'],
['core', 'shareapi_expire_after_n_days', '7', '3'], ['core', 'shareapi_expire_after_n_days', '7', '3'],
])); ]));
$future = $this->invokePrivate($this->manager, 'validateExpirationDate', [$future]); $hookListner = $this->getMockBuilder('Dummy')->setMethods(['listener'])->getMock();
\OCP\Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListner, 'listener');
$hookListner->expects($this->once())->method('listener')->with($this->callback(function ($data) use ($future) {
return $data['expirationDate'] == $future;
}));
$this->assertEquals($expected, $future->format(\DateTime::ISO8601)); $future = $this->invokePrivate($this->manager, 'validateExpirationDate', [$share]);
$this->assertEquals($expected, $future);
} }
public function testvalidateExpirationDateNoDateNoDefaultNull() { public function testvalidateExpirationDateNoDateNoDefaultNull() {
$date = new \DateTime(); $date = new \DateTime();
$date->add(new \DateInterval('P5D')); $date->add(new \DateInterval('P5D'));
$res = $this->invokePrivate($this->manager, 'validateExpirationDate', [$date]); $expected = clone $date;
$expected->setTime(0,0,0);
$this->assertEquals($date, $res); $share = $this->manager->newShare();
$share->setExpirationDate($date);
$hookListner = $this->getMockBuilder('Dummy')->setMethods(['listener'])->getMock();
\OCP\Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListner, 'listener');
$hookListner->expects($this->once())->method('listener')->with($this->callback(function ($data) use ($expected) {
return $data['expirationDate'] == $expected;
}));
$res = $this->invokePrivate($this->manager, 'validateExpirationDate', [$share]);
$this->assertEquals($expected, $res);
} }
public function testvalidateExpirationDateNoDateNoDefault() { public function testvalidateExpirationDateNoDateNoDefault() {
$date = $this->invokePrivate($this->manager, 'validateExpirationDate', [null]); $hookListner = $this->getMockBuilder('Dummy')->setMethods(['listener'])->getMock();
\OCP\Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListner, 'listener');
$hookListner->expects($this->once())->method('listener')->with($this->callback(function ($data) {
return $data['expirationDate'] === null;
}));
$share = $this->manager->newShare();
$date = $this->invokePrivate($this->manager, 'validateExpirationDate', [$share]);
$this->assertNull($date); $this->assertNull($date);
} }
@ -682,15 +720,70 @@ class ManagerTest extends \Test\TestCase {
$future->add(new \DateInterval('P3D')); $future->add(new \DateInterval('P3D'));
$future->setTime(0,0,0); $future->setTime(0,0,0);
$expected = clone $future;
$share = $this->manager->newShare();
$share->setExpirationDate($future);
$this->config->method('getAppValue') $this->config->method('getAppValue')
->will($this->returnValueMap([ ->will($this->returnValueMap([
['core', 'shareapi_default_expire_date', 'no', 'yes'], ['core', 'shareapi_default_expire_date', 'no', 'yes'],
['core', 'shareapi_expire_after_n_days', '7', '3'], ['core', 'shareapi_expire_after_n_days', '7', '3'],
])); ]));
$date = $this->invokePrivate($this->manager, 'validateExpirationDate', [null]); $hookListner = $this->getMockBuilder('Dummy')->setMethods(['listener'])->getMock();
\OCP\Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListner, 'listener');
$hookListner->expects($this->once())->method('listener')->with($this->callback(function ($data) use ($expected) {
return $data['expirationDate'] == $expected;
}));
$this->assertEquals($future->format(\DateTime::ISO8601), $date->format(\DateTime::ISO8601)); $this->invokePrivate($this->manager, 'validateExpirationDate', [$share]);
$this->assertEquals($expected, $share->getExpirationDate());
}
public function testValidateExpirationDateHookModification() {
$nextWeek = new \DateTime();
$nextWeek->add(new \DateInterval('P7D'));
$nextWeek->setTime(0,0,0);
$save = clone $nextWeek;
$hookListner = $this->getMockBuilder('Dummy')->setMethods(['listener'])->getMock();
\OCP\Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListner, 'listener');
$hookListner->expects($this->once())->method('listener')->will($this->returnCallback(function ($data) {
$data['expirationDate']->sub(new \DateInterval('P2D'));
}));
$share = $this->manager->newShare();
$share->setExpirationDate($nextWeek);
$this->invokePrivate($this->manager, 'validateExpirationDate', [$share]);
$save->sub(new \DateInterval('P2D'));
$this->assertEquals($save, $share->getExpirationDate());
}
/**
* @expectedException \Exception
* @expectedExceptionMessage Invalid date!
*/
public function testValidateExpirationDateHookException() {
$nextWeek = new \DateTime();
$nextWeek->add(new \DateInterval('P7D'));
$nextWeek->setTime(0,0,0);
$share = $this->manager->newShare();
$share->setExpirationDate($nextWeek);
$hookListner = $this->getMockBuilder('Dummy')->setMethods(['listener'])->getMock();
\OCP\Util::connectHook('\OC\Share', 'verifyExpirationDate', $hookListner, 'listener');
$hookListner->expects($this->once())->method('listener')->will($this->returnCallback(function ($data) {
$data['accepted'] = false;
$data['message'] = 'Invalid date!';
}));
$this->invokePrivate($this->manager, 'validateExpirationDate', [$share]);
} }
/** /**
@ -1332,7 +1425,7 @@ class ManagerTest extends \Test\TestCase {
$date = new \DateTime(); $date = new \DateTime();
$share = new \OC\Share20\Share(); $share = $this->manager->newShare();
$share->setShareType(\OCP\Share::SHARE_TYPE_LINK) $share->setShareType(\OCP\Share::SHARE_TYPE_LINK)
->setNode($path) ->setNode($path)
->setSharedBy($sharedBy) ->setSharedBy($sharedBy)
@ -1355,8 +1448,7 @@ class ManagerTest extends \Test\TestCase {
->with($path); ->with($path);
$manager->expects($this->once()) $manager->expects($this->once())
->method('validateExpirationDate') ->method('validateExpirationDate')
->with($date) ->with($share);
->will($this->returnArgument(0));
$manager->expects($this->once()) $manager->expects($this->once())
->method('verifyPassword') ->method('verifyPassword')
->with('password'); ->with('password');
@ -1761,14 +1853,10 @@ class ManagerTest extends \Test\TestCase {
$tomorrow->setTime(0,0,0); $tomorrow->setTime(0,0,0);
$tomorrow->add(new \DateInterval('P1D')); $tomorrow->add(new \DateInterval('P1D'));
$manager->expects($this->once())->method('canShare')->willReturn(true);
$manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
$manager->expects($this->once())->method('validateExpirationDate')->with($tomorrow)->willReturn($tomorrow);
$file = $this->getMock('OCP\Files\File', [], [], 'File'); $file = $this->getMock('OCP\Files\File', [], [], 'File');
$file->method('getId')->willReturn(100); $file->method('getId')->willReturn(100);
$share = new \OC\Share20\Share(); $share = $this->manager->newShare();
$share->setProviderId('foo') $share->setProviderId('foo')
->setId('42') ->setId('42')
->setShareType(\OCP\Share::SHARE_TYPE_LINK) ->setShareType(\OCP\Share::SHARE_TYPE_LINK)
@ -1778,6 +1866,10 @@ class ManagerTest extends \Test\TestCase {
->setExpirationDate($tomorrow) ->setExpirationDate($tomorrow)
->setNode($file); ->setNode($file);
$manager->expects($this->once())->method('canShare')->willReturn(true);
$manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
$manager->expects($this->once())->method('validateExpirationDate')->with($share);
$this->defaultProvider->expects($this->once()) $this->defaultProvider->expects($this->once())
->method('update') ->method('update')
->with($share) ->with($share)