diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/dav/lib/Connector/Sabre/ExceptionLoggerPlugin.php | 7 | ||||
-rw-r--r-- | apps/dav/lib/Connector/Sabre/ObjectTree.php | 2 | ||||
-rw-r--r-- | apps/files/ajax/list.php | 10 | ||||
-rw-r--r-- | apps/files/js/filelist.js | 2 | ||||
-rw-r--r-- | apps/files/tests/js/filelistSpec.js | 2 | ||||
-rw-r--r-- | apps/files_sharing/lib/Controller/ShareesAPIController.php | 70 | ||||
-rw-r--r-- | apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php | 256 |
7 files changed, 327 insertions, 22 deletions
diff --git a/apps/dav/lib/Connector/Sabre/ExceptionLoggerPlugin.php b/apps/dav/lib/Connector/Sabre/ExceptionLoggerPlugin.php index 56a8b2b7641..4f7c2286827 100644 --- a/apps/dav/lib/Connector/Sabre/ExceptionLoggerPlugin.php +++ b/apps/dav/lib/Connector/Sabre/ExceptionLoggerPlugin.php @@ -32,7 +32,7 @@ use Sabre\DAV\Exception; use Sabre\HTTP\Response; class ExceptionLoggerPlugin extends \Sabre\DAV\ServerPlugin { - protected $nonFatalExceptions = array( + protected $nonFatalExceptions = [ 'Sabre\DAV\Exception\NotAuthenticated' => true, // If tokenauth can throw this exception (which is basically as // NotAuthenticated. So not fatal. @@ -47,7 +47,10 @@ class ExceptionLoggerPlugin extends \Sabre\DAV\ServerPlugin { // forbidden can be expected when trying to upload to // read-only folders for example 'Sabre\DAV\Exception\Forbidden' => true, - ); + // Happens when an external storage or federated share is temporarily + // not available + 'Sabre\DAV\Exception\StorageNotAvailableException' => true, + ]; /** @var string */ private $appName; diff --git a/apps/dav/lib/Connector/Sabre/ObjectTree.php b/apps/dav/lib/Connector/Sabre/ObjectTree.php index af1cf79e1db..554a7ad86ca 100644 --- a/apps/dav/lib/Connector/Sabre/ObjectTree.php +++ b/apps/dav/lib/Connector/Sabre/ObjectTree.php @@ -159,7 +159,7 @@ class ObjectTree extends \Sabre\DAV\Tree { try { $info = $this->fileView->getFileInfo($path); } catch (StorageNotAvailableException $e) { - throw new \Sabre\DAV\Exception\ServiceUnavailable('Storage not available'); + throw new \Sabre\DAV\Exception\ServiceUnavailable('Storage is temporarily not available'); } catch (StorageInvalidException $e) { throw new \Sabre\DAV\Exception\NotFound('Storage ' . $path . ' is invalid'); } catch (LockedException $e) { diff --git a/apps/files/ajax/list.php b/apps/files/ajax/list.php index bb95f124dab..2cd09765435 100644 --- a/apps/files/ajax/list.php +++ b/apps/files/ajax/list.php @@ -79,12 +79,12 @@ try { OCP\JSON::success(array('data' => $data)); } catch (\OCP\Files\StorageNotAvailableException $e) { \OCP\Util::logException('files', $e); - OCP\JSON::error(array( - 'data' => array( + OCP\JSON::error([ + 'data' => [ 'exception' => '\OCP\Files\StorageNotAvailableException', - 'message' => $l->t('Storage not available') - ) - )); + 'message' => $l->t('Storage is temporarily not available') + ] + ]); } catch (\OCP\Files\StorageInvalidException $e) { \OCP\Util::logException('files', $e); OCP\JSON::error(array( diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index e728a816cc0..bf4fd75d4cc 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -1625,7 +1625,7 @@ this.changeDirectory('/'); // TODO: read error message from exception OC.Notification.showTemporary( - t('files', 'Storage not available') + t('files', 'Storage is temporarily not available') ); } return false; diff --git a/apps/files/tests/js/filelistSpec.js b/apps/files/tests/js/filelistSpec.js index 1c73bc845c5..3b0e0b83b82 100644 --- a/apps/files/tests/js/filelistSpec.js +++ b/apps/files/tests/js/filelistSpec.js @@ -2836,7 +2836,7 @@ describe('OCA.Files.FileList tests', function() { }); it('redirects to root folder and shows notification in case of storage not available', function () { expect(notificationStub.notCalled).toEqual(true); - deferredList.reject(503, 'Storage not available'); + deferredList.reject(503, 'Storage is temporarily not available'); expect(fileList.getCurrentDirectory()).toEqual('/'); expect(getFolderContentsStub.calledTwice).toEqual(true); diff --git a/apps/files_sharing/lib/Controller/ShareesAPIController.php b/apps/files_sharing/lib/Controller/ShareesAPIController.php index a2063803450..99c6b55240d 100644 --- a/apps/files_sharing/lib/Controller/ShareesAPIController.php +++ b/apps/files_sharing/lib/Controller/ShareesAPIController.php @@ -83,10 +83,12 @@ class ShareesAPIController extends OCSController { 'users' => [], 'groups' => [], 'remotes' => [], + 'emails' => [], ], 'users' => [], 'groups' => [], 'remotes' => [], + 'emails' => [], ]; protected $reachedEndFor = []; @@ -403,6 +405,68 @@ class ShareesAPIController extends OCSController { } /** + * @param string $search + */ + protected function getEmails($search) { + $this->result['emails'] = []; + $this->result['exact']['emails'] = []; + + $foundEmail = false; + + // Search in contacts + //@todo Pagination missing + $addressBookContacts = $this->contactsManager->search($search, ['FN', 'EMAIL']); + foreach ($addressBookContacts as $contact) { + if (!isset($contact['EMAIL'])) { + continue; + } + + $emails = $contact['EMAIL']; + if (!is_array($emails)) { + $emails = [$emails]; + } + + foreach ($emails as $email) { + if (strtolower($search) === strtolower($contact['FN']) || + strtolower($search) === strtolower($email) + ) { + if (strtolower($search) === strtolower($email)) { + $foundEmail = true; + } + + $this->result['exact']['emails'][] = [ + 'label' => $contact['FN'], + 'value' => [ + 'shareType' => Share::SHARE_TYPE_EMAIL, + 'shareWith' => $email, + ], + ]; + } else if ($this->shareeEnumeration) { + $this->result['emails'][] = [ + 'label' => $contact['FN'], + 'value' => [ + 'shareType' => Share::SHARE_TYPE_EMAIL, + 'shareWith' => $email, + ], + ]; + } + } + } + + if (!$foundEmail && substr_count($search, '@') >= 1 && $this->offset === 0) { + $this->result['exact']['emails'][] = [ + 'label' => $search, + 'value' => [ + 'shareType' => Share::SHARE_TYPE_EMAIL, + 'shareWith' => $search, + ], + ]; + } + + $this->reachedEndFor[] = 'emails'; + } + + /** * @NoAdminRequired * * @param string $search @@ -429,6 +493,7 @@ class ShareesAPIController extends OCSController { $shareTypes[] = Share::SHARE_TYPE_GROUP; } + $shareTypes[] = Share::SHARE_TYPE_EMAIL; $shareTypes[] = Share::SHARE_TYPE_REMOTE; if (is_array($shareType)) { @@ -499,6 +564,11 @@ class ShareesAPIController extends OCSController { $this->getRemote($search); } + // Get email + if (in_array(Share::SHARE_TYPE_EMAIL, $shareTypes)) { + $this->getEmails($search); + } + $response = new Http\DataResponse($this->result); if (sizeof($this->reachedEndFor) < 3) { diff --git a/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php b/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php index 161cc8a184b..6ee1ff596e4 100644 --- a/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php +++ b/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php @@ -39,7 +39,7 @@ use OCP\Share; * @package OCA\Files_Sharing\Tests\API */ class ShareesAPIControllerTest extends TestCase { - /** @var Sharees */ + /** @var ShareesAPIController */ protected $sharees; /** @var \OCP\IUserManager|\PHPUnit_Framework_MockObject_MockObject */ @@ -1025,8 +1025,234 @@ class ShareesAPIControllerTest extends TestCase { $this->assertCount((int) $reachedEnd, $this->invokePrivate($this->sharees, 'reachedEndFor')); } + public function dataGetEmails() { + return [ + ['test', [], true, [], [], true], + ['test', [], false, [], [], true], + [ + 'test@remote.com', + [], + true, + [ + ['label' => 'test@remote.com', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'test@remote.com']], + ], + [], + true, + ], + [ + 'test@remote.com', + [], + false, + [ + ['label' => 'test@remote.com', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'test@remote.com']], + ], + [], + true, + ], + [ + 'test', + [ + [ + 'FN' => 'User3 @ Localhost', + ], + [ + 'FN' => 'User2 @ Localhost', + 'EMAIL' => [ + ], + ], + [ + 'FN' => 'User @ Localhost', + 'EMAIL' => [ + 'username@localhost.com', + ], + ], + ], + true, + [], + [ + ['label' => 'User @ Localhost', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'username@localhost.com']], + ], + true, + ], + [ + 'test', + [ + [ + 'FN' => 'User3 @ Localhost', + ], + [ + 'FN' => 'User2 @ Localhost', + 'EMAIL' => [ + ], + ], + [ + 'FN' => 'User @ Localhost', + 'EMAIL' => [ + 'username@localhost.com', + ], + ], + ], + false, + [], + [], + true, + ], + [ + 'test@remote.com', + [ + [ + 'FN' => 'User3 @ Localhost', + ], + [ + 'FN' => 'User2 @ Localhost', + 'EMAIL' => [ + ], + ], + [ + 'FN' => 'User @ Localhost', + 'EMAIL' => [ + 'username@localhost.com', + ], + ], + ], + true, + [ + ['label' => 'test@remote.com', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'test@remote.com']], + ], + [ + ['label' => 'User @ Localhost', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'username@localhost.com']], + ], + true, + ], + [ + 'test@remote.com', + [ + [ + 'FN' => 'User3 @ Localhost', + ], + [ + 'FN' => 'User2 @ Localhost', + 'EMAIL' => [ + ], + ], + [ + 'FN' => 'User @ Localhost', + 'EMAIL' => [ + 'username@localhost.com', + ], + ], + ], + false, + [ + ['label' => 'test@remote.com', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'test@remote.com']], + ], + [], + true, + ], + [ + 'username@localhost.com', + [ + [ + 'FN' => 'User3 @ Localhost', + ], + [ + 'FN' => 'User2 @ Localhost', + 'EMAIL' => [ + ], + ], + [ + 'FN' => 'User @ Localhost', + 'EMAIL' => [ + 'username@localhost.com', + ], + ], + ], + true, + [ + ['label' => 'User @ Localhost', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'username@localhost.com']], + ], + [], + true, + ], + [ + 'username@localhost.com', + [ + [ + 'FN' => 'User3 @ Localhost', + ], + [ + 'FN' => 'User2 @ Localhost', + 'EMAIL' => [ + ], + ], + [ + 'FN' => 'User @ Localhost', + 'EMAIL' => [ + 'username@localhost.com', + ], + ], + ], + false, + [ + ['label' => 'User @ Localhost', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'username@localhost.com']], + ], + [], + true, + ], + // Test single email + [ + 'username@localhost.com', + [ + [ + 'FN' => 'User3 @ Localhost', + ], + [ + 'FN' => 'User2 @ Localhost', + 'EMAIL' => [ + ], + ], + [ + 'FN' => 'User @ Localhost', + 'EMAIL' => 'username@localhost.com', + ], + ], + false, + [ + ['label' => 'User @ Localhost', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'username@localhost.com']], + ], + [], + true, + ], + ]; + } + + /** + * @dataProvider dataGetEmails + * + * @param string $searchTerm + * @param array $contacts + * @param bool $shareeEnumeration + * @param array $exactExpected + * @param array $expected + * @param bool $reachedEnd + */ + public function testGetEmails($searchTerm, $contacts, $shareeEnumeration, $exactExpected, $expected, $reachedEnd) { + $this->invokePrivate($this->sharees, 'shareeEnumeration', [$shareeEnumeration]); + $this->contactsManager->expects($this->any()) + ->method('search') + ->with($searchTerm, ['FN', 'EMAIL']) + ->willReturn($contacts); + + $this->invokePrivate($this->sharees, 'getEmails', [$searchTerm]); + $result = $this->invokePrivate($this->sharees, 'result'); + + $this->assertEquals($exactExpected, $result['exact']['emails']); + $this->assertEquals($expected, $result['emails']); + $this->assertCount((int) $reachedEnd, $this->invokePrivate($this->sharees, 'reachedEndFor')); + } + public function dataSearch() { - $allTypes = [Share::SHARE_TYPE_USER, Share::SHARE_TYPE_GROUP, Share::SHARE_TYPE_REMOTE]; + $allTypes = [Share::SHARE_TYPE_USER, Share::SHARE_TYPE_GROUP, Share::SHARE_TYPE_EMAIL, Share::SHARE_TYPE_REMOTE]; return [ [[], '', 'yes', true, '', null, $allTypes, 1, 200, false, true, true], @@ -1082,13 +1308,13 @@ class ShareesAPIControllerTest extends TestCase { ], '', 'yes', true, '', null, $allTypes, 1, 200, false, true, true], [[ 'shareType' => $allTypes, - ], '', 'yes', false, '', null, [0, 1], 1, 200, false, true, true], + ], '', 'yes', false, '', null, [0, 1, 4], 1, 200, false, true, true], [[ 'shareType' => $allTypes, - ], '', 'yes', true, '', null, [0, 6], 1, 200, false, true, false], + ], '', 'yes', true, '', null, [0, 4, 6], 1, 200, false, true, false], [[ 'shareType' => $allTypes, - ], '', 'yes', false, '', null, [0], 1, 200, false, true, false], + ], '', 'yes', false, '', null, [0, 4], 1, 200, false, true, false], // Test pagination [[ @@ -1195,7 +1421,7 @@ class ShareesAPIControllerTest extends TestCase { ->with($itemType) ->willReturn($remoteSharingEnabled); - $this->assertInstanceOf('\OCP\AppFramework\Http\DataResponse', $sharees->search($search, $itemType, $page, $perPage, $shareType)); + $this->assertInstanceOf(Http\DataResponse::class, $sharees->search($search, $itemType, $page, $perPage, $shareType)); $this->assertSame($shareWithGroupOnly, $this->invokePrivate($sharees, 'shareWithGroupOnly')); $this->assertSame($shareeEnumeration, $this->invokePrivate($sharees, 'shareeEnumeration')); @@ -1295,17 +1521,19 @@ class ShareesAPIControllerTest extends TestCase { return [ ['test', 'folder', [Share::SHARE_TYPE_USER, Share::SHARE_TYPE_GROUP, Share::SHARE_TYPE_REMOTE], 1, 2, false, [], [], [], [ - 'exact' => ['users' => [], 'groups' => [], 'remotes' => []], + 'exact' => ['users' => [], 'groups' => [], 'remotes' => [], 'emails' => []], 'users' => [], 'groups' => [], 'remotes' => [], + 'emails' => [], ], false], ['test', 'folder', [Share::SHARE_TYPE_USER, Share::SHARE_TYPE_GROUP, Share::SHARE_TYPE_REMOTE], 1, 2, false, [], [], [], [ - 'exact' => ['users' => [], 'groups' => [], 'remotes' => []], + 'exact' => ['users' => [], 'groups' => [], 'remotes' => [], 'emails' => []], 'users' => [], 'groups' => [], 'remotes' => [], + 'emails' => [], ], false], [ 'test', 'folder', [Share::SHARE_TYPE_USER, Share::SHARE_TYPE_GROUP, Share::SHARE_TYPE_REMOTE], 1, 2, false, [ @@ -1316,7 +1544,7 @@ class ShareesAPIControllerTest extends TestCase { ['label' => 'testz@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'testz@remote']], ], [ - 'exact' => ['users' => [], 'groups' => [], 'remotes' => []], + 'exact' => ['users' => [], 'groups' => [], 'remotes' => [], 'emails' => []], 'users' => [ ['label' => 'test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']], ], @@ -1326,6 +1554,7 @@ class ShareesAPIControllerTest extends TestCase { 'remotes' => [ ['label' => 'testz@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'testz@remote']], ], + 'emails' => [], ], true, ], // No groups requested @@ -1336,7 +1565,7 @@ class ShareesAPIControllerTest extends TestCase { ['label' => 'testz@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'testz@remote']], ], [ - 'exact' => ['users' => [], 'groups' => [], 'remotes' => []], + 'exact' => ['users' => [], 'groups' => [], 'remotes' => [], 'emails' => []], 'users' => [ ['label' => 'test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']], ], @@ -1344,6 +1573,7 @@ class ShareesAPIControllerTest extends TestCase { 'remotes' => [ ['label' => 'testz@remote', 'value' => ['shareType' => Share::SHARE_TYPE_REMOTE, 'shareWith' => 'testz@remote']], ], + 'emails' => [], ], false, ], // Share type restricted to user - Only one user @@ -1352,12 +1582,13 @@ class ShareesAPIControllerTest extends TestCase { ['label' => 'test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']], ], null, null, [ - 'exact' => ['users' => [], 'groups' => [], 'remotes' => []], + 'exact' => ['users' => [], 'groups' => [], 'remotes' => [], 'emails' => []], 'users' => [ ['label' => 'test One', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']], ], 'groups' => [], 'remotes' => [], + 'emails' => [], ], false, ], // Share type restricted to user - Multipage result @@ -1367,13 +1598,14 @@ class ShareesAPIControllerTest extends TestCase { ['label' => 'test 2', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test2']], ], null, null, [ - 'exact' => ['users' => [], 'groups' => [], 'remotes' => []], + 'exact' => ['users' => [], 'groups' => [], 'remotes' => [], 'emails' => []], 'users' => [ ['label' => 'test 1', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']], ['label' => 'test 2', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test2']], ], 'groups' => [], 'remotes' => [], + 'emails' => [], ], true, ], ]; |