diff options
author | Thomas Müller <thomas.mueller@tmit.eu> | 2016-01-25 22:49:26 +0100 |
---|---|---|
committer | Thomas Müller <thomas.mueller@tmit.eu> | 2016-01-27 09:45:32 +0100 |
commit | ba565edc1e5b24da8c7ec7a4fae7164eac8cac50 (patch) | |
tree | 000a865f52f31f57201cb41810ee1da58f42ae93 | |
parent | 92c7d1573934eb0fef2f901d90d5303e19bc34f1 (diff) | |
download | nextcloud-server-ba565edc1e5b24da8c7ec7a4fae7164eac8cac50.tar.gz nextcloud-server-ba565edc1e5b24da8c7ec7a4fae7164eac8cac50.zip |
Extract sharing functionality into own backend class for reusability
-rw-r--r-- | apps/dav/lib/carddav/addressbook.php | 11 | ||||
-rw-r--r-- | apps/dav/lib/carddav/carddavbackend.php | 96 | ||||
-rw-r--r-- | apps/dav/lib/dav/sharing/backend.php | 173 | ||||
-rw-r--r-- | apps/dav/lib/dav/sharing/ishareable.php | 10 | ||||
-rw-r--r-- | apps/dav/lib/dav/sharing/plugin.php | 2 | ||||
-rw-r--r-- | apps/dav/tests/unit/carddav/carddavbackendtest.php | 7 |
6 files changed, 203 insertions, 96 deletions
diff --git a/apps/dav/lib/carddav/addressbook.php b/apps/dav/lib/carddav/addressbook.php index 6c3caecddf6..513eae4d723 100644 --- a/apps/dav/lib/carddav/addressbook.php +++ b/apps/dav/lib/carddav/addressbook.php @@ -68,7 +68,7 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable { function getShares() { /** @var CardDavBackend $carddavBackend */ $carddavBackend = $this->carddavBackend; - return $carddavBackend->getShares($this->getBookId()); + return $carddavBackend->getShares($this->getResourceId()); } function getACL() { @@ -100,7 +100,7 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable { /** @var CardDavBackend $carddavBackend */ $carddavBackend = $this->carddavBackend; - return $carddavBackend->applyShareAcl($this->getBookId(), $acl); + return $carddavBackend->applyShareAcl($this->getResourceId(), $acl); } function getChildACL() { @@ -115,11 +115,11 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable { /** @var CardDavBackend $carddavBackend */ $carddavBackend = $this->carddavBackend; - return $carddavBackend->applyShareAcl($this->getBookId(), $acl); + return $carddavBackend->applyShareAcl($this->getResourceId(), $acl); } function getChild($name) { - $obj = $this->carddavBackend->getCard($this->getBookId(), $name); + $obj = $this->carddavBackend->getCard($this->getResourceId(), $name); if (!$obj) { throw new NotFound('Card not found'); } @@ -129,8 +129,7 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable { /** * @return int */ - public function getBookId() { + public function getResourceId() { return $this->addressBookInfo['id']; } - } diff --git a/apps/dav/lib/carddav/carddavbackend.php b/apps/dav/lib/carddav/carddavbackend.php index 81a3ba7c519..3dc5c00e10b 100644 --- a/apps/dav/lib/carddav/carddavbackend.php +++ b/apps/dav/lib/carddav/carddavbackend.php @@ -24,9 +24,10 @@ namespace OCA\DAV\CardDAV; -use Doctrine\DBAL\Connection; use OCA\DAV\Connector\Sabre\Principal; use OCP\DB\QueryBuilder\IQueryBuilder; +use OCA\DAV\DAV\Sharing\Backend; +use OCA\DAV\DAV\Sharing\IShareable; use OCP\IDBConnection; use Sabre\CardDAV\Backend\BackendInterface; use Sabre\CardDAV\Backend\SyncSupport; @@ -50,6 +51,9 @@ class CardDavBackend implements BackendInterface, SyncSupport { /** @var IDBConnection */ private $db; + /** @var Backend */ + private $sharingBackend; + /** @var array properties to index */ public static $indexProperties = array( 'BDAY', 'UID', 'N', 'FN', 'TITLE', 'ROLE', 'NOTE', 'NICKNAME', @@ -68,6 +72,7 @@ class CardDavBackend implements BackendInterface, SyncSupport { public function __construct(IDBConnection $db, Principal $principalBackend) { $this->db = $db; $this->principalBackend = $principalBackend; + $this->sharingBackend = new Backend($this->db, 'addressbook'); } /** @@ -715,17 +720,12 @@ class CardDavBackend implements BackendInterface, SyncSupport { } /** - * @param AddressBook $book + * @param IShareable $shareable * @param string[] $add * @param string[] $remove */ - public function updateShares($book, $add, $remove) { - foreach($add as $element) { - $this->shareWith($book, $element); - } - foreach($remove as $element) { - $this->unshare($book->getBookId(), $element); - } + public function updateShares(IShareable $shareable, $add, $remove) { + $this->sharingBackend->updateShares($shareable, $add, $remove); } /** @@ -808,63 +808,6 @@ class CardDavBackend implements BackendInterface, SyncSupport { return $result; } - - /** - * @param AddressBook $addressBook - * @param string $element - */ - private function shareWith($addressBook, $element) { - $user = $element['href']; - $parts = explode(':', $user, 2); - if ($parts[0] !== 'principal') { - return; - } - $p = $this->principalBackend->getPrincipalByPath($parts[1]); - if (is_null($p)) { - return; - } - - // remove the share if it already exists - $this->unshare($addressBook->getBookId(), $element['href']); - $access = self::ACCESS_READ; - if (isset($element['readOnly'])) { - $access = $element['readOnly'] ? self::ACCESS_READ : self::ACCESS_READ_WRITE; - } - - $query = $this->db->getQueryBuilder(); - $query->insert('dav_shares') - ->values([ - 'principaluri' => $query->createNamedParameter($parts[1]), - 'type' => $query->createNamedParameter('addressbook'), - 'access' => $query->createNamedParameter($access), - 'resourceid' => $query->createNamedParameter($addressBook->getBookId()) - ]); - $query->execute(); - } - - /** - * @param int $addressBookId - * @param string $element - */ - private function unshare($addressBookId, $element) { - $parts = explode(':', $element, 2); - if ($parts[0] !== 'principal') { - return; - } - $p = $this->principalBackend->getPrincipalByPath($parts[1]); - if (is_null($p)) { - return; - } - - $query = $this->db->getQueryBuilder(); - $query->delete('dav_shares') - ->where($query->expr()->eq('resourceid', $query->createNamedParameter($addressBookId))) - ->andWhere($query->expr()->eq('type', $query->createNamedParameter('addressbook'))) - ->andWhere($query->expr()->eq('principaluri', $query->createNamedParameter($parts[1]))) - ; - $query->execute(); - } - /** * Returns the list of people whom this address book is shared with. * @@ -878,26 +821,7 @@ class CardDavBackend implements BackendInterface, SyncSupport { * @return array */ public function getShares($addressBookId) { - $query = $this->db->getQueryBuilder(); - $result = $query->select(['principaluri', 'access']) - ->from('dav_shares') - ->where($query->expr()->eq('resourceid', $query->createNamedParameter($addressBookId))) - ->andWhere($query->expr()->eq('type', $query->createNamedParameter('addressbook'))) - ->execute(); - - $shares = []; - while($row = $result->fetch()) { - $p = $this->principalBackend->getPrincipalByPath($row['principaluri']); - $shares[]= [ - 'href' => "principal:${p['uri']}", - 'commonName' => isset($p['{DAV:}displayname']) ? $p['{DAV:}displayname'] : '', - 'status' => 1, - 'readOnly' => ($row['access'] === self::ACCESS_READ), - '{'.\OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD.'}principal' => $p['uri'] - ]; - } - - return $shares; + return $this->sharingBackend->getShares($addressBookId); } /** diff --git a/apps/dav/lib/dav/sharing/backend.php b/apps/dav/lib/dav/sharing/backend.php new file mode 100644 index 00000000000..fee864ffe6f --- /dev/null +++ b/apps/dav/lib/dav/sharing/backend.php @@ -0,0 +1,173 @@ +<?php +/** + * @author Arthur Schiwon <blizzz@owncloud.com> + * @author Björn Schießle <schiessle@owncloud.com> + * @author Scrutinizer Auto-Fixer <auto-fixer@scrutinizer-ci.com> + * @author Thomas Müller <thomas.mueller@tmit.eu> + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * 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, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace OCA\DAV\DAV\Sharing; + +use OCP\IDBConnection; + +class Backend { + + /** @var IDBConnection */ + private $db; + + const ACCESS_OWNER = 1; + const ACCESS_READ_WRITE = 2; + const ACCESS_READ = 3; + + /** @var string */ + private $resourceType; + + /** + * CardDavBackend constructor. + * + * @param IDBConnection $db + */ + public function __construct(IDBConnection $db, $resourceType) { + $this->db = $db; + $this->resourceType = $resourceType; + } + + /** + * @param IShareable $shareable + * @param string[] $add + * @param string[] $remove + */ + public function updateShares($shareable, $add, $remove) { + foreach($add as $element) { + $this->shareWith($shareable, $element); + } + foreach($remove as $element) { + $this->unshare($shareable->getResourceId(), $element); + } + } + + /** + * @param IShareable $shareable + * @param string $element + */ + private function shareWith($shareable, $element) { + $user = $element['href']; + $parts = explode(':', $user, 2); + if ($parts[0] !== 'principal') { + return; + } + + // remove the share if it already exists + $this->unshare($shareable->getResourceId(), $element['href']); + $access = self::ACCESS_READ; + if (isset($element['readOnly'])) { + $access = $element['readOnly'] ? self::ACCESS_READ : self::ACCESS_READ_WRITE; + } + + $query = $this->db->getQueryBuilder(); + $query->insert('dav_shares') + ->values([ + 'principaluri' => $query->createNamedParameter($parts[1]), + 'type' => $query->createNamedParameter($this->resourceType), + 'access' => $query->createNamedParameter($access), + 'resourceid' => $query->createNamedParameter($shareable->getResourceId()) + ]); + $query->execute(); + } + + /** + * @param int $resourceId + * @param string $element + */ + private function unshare($resourceId, $element) { + $parts = explode(':', $element, 2); + if ($parts[0] !== 'principal') { + return; + } + + $query = $this->db->getQueryBuilder(); + $query->delete('dav_shares') + ->where($query->expr()->eq('resourceid', $query->createNamedParameter($resourceId))) + ->andWhere($query->expr()->eq('type', $query->createNamedParameter($this->resourceType))) + ->andWhere($query->expr()->eq('principaluri', $query->createNamedParameter($parts[1]))) + ; + $query->execute(); + } + + /** + * Returns the list of people whom this resource is shared with. + * + * Every element in this array should have the following properties: + * * href - Often a mailto: address + * * commonName - Optional, for example a first + last name + * * status - See the Sabre\CalDAV\SharingPlugin::STATUS_ constants. + * * readOnly - boolean + * * summary - Optional, a description for the share + * + * @return array + */ + public function getShares($resourceId) { + $query = $this->db->getQueryBuilder(); + $result = $query->select(['principaluri', 'access']) + ->from('dav_shares') + ->where($query->expr()->eq('resourceid', $query->createNamedParameter($resourceId))) + ->andWhere($query->expr()->eq('type', $query->createNamedParameter($this->resourceType))) + ->execute(); + + $shares = []; + while($row = $result->fetch()) { + $shares[]= [ + 'href' => "principal:${row['principaluri']}", +// 'commonName' => isset($p['{DAV:}displayname']) ? $p['{DAV:}displayname'] : '', + 'status' => 1, + 'readOnly' => ($row['access'] === self::ACCESS_READ), + '{'.\OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD.'}principal' => $row['principaluri'] + ]; + } + + return $shares; + } + + /** + * For shared resources the sharee is set in the ACL of the resource + * + * @param int $resourceId + * @param array $acl + * @return array + */ + public function applyShareAcl($resourceId, $acl) { + + $shares = $this->getShares($resourceId); + foreach ($shares as $share) { + $acl[] = [ + 'privilege' => '{DAV:}read', + 'principal' => $share['{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}principal'], + 'protected' => true, + ]; + if (!$share['readOnly']) { + $acl[] = [ + 'privilege' => '{DAV:}write', + 'principal' => $share['{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}principal'], + 'protected' => true, + ]; + } + } + return $acl; + } +} diff --git a/apps/dav/lib/dav/sharing/ishareable.php b/apps/dav/lib/dav/sharing/ishareable.php index e82c03a6af8..f6b6bfa8862 100644 --- a/apps/dav/lib/dav/sharing/ishareable.php +++ b/apps/dav/lib/dav/sharing/ishareable.php @@ -61,4 +61,14 @@ interface IShareable extends INode { */ function getShares(); + /** + * @return int + */ + public function getResourceId(); + + /** + * @return string + */ + public function getOwner(); + }
\ No newline at end of file diff --git a/apps/dav/lib/dav/sharing/plugin.php b/apps/dav/lib/dav/sharing/plugin.php index d3fdd8aa969..cbb4408e29b 100644 --- a/apps/dav/lib/dav/sharing/plugin.php +++ b/apps/dav/lib/dav/sharing/plugin.php @@ -151,7 +151,7 @@ class Plugin extends ServerPlugin { return; } - $this->server->transactionType = 'post-oc-addressbook-share'; + $this->server->transactionType = 'post-oc-resource-share'; // Getting ACL info $acl = $this->server->getPlugin('acl'); diff --git a/apps/dav/tests/unit/carddav/carddavbackendtest.php b/apps/dav/tests/unit/carddav/carddavbackendtest.php index 1a0d32c186c..0158330a194 100644 --- a/apps/dav/tests/unit/carddav/carddavbackendtest.php +++ b/apps/dav/tests/unit/carddav/carddavbackendtest.php @@ -292,13 +292,13 @@ class CardDavBackendTest extends TestCase { $exampleBook = new AddressBook($this->backend, $books[0]); $this->backend->updateShares($exampleBook, [['href' => 'principal:principals/best-friend']], []); - $shares = $this->backend->getShares($exampleBook->getBookId()); + $shares = $this->backend->getShares($exampleBook->getResourceId()); $this->assertEquals(1, count($shares)); // adding the same sharee again has no effect $this->backend->updateShares($exampleBook, [['href' => 'principal:principals/best-friend']], []); - $shares = $this->backend->getShares($exampleBook->getBookId()); + $shares = $this->backend->getShares($exampleBook->getResourceId()); $this->assertEquals(1, count($shares)); $books = $this->backend->getAddressBooksForUser('principals/best-friend'); @@ -306,7 +306,7 @@ class CardDavBackendTest extends TestCase { $this->backend->updateShares($exampleBook, [], ['principal:principals/best-friend']); - $shares = $this->backend->getShares($exampleBook->getBookId()); + $shares = $this->backend->getShares($exampleBook->getResourceId()); $this->assertEquals(0, count($shares)); $books = $this->backend->getAddressBooksForUser('principals/best-friend'); @@ -432,6 +432,7 @@ class CardDavBackendTest extends TestCase { * @dataProvider dataTestSearch * * @param string $pattern + * @param array $properties * @param array $expected */ public function testSearch($pattern, $properties, $expected) { |