Merge pull request #10238 from nextcloud/add-support-for-sending-the-password-for-a-share-by-nextcloud-talk
Add support for sending the password for a share by Nextcloud Talk
This commit is contained in:
commit
9b9d729acf
16 changed files with 959 additions and 48 deletions
|
@ -30,6 +30,7 @@ declare(strict_types=1);
|
||||||
namespace OCA\Files_Sharing\Controller;
|
namespace OCA\Files_Sharing\Controller;
|
||||||
|
|
||||||
use OCA\Files\Helper;
|
use OCA\Files\Helper;
|
||||||
|
use OCP\App\IAppManager;
|
||||||
use OCP\AppFramework\Http\DataResponse;
|
use OCP\AppFramework\Http\DataResponse;
|
||||||
use OCP\AppFramework\OCS\OCSBadRequestException;
|
use OCP\AppFramework\OCS\OCSBadRequestException;
|
||||||
use OCP\AppFramework\OCS\OCSException;
|
use OCP\AppFramework\OCS\OCSException;
|
||||||
|
@ -81,6 +82,8 @@ class ShareAPIController extends OCSController {
|
||||||
private $lockedNode;
|
private $lockedNode;
|
||||||
/** @var IConfig */
|
/** @var IConfig */
|
||||||
private $config;
|
private $config;
|
||||||
|
/** @var IAppManager */
|
||||||
|
private $appManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Share20OCS constructor.
|
* Share20OCS constructor.
|
||||||
|
@ -95,6 +98,7 @@ class ShareAPIController extends OCSController {
|
||||||
* @param string $userId
|
* @param string $userId
|
||||||
* @param IL10N $l10n
|
* @param IL10N $l10n
|
||||||
* @param IConfig $config
|
* @param IConfig $config
|
||||||
|
* @param IAppManager $appManager
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
string $appName,
|
string $appName,
|
||||||
|
@ -106,7 +110,8 @@ class ShareAPIController extends OCSController {
|
||||||
IURLGenerator $urlGenerator,
|
IURLGenerator $urlGenerator,
|
||||||
string $userId,
|
string $userId,
|
||||||
IL10N $l10n,
|
IL10N $l10n,
|
||||||
IConfig $config
|
IConfig $config,
|
||||||
|
IAppManager $appManager
|
||||||
) {
|
) {
|
||||||
parent::__construct($appName, $request);
|
parent::__construct($appName, $request);
|
||||||
|
|
||||||
|
@ -119,6 +124,7 @@ class ShareAPIController extends OCSController {
|
||||||
$this->currentUser = $userId;
|
$this->currentUser = $userId;
|
||||||
$this->l = $l10n;
|
$this->l = $l10n;
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
|
$this->appManager = $appManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -206,6 +212,7 @@ class ShareAPIController extends OCSController {
|
||||||
} else if ($share->getShareType() === Share::SHARE_TYPE_EMAIL) {
|
} else if ($share->getShareType() === Share::SHARE_TYPE_EMAIL) {
|
||||||
$result['share_with'] = $share->getSharedWith();
|
$result['share_with'] = $share->getSharedWith();
|
||||||
$result['password'] = $share->getPassword();
|
$result['password'] = $share->getPassword();
|
||||||
|
$result['send_password_by_talk'] = $share->getSendPasswordByTalk();
|
||||||
$result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'EMAIL');
|
$result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'EMAIL');
|
||||||
$result['token'] = $share->getToken();
|
$result['token'] = $share->getToken();
|
||||||
} else if ($share->getShareType() === Share::SHARE_TYPE_CIRCLE) {
|
} else if ($share->getShareType() === Share::SHARE_TYPE_CIRCLE) {
|
||||||
|
@ -328,6 +335,7 @@ class ShareAPIController extends OCSController {
|
||||||
* @param string $shareWith
|
* @param string $shareWith
|
||||||
* @param string $publicUpload
|
* @param string $publicUpload
|
||||||
* @param string $password
|
* @param string $password
|
||||||
|
* @param bool $sendPasswordByTalk
|
||||||
* @param string $expireDate
|
* @param string $expireDate
|
||||||
*
|
*
|
||||||
* @return DataResponse
|
* @return DataResponse
|
||||||
|
@ -345,6 +353,7 @@ class ShareAPIController extends OCSController {
|
||||||
string $shareWith = null,
|
string $shareWith = null,
|
||||||
string $publicUpload = 'false',
|
string $publicUpload = 'false',
|
||||||
string $password = '',
|
string $password = '',
|
||||||
|
string $sendPasswordByTalk = null,
|
||||||
string $expireDate = ''
|
string $expireDate = ''
|
||||||
): DataResponse {
|
): DataResponse {
|
||||||
$share = $this->shareManager->newShare();
|
$share = $this->shareManager->newShare();
|
||||||
|
@ -485,6 +494,14 @@ class ShareAPIController extends OCSController {
|
||||||
$share->setPermissions($permissions);
|
$share->setPermissions($permissions);
|
||||||
}
|
}
|
||||||
$share->setSharedWith($shareWith);
|
$share->setSharedWith($shareWith);
|
||||||
|
|
||||||
|
if ($sendPasswordByTalk === 'true') {
|
||||||
|
if (!$this->appManager->isEnabledForUser('spreed')) {
|
||||||
|
throw new OCSForbiddenException($this->l->t('Sharing %s sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled', [$path->getPath()]));
|
||||||
|
}
|
||||||
|
|
||||||
|
$share->setSendPasswordByTalk(true);
|
||||||
|
}
|
||||||
} else if ($shareType === Share::SHARE_TYPE_CIRCLE) {
|
} else if ($shareType === Share::SHARE_TYPE_CIRCLE) {
|
||||||
if (!\OC::$server->getAppManager()->isEnabledForUser('circles') || !class_exists('\OCA\Circles\ShareByCircleProvider')) {
|
if (!\OC::$server->getAppManager()->isEnabledForUser('circles') || !class_exists('\OCA\Circles\ShareByCircleProvider')) {
|
||||||
throw new OCSNotFoundException($this->l->t('You cannot share to a Circle if the app is not enabled'));
|
throw new OCSNotFoundException($this->l->t('You cannot share to a Circle if the app is not enabled'));
|
||||||
|
@ -697,6 +714,7 @@ class ShareAPIController extends OCSController {
|
||||||
* @param string $id
|
* @param string $id
|
||||||
* @param int $permissions
|
* @param int $permissions
|
||||||
* @param string $password
|
* @param string $password
|
||||||
|
* @param string $sendPasswordByTalk
|
||||||
* @param string $publicUpload
|
* @param string $publicUpload
|
||||||
* @param string $expireDate
|
* @param string $expireDate
|
||||||
* @param string $note
|
* @param string $note
|
||||||
|
@ -711,6 +729,7 @@ class ShareAPIController extends OCSController {
|
||||||
string $id,
|
string $id,
|
||||||
int $permissions = null,
|
int $permissions = null,
|
||||||
string $password = null,
|
string $password = null,
|
||||||
|
string $sendPasswordByTalk = null,
|
||||||
string $publicUpload = null,
|
string $publicUpload = null,
|
||||||
string $expireDate = null,
|
string $expireDate = null,
|
||||||
string $note = null
|
string $note = null
|
||||||
|
@ -727,7 +746,7 @@ class ShareAPIController extends OCSController {
|
||||||
throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
|
throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($permissions === null && $password === null && $publicUpload === null && $expireDate === null && $note === null) {
|
if ($permissions === null && $password === null && $sendPasswordByTalk === null && $publicUpload === null && $expireDate === null && $note === null) {
|
||||||
throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given'));
|
throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -816,6 +835,16 @@ class ShareAPIController extends OCSController {
|
||||||
} else if ($password !== null) {
|
} else if ($password !== null) {
|
||||||
$share->setPassword($password);
|
$share->setPassword($password);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($sendPasswordByTalk === 'true') {
|
||||||
|
if (!$this->appManager->isEnabledForUser('spreed')) {
|
||||||
|
throw new OCSForbiddenException($this->l->t('Sharing sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$share->setSendPasswordByTalk(true);
|
||||||
|
} else {
|
||||||
|
$share->setSendPasswordByTalk(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($expireDate === '') {
|
if ($expireDate === '') {
|
||||||
|
|
|
@ -61,6 +61,7 @@ use OCP\Files\NotFoundException;
|
||||||
use OCP\Files\IRootFolder;
|
use OCP\Files\IRootFolder;
|
||||||
use OCP\Share\Exceptions\ShareNotFound;
|
use OCP\Share\Exceptions\ShareNotFound;
|
||||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||||
|
use Symfony\Component\EventDispatcher\GenericEvent;
|
||||||
use OCP\Share\IManager as ShareManager;
|
use OCP\Share\IManager as ShareManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -143,6 +144,34 @@ class ShareController extends AuthPublicShareController {
|
||||||
$this->shareManager = $shareManager;
|
$this->shareManager = $shareManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @PublicPage
|
||||||
|
* @NoCSRFRequired
|
||||||
|
*
|
||||||
|
* Show the authentication page
|
||||||
|
* The form has to submit to the authenticate method route
|
||||||
|
*/
|
||||||
|
public function showAuthenticate(): TemplateResponse {
|
||||||
|
$templateParameters = ['share' => $this->share];
|
||||||
|
|
||||||
|
$event = new GenericEvent(null, $templateParameters);
|
||||||
|
$this->eventDispatcher->dispatch('OCA\Files_Sharing::loadAdditionalScripts::publicShareAuth', $event);
|
||||||
|
|
||||||
|
return new TemplateResponse('core', 'publicshareauth', $templateParameters, 'guest');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The template to show when authentication failed
|
||||||
|
*/
|
||||||
|
protected function showAuthFailed(): TemplateResponse {
|
||||||
|
$templateParameters = ['share' => $this->share, 'wrongpw' => true];
|
||||||
|
|
||||||
|
$event = new GenericEvent(null, $templateParameters);
|
||||||
|
$this->eventDispatcher->dispatch('OCA\Files_Sharing::loadAdditionalScripts::publicShareAuth', $event);
|
||||||
|
|
||||||
|
return new TemplateResponse('core', 'publicshareauth', $templateParameters, 'guest');
|
||||||
|
}
|
||||||
|
|
||||||
protected function verifyPassword(string $password): bool {
|
protected function verifyPassword(string $password): bool {
|
||||||
return $this->shareManager->checkPassword($this->share, $password);
|
return $this->shareManager->checkPassword($this->share, $password);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ namespace OCA\Files_Sharing\Tests;
|
||||||
|
|
||||||
use OC\Files\Cache\Scanner;
|
use OC\Files\Cache\Scanner;
|
||||||
use OCA\Files_Sharing\Controller\ShareAPIController;
|
use OCA\Files_Sharing\Controller\ShareAPIController;
|
||||||
|
use OCP\App\IAppManager;
|
||||||
use OCP\AppFramework\OCS\OCSBadRequestException;
|
use OCP\AppFramework\OCS\OCSBadRequestException;
|
||||||
use OCP\AppFramework\OCS\OCSException;
|
use OCP\AppFramework\OCS\OCSException;
|
||||||
use OCP\AppFramework\OCS\OCSForbiddenException;
|
use OCP\AppFramework\OCS\OCSForbiddenException;
|
||||||
|
@ -107,6 +108,7 @@ class ApiTest extends TestCase {
|
||||||
return vsprintf($text, $parameters);
|
return vsprintf($text, $parameters);
|
||||||
}));
|
}));
|
||||||
$config = $this->createMock(IConfig::class);
|
$config = $this->createMock(IConfig::class);
|
||||||
|
$appManager = $this->createMock(IAppManager::class);
|
||||||
|
|
||||||
return new ShareAPIController(
|
return new ShareAPIController(
|
||||||
self::APP_NAME,
|
self::APP_NAME,
|
||||||
|
@ -118,7 +120,8 @@ class ApiTest extends TestCase {
|
||||||
\OC::$server->getURLGenerator(),
|
\OC::$server->getURLGenerator(),
|
||||||
$userId,
|
$userId,
|
||||||
$l,
|
$l,
|
||||||
$config
|
$config,
|
||||||
|
$appManager
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -960,7 +963,7 @@ class ApiTest extends TestCase {
|
||||||
|
|
||||||
// update public upload
|
// update public upload
|
||||||
$ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
|
$ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
|
||||||
$ocs->updateShare($share1->getId(), null, null, 'true');
|
$ocs->updateShare($share1->getId(), null, null, null, 'true');
|
||||||
$ocs->cleanup();
|
$ocs->cleanup();
|
||||||
|
|
||||||
$share1 = $this->shareManager->getShareById($share1->getFullId());
|
$share1 = $this->shareManager->getShareById($share1->getFullId());
|
||||||
|
@ -1003,7 +1006,7 @@ class ApiTest extends TestCase {
|
||||||
|
|
||||||
// update expire date to a valid value
|
// update expire date to a valid value
|
||||||
$ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
|
$ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
|
||||||
$ocs->updateShare($share1->getId(), null, null, null, $dateWithinRange->format('Y-m-d'));
|
$ocs->updateShare($share1->getId(), null, null, null, null, $dateWithinRange->format('Y-m-d'));
|
||||||
$ocs->cleanup();
|
$ocs->cleanup();
|
||||||
|
|
||||||
$share1 = $this->shareManager->getShareById($share1->getFullId());
|
$share1 = $this->shareManager->getShareById($share1->getFullId());
|
||||||
|
@ -1234,7 +1237,7 @@ class ApiTest extends TestCase {
|
||||||
$ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
|
$ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$result = $ocs->createShare($this->folder, \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'false', '', $date);
|
$result = $ocs->createShare($this->folder, \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'false', '', null, $date);
|
||||||
$this->assertTrue($valid);
|
$this->assertTrue($valid);
|
||||||
} catch (OCSNotFoundException $e) {
|
} catch (OCSNotFoundException $e) {
|
||||||
$this->assertFalse($valid);
|
$this->assertFalse($valid);
|
||||||
|
@ -1270,7 +1273,7 @@ class ApiTest extends TestCase {
|
||||||
$date->add(new \DateInterval('P5D'));
|
$date->add(new \DateInterval('P5D'));
|
||||||
|
|
||||||
$ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
|
$ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
|
||||||
$result = $ocs->createShare($this->filename, \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'false', '', $date->format('Y-m-d'));
|
$result = $ocs->createShare($this->filename, \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'false', '', null, $date->format('Y-m-d'));
|
||||||
$ocs->cleanup();
|
$ocs->cleanup();
|
||||||
|
|
||||||
$data = $result->getData();
|
$data = $result->getData();
|
||||||
|
@ -1304,7 +1307,7 @@ class ApiTest extends TestCase {
|
||||||
$ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
|
$ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$ocs->createShare($this->filename, \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'false', '', $date->format('Y-m-d'));
|
$ocs->createShare($this->filename, \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'false', '', null, $date->format('Y-m-d'));
|
||||||
$this->fail();
|
$this->fail();
|
||||||
} catch (OCSException $e) {
|
} catch (OCSException $e) {
|
||||||
$this->assertEquals(404, $e->getCode());
|
$this->assertEquals(404, $e->getCode());
|
||||||
|
@ -1325,7 +1328,7 @@ class ApiTest extends TestCase {
|
||||||
$ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
|
$ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$ocs->createShare($this->filename, \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'false', '', $date->format('Y-m-d'));
|
$ocs->createShare($this->filename, \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'false', '', null, $date->format('Y-m-d'));
|
||||||
$this->fail();
|
$this->fail();
|
||||||
} catch(OCSException $e) {
|
} catch(OCSException $e) {
|
||||||
$this->assertEquals(404, $e->getCode());
|
$this->assertEquals(404, $e->getCode());
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
*/
|
*/
|
||||||
namespace OCA\Files_Sharing\Tests\Controller;
|
namespace OCA\Files_Sharing\Tests\Controller;
|
||||||
|
|
||||||
|
use OCP\App\IAppManager;
|
||||||
use OCP\AppFramework\Http\DataResponse;
|
use OCP\AppFramework\Http\DataResponse;
|
||||||
use OCP\AppFramework\OCS\OCSNotFoundException;
|
use OCP\AppFramework\OCS\OCSNotFoundException;
|
||||||
use OCP\Files\File;
|
use OCP\Files\File;
|
||||||
|
@ -88,6 +89,9 @@ class ShareAPIControllerTest extends TestCase {
|
||||||
/** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
|
/** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
|
||||||
private $config;
|
private $config;
|
||||||
|
|
||||||
|
/** @var IAppManager|\PHPUnit_Framework_MockObject_MockObject */
|
||||||
|
private $appManager;
|
||||||
|
|
||||||
protected function setUp() {
|
protected function setUp() {
|
||||||
$this->shareManager = $this->createMock(IManager::class);
|
$this->shareManager = $this->createMock(IManager::class);
|
||||||
$this->shareManager
|
$this->shareManager
|
||||||
|
@ -107,6 +111,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||||
return vsprintf($text, $parameters);
|
return vsprintf($text, $parameters);
|
||||||
}));
|
}));
|
||||||
$this->config = $this->createMock(IConfig::class);
|
$this->config = $this->createMock(IConfig::class);
|
||||||
|
$this->appManager = $this->createMock(IAppManager::class);
|
||||||
|
|
||||||
$this->ocs = new ShareAPIController(
|
$this->ocs = new ShareAPIController(
|
||||||
$this->appName,
|
$this->appName,
|
||||||
|
@ -118,7 +123,8 @@ class ShareAPIControllerTest extends TestCase {
|
||||||
$this->urlGenerator,
|
$this->urlGenerator,
|
||||||
$this->currentUser,
|
$this->currentUser,
|
||||||
$this->l,
|
$this->l,
|
||||||
$this->config
|
$this->config,
|
||||||
|
$this->appManager
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +143,8 @@ class ShareAPIControllerTest extends TestCase {
|
||||||
$this->urlGenerator,
|
$this->urlGenerator,
|
||||||
$this->currentUser,
|
$this->currentUser,
|
||||||
$this->l,
|
$this->l,
|
||||||
$this->config
|
$this->config,
|
||||||
|
$this->appManager
|
||||||
])->setMethods(['formatShare'])
|
])->setMethods(['formatShare'])
|
||||||
->getMock();
|
->getMock();
|
||||||
}
|
}
|
||||||
|
@ -453,7 +460,8 @@ class ShareAPIControllerTest extends TestCase {
|
||||||
$this->urlGenerator,
|
$this->urlGenerator,
|
||||||
$this->currentUser,
|
$this->currentUser,
|
||||||
$this->l,
|
$this->l,
|
||||||
$this->config
|
$this->config,
|
||||||
|
$this->appManager
|
||||||
])->setMethods(['canAccessShare'])
|
])->setMethods(['canAccessShare'])
|
||||||
->getMock();
|
->getMock();
|
||||||
|
|
||||||
|
@ -724,7 +732,8 @@ class ShareAPIControllerTest extends TestCase {
|
||||||
$this->urlGenerator,
|
$this->urlGenerator,
|
||||||
$this->currentUser,
|
$this->currentUser,
|
||||||
$this->l,
|
$this->l,
|
||||||
$this->config
|
$this->config,
|
||||||
|
$this->appManager
|
||||||
])->setMethods(['formatShare'])
|
])->setMethods(['formatShare'])
|
||||||
->getMock();
|
->getMock();
|
||||||
|
|
||||||
|
@ -822,7 +831,8 @@ class ShareAPIControllerTest extends TestCase {
|
||||||
$this->urlGenerator,
|
$this->urlGenerator,
|
||||||
$this->currentUser,
|
$this->currentUser,
|
||||||
$this->l,
|
$this->l,
|
||||||
$this->config
|
$this->config,
|
||||||
|
$this->appManager
|
||||||
])->setMethods(['formatShare'])
|
])->setMethods(['formatShare'])
|
||||||
->getMock();
|
->getMock();
|
||||||
|
|
||||||
|
@ -1008,7 +1018,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||||
)->will($this->returnArgument(0));
|
)->will($this->returnArgument(0));
|
||||||
|
|
||||||
$expected = new DataResponse([]);
|
$expected = new DataResponse([]);
|
||||||
$result = $ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'true', '', '');
|
$result = $ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'true', '', null, '');
|
||||||
|
|
||||||
$this->assertInstanceOf(get_class($expected), $result);
|
$this->assertInstanceOf(get_class($expected), $result);
|
||||||
$this->assertEquals($expected->getData(), $result->getData());
|
$this->assertEquals($expected->getData(), $result->getData());
|
||||||
|
@ -1042,7 +1052,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||||
)->will($this->returnArgument(0));
|
)->will($this->returnArgument(0));
|
||||||
|
|
||||||
$expected = new DataResponse([]);
|
$expected = new DataResponse([]);
|
||||||
$result = $ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'false', 'password', '');
|
$result = $ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'false', 'password', null, '');
|
||||||
|
|
||||||
$this->assertInstanceOf(get_class($expected), $result);
|
$this->assertInstanceOf(get_class($expected), $result);
|
||||||
$this->assertEquals($expected->getData(), $result->getData());
|
$this->assertEquals($expected->getData(), $result->getData());
|
||||||
|
@ -1089,7 +1099,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||||
)->will($this->returnArgument(0));
|
)->will($this->returnArgument(0));
|
||||||
|
|
||||||
$expected = new DataResponse([]);
|
$expected = new DataResponse([]);
|
||||||
$result = $ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'false', '', '2000-01-01');
|
$result = $ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'false', '', null, '2000-01-01');
|
||||||
|
|
||||||
$this->assertInstanceOf(get_class($expected), $result);
|
$this->assertInstanceOf(get_class($expected), $result);
|
||||||
$this->assertEquals($expected->getData(), $result->getData());
|
$this->assertEquals($expected->getData(), $result->getData());
|
||||||
|
@ -1115,7 +1125,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||||
$this->shareManager->method('shareApiAllowLinks')->willReturn(true);
|
$this->shareManager->method('shareApiAllowLinks')->willReturn(true);
|
||||||
$this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
|
$this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
|
||||||
|
|
||||||
$ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'false', '', 'a1b2d3');
|
$ocs->createShare('valid-path', \OCP\Constants::PERMISSION_ALL, \OCP\Share::SHARE_TYPE_LINK, null, 'false', '', null, 'a1b2d3');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1138,7 +1148,8 @@ class ShareAPIControllerTest extends TestCase {
|
||||||
$this->urlGenerator,
|
$this->urlGenerator,
|
||||||
$this->currentUser,
|
$this->currentUser,
|
||||||
$this->l,
|
$this->l,
|
||||||
$this->config
|
$this->config,
|
||||||
|
$this->appManager
|
||||||
])->setMethods(['formatShare'])
|
])->setMethods(['formatShare'])
|
||||||
->getMock();
|
->getMock();
|
||||||
|
|
||||||
|
@ -1264,7 +1275,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||||
->willReturn([]);
|
->willReturn([]);
|
||||||
|
|
||||||
$expected = new DataResponse([]);
|
$expected = new DataResponse([]);
|
||||||
$result = $ocs->updateShare(42, null, '', 'false', '');
|
$result = $ocs->updateShare(42, null, '', null, 'false', '');
|
||||||
|
|
||||||
$this->assertInstanceOf(get_class($expected), $result);
|
$this->assertInstanceOf(get_class($expected), $result);
|
||||||
$this->assertEquals($expected->getData(), $result->getData());
|
$this->assertEquals($expected->getData(), $result->getData());
|
||||||
|
@ -1299,7 +1310,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||||
->willReturn([]);
|
->willReturn([]);
|
||||||
|
|
||||||
$expected = new DataResponse([]);
|
$expected = new DataResponse([]);
|
||||||
$result = $ocs->updateShare(42, null, 'password', 'true', '2000-01-01');
|
$result = $ocs->updateShare(42, null, 'password', null, 'true', '2000-01-01');
|
||||||
|
|
||||||
$this->assertInstanceOf(get_class($expected), $result);
|
$this->assertInstanceOf(get_class($expected), $result);
|
||||||
$this->assertEquals($expected->getData(), $result->getData());
|
$this->assertEquals($expected->getData(), $result->getData());
|
||||||
|
@ -1333,7 +1344,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||||
)->will($this->returnArgument(0));
|
)->will($this->returnArgument(0));
|
||||||
|
|
||||||
$expected = new DataResponse([]);
|
$expected = new DataResponse([]);
|
||||||
$result = $ocs->updateShare(42, $permissions, $password, $publicUpload, $expireDate);
|
$result = $ocs->updateShare(42, $permissions, $password, null, $publicUpload, $expireDate);
|
||||||
|
|
||||||
$this->assertInstanceOf(get_class($expected), $result);
|
$this->assertInstanceOf(get_class($expected), $result);
|
||||||
$this->assertEquals($expected->getData(), $result->getData());
|
$this->assertEquals($expected->getData(), $result->getData());
|
||||||
|
@ -1357,7 +1368,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||||
$this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
|
$this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
|
||||||
$this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
|
$this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
|
||||||
|
|
||||||
$ocs->updateShare(42, null, 'password', 'true', '2000-01-a');
|
$ocs->updateShare(42, null, 'password', null, 'true', '2000-01-a');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function publicUploadParamsProvider() {
|
public function publicUploadParamsProvider() {
|
||||||
|
@ -1395,7 +1406,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||||
$this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
|
$this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
|
||||||
$this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(false);
|
$this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(false);
|
||||||
|
|
||||||
$ocs->updateShare(42, $permissions, $password, $publicUpload, $expireDate);
|
$ocs->updateShare(42, $permissions, $password, null, $publicUpload, $expireDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1416,7 +1427,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||||
$this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
|
$this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
|
||||||
$this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
|
$this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
|
||||||
|
|
||||||
$ocs->updateShare(42, null, 'password', 'true', '');
|
$ocs->updateShare(42, null, 'password', null, 'true', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testUpdateLinkSharePasswordDoesNotChangeOther() {
|
public function testUpdateLinkSharePasswordDoesNotChangeOther() {
|
||||||
|
@ -1450,7 +1461,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||||
)->will($this->returnArgument(0));
|
)->will($this->returnArgument(0));
|
||||||
|
|
||||||
$expected = new DataResponse([]);
|
$expected = new DataResponse([]);
|
||||||
$result = $ocs->updateShare(42, null, 'newpassword', null, null);
|
$result = $ocs->updateShare(42, null, 'newpassword', null, null, null);
|
||||||
|
|
||||||
$this->assertInstanceOf(get_class($expected), $result);
|
$this->assertInstanceOf(get_class($expected), $result);
|
||||||
$this->assertEquals($expected->getData(), $result->getData());
|
$this->assertEquals($expected->getData(), $result->getData());
|
||||||
|
@ -1487,7 +1498,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||||
)->will($this->returnArgument(0));
|
)->will($this->returnArgument(0));
|
||||||
|
|
||||||
$expected = new DataResponse([]);
|
$expected = new DataResponse([]);
|
||||||
$result = $ocs->updateShare(42, null, null, null, '2010-12-23');
|
$result = $ocs->updateShare(42, null, null, null, null, '2010-12-23');
|
||||||
|
|
||||||
$this->assertInstanceOf(get_class($expected), $result);
|
$this->assertInstanceOf(get_class($expected), $result);
|
||||||
$this->assertEquals($expected->getData(), $result->getData());
|
$this->assertEquals($expected->getData(), $result->getData());
|
||||||
|
@ -1524,7 +1535,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||||
->willReturn([]);
|
->willReturn([]);
|
||||||
|
|
||||||
$expected = new DataResponse([]);
|
$expected = new DataResponse([]);
|
||||||
$result = $ocs->updateShare(42, null, null, 'true', null);
|
$result = $ocs->updateShare(42, null, null, null, 'true', null);
|
||||||
|
|
||||||
$this->assertInstanceOf(get_class($expected), $result);
|
$this->assertInstanceOf(get_class($expected), $result);
|
||||||
$this->assertEquals($expected->getData(), $result->getData());
|
$this->assertEquals($expected->getData(), $result->getData());
|
||||||
|
@ -1560,7 +1571,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||||
$this->shareManager->method('getSharedWith')->willReturn([]);
|
$this->shareManager->method('getSharedWith')->willReturn([]);
|
||||||
|
|
||||||
$expected = new DataResponse([]);
|
$expected = new DataResponse([]);
|
||||||
$result = $ocs->updateShare(42, 7, null, null, null);
|
$result = $ocs->updateShare(42, 7, null, null, null, null);
|
||||||
|
|
||||||
$this->assertInstanceOf(get_class($expected), $result);
|
$this->assertInstanceOf(get_class($expected), $result);
|
||||||
$this->assertEquals($expected->getData(), $result->getData());
|
$this->assertEquals($expected->getData(), $result->getData());
|
||||||
|
@ -1596,7 +1607,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||||
$this->shareManager->method('getSharedWith')->willReturn([]);
|
$this->shareManager->method('getSharedWith')->willReturn([]);
|
||||||
|
|
||||||
$expected = new DataResponse([]);
|
$expected = new DataResponse([]);
|
||||||
$result = $ocs->updateShare(42, 31, null, null, null);
|
$result = $ocs->updateShare(42, 31, null, null, null, null);
|
||||||
|
|
||||||
$this->assertInstanceOf(get_class($expected), $result);
|
$this->assertInstanceOf(get_class($expected), $result);
|
||||||
$this->assertEquals($expected->getData(), $result->getData());
|
$this->assertEquals($expected->getData(), $result->getData());
|
||||||
|
@ -1625,7 +1636,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||||
$this->shareManager->method('getSharedWith')->willReturn([]);
|
$this->shareManager->method('getSharedWith')->willReturn([]);
|
||||||
|
|
||||||
$expected = new DataResponse([]);
|
$expected = new DataResponse([]);
|
||||||
$result = $ocs->updateShare(42, 31, null, null, null);
|
$result = $ocs->updateShare(42, 31, null, null, null, null);
|
||||||
|
|
||||||
$this->assertInstanceOf(get_class($expected), $result);
|
$this->assertInstanceOf(get_class($expected), $result);
|
||||||
$this->assertEquals($expected->getData(), $result->getData());
|
$this->assertEquals($expected->getData(), $result->getData());
|
||||||
|
@ -1722,7 +1733,7 @@ class ShareAPIControllerTest extends TestCase {
|
||||||
$this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
|
$this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$ocs->updateShare(42, null, null, 'true');
|
$ocs->updateShare(42, null, null, null, 'true');
|
||||||
$this->fail();
|
$this->fail();
|
||||||
} catch (OCSNotFoundException $e) {
|
} catch (OCSNotFoundException $e) {
|
||||||
$this->assertEquals('Cannot increase permissions', $e->getMessage());
|
$this->assertEquals('Cannot increase permissions', $e->getMessage());
|
||||||
|
@ -2276,7 +2287,52 @@ class ShareAPIControllerTest extends TestCase {
|
||||||
'share_with_displayname' => 'mail display name',
|
'share_with_displayname' => 'mail display name',
|
||||||
'mail_send' => 0,
|
'mail_send' => 0,
|
||||||
'mimetype' => 'myFolderMimeType',
|
'mimetype' => 'myFolderMimeType',
|
||||||
'password' => 'password'
|
'password' => 'password',
|
||||||
|
'send_password_by_talk' => false
|
||||||
|
], $share, [], false
|
||||||
|
];
|
||||||
|
|
||||||
|
$share = \OC::$server->getShareManager()->newShare();
|
||||||
|
$share->setShareType(\OCP\Share::SHARE_TYPE_EMAIL)
|
||||||
|
->setSharedBy('initiator')
|
||||||
|
->setSharedWith('user@server.com')
|
||||||
|
->setShareOwner('owner')
|
||||||
|
->setPermissions(\OCP\Constants::PERMISSION_READ)
|
||||||
|
->setNode($folder)
|
||||||
|
->setShareTime(new \DateTime('2000-01-01T00:01:02'))
|
||||||
|
->setTarget('myTarget')
|
||||||
|
->setId(42)
|
||||||
|
->setPassword('password')
|
||||||
|
->setSendPasswordByTalk(true);
|
||||||
|
|
||||||
|
$result[] = [
|
||||||
|
[
|
||||||
|
'id' => 42,
|
||||||
|
'share_type' => \OCP\Share::SHARE_TYPE_EMAIL,
|
||||||
|
'uid_owner' => 'initiator',
|
||||||
|
'displayname_owner' => 'initiator',
|
||||||
|
'permissions' => 1,
|
||||||
|
'stime' => 946684862,
|
||||||
|
'parent' => null,
|
||||||
|
'expiration' => null,
|
||||||
|
'token' => null,
|
||||||
|
'uid_file_owner' => 'owner',
|
||||||
|
'displayname_file_owner' => 'owner',
|
||||||
|
'note' => '',
|
||||||
|
'path' => 'folder',
|
||||||
|
'item_type' => 'folder',
|
||||||
|
'storage_id' => 'storageId',
|
||||||
|
'storage' => 100,
|
||||||
|
'item_source' => 2,
|
||||||
|
'file_source' => 2,
|
||||||
|
'file_parent' => 1,
|
||||||
|
'file_target' => 'myTarget',
|
||||||
|
'share_with' => 'user@server.com',
|
||||||
|
'share_with_displayname' => 'mail display name',
|
||||||
|
'mail_send' => 0,
|
||||||
|
'mimetype' => 'myFolderMimeType',
|
||||||
|
'password' => 'password',
|
||||||
|
'send_password_by_talk' => true
|
||||||
], $share, [], false
|
], $share, [], false
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -338,7 +338,8 @@ class ShareByMailProvider implements IShareProvider {
|
||||||
$share->getShareOwner(),
|
$share->getShareOwner(),
|
||||||
$share->getPermissions(),
|
$share->getPermissions(),
|
||||||
$share->getToken(),
|
$share->getToken(),
|
||||||
$share->getPassword()
|
$share->getPassword(),
|
||||||
|
$share->getSendPasswordByTalk()
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -453,7 +454,7 @@ class ShareByMailProvider implements IShareProvider {
|
||||||
$initiator = $share->getSharedBy();
|
$initiator = $share->getSharedBy();
|
||||||
$shareWith = $share->getSharedWith();
|
$shareWith = $share->getSharedWith();
|
||||||
|
|
||||||
if ($password === '' || $this->settingsManager->sendPasswordByMail() === false) {
|
if ($password === '' || $this->settingsManager->sendPasswordByMail() === false || $share->getSendPasswordByTalk()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -660,9 +661,11 @@ class ShareByMailProvider implements IShareProvider {
|
||||||
* @param string $uidOwner
|
* @param string $uidOwner
|
||||||
* @param int $permissions
|
* @param int $permissions
|
||||||
* @param string $token
|
* @param string $token
|
||||||
|
* @param string $password
|
||||||
|
* @param bool $sendPasswordByTalk
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
protected function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token, $password) {
|
protected function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token, $password, $sendPasswordByTalk) {
|
||||||
$qb = $this->dbConnection->getQueryBuilder();
|
$qb = $this->dbConnection->getQueryBuilder();
|
||||||
$qb->insert('share')
|
$qb->insert('share')
|
||||||
->setValue('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))
|
->setValue('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))
|
||||||
|
@ -675,6 +678,7 @@ class ShareByMailProvider implements IShareProvider {
|
||||||
->setValue('permissions', $qb->createNamedParameter($permissions))
|
->setValue('permissions', $qb->createNamedParameter($permissions))
|
||||||
->setValue('token', $qb->createNamedParameter($token))
|
->setValue('token', $qb->createNamedParameter($token))
|
||||||
->setValue('password', $qb->createNamedParameter($password))
|
->setValue('password', $qb->createNamedParameter($password))
|
||||||
|
->setValue('password_by_talk', $qb->createNamedParameter($sendPasswordByTalk, IQueryBuilder::PARAM_BOOL))
|
||||||
->setValue('stime', $qb->createNamedParameter(time()));
|
->setValue('stime', $qb->createNamedParameter(time()));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -703,7 +707,8 @@ class ShareByMailProvider implements IShareProvider {
|
||||||
// a real password was given
|
// a real password was given
|
||||||
$validPassword = $plainTextPassword !== null && $plainTextPassword !== '';
|
$validPassword = $plainTextPassword !== null && $plainTextPassword !== '';
|
||||||
|
|
||||||
if($validPassword && $originalShare->getPassword() !== $share->getPassword()) {
|
if($validPassword && ($originalShare->getPassword() !== $share->getPassword() ||
|
||||||
|
($originalShare->getSendPasswordByTalk() && !$share->getSendPasswordByTalk()))) {
|
||||||
$this->sendPassword($share, $plainTextPassword);
|
$this->sendPassword($share, $plainTextPassword);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -716,6 +721,7 @@ class ShareByMailProvider implements IShareProvider {
|
||||||
->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
|
->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
|
||||||
->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
|
->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
|
||||||
->set('password', $qb->createNamedParameter($share->getPassword()))
|
->set('password', $qb->createNamedParameter($share->getPassword()))
|
||||||
|
->set('password_by_talk', $qb->createNamedParameter($share->getSendPasswordByTalk(), IQueryBuilder::PARAM_BOOL))
|
||||||
->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
|
->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
|
||||||
->set('note', $qb->createNamedParameter($share->getNote()))
|
->set('note', $qb->createNamedParameter($share->getNote()))
|
||||||
->execute();
|
->execute();
|
||||||
|
@ -972,6 +978,7 @@ class ShareByMailProvider implements IShareProvider {
|
||||||
$share->setShareTime($shareTime);
|
$share->setShareTime($shareTime);
|
||||||
$share->setSharedWith($data['share_with']);
|
$share->setSharedWith($data['share_with']);
|
||||||
$share->setPassword($data['password']);
|
$share->setPassword($data['password']);
|
||||||
|
$share->setSendPasswordByTalk($data['password_by_talk']);
|
||||||
|
|
||||||
if ($data['uid_initiator'] !== null) {
|
if ($data['uid_initiator'] !== null) {
|
||||||
$share->setShareOwner($data['uid_owner']);
|
$share->setShareOwner($data['uid_owner']);
|
||||||
|
|
|
@ -38,6 +38,7 @@ use OCP\IUser;
|
||||||
use OCP\IUserManager;
|
use OCP\IUserManager;
|
||||||
use OCP\Mail\IEMailTemplate;
|
use OCP\Mail\IEMailTemplate;
|
||||||
use OCP\Mail\IMailer;
|
use OCP\Mail\IMailer;
|
||||||
|
use OCP\Mail\IMessage;
|
||||||
use OCP\Security\IHasher;
|
use OCP\Security\IHasher;
|
||||||
use OCP\Security\ISecureRandom;
|
use OCP\Security\ISecureRandom;
|
||||||
use OCP\Share\IManager;
|
use OCP\Share\IManager;
|
||||||
|
@ -204,6 +205,107 @@ class ShareByMailProviderTest extends TestCase {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testCreateSendPasswordByMailWithoutEnforcedPasswordProtection() {
|
||||||
|
$share = $this->getMockBuilder(IShare::class)->getMock();
|
||||||
|
$share->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com');
|
||||||
|
$share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(false);
|
||||||
|
$share->expects($this->any())->method('getSharedBy')->willReturn('owner');
|
||||||
|
|
||||||
|
$node = $this->getMockBuilder(File::class)->getMock();
|
||||||
|
$node->expects($this->any())->method('getName')->willReturn('filename');
|
||||||
|
|
||||||
|
$instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity']);
|
||||||
|
|
||||||
|
$instance->expects($this->once())->method('getSharedWith')->willReturn([]);
|
||||||
|
$instance->expects($this->once())->method('createMailShare')->with($share)->willReturn(42);
|
||||||
|
$instance->expects($this->once())->method('createShareActivity')->with($share);
|
||||||
|
$instance->expects($this->once())->method('getRawShare')->with(42)->willReturn('rawShare');
|
||||||
|
$instance->expects($this->once())->method('createShareObject')->with('rawShare')->willReturn('shareObject');
|
||||||
|
$share->expects($this->any())->method('getNode')->willReturn($node);
|
||||||
|
|
||||||
|
// The autogenerated password should not be mailed.
|
||||||
|
$this->settingsManager->expects($this->any())->method('enforcePasswordProtection')->willReturn(false);
|
||||||
|
$this->settingsManager->expects($this->any())->method('sendPasswordByMail')->willReturn(true);
|
||||||
|
$instance->expects($this->never())->method('autoGeneratePassword');
|
||||||
|
|
||||||
|
$this->mailer->expects($this->never())->method('send');
|
||||||
|
|
||||||
|
$this->assertSame('shareObject',
|
||||||
|
$instance->create($share)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCreateSendPasswordByMailWithEnforcedPasswordProtection() {
|
||||||
|
$share = $this->getMockBuilder(IShare::class)->getMock();
|
||||||
|
$share->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com');
|
||||||
|
$share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(false);
|
||||||
|
$share->expects($this->any())->method('getSharedBy')->willReturn('owner');
|
||||||
|
|
||||||
|
$node = $this->getMockBuilder(File::class)->getMock();
|
||||||
|
$node->expects($this->any())->method('getName')->willReturn('filename');
|
||||||
|
|
||||||
|
$instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity']);
|
||||||
|
|
||||||
|
$instance->expects($this->once())->method('getSharedWith')->willReturn([]);
|
||||||
|
$instance->expects($this->once())->method('createMailShare')->with($share)->willReturn(42);
|
||||||
|
$instance->expects($this->once())->method('createShareActivity')->with($share);
|
||||||
|
$instance->expects($this->once())->method('getRawShare')->with(42)->willReturn('rawShare');
|
||||||
|
$instance->expects($this->once())->method('createShareObject')->with('rawShare')->willReturn('shareObject');
|
||||||
|
$share->expects($this->any())->method('getNode')->willReturn($node);
|
||||||
|
|
||||||
|
// The autogenerated password should be mailed to the receiver of the share.
|
||||||
|
$this->settingsManager->expects($this->any())->method('enforcePasswordProtection')->willReturn(true);
|
||||||
|
$this->settingsManager->expects($this->any())->method('sendPasswordByMail')->willReturn(true);
|
||||||
|
$instance->expects($this->once())->method('autoGeneratePassword')->with($share)->willReturn('password');
|
||||||
|
|
||||||
|
$message = $this->createMock(IMessage::class);
|
||||||
|
$message->expects($this->once())->method('setTo')->with(['receiver@example.com']);
|
||||||
|
$this->mailer->expects($this->once())->method('createMessage')->willReturn($message);
|
||||||
|
$this->mailer->expects($this->once())->method('send');
|
||||||
|
|
||||||
|
$this->assertSame('shareObject',
|
||||||
|
$instance->create($share)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCreateSendPasswordByTalkWithEnforcedPasswordProtection() {
|
||||||
|
$share = $this->getMockBuilder(IShare::class)->getMock();
|
||||||
|
$share->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com');
|
||||||
|
$share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(true);
|
||||||
|
$share->expects($this->any())->method('getSharedBy')->willReturn('owner');
|
||||||
|
|
||||||
|
$node = $this->getMockBuilder(File::class)->getMock();
|
||||||
|
$node->expects($this->any())->method('getName')->willReturn('filename');
|
||||||
|
|
||||||
|
$instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity']);
|
||||||
|
|
||||||
|
$instance->expects($this->once())->method('getSharedWith')->willReturn([]);
|
||||||
|
$instance->expects($this->once())->method('createMailShare')->with($share)->willReturn(42);
|
||||||
|
$instance->expects($this->once())->method('createShareActivity')->with($share);
|
||||||
|
$instance->expects($this->once())->method('getRawShare')->with(42)->willReturn('rawShare');
|
||||||
|
$instance->expects($this->once())->method('createShareObject')->with('rawShare')->willReturn('shareObject');
|
||||||
|
$share->expects($this->any())->method('getNode')->willReturn($node);
|
||||||
|
|
||||||
|
// The autogenerated password should be mailed to the owner of the share.
|
||||||
|
$this->settingsManager->expects($this->any())->method('enforcePasswordProtection')->willReturn(true);
|
||||||
|
$this->settingsManager->expects($this->any())->method('sendPasswordByMail')->willReturn(true);
|
||||||
|
$instance->expects($this->once())->method('autoGeneratePassword')->with($share)->willReturn('password');
|
||||||
|
|
||||||
|
$message = $this->createMock(IMessage::class);
|
||||||
|
$message->expects($this->once())->method('setTo')->with(['owner@example.com' => 'Owner display name']);
|
||||||
|
$this->mailer->expects($this->once())->method('createMessage')->willReturn($message);
|
||||||
|
$this->mailer->expects($this->once())->method('send');
|
||||||
|
|
||||||
|
$user = $this->createMock(IUser::class);
|
||||||
|
$this->userManager->expects($this->once())->method('get')->with('owner')->willReturn($user);
|
||||||
|
$user->expects($this->once())->method('getDisplayName')->willReturn('Owner display name');
|
||||||
|
$user->expects($this->once())->method('getEMailAddress')->willReturn('owner@example.com');
|
||||||
|
|
||||||
|
$this->assertSame('shareObject',
|
||||||
|
$instance->create($share)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \Exception
|
* @expectedException \Exception
|
||||||
*/
|
*/
|
||||||
|
@ -296,6 +398,7 @@ class ShareByMailProviderTest extends TestCase {
|
||||||
$permissions = 1;
|
$permissions = 1;
|
||||||
$token = 'token';
|
$token = 'token';
|
||||||
$password = 'password';
|
$password = 'password';
|
||||||
|
$sendPasswordByTalk = true;
|
||||||
|
|
||||||
|
|
||||||
$instance = $this->getInstance();
|
$instance = $this->getInstance();
|
||||||
|
@ -310,7 +413,8 @@ class ShareByMailProviderTest extends TestCase {
|
||||||
$uidOwner,
|
$uidOwner,
|
||||||
$permissions,
|
$permissions,
|
||||||
$token,
|
$token,
|
||||||
$password
|
$password,
|
||||||
|
$sendPasswordByTalk
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -330,6 +434,7 @@ class ShareByMailProviderTest extends TestCase {
|
||||||
$this->assertSame($permissions, (int)$result[0]['permissions']);
|
$this->assertSame($permissions, (int)$result[0]['permissions']);
|
||||||
$this->assertSame($token, $result[0]['token']);
|
$this->assertSame($token, $result[0]['token']);
|
||||||
$this->assertSame($password, $result[0]['password']);
|
$this->assertSame($password, $result[0]['password']);
|
||||||
|
$this->assertSame($sendPasswordByTalk, (bool)$result[0]['password_by_talk']);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,6 +482,60 @@ class ShareByMailProviderTest extends TestCase {
|
||||||
$this->assertSame($note, $result[0]['note']);
|
$this->assertSame($note, $result[0]['note']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function dataUpdateSendPassword() {
|
||||||
|
return [
|
||||||
|
['password', 'hashed', 'hashed new', false, false, true],
|
||||||
|
['', 'hashed', 'hashed new', false, false, false],
|
||||||
|
[null, 'hashed', 'hashed new', false, false, false],
|
||||||
|
['password', 'hashed', 'hashed', false, false, false],
|
||||||
|
['password', 'hashed', 'hashed new', false, true, false],
|
||||||
|
['password', 'hashed', 'hashed new', true, false, true],
|
||||||
|
['password', 'hashed', 'hashed', true, false, true],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider dataUpdateSendPassword
|
||||||
|
*
|
||||||
|
* @param string|null plainTextPassword
|
||||||
|
* @param string originalPassword
|
||||||
|
* @param string newPassword
|
||||||
|
* @param string originalSendPasswordByTalk
|
||||||
|
* @param string newSendPasswordByTalk
|
||||||
|
* @param bool sendMail
|
||||||
|
*/
|
||||||
|
public function testUpdateSendPassword($plainTextPassword, string $originalPassword, string $newPassword, string $originalSendPasswordByTalk, string $newSendPasswordByTalk, bool $sendMail) {
|
||||||
|
$node = $this->getMockBuilder(File::class)->getMock();
|
||||||
|
$node->expects($this->any())->method('getName')->willReturn('filename');
|
||||||
|
|
||||||
|
$originalShare = $this->getMockBuilder(IShare::class)->getMock();
|
||||||
|
$originalShare->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com');
|
||||||
|
$originalShare->expects($this->any())->method('getNode')->willReturn($node);
|
||||||
|
$originalShare->expects($this->any())->method('getId')->willReturn(42);
|
||||||
|
$originalShare->expects($this->any())->method('getPassword')->willReturn($originalPassword);
|
||||||
|
$originalShare->expects($this->any())->method('getSendPasswordByTalk')->willReturn($originalSendPasswordByTalk);
|
||||||
|
|
||||||
|
$share = $this->getMockBuilder(IShare::class)->getMock();
|
||||||
|
$share->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com');
|
||||||
|
$share->expects($this->any())->method('getNode')->willReturn($node);
|
||||||
|
$share->expects($this->any())->method('getId')->willReturn(42);
|
||||||
|
$share->expects($this->any())->method('getPassword')->willReturn($newPassword);
|
||||||
|
$share->expects($this->any())->method('getSendPasswordByTalk')->willReturn($newSendPasswordByTalk);
|
||||||
|
|
||||||
|
if ($sendMail) {
|
||||||
|
$this->mailer->expects($this->once())->method('send');
|
||||||
|
} else {
|
||||||
|
$this->mailer->expects($this->never())->method('send');
|
||||||
|
}
|
||||||
|
|
||||||
|
$instance = $this->getInstance(['getShareById', 'createPasswordSendActivity']);
|
||||||
|
$instance->expects($this->once())->method('getShareById')->willReturn($originalShare);
|
||||||
|
|
||||||
|
$this->assertSame($share,
|
||||||
|
$instance->update($share, $plainTextPassword)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function testDelete() {
|
public function testDelete() {
|
||||||
$instance = $this->getInstance(['removeShareFromTable']);
|
$instance = $this->getInstance(['removeShareFromTable']);
|
||||||
$this->share->expects($this->once())->method('getId')->willReturn(42);
|
$this->share->expects($this->once())->method('getId')->willReturn(42);
|
||||||
|
|
48
core/Migrations/Version14000Date20180710092004.php
Normal file
48
core/Migrations/Version14000Date20180710092004.php
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2018, Daniel Calviño Sánchez (danxuliu@gmail.com)
|
||||||
|
*
|
||||||
|
* @license GNU AGPL version 3 or any later version
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OC\Core\Migrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Types\Type;
|
||||||
|
use OCP\DB\ISchemaWrapper;
|
||||||
|
use OCP\Migration\SimpleMigrationStep;
|
||||||
|
use OCP\Migration\IOutput;
|
||||||
|
|
||||||
|
class Version14000Date20180710092004 extends SimpleMigrationStep {
|
||||||
|
|
||||||
|
public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) {
|
||||||
|
/** @var ISchemaWrapper $schema */
|
||||||
|
$schema = $schemaClosure();
|
||||||
|
|
||||||
|
$table = $schema->getTable('share');
|
||||||
|
|
||||||
|
if (!$table->hasColumn('password_by_talk')) {
|
||||||
|
$table->addColumn('password_by_talk', Type::BOOLEAN, [
|
||||||
|
'default' => 0,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $schema;
|
||||||
|
}
|
||||||
|
}
|
|
@ -112,6 +112,21 @@
|
||||||
' <span class="icon-loading-small hidden"></span>' +
|
' <span class="icon-loading-small hidden"></span>' +
|
||||||
'</span>' +
|
'</span>' +
|
||||||
'</li>' +
|
'</li>' +
|
||||||
|
'{{#if isTalkEnabled}}' +
|
||||||
|
'<li>' +
|
||||||
|
'<span class="shareOption menuitem">' +
|
||||||
|
'<input id="passwordByTalk-{{cid}}-{{shareId}}" type="checkbox" name="passwordByTalk" class="passwordByTalk checkbox" {{#if isPasswordByTalkSet}}checked="checked"{{/if}} />' +
|
||||||
|
'<label for="passwordByTalk-{{cid}}-{{shareId}}">{{passwordByTalkLabel}}</label>' +
|
||||||
|
'</span>' +
|
||||||
|
'</li>' +
|
||||||
|
'<li class="passwordByTalkMenu-{{cid}}-{{shareId}} {{#unless isPasswordByTalkSet}}hidden{{/unless}}">' +
|
||||||
|
'<span class="passwordByTalkContainer-{{cid}}-{{shareId}} icon-passwordtalk menuitem">' +
|
||||||
|
' <label for="passwordByTalkField-{{cid}}-{{shareId}}" class="hidden-visually" value="{{password}}">{{passwordByTalkLabel}}</label>' +
|
||||||
|
' <input id="passwordByTalkField-{{cid}}-{{shareId}}" class="passwordField" type="password" placeholder="{{passwordByTalkPlaceholder}}" value="{{passwordValue}}" autocomplete="new-password" />' +
|
||||||
|
' <span class="icon-loading-small hidden"></span>' +
|
||||||
|
'</span>' +
|
||||||
|
'</li>' +
|
||||||
|
'{{/if}}' +
|
||||||
'{{/if}}' +
|
'{{/if}}' +
|
||||||
'<li>' +
|
'<li>' +
|
||||||
'<span class="shareOption menuitem">' +
|
'<span class="shareOption menuitem">' +
|
||||||
|
@ -183,6 +198,7 @@
|
||||||
'click .permissions': 'onPermissionChange',
|
'click .permissions': 'onPermissionChange',
|
||||||
'click .expireDate' : 'onExpireDateChange',
|
'click .expireDate' : 'onExpireDateChange',
|
||||||
'click .password' : 'onMailSharePasswordProtectChange',
|
'click .password' : 'onMailSharePasswordProtectChange',
|
||||||
|
'click .passwordByTalk' : 'onMailSharePasswordProtectByTalkChange',
|
||||||
'click .secureDrop' : 'onSecureDropChange',
|
'click .secureDrop' : 'onSecureDropChange',
|
||||||
'keyup input.passwordField': 'onMailSharePasswordKeyUp',
|
'keyup input.passwordField': 'onMailSharePasswordKeyUp',
|
||||||
'focusout input.passwordField': 'onMailSharePasswordEntered',
|
'focusout input.passwordField': 'onMailSharePasswordEntered',
|
||||||
|
@ -260,7 +276,7 @@
|
||||||
var share = this.model.get('shares')[shareIndex];
|
var share = this.model.get('shares')[shareIndex];
|
||||||
var password = share.password;
|
var password = share.password;
|
||||||
var hasPassword = password !== null && password !== '';
|
var hasPassword = password !== null && password !== '';
|
||||||
|
var sendPasswordByTalk = share.send_password_by_talk;
|
||||||
|
|
||||||
return _.extend(hasPermissionOverride, {
|
return _.extend(hasPermissionOverride, {
|
||||||
cid: this.cid,
|
cid: this.cid,
|
||||||
|
@ -282,12 +298,22 @@
|
||||||
isMailShare: shareType === OC.Share.SHARE_TYPE_EMAIL,
|
isMailShare: shareType === OC.Share.SHARE_TYPE_EMAIL,
|
||||||
isCircleShare: shareType === OC.Share.SHARE_TYPE_CIRCLE,
|
isCircleShare: shareType === OC.Share.SHARE_TYPE_CIRCLE,
|
||||||
isFileSharedByMail: shareType === OC.Share.SHARE_TYPE_EMAIL && !this.model.isFolder(),
|
isFileSharedByMail: shareType === OC.Share.SHARE_TYPE_EMAIL && !this.model.isFolder(),
|
||||||
isPasswordSet: hasPassword,
|
isPasswordSet: hasPassword && !sendPasswordByTalk,
|
||||||
|
isPasswordByTalkSet: hasPassword && sendPasswordByTalk,
|
||||||
|
isTalkEnabled: oc_appswebroots['spreed'] !== undefined,
|
||||||
secureDropMode: !this.model.hasReadPermission(shareIndex),
|
secureDropMode: !this.model.hasReadPermission(shareIndex),
|
||||||
hasExpireDate: this.model.getExpireDate(shareIndex) !== null,
|
hasExpireDate: this.model.getExpireDate(shareIndex) !== null,
|
||||||
shareNote: this.model.getNote(shareIndex),
|
shareNote: this.model.getNote(shareIndex),
|
||||||
expireDate: moment(this.model.getExpireDate(shareIndex), 'YYYY-MM-DD').format('DD-MM-YYYY'),
|
expireDate: moment(this.model.getExpireDate(shareIndex), 'YYYY-MM-DD').format('DD-MM-YYYY'),
|
||||||
|
// The password placeholder does not take into account if
|
||||||
|
// sending the password by Talk is enabled or not; when
|
||||||
|
// switching from sending the password by Talk to sending the
|
||||||
|
// password by email the password is reused and the share
|
||||||
|
// updated, so the placeholder already shows the password in the
|
||||||
|
// brief time between disabling sending the password by email
|
||||||
|
// and receiving the updated share.
|
||||||
passwordPlaceholder: hasPassword ? PASSWORD_PLACEHOLDER : PASSWORD_PLACEHOLDER_MESSAGE,
|
passwordPlaceholder: hasPassword ? PASSWORD_PLACEHOLDER : PASSWORD_PLACEHOLDER_MESSAGE,
|
||||||
|
passwordByTalkPlaceholder: (hasPassword && sendPasswordByTalk)? PASSWORD_PLACEHOLDER : PASSWORD_PLACEHOLDER_MESSAGE,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -303,6 +329,7 @@
|
||||||
secureDropLabel: t('core', 'File drop (upload only)'),
|
secureDropLabel: t('core', 'File drop (upload only)'),
|
||||||
expireDateLabel: t('core', 'Set expiration date'),
|
expireDateLabel: t('core', 'Set expiration date'),
|
||||||
passwordLabel: t('core', 'Password protect'),
|
passwordLabel: t('core', 'Password protect'),
|
||||||
|
passwordByTalkLabel: t('core', 'Password protect by Talk'),
|
||||||
crudsLabel: t('core', 'Access control'),
|
crudsLabel: t('core', 'Access control'),
|
||||||
expirationDatePlaceholder: t('core', 'Expiration date'),
|
expirationDatePlaceholder: t('core', 'Expiration date'),
|
||||||
defaultExpireDate: moment().add(1, 'day').format('DD-MM-YYYY'), // Can't expire today
|
defaultExpireDate: moment().add(1, 'day').format('DD-MM-YYYY'), // Can't expire today
|
||||||
|
@ -674,8 +701,10 @@
|
||||||
var inputClass = '#passwordField-' + this.cid + '-' + shareId;
|
var inputClass = '#passwordField-' + this.cid + '-' + shareId;
|
||||||
var passwordField = $(inputClass);
|
var passwordField = $(inputClass);
|
||||||
var state = element.prop('checked');
|
var state = element.prop('checked');
|
||||||
if (!state) {
|
var passwordByTalkElement = $('#passwordByTalk-' + this.cid + '-' + shareId);
|
||||||
this.model.updateShare(shareId, {password: ''});
|
var passwordByTalkState = passwordByTalkElement.prop('checked');
|
||||||
|
if (!state && !passwordByTalkState) {
|
||||||
|
this.model.updateShare(shareId, {password: '', sendPasswordByTalk: false});
|
||||||
passwordField.attr('value', '');
|
passwordField.attr('value', '');
|
||||||
passwordField.removeClass('error');
|
passwordField.removeClass('error');
|
||||||
passwordField.tooltip('hide');
|
passwordField.tooltip('hide');
|
||||||
|
@ -683,13 +712,67 @@
|
||||||
passwordField.attr('placeholder', PASSWORD_PLACEHOLDER_MESSAGE);
|
passwordField.attr('placeholder', PASSWORD_PLACEHOLDER_MESSAGE);
|
||||||
// We first need to reset the password field before we hide it
|
// We first need to reset the password field before we hide it
|
||||||
passwordContainer.toggleClass('hidden', !state);
|
passwordContainer.toggleClass('hidden', !state);
|
||||||
} else {
|
} else if (state) {
|
||||||
|
if (passwordByTalkState) {
|
||||||
|
// Switching from sending the password by Talk to sending
|
||||||
|
// the password by mail can be done keeping the previous
|
||||||
|
// password sent by Talk.
|
||||||
|
this.model.updateShare(shareId, {sendPasswordByTalk: false});
|
||||||
|
|
||||||
|
var passwordByTalkContainerClass = '.passwordByTalkMenu-' + this.cid + '-' + shareId;
|
||||||
|
var passwordByTalkContainer = $(passwordByTalkContainerClass);
|
||||||
|
passwordByTalkContainer.addClass('hidden');
|
||||||
|
passwordByTalkElement.prop('checked', false);
|
||||||
|
}
|
||||||
|
|
||||||
passwordContainer.toggleClass('hidden', !state);
|
passwordContainer.toggleClass('hidden', !state);
|
||||||
passwordField = '#passwordField-' + this.cid + '-' + shareId;
|
passwordField = '#passwordField-' + this.cid + '-' + shareId;
|
||||||
this.$(passwordField).focus();
|
this.$(passwordField).focus();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onMailSharePasswordProtectByTalkChange: function(event) {
|
||||||
|
var element = $(event.target);
|
||||||
|
var li = element.closest('li[data-share-id]');
|
||||||
|
var shareId = li.data('share-id');
|
||||||
|
var passwordByTalkContainerClass = '.passwordByTalkMenu-' + this.cid + '-' + shareId;
|
||||||
|
var passwordByTalkContainer = $(passwordByTalkContainerClass);
|
||||||
|
var loading = this.$el.find(passwordByTalkContainerClass + ' .icon-loading-small');
|
||||||
|
var inputClass = '#passwordByTalkField-' + this.cid + '-' + shareId;
|
||||||
|
var passwordByTalkField = $(inputClass);
|
||||||
|
var state = element.prop('checked');
|
||||||
|
var passwordElement = $('#password-' + this.cid + '-' + shareId);
|
||||||
|
var passwordState = passwordElement.prop('checked');
|
||||||
|
if (!state) {
|
||||||
|
this.model.updateShare(shareId, {password: '', sendPasswordByTalk: false});
|
||||||
|
passwordByTalkField.attr('value', '');
|
||||||
|
passwordByTalkField.removeClass('error');
|
||||||
|
passwordByTalkField.tooltip('hide');
|
||||||
|
loading.addClass('hidden');
|
||||||
|
passwordByTalkField.attr('placeholder', PASSWORD_PLACEHOLDER_MESSAGE);
|
||||||
|
// We first need to reset the password field before we hide it
|
||||||
|
passwordByTalkContainer.toggleClass('hidden', !state);
|
||||||
|
} else if (state) {
|
||||||
|
if (passwordState) {
|
||||||
|
// Enabling sending the password by Talk requires a new
|
||||||
|
// password to be given (the one sent by mail is not reused,
|
||||||
|
// as it would defeat the purpose of checking the identity
|
||||||
|
// of the sharee by Talk if it was already sent by mail), so
|
||||||
|
// the share is not updated until the user explicitly gives
|
||||||
|
// the new password.
|
||||||
|
|
||||||
|
var passwordContainerClass = '.passwordMenu-' + this.cid + '-' + shareId;
|
||||||
|
var passwordContainer = $(passwordContainerClass);
|
||||||
|
passwordContainer.addClass('hidden');
|
||||||
|
passwordElement.prop('checked', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
passwordByTalkContainer.toggleClass('hidden', !state);
|
||||||
|
passwordByTalkField = '#passwordByTalkField-' + this.cid + '-' + shareId;
|
||||||
|
this.$(passwordByTalkField).focus();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
onMailSharePasswordKeyUp: function(event) {
|
onMailSharePasswordKeyUp: function(event) {
|
||||||
if(event.keyCode === 13) {
|
if(event.keyCode === 13) {
|
||||||
this.onMailSharePasswordEntered(event);
|
this.onMailSharePasswordEntered(event);
|
||||||
|
@ -700,8 +783,15 @@
|
||||||
var passwordField = $(event.target);
|
var passwordField = $(event.target);
|
||||||
var li = passwordField.closest('li[data-share-id]');
|
var li = passwordField.closest('li[data-share-id]');
|
||||||
var shareId = li.data('share-id');
|
var shareId = li.data('share-id');
|
||||||
var passwordContainerClass = '.passwordContainer-' + this.cid + '-' + shareId;
|
var passwordContainerClass = '.passwordMenu-' + this.cid + '-' + shareId;
|
||||||
var loading = this.$el.find(passwordContainerClass + ' .icon-loading-small');
|
var passwordByTalkContainerClass = '.passwordByTalkMenu-' + this.cid + '-' + shareId;
|
||||||
|
var sendPasswordByTalk = passwordField.attr('id').startsWith('passwordByTalk');
|
||||||
|
var loading;
|
||||||
|
if (sendPasswordByTalk) {
|
||||||
|
loading = this.$el.find(passwordByTalkContainerClass + ' .icon-loading-small');
|
||||||
|
} else {
|
||||||
|
loading = this.$el.find(passwordContainerClass + ' .icon-loading-small');
|
||||||
|
}
|
||||||
if (!loading.hasClass('hidden')) {
|
if (!loading.hasClass('hidden')) {
|
||||||
// still in process
|
// still in process
|
||||||
return;
|
return;
|
||||||
|
@ -720,7 +810,8 @@
|
||||||
|
|
||||||
|
|
||||||
this.model.updateShare(shareId, {
|
this.model.updateShare(shareId, {
|
||||||
password: password
|
password: password,
|
||||||
|
sendPasswordByTalk: sendPasswordByTalk
|
||||||
}, {
|
}, {
|
||||||
error: function(model, msg) {
|
error: function(model, msg) {
|
||||||
// destroy old tooltips
|
// destroy old tooltips
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
placeholder="<?php p($l->t('Password')); ?>" value=""
|
placeholder="<?php p($l->t('Password')); ?>" value=""
|
||||||
autocomplete="new-password" autocapitalize="off" autocorrect="off"
|
autocomplete="new-password" autocapitalize="off" autocorrect="off"
|
||||||
autofocus />
|
autofocus />
|
||||||
|
<input type="hidden" name="sharingToken" value="<?php p($_['share']->getToken()) ?>" id="sharingToken">
|
||||||
<input type="submit" id="password-submit"
|
<input type="submit" id="password-submit"
|
||||||
class="svg icon-confirm input-button-inline" value="" disabled="disabled" />
|
class="svg icon-confirm input-button-inline" value="" disabled="disabled" />
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -611,6 +611,7 @@ return array(
|
||||||
'OC\\Core\\Migrations\\Version14000Date20180518120534' => $baseDir . '/core/Migrations/Version14000Date20180518120534.php',
|
'OC\\Core\\Migrations\\Version14000Date20180518120534' => $baseDir . '/core/Migrations/Version14000Date20180518120534.php',
|
||||||
'OC\\Core\\Migrations\\Version14000Date20180522074438' => $baseDir . '/core/Migrations/Version14000Date20180522074438.php',
|
'OC\\Core\\Migrations\\Version14000Date20180522074438' => $baseDir . '/core/Migrations/Version14000Date20180522074438.php',
|
||||||
'OC\\Core\\Migrations\\Version14000Date20180626223656' => $baseDir . '/core/Migrations/Version14000Date20180626223656.php',
|
'OC\\Core\\Migrations\\Version14000Date20180626223656' => $baseDir . '/core/Migrations/Version14000Date20180626223656.php',
|
||||||
|
'OC\\Core\\Migrations\\Version14000Date20180710092004' => $baseDir . '/core/Migrations/Version14000Date20180710092004.php',
|
||||||
'OC\\Core\\Migrations\\Version14000Date20180712153140' => $baseDir . '/core/Migrations/Version14000Date20180712153140.php',
|
'OC\\Core\\Migrations\\Version14000Date20180712153140' => $baseDir . '/core/Migrations/Version14000Date20180712153140.php',
|
||||||
'OC\\DB\\Adapter' => $baseDir . '/lib/private/DB/Adapter.php',
|
'OC\\DB\\Adapter' => $baseDir . '/lib/private/DB/Adapter.php',
|
||||||
'OC\\DB\\AdapterMySQL' => $baseDir . '/lib/private/DB/AdapterMySQL.php',
|
'OC\\DB\\AdapterMySQL' => $baseDir . '/lib/private/DB/AdapterMySQL.php',
|
||||||
|
|
|
@ -641,6 +641,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
|
||||||
'OC\\Core\\Migrations\\Version14000Date20180518120534' => __DIR__ . '/../../..' . '/core/Migrations/Version14000Date20180518120534.php',
|
'OC\\Core\\Migrations\\Version14000Date20180518120534' => __DIR__ . '/../../..' . '/core/Migrations/Version14000Date20180518120534.php',
|
||||||
'OC\\Core\\Migrations\\Version14000Date20180522074438' => __DIR__ . '/../../..' . '/core/Migrations/Version14000Date20180522074438.php',
|
'OC\\Core\\Migrations\\Version14000Date20180522074438' => __DIR__ . '/../../..' . '/core/Migrations/Version14000Date20180522074438.php',
|
||||||
'OC\\Core\\Migrations\\Version14000Date20180626223656' => __DIR__ . '/../../..' . '/core/Migrations/Version14000Date20180626223656.php',
|
'OC\\Core\\Migrations\\Version14000Date20180626223656' => __DIR__ . '/../../..' . '/core/Migrations/Version14000Date20180626223656.php',
|
||||||
|
'OC\\Core\\Migrations\\Version14000Date20180710092004' => __DIR__ . '/../../..' . '/core/Migrations/Version14000Date20180710092004.php',
|
||||||
'OC\\Core\\Migrations\\Version14000Date20180712153140' => __DIR__ . '/../../..' . '/core/Migrations/Version14000Date20180712153140.php',
|
'OC\\Core\\Migrations\\Version14000Date20180712153140' => __DIR__ . '/../../..' . '/core/Migrations/Version14000Date20180712153140.php',
|
||||||
'OC\\DB\\Adapter' => __DIR__ . '/../../..' . '/lib/private/DB/Adapter.php',
|
'OC\\DB\\Adapter' => __DIR__ . '/../../..' . '/lib/private/DB/Adapter.php',
|
||||||
'OC\\DB\\AdapterMySQL' => __DIR__ . '/../../..' . '/lib/private/DB/AdapterMySQL.php',
|
'OC\\DB\\AdapterMySQL' => __DIR__ . '/../../..' . '/lib/private/DB/AdapterMySQL.php',
|
||||||
|
|
|
@ -827,10 +827,20 @@ class Manager implements IManager {
|
||||||
$expirationDateUpdated = true;
|
$expirationDateUpdated = true;
|
||||||
}
|
}
|
||||||
} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
|
} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
|
||||||
|
// The new password is not set again if it is the same as the old
|
||||||
|
// one, unless when switching from sending by Talk to sending by
|
||||||
|
// mail.
|
||||||
$plainTextPassword = $share->getPassword();
|
$plainTextPassword = $share->getPassword();
|
||||||
if (!$this->updateSharePasswordIfNeeded($share, $originalShare)) {
|
if (!empty($plainTextPassword) && !$this->updateSharePasswordIfNeeded($share, $originalShare) &&
|
||||||
|
!($originalShare->getSendPasswordByTalk() && !$share->getSendPasswordByTalk())) {
|
||||||
$plainTextPassword = null;
|
$plainTextPassword = null;
|
||||||
}
|
}
|
||||||
|
if (empty($plainTextPassword) && !$originalShare->getSendPasswordByTalk() && $share->getSendPasswordByTalk()) {
|
||||||
|
// If the same password was already sent by mail the recipient
|
||||||
|
// would already have access to the share without having to call
|
||||||
|
// the sharer to verify her identity
|
||||||
|
throw new \InvalidArgumentException('Can’t enable sending the password by Talk without setting a new password');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->pathCreateChecks($share->getNode());
|
$this->pathCreateChecks($share->getNode());
|
||||||
|
|
|
@ -63,6 +63,8 @@ class Share implements \OCP\Share\IShare {
|
||||||
private $expireDate;
|
private $expireDate;
|
||||||
/** @var string */
|
/** @var string */
|
||||||
private $password;
|
private $password;
|
||||||
|
/** @var bool */
|
||||||
|
private $sendPasswordByTalk = false;
|
||||||
/** @var string */
|
/** @var string */
|
||||||
private $token;
|
private $token;
|
||||||
/** @var int */
|
/** @var int */
|
||||||
|
@ -402,6 +404,21 @@ class Share implements \OCP\Share\IShare {
|
||||||
return $this->password;
|
return $this->password;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function setSendPasswordByTalk(bool $sendPasswordByTalk) {
|
||||||
|
$this->sendPasswordByTalk = $sendPasswordByTalk;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
|
public function getSendPasswordByTalk(): bool {
|
||||||
|
return $this->sendPasswordByTalk;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -312,6 +312,29 @@ interface IShare {
|
||||||
*/
|
*/
|
||||||
public function getPassword();
|
public function getPassword();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set if the recipient can start a conversation with the owner to get the
|
||||||
|
* password using Nextcloud Talk.
|
||||||
|
*
|
||||||
|
* @param bool $sendPasswordByTalk
|
||||||
|
* @return \OCP\Share\IShare The modified object
|
||||||
|
* @since 14.0.0
|
||||||
|
*/
|
||||||
|
public function setSendPasswordByTalk(bool $sendPasswordByTalk);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if the recipient can start a conversation with the owner to get the
|
||||||
|
* password using Nextcloud Talk.
|
||||||
|
* The returned value does not take into account other factors, like Talk
|
||||||
|
* being enabled for the owner of the share or not; it just cover whether
|
||||||
|
* the option is enabled for the share itself or not.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
* @since 14.0.0
|
||||||
|
*/
|
||||||
|
public function getSendPasswordByTalk(): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the public link token.
|
* Set the public link token.
|
||||||
*
|
*
|
||||||
|
|
|
@ -2716,6 +2716,442 @@ class ManagerTest extends \Test\TestCase {
|
||||||
$manager->updateShare($share);
|
$manager->updateShare($share);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testUpdateShareMailEnableSendPasswordByTalk() {
|
||||||
|
$manager = $this->createManagerMock()
|
||||||
|
->setMethods([
|
||||||
|
'canShare',
|
||||||
|
'getShareById',
|
||||||
|
'generalCreateChecks',
|
||||||
|
'verifyPassword',
|
||||||
|
'pathCreateChecks',
|
||||||
|
'linkCreateChecks',
|
||||||
|
'validateExpirationDate',
|
||||||
|
])
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$originalShare = $this->manager->newShare();
|
||||||
|
$originalShare->setShareType(\OCP\Share::SHARE_TYPE_EMAIL)
|
||||||
|
->setPermissions(\OCP\Constants::PERMISSION_ALL)
|
||||||
|
->setPassword(null)
|
||||||
|
->setSendPasswordByTalk(false);
|
||||||
|
|
||||||
|
$tomorrow = new \DateTime();
|
||||||
|
$tomorrow->setTime(0,0,0);
|
||||||
|
$tomorrow->add(new \DateInterval('P1D'));
|
||||||
|
|
||||||
|
$file = $this->createMock(File::class);
|
||||||
|
$file->method('getId')->willReturn(100);
|
||||||
|
|
||||||
|
$share = $this->manager->newShare();
|
||||||
|
$share->setProviderId('foo')
|
||||||
|
->setId('42')
|
||||||
|
->setShareType(\OCP\Share::SHARE_TYPE_EMAIL)
|
||||||
|
->setToken('token')
|
||||||
|
->setSharedBy('owner')
|
||||||
|
->setShareOwner('owner')
|
||||||
|
->setPassword('password')
|
||||||
|
->setSendPasswordByTalk(true)
|
||||||
|
->setExpirationDate($tomorrow)
|
||||||
|
->setNode($file)
|
||||||
|
->setPermissions(\OCP\Constants::PERMISSION_ALL);
|
||||||
|
|
||||||
|
$manager->expects($this->once())->method('canShare')->willReturn(true);
|
||||||
|
$manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
|
||||||
|
$manager->expects($this->once())->method('generalCreateChecks')->with($share);
|
||||||
|
$manager->expects($this->once())->method('verifyPassword')->with('password');
|
||||||
|
$manager->expects($this->once())->method('pathCreateChecks')->with($file);
|
||||||
|
$manager->expects($this->never())->method('linkCreateChecks');
|
||||||
|
$manager->expects($this->never())->method('validateExpirationDate');
|
||||||
|
|
||||||
|
$this->hasher->expects($this->once())
|
||||||
|
->method('hash')
|
||||||
|
->with('password')
|
||||||
|
->willReturn('hashed');
|
||||||
|
|
||||||
|
$this->defaultProvider->expects($this->once())
|
||||||
|
->method('update')
|
||||||
|
->with($share, 'password')
|
||||||
|
->willReturn($share);
|
||||||
|
|
||||||
|
$hookListner = $this->getMockBuilder('Dummy')->setMethods(['post'])->getMock();
|
||||||
|
\OCP\Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListner, 'post');
|
||||||
|
$hookListner->expects($this->never())->method('post');
|
||||||
|
|
||||||
|
$hookListner2 = $this->getMockBuilder('Dummy')->setMethods(['post'])->getMock();
|
||||||
|
\OCP\Util::connectHook('OCP\Share', 'post_update_password', $hookListner2, 'post');
|
||||||
|
$hookListner2->expects($this->once())->method('post')->with([
|
||||||
|
'itemType' => 'file',
|
||||||
|
'itemSource' => 100,
|
||||||
|
'uidOwner' => 'owner',
|
||||||
|
'token' => 'token',
|
||||||
|
'disabled' => false,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$hookListner3 = $this->getMockBuilder('Dummy')->setMethods(['post'])->getMock();
|
||||||
|
\OCP\Util::connectHook('OCP\Share', 'post_update_permissions', $hookListner3, 'post');
|
||||||
|
$hookListner3->expects($this->never())->method('post');
|
||||||
|
|
||||||
|
$manager->updateShare($share);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \InvalidArgumentException
|
||||||
|
* @expectedExceptionMessage Can’t enable sending the password by Talk without setting a new password
|
||||||
|
*/
|
||||||
|
public function testUpdateShareMailEnableSendPasswordByTalkWithNoPassword() {
|
||||||
|
$manager = $this->createManagerMock()
|
||||||
|
->setMethods([
|
||||||
|
'canShare',
|
||||||
|
'getShareById',
|
||||||
|
'generalCreateChecks',
|
||||||
|
'verifyPassword',
|
||||||
|
'pathCreateChecks',
|
||||||
|
'linkCreateChecks',
|
||||||
|
'validateExpirationDate',
|
||||||
|
])
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$originalShare = $this->manager->newShare();
|
||||||
|
$originalShare->setShareType(\OCP\Share::SHARE_TYPE_EMAIL)
|
||||||
|
->setPermissions(\OCP\Constants::PERMISSION_ALL)
|
||||||
|
->setPassword(null)
|
||||||
|
->setSendPasswordByTalk(false);
|
||||||
|
|
||||||
|
$tomorrow = new \DateTime();
|
||||||
|
$tomorrow->setTime(0,0,0);
|
||||||
|
$tomorrow->add(new \DateInterval('P1D'));
|
||||||
|
|
||||||
|
$file = $this->createMock(File::class);
|
||||||
|
$file->method('getId')->willReturn(100);
|
||||||
|
|
||||||
|
$share = $this->manager->newShare();
|
||||||
|
$share->setProviderId('foo')
|
||||||
|
->setId('42')
|
||||||
|
->setShareType(\OCP\Share::SHARE_TYPE_EMAIL)
|
||||||
|
->setToken('token')
|
||||||
|
->setSharedBy('owner')
|
||||||
|
->setShareOwner('owner')
|
||||||
|
->setPassword(null)
|
||||||
|
->setSendPasswordByTalk(true)
|
||||||
|
->setExpirationDate($tomorrow)
|
||||||
|
->setNode($file)
|
||||||
|
->setPermissions(\OCP\Constants::PERMISSION_ALL);
|
||||||
|
|
||||||
|
$manager->expects($this->once())->method('canShare')->willReturn(true);
|
||||||
|
$manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
|
||||||
|
$manager->expects($this->once())->method('generalCreateChecks')->with($share);
|
||||||
|
$manager->expects($this->never())->method('verifyPassword');
|
||||||
|
$manager->expects($this->never())->method('pathCreateChecks');
|
||||||
|
$manager->expects($this->never())->method('linkCreateChecks');
|
||||||
|
$manager->expects($this->never())->method('validateExpirationDate');
|
||||||
|
|
||||||
|
$this->hasher->expects($this->never())
|
||||||
|
->method('hash');
|
||||||
|
|
||||||
|
$this->defaultProvider->expects($this->never())
|
||||||
|
->method('update');
|
||||||
|
|
||||||
|
$hookListner = $this->getMockBuilder('Dummy')->setMethods(['post'])->getMock();
|
||||||
|
\OCP\Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListner, 'post');
|
||||||
|
$hookListner->expects($this->never())->method('post');
|
||||||
|
|
||||||
|
$hookListner2 = $this->getMockBuilder('Dummy')->setMethods(['post'])->getMock();
|
||||||
|
\OCP\Util::connectHook('OCP\Share', 'post_update_password', $hookListner2, 'post');
|
||||||
|
$hookListner2->expects($this->never())->method('post');
|
||||||
|
|
||||||
|
$hookListner3 = $this->getMockBuilder('Dummy')->setMethods(['post'])->getMock();
|
||||||
|
\OCP\Util::connectHook('OCP\Share', 'post_update_permissions', $hookListner3, 'post');
|
||||||
|
$hookListner3->expects($this->never())->method('post');
|
||||||
|
|
||||||
|
$manager->updateShare($share);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \InvalidArgumentException
|
||||||
|
* @expectedExceptionMessage Can’t enable sending the password by Talk without setting a new password
|
||||||
|
*/
|
||||||
|
public function testUpdateShareMailEnableSendPasswordByTalkRemovingPassword() {
|
||||||
|
$manager = $this->createManagerMock()
|
||||||
|
->setMethods([
|
||||||
|
'canShare',
|
||||||
|
'getShareById',
|
||||||
|
'generalCreateChecks',
|
||||||
|
'verifyPassword',
|
||||||
|
'pathCreateChecks',
|
||||||
|
'linkCreateChecks',
|
||||||
|
'validateExpirationDate',
|
||||||
|
])
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$originalShare = $this->manager->newShare();
|
||||||
|
$originalShare->setShareType(\OCP\Share::SHARE_TYPE_EMAIL)
|
||||||
|
->setPermissions(\OCP\Constants::PERMISSION_ALL)
|
||||||
|
->setPassword('password')
|
||||||
|
->setSendPasswordByTalk(false);
|
||||||
|
|
||||||
|
$tomorrow = new \DateTime();
|
||||||
|
$tomorrow->setTime(0,0,0);
|
||||||
|
$tomorrow->add(new \DateInterval('P1D'));
|
||||||
|
|
||||||
|
$file = $this->createMock(File::class);
|
||||||
|
$file->method('getId')->willReturn(100);
|
||||||
|
|
||||||
|
$share = $this->manager->newShare();
|
||||||
|
$share->setProviderId('foo')
|
||||||
|
->setId('42')
|
||||||
|
->setShareType(\OCP\Share::SHARE_TYPE_EMAIL)
|
||||||
|
->setToken('token')
|
||||||
|
->setSharedBy('owner')
|
||||||
|
->setShareOwner('owner')
|
||||||
|
->setPassword(null)
|
||||||
|
->setSendPasswordByTalk(true)
|
||||||
|
->setExpirationDate($tomorrow)
|
||||||
|
->setNode($file)
|
||||||
|
->setPermissions(\OCP\Constants::PERMISSION_ALL);
|
||||||
|
|
||||||
|
$manager->expects($this->once())->method('canShare')->willReturn(true);
|
||||||
|
$manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
|
||||||
|
$manager->expects($this->once())->method('generalCreateChecks')->with($share);
|
||||||
|
$manager->expects($this->never())->method('verifyPassword');
|
||||||
|
$manager->expects($this->never())->method('pathCreateChecks');
|
||||||
|
$manager->expects($this->never())->method('linkCreateChecks');
|
||||||
|
$manager->expects($this->never())->method('validateExpirationDate');
|
||||||
|
|
||||||
|
$this->hasher->expects($this->never())
|
||||||
|
->method('hash');
|
||||||
|
|
||||||
|
$this->defaultProvider->expects($this->never())
|
||||||
|
->method('update');
|
||||||
|
|
||||||
|
$hookListner = $this->getMockBuilder('Dummy')->setMethods(['post'])->getMock();
|
||||||
|
\OCP\Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListner, 'post');
|
||||||
|
$hookListner->expects($this->never())->method('post');
|
||||||
|
|
||||||
|
$hookListner2 = $this->getMockBuilder('Dummy')->setMethods(['post'])->getMock();
|
||||||
|
\OCP\Util::connectHook('OCP\Share', 'post_update_password', $hookListner2, 'post');
|
||||||
|
$hookListner2->expects($this->never())->method('post');
|
||||||
|
|
||||||
|
$hookListner3 = $this->getMockBuilder('Dummy')->setMethods(['post'])->getMock();
|
||||||
|
\OCP\Util::connectHook('OCP\Share', 'post_update_permissions', $hookListner3, 'post');
|
||||||
|
$hookListner3->expects($this->never())->method('post');
|
||||||
|
|
||||||
|
$manager->updateShare($share);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \InvalidArgumentException
|
||||||
|
* @expectedExceptionMessage Can’t enable sending the password by Talk without setting a new password
|
||||||
|
*/
|
||||||
|
public function testUpdateShareMailEnableSendPasswordByTalkRemovingPasswordWithEmptyString() {
|
||||||
|
$manager = $this->createManagerMock()
|
||||||
|
->setMethods([
|
||||||
|
'canShare',
|
||||||
|
'getShareById',
|
||||||
|
'generalCreateChecks',
|
||||||
|
'verifyPassword',
|
||||||
|
'pathCreateChecks',
|
||||||
|
'linkCreateChecks',
|
||||||
|
'validateExpirationDate',
|
||||||
|
])
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$originalShare = $this->manager->newShare();
|
||||||
|
$originalShare->setShareType(\OCP\Share::SHARE_TYPE_EMAIL)
|
||||||
|
->setPermissions(\OCP\Constants::PERMISSION_ALL)
|
||||||
|
->setPassword('password')
|
||||||
|
->setSendPasswordByTalk(false);
|
||||||
|
|
||||||
|
$tomorrow = new \DateTime();
|
||||||
|
$tomorrow->setTime(0,0,0);
|
||||||
|
$tomorrow->add(new \DateInterval('P1D'));
|
||||||
|
|
||||||
|
$file = $this->createMock(File::class);
|
||||||
|
$file->method('getId')->willReturn(100);
|
||||||
|
|
||||||
|
$share = $this->manager->newShare();
|
||||||
|
$share->setProviderId('foo')
|
||||||
|
->setId('42')
|
||||||
|
->setShareType(\OCP\Share::SHARE_TYPE_EMAIL)
|
||||||
|
->setToken('token')
|
||||||
|
->setSharedBy('owner')
|
||||||
|
->setShareOwner('owner')
|
||||||
|
->setPassword('')
|
||||||
|
->setSendPasswordByTalk(true)
|
||||||
|
->setExpirationDate($tomorrow)
|
||||||
|
->setNode($file)
|
||||||
|
->setPermissions(\OCP\Constants::PERMISSION_ALL);
|
||||||
|
|
||||||
|
$manager->expects($this->once())->method('canShare')->willReturn(true);
|
||||||
|
$manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
|
||||||
|
$manager->expects($this->once())->method('generalCreateChecks')->with($share);
|
||||||
|
$manager->expects($this->never())->method('verifyPassword');
|
||||||
|
$manager->expects($this->never())->method('pathCreateChecks');
|
||||||
|
$manager->expects($this->never())->method('linkCreateChecks');
|
||||||
|
$manager->expects($this->never())->method('validateExpirationDate');
|
||||||
|
|
||||||
|
$this->hasher->expects($this->never())
|
||||||
|
->method('hash');
|
||||||
|
|
||||||
|
$this->defaultProvider->expects($this->never())
|
||||||
|
->method('update');
|
||||||
|
|
||||||
|
$hookListner = $this->getMockBuilder('Dummy')->setMethods(['post'])->getMock();
|
||||||
|
\OCP\Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListner, 'post');
|
||||||
|
$hookListner->expects($this->never())->method('post');
|
||||||
|
|
||||||
|
$hookListner2 = $this->getMockBuilder('Dummy')->setMethods(['post'])->getMock();
|
||||||
|
\OCP\Util::connectHook('OCP\Share', 'post_update_password', $hookListner2, 'post');
|
||||||
|
$hookListner2->expects($this->never())->method('post');
|
||||||
|
|
||||||
|
$hookListner3 = $this->getMockBuilder('Dummy')->setMethods(['post'])->getMock();
|
||||||
|
\OCP\Util::connectHook('OCP\Share', 'post_update_permissions', $hookListner3, 'post');
|
||||||
|
$hookListner3->expects($this->never())->method('post');
|
||||||
|
|
||||||
|
$manager->updateShare($share);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \InvalidArgumentException
|
||||||
|
* @expectedExceptionMessage Can’t enable sending the password by Talk without setting a new password
|
||||||
|
*/
|
||||||
|
public function testUpdateShareMailEnableSendPasswordByTalkWithPreviousPassword() {
|
||||||
|
$manager = $this->createManagerMock()
|
||||||
|
->setMethods([
|
||||||
|
'canShare',
|
||||||
|
'getShareById',
|
||||||
|
'generalCreateChecks',
|
||||||
|
'verifyPassword',
|
||||||
|
'pathCreateChecks',
|
||||||
|
'linkCreateChecks',
|
||||||
|
'validateExpirationDate',
|
||||||
|
])
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$originalShare = $this->manager->newShare();
|
||||||
|
$originalShare->setShareType(\OCP\Share::SHARE_TYPE_EMAIL)
|
||||||
|
->setPermissions(\OCP\Constants::PERMISSION_ALL)
|
||||||
|
->setPassword('password')
|
||||||
|
->setSendPasswordByTalk(false);
|
||||||
|
|
||||||
|
$tomorrow = new \DateTime();
|
||||||
|
$tomorrow->setTime(0,0,0);
|
||||||
|
$tomorrow->add(new \DateInterval('P1D'));
|
||||||
|
|
||||||
|
$file = $this->createMock(File::class);
|
||||||
|
$file->method('getId')->willReturn(100);
|
||||||
|
|
||||||
|
$share = $this->manager->newShare();
|
||||||
|
$share->setProviderId('foo')
|
||||||
|
->setId('42')
|
||||||
|
->setShareType(\OCP\Share::SHARE_TYPE_EMAIL)
|
||||||
|
->setToken('token')
|
||||||
|
->setSharedBy('owner')
|
||||||
|
->setShareOwner('owner')
|
||||||
|
->setPassword('password')
|
||||||
|
->setSendPasswordByTalk(true)
|
||||||
|
->setExpirationDate($tomorrow)
|
||||||
|
->setNode($file)
|
||||||
|
->setPermissions(\OCP\Constants::PERMISSION_ALL);
|
||||||
|
|
||||||
|
$manager->expects($this->once())->method('canShare')->willReturn(true);
|
||||||
|
$manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
|
||||||
|
$manager->expects($this->once())->method('generalCreateChecks')->with($share);
|
||||||
|
$manager->expects($this->never())->method('verifyPassword');
|
||||||
|
$manager->expects($this->never())->method('pathCreateChecks');
|
||||||
|
$manager->expects($this->never())->method('linkCreateChecks');
|
||||||
|
$manager->expects($this->never())->method('validateExpirationDate');
|
||||||
|
|
||||||
|
$this->hasher->expects($this->never())
|
||||||
|
->method('hash');
|
||||||
|
|
||||||
|
$this->defaultProvider->expects($this->never())
|
||||||
|
->method('update');
|
||||||
|
|
||||||
|
$hookListner = $this->getMockBuilder('Dummy')->setMethods(['post'])->getMock();
|
||||||
|
\OCP\Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListner, 'post');
|
||||||
|
$hookListner->expects($this->never())->method('post');
|
||||||
|
|
||||||
|
$hookListner2 = $this->getMockBuilder('Dummy')->setMethods(['post'])->getMock();
|
||||||
|
\OCP\Util::connectHook('OCP\Share', 'post_update_password', $hookListner2, 'post');
|
||||||
|
$hookListner2->expects($this->never())->method('post');
|
||||||
|
|
||||||
|
$hookListner3 = $this->getMockBuilder('Dummy')->setMethods(['post'])->getMock();
|
||||||
|
\OCP\Util::connectHook('OCP\Share', 'post_update_permissions', $hookListner3, 'post');
|
||||||
|
$hookListner3->expects($this->never())->method('post');
|
||||||
|
|
||||||
|
$manager->updateShare($share);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUpdateShareMailDisableSendPasswordByTalkWithPreviousPassword() {
|
||||||
|
$manager = $this->createManagerMock()
|
||||||
|
->setMethods([
|
||||||
|
'canShare',
|
||||||
|
'getShareById',
|
||||||
|
'generalCreateChecks',
|
||||||
|
'verifyPassword',
|
||||||
|
'pathCreateChecks',
|
||||||
|
'linkCreateChecks',
|
||||||
|
'validateExpirationDate',
|
||||||
|
])
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$originalShare = $this->manager->newShare();
|
||||||
|
$originalShare->setShareType(\OCP\Share::SHARE_TYPE_EMAIL)
|
||||||
|
->setPermissions(\OCP\Constants::PERMISSION_ALL)
|
||||||
|
->setPassword('password')
|
||||||
|
->setSendPasswordByTalk(true);
|
||||||
|
|
||||||
|
$tomorrow = new \DateTime();
|
||||||
|
$tomorrow->setTime(0,0,0);
|
||||||
|
$tomorrow->add(new \DateInterval('P1D'));
|
||||||
|
|
||||||
|
$file = $this->createMock(File::class);
|
||||||
|
$file->method('getId')->willReturn(100);
|
||||||
|
|
||||||
|
$share = $this->manager->newShare();
|
||||||
|
$share->setProviderId('foo')
|
||||||
|
->setId('42')
|
||||||
|
->setShareType(\OCP\Share::SHARE_TYPE_EMAIL)
|
||||||
|
->setToken('token')
|
||||||
|
->setSharedBy('owner')
|
||||||
|
->setShareOwner('owner')
|
||||||
|
->setPassword('password')
|
||||||
|
->setSendPasswordByTalk(false)
|
||||||
|
->setExpirationDate($tomorrow)
|
||||||
|
->setNode($file)
|
||||||
|
->setPermissions(\OCP\Constants::PERMISSION_ALL);
|
||||||
|
|
||||||
|
$manager->expects($this->once())->method('canShare')->willReturn(true);
|
||||||
|
$manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare);
|
||||||
|
$manager->expects($this->once())->method('generalCreateChecks')->with($share);
|
||||||
|
$manager->expects($this->once())->method('pathCreateChecks')->with($file);
|
||||||
|
$manager->expects($this->never())->method('verifyPassword');
|
||||||
|
$manager->expects($this->never())->method('linkCreateChecks');
|
||||||
|
$manager->expects($this->never())->method('validateExpirationDate');
|
||||||
|
|
||||||
|
$this->hasher->expects($this->never())
|
||||||
|
->method('hash');
|
||||||
|
|
||||||
|
$this->defaultProvider->expects($this->once())
|
||||||
|
->method('update')
|
||||||
|
->with($share, 'password')
|
||||||
|
->willReturn($share);
|
||||||
|
|
||||||
|
$hookListner = $this->getMockBuilder('Dummy')->setMethods(['post'])->getMock();
|
||||||
|
\OCP\Util::connectHook('OCP\Share', 'post_set_expiration_date', $hookListner, 'post');
|
||||||
|
$hookListner->expects($this->never())->method('post');
|
||||||
|
|
||||||
|
$hookListner2 = $this->getMockBuilder('Dummy')->setMethods(['post'])->getMock();
|
||||||
|
\OCP\Util::connectHook('OCP\Share', 'post_update_password', $hookListner2, 'post');
|
||||||
|
$hookListner2->expects($this->never())->method('post');
|
||||||
|
|
||||||
|
$hookListner3 = $this->getMockBuilder('Dummy')->setMethods(['post'])->getMock();
|
||||||
|
\OCP\Util::connectHook('OCP\Share', 'post_update_permissions', $hookListner3, 'post');
|
||||||
|
$hookListner3->expects($this->never())->method('post');
|
||||||
|
|
||||||
|
$manager->updateShare($share);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException \InvalidArgumentException
|
* @expectedException \InvalidArgumentException
|
||||||
* @expectedExceptionMessage Can’t change target of link share
|
* @expectedExceptionMessage Can’t change target of link share
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
// between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel
|
// between betas, final and RCs. This is _not_ the public version number. Reset minor/patchlevel
|
||||||
// when updating major/minor version number.
|
// when updating major/minor version number.
|
||||||
|
|
||||||
$OC_Version = array(14, 0, 0, 11);
|
$OC_Version = array(14, 0, 0, 12);
|
||||||
|
|
||||||
// The human readable string
|
// The human readable string
|
||||||
$OC_VersionString = '14.0.0 alpha';
|
$OC_VersionString = '14.0.0 alpha';
|
||||||
|
|
Loading…
Reference in a new issue