diff options
53 files changed, 3110 insertions, 1479 deletions
diff --git a/.mention-bot b/.mention-bot index 766ea2bacf2..5997a7a03bb 100644 --- a/.mention-bot +++ b/.mention-bot @@ -9,6 +9,15 @@ ] }, { + "name": "nickvergessen", + "files": [ + "lib/private/activity/**", + "lib/private/notification/**", + "lib/public/activity/**", + "lib/public/notification/**" + ] + }, + { "name": "Xenopathic", "files": [ "apps/files_external/**" @@ -18,6 +27,7 @@ "userBlacklist": [ "owncloud-bot", "scrutinizer-auto-fixer", - "th3fallen" + "th3fallen", + "zander" ] } diff --git a/apps/dav/lib/carddav/addressbook.php b/apps/dav/lib/carddav/addressbook.php index 2cfaa7b708c..513eae4d723 100644 --- a/apps/dav/lib/carddav/addressbook.php +++ b/apps/dav/lib/carddav/addressbook.php @@ -20,10 +20,10 @@ */ namespace OCA\DAV\CardDAV; -use OCA\DAV\CardDAV\Sharing\IShareableAddressBook; +use OCA\DAV\DAV\Sharing\IShareable; use Sabre\DAV\Exception\NotFound; -class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareableAddressBook { +class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable { public function __construct(CardDavBackend $carddavBackend, array $addressBookInfo) { parent::__construct($carddavBackend, $addressBookInfo); @@ -68,7 +68,7 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareableAddres function getShares() { /** @var CardDavBackend $carddavBackend */ $carddavBackend = $this->carddavBackend; - return $carddavBackend->getShares($this->getBookId()); + return $carddavBackend->getShares($this->getResourceId()); } function getACL() { @@ -82,14 +82,14 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareableAddres } // add the current user - if (isset($this->addressBookInfo['{' . \OCA\DAV\CardDAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal'])) { - $owner = $this->addressBookInfo['{' . \OCA\DAV\CardDAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal']; + if (isset($this->addressBookInfo['{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal'])) { + $owner = $this->addressBookInfo['{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal']; $acl[] = [ 'privilege' => '{DAV:}read', 'principal' => $owner, 'protected' => true, ]; - if ($this->addressBookInfo['{' . \OCA\DAV\CardDAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only']) { + if ($this->addressBookInfo['{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only']) { $acl[] = [ 'privilege' => '{DAV:}write', 'principal' => $owner, @@ -100,7 +100,7 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareableAddres /** @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 IShareableAddres /** @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 IShareableAddres /** * @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 28f6099b639..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'); } /** @@ -136,8 +141,8 @@ class CardDavBackend implements BackendInterface, SyncSupport { '{' . Plugin::NS_CARDDAV . '}addressbook-description' => $row['description'], '{http://calendarserver.org/ns/}getctag' => $row['synctoken'], '{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0', - '{' . \OCA\DAV\CardDAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $row['principaluri'], - '{' . \OCA\DAV\CardDAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only' => $row['access'] === self::ACCESS_READ, + '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $row['principaluri'], + '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only' => $row['access'] === self::ACCESS_READ, ]; } $result->closeCursor(); @@ -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\CardDAV\Sharing\Plugin::NS_OWNCLOUD.'}principal' => $p['uri'] - ]; - } - - return $shares; + return $this->sharingBackend->getShares($addressBookId); } /** @@ -1001,13 +925,13 @@ class CardDavBackend implements BackendInterface, SyncSupport { foreach ($shares as $share) { $acl[] = [ 'privilege' => '{DAV:}read', - 'principal' => $share['{' . \OCA\DAV\CardDAV\Sharing\Plugin::NS_OWNCLOUD . '}principal'], + 'principal' => $share['{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}principal'], 'protected' => true, ]; if (!$share['readOnly']) { $acl[] = [ 'privilege' => '{DAV:}write', - 'principal' => $share['{' . \OCA\DAV\CardDAV\Sharing\Plugin::NS_OWNCLOUD . '}principal'], + 'principal' => $share['{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}principal'], 'protected' => true, ]; } 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/carddav/sharing/ishareableaddressbook.php b/apps/dav/lib/dav/sharing/ishareable.php index 8e348a90991..f6b6bfa8862 100644 --- a/apps/dav/lib/carddav/sharing/ishareableaddressbook.php +++ b/apps/dav/lib/dav/sharing/ishareable.php @@ -18,20 +18,20 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ -namespace OCA\DAV\CardDAV\Sharing; -use Sabre\CardDAV\IAddressBook; +namespace OCA\DAV\DAV\Sharing; +use Sabre\DAV\INode; /** - * This interface represents a Calendar that can be shared with other users. + * This interface represents a dav resource that can be shared with other users. * */ -interface IShareableAddressBook extends IAddressBook { +interface IShareable extends INode { /** * Updates the list of shares. * * The first array is a list of people that are to be added to the - * addressbook. + * resource. * * Every element in the add array has the following properties: * * href - A url. Usually a mailto: address @@ -48,7 +48,7 @@ interface IShareableAddressBook extends IAddressBook { function updateShares(array $add, array $remove); /** - * Returns the list of people whom this addressbook is shared with. + * 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 @@ -61,4 +61,14 @@ interface IShareableAddressBook extends IAddressBook { */ function getShares(); + /** + * @return int + */ + public function getResourceId(); + + /** + * @return string + */ + public function getOwner(); + }
\ No newline at end of file diff --git a/apps/dav/lib/carddav/sharing/plugin.php b/apps/dav/lib/dav/sharing/plugin.php index d25b84d01f3..cbb4408e29b 100644 --- a/apps/dav/lib/carddav/sharing/plugin.php +++ b/apps/dav/lib/dav/sharing/plugin.php @@ -19,7 +19,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ -namespace OCA\DAV\CardDAV\Sharing; + +namespace OCA\DAV\DAV\Sharing; use OCA\DAV\Connector\Sabre\Auth; use OCP\IRequest; @@ -27,8 +28,6 @@ use Sabre\DAV\Exception\BadRequest; use Sabre\DAV\Exception\NotFound; use Sabre\DAV\Server; use Sabre\DAV\ServerPlugin; -use Sabre\DAV\XMLUtil; -use Sabre\DAVACL\IACL; use Sabre\HTTP\RequestInterface; use Sabre\HTTP\ResponseInterface; @@ -69,9 +68,7 @@ class Plugin extends ServerPlugin { * @return string[] */ function getFeatures() { - - return ['oc-addressbook-sharing']; - + return ['oc-resource-sharing']; } /** @@ -83,9 +80,7 @@ class Plugin extends ServerPlugin { * @return string */ function getPluginName() { - - return 'carddav-sharing'; - + return 'oc-resource-sharing'; } /** @@ -101,14 +96,13 @@ class Plugin extends ServerPlugin { */ function initialize(Server $server) { $this->server = $server; - $server->resourceTypeMapping['OCA\\DAV\CardDAV\\ISharedAddressbook'] = '{' . \Sabre\CardDAV\Plugin::NS_CARDDAV . '}shared'; - $this->server->xml->elementMap['{' . Plugin::NS_OWNCLOUD . '}share'] = 'OCA\\DAV\\CardDAV\\Sharing\\Xml\\ShareRequest'; + $this->server->xml->elementMap['{' . Plugin::NS_OWNCLOUD . '}share'] = 'OCA\\DAV\\DAV\\Sharing\\Xml\\ShareRequest'; $this->server->on('method:POST', [$this, 'httpPost']); } /** - * We intercept this to handle POST requests on calendars. + * We intercept this to handle POST requests on a dav resource. * * @param RequestInterface $request * @param ResponseInterface $response @@ -153,11 +147,11 @@ class Plugin extends ServerPlugin { case '{' . self::NS_OWNCLOUD . '}share' : // We can only deal with IShareableCalendar objects - if (!$node instanceof IShareableAddressBook) { + if (!$node instanceof IShareable) { 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/lib/carddav/sharing/xml/sharerequest.php b/apps/dav/lib/dav/sharing/xml/sharerequest.php index bd55dd4073e..776fb446b6c 100644 --- a/apps/dav/lib/carddav/sharing/xml/sharerequest.php +++ b/apps/dav/lib/dav/sharing/xml/sharerequest.php @@ -18,9 +18,9 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ -namespace OCA\DAV\CardDAV\Sharing\Xml; +namespace OCA\DAV\DAV\Sharing\Xml; -use OCA\DAV\CardDAV\Sharing\Plugin; +use OCA\DAV\DAV\Sharing\Plugin; use Sabre\Xml\Reader; use Sabre\Xml\XmlDeserializable; diff --git a/apps/dav/lib/server.php b/apps/dav/lib/server.php index 7519a631d5a..3bf8e155082 100644 --- a/apps/dav/lib/server.php +++ b/apps/dav/lib/server.php @@ -79,10 +79,9 @@ class Server { $this->server->addPlugin(new \Sabre\CalDAV\ICSExportPlugin()); $this->server->addPlugin(new \Sabre\CalDAV\Schedule\Plugin()); $this->server->addPlugin(new IMipPlugin($mailer, $logger)); - $this->server->addPlugin(new \Sabre\CalDAV\SharingPlugin()); $this->server->addPlugin(new \Sabre\CalDAV\Subscriptions\Plugin()); $this->server->addPlugin(new \Sabre\CalDAV\Notifications\Plugin()); - $this->server->addPlugin(new CardDAV\Sharing\Plugin($authBackend, \OC::$server->getRequest())); + $this->server->addPlugin(new DAV\Sharing\Plugin($authBackend, \OC::$server->getRequest())); // addressbook plugins $this->server->addPlugin(new \OCA\DAV\CardDAV\Plugin()); diff --git a/apps/dav/tests/travis/caldavtest/tests/CalDAV/sharing-calendars.xml b/apps/dav/tests/travis/caldavtest/tests/CalDAV/sharing-calendars.xml new file mode 100644 index 00000000000..fa20a6e4862 --- /dev/null +++ b/apps/dav/tests/travis/caldavtest/tests/CalDAV/sharing-calendars.xml @@ -0,0 +1,573 @@ +<?xml version="1.0" standalone="no"?> + +<!DOCTYPE caldavtest SYSTEM "caldavtest.dtd"> + +<!-- + Copyright (c) 2006-2015 Apple Inc. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + --> + +<caldavtest> + <description>Test calendar sharing calendars</description> + + <require-feature> + <feature>caldav</feature> + <feature>shared-calendars</feature> + </require-feature> + + <start> + <request user="$userid1:" pswd="$pswd1:"> + <method>DELETEALL</method> + <ruri>$notificationpath1:/</ruri> + </request> + <request user="$userid2:" pswd="$pswd2:"> + <method>DELETEALL</method> + <ruri>$notificationpath2:/</ruri> + </request> + <request end-delete="yes"> + <method>MKCALENDAR</method> + <ruri>$calendarhome1:/shared/</ruri> + <verify> + <callback>statusCode</callback> + </verify> + </request> + <request> + <method>PROPPATCH</method> + <ruri>$calendarhome1:/shared/</ruri> + <data> + <content-type>text/xml; charset=utf-8</content-type> + <filepath>Resource/Common/PROPPATCH/calendar-transp-opaque.xml</filepath> + </data> + </request> + </start> + + <test-suite name='Read-write calendar'> + <test name='1'> + <description>POST invitation</description> + <request> + <method>POST</method> + <ruri>$calendarhome1:/shared/</ruri> + <data> + <content-type>text/xml; charset=utf-8</content-type> + <filepath>Resource/CalDAV/sharing/calendars/read-write/1.xml</filepath> + </data> + <verify> + <callback>statusCode</callback> + </verify> + </request> + </test> + <test name='2'> + <description>Check Sharee notification collection</description> + <request user="$userid2:" pswd="$pswd2:"> + <method>WAITCOUNT 1</method> + <ruri>$notificationpath2:/</ruri> + </request> + <request user="$userid2:" pswd="$pswd2:"> + <method>GETNEW</method> + <ruri>$notificationpath2:/</ruri> + <verify> + <callback>xmlDataMatch</callback> + <arg> + <name>filepath</name> + <value>Resource/CalDAV/sharing/calendars/read-write/2.xml</value> + </arg> + <arg> + <name>filter</name> + <value>{http://calendarserver.org/ns/}dtstamp</value> + <value>{http://calendarserver.org/ns/}uid</value> + </arg> + </verify> + <grabelement> + <name>{http://calendarserver.org/ns/}invite-notification/{http://calendarserver.org/ns/}uid</name> + <variable>$inviteuid:</variable> + </grabelement> + </request> + </test> + <test name='3'> + <description>Sharee replies ACCEPTED</description> + <request user="$userid2:" pswd="$pswd2:"> + <method>POST</method> + <ruri>$calendarhome2:/</ruri> + <data> + <content-type>application/xml; charset=utf-8</content-type> + <filepath>Resource/CalDAV/sharing/calendars/read-write/3.xml</filepath> + </data> + <verify> + <callback>statusCode</callback> + </verify> + <grabelement> + <name>{DAV:}href</name> + <variable>$sharedcalendar:</variable> + </grabelement> + </request> + </test> + <test name='4'> + <description>Shared calendar exists</description> + <request user="$userid2:" pswd="$pswd2:"> + <method>PROPFIND</method> + <ruri>$sharedcalendar:/</ruri> + <header> + <name>Depth</name> + <value>0</value> + </header> + <data> + <content-type>text/xml; charset=utf-8</content-type> + <filepath>Resource/CalDAV/sharing/calendars/read-write/4.xml</filepath> + </data> + <verify> + <callback>xmlElementMatch</callback> + <arg> + <name>exists</name> + <value>$verify-property-prefix:/{DAV:}owner/{DAV:}href[=$principaluri1:]</value> + <value>$verify-property-prefix:/{DAV:}resourcetype/{DAV:}collection</value> + <value>$verify-property-prefix:/{DAV:}resourcetype/{urn:ietf:params:xml:ns:caldav}calendar</value> + <value>$verify-property-prefix:/{DAV:}resourcetype/{http://calendarserver.org/ns/}shared</value> + <value>$verify-property-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}read</value> + <value>$verify-property-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}write</value> + <value>$verify-property-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}bind</value> + <value>$verify-property-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}unbind</value> + <value>$verify-property-prefix:/{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp/{urn:ietf:params:xml:ns:caldav}transparent</value> + </arg> + <arg> + <name>notexists</name> + <value>$verify-property-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}admin</value> + <value>$verify-property-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}all</value> + </arg> + </verify> + </request> + </test> + <test name='4a'> + <description>Shared calendar exists Depth:1</description> + <request user="$userid2:" pswd="$pswd2:"> + <method>PROPFIND</method> + <ruri>$calendarhome2:/</ruri> + <header> + <name>Depth</name> + <value>1</value> + </header> + <data> + <content-type>text/xml; charset=utf-8</content-type> + <filepath>Resource/CalDAV/sharing/calendars/read-write/4.xml</filepath> + </data> + <verify> + <callback>xmlElementMatch</callback> + <arg> + <name>parent</name> + <value>$multistatus-response-prefix:[^{DAV:}href=$sharedcalendar:/]</value> + </arg> + <arg> + <name>exists</name> + <value>$verify-response-prefix:/{DAV:}owner/{DAV:}href[=$principaluri1:]</value> + <value>$verify-response-prefix:/{DAV:}resourcetype/{DAV:}collection</value> + <value>$verify-response-prefix:/{DAV:}resourcetype/{urn:ietf:params:xml:ns:caldav}calendar</value> + <value>$verify-response-prefix:/{DAV:}resourcetype/{http://calendarserver.org/ns/}shared</value> + <value>$verify-response-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}read</value> + <value>$verify-response-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}write</value> + <value>$verify-response-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}bind</value> + <value>$verify-response-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}unbind</value> + <value>$verify-response-prefix:/{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp/{urn:ietf:params:xml:ns:caldav}transparent</value> + </arg> + <arg> + <name>notexists</name> + <value>$verify-response-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}admin</value> + <value>$verify-response-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}all</value> + </arg> + </verify> + </request> + </test> + <test name='4b'> + <description>Shared calendar has invite property</description> + <request user="$userid2:" pswd="$pswd2:"> + <method>PROPFIND</method> + <ruri>$sharedcalendar:/</ruri> + <header> + <name>Depth</name> + <value>0</value> + </header> + <data> + <content-type>text/xml; charset=utf-8</content-type> + <filepath>Resource/CalDAV/sharing/calendars/read-write/5.xml</filepath> + </data> + <verify> + <callback>propfindItems</callback> + <arg> + <name>okprops</name> + <value>{http://calendarserver.org/ns/}invite</value> + </arg> + </verify> + <verify> + <callback>xmlElementMatch</callback> + <arg> + <name>exists</name> + <value>$verify-property-prefix:/{http://calendarserver.org/ns/}invite</value> + <value>$verify-property-prefix:/{http://calendarserver.org/ns/}invite/{http://calendarserver.org/ns/}organizer</value> + <value>$verify-property-prefix:/{http://calendarserver.org/ns/}invite/{http://calendarserver.org/ns/}organizer/{DAV:}href[=$principaluri1:]</value> + <value>$verify-property-prefix:/{http://calendarserver.org/ns/}invite/{http://calendarserver.org/ns/}organizer/{http://calendarserver.org/ns/}common-name[=$username1:]</value> + <value>$verify-property-prefix:/{http://calendarserver.org/ns/}invite/{http://calendarserver.org/ns/}user</value> + <value>$verify-property-prefix:/{http://calendarserver.org/ns/}invite/{http://calendarserver.org/ns/}user/{DAV:}href[=$cuaddrurn2:]</value> + <value>$verify-property-prefix:/{http://calendarserver.org/ns/}invite/{http://calendarserver.org/ns/}user/{http://calendarserver.org/ns/}access/{http://calendarserver.org/ns/}read-write</value> + <value>$verify-property-prefix:/{http://calendarserver.org/ns/}invite/{http://calendarserver.org/ns/}user/{http://calendarserver.org/ns/}invite-accepted</value> + </arg> + </verify> + </request> + </test> + <test name='5'> + <description>Original calendar unchanged</description> + <request> + <method>PROPFIND</method> + <ruri>$calendarhome1:/shared/</ruri> + <header> + <name>Depth</name> + <value>0</value> + </header> + <data> + <content-type>text/xml; charset=utf-8</content-type> + <filepath>Resource/CalDAV/sharing/calendars/read-write/4.xml</filepath> + </data> + <verify> + <callback>xmlElementMatch</callback> + <arg> + <name>exists</name> + <value>$verify-property-prefix:/{DAV:}owner/{DAV:}href[=$principaluri1:]</value> + <value>$verify-property-prefix:/{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp/{urn:ietf:params:xml:ns:caldav}opaque</value> + </arg> + </verify> + </request> + </test> + <test name='6'> + <description>Sharee creates event</description> + <request user="$userid2:" pswd="$pswd2:"> + <method>PUT</method> + <ruri>$sharedcalendar:/1.ics</ruri> + <data> + <content-type>text/calendar; charset=utf-8</content-type> + <filepath>Resource/CalDAV/sharing/calendars/read-write/5.ics</filepath> + </data> + <verify> + <callback>statusCode</callback> + </verify> + </request> + </test> + <test name='7'> + <description>Sharer sees event</description> + <request> + <method>GET</method> + <ruri>$calendarhome1:/shared/1.ics</ruri> + <verify> + <callback>calendarDataMatch</callback> + <arg> + <name>filepath</name> + <value>Resource/CalDAV/sharing/calendars/read-write/5.ics</value> + </arg> + </verify> + </request> + </test> + <test name='8'> + <description>Sharer changes event</description> + <request> + <method>PUT</method> + <ruri>$calendarhome1:/shared/1.ics</ruri> + <data> + <content-type>text/calendar; charset=utf-8</content-type> + <filepath>Resource/CalDAV/sharing/calendars/read-write/6.ics</filepath> + </data> + <verify> + <callback>statusCode</callback> + </verify> + </request> + </test> + <test name='9'> + <description>Sharee sees changed event</description> + <request user="$userid2:" pswd="$pswd2:"> + <method>GET</method> + <ruri>$sharedcalendar:/1.ics</ruri> + <verify> + <callback>calendarDataMatch</callback> + <arg> + <name>filepath</name> + <value>Resource/CalDAV/sharing/calendars/read-write/6.ics</value> + </arg> + </verify> + </request> + </test> + <test name='10'> + <description>Sharer creates event</description> + <request> + <method>PUT</method> + <ruri>$calendarhome1:/shared/2.ics</ruri> + <data> + <content-type>text/calendar; charset=utf-8</content-type> + <filepath>Resource/CalDAV/sharing/calendars/read-write/7.ics</filepath> + </data> + <verify> + <callback>statusCode</callback> + </verify> + </request> + </test> + <test name='11'> + <description>Sharee sees new event</description> + <request user="$userid2:" pswd="$pswd2:"> + <method>GET</method> + <ruri>$sharedcalendar:/2.ics</ruri> + <verify> + <callback>calendarDataMatch</callback> + <arg> + <name>filepath</name> + <value>Resource/CalDAV/sharing/calendars/read-write/7.ics</value> + </arg> + </verify> + </request> + </test> + <test name='12'> + <description>Sharee changes event</description> + <request user="$userid2:" pswd="$pswd2:"> + <method>PUT</method> + <ruri>$sharedcalendar:/2.ics</ruri> + <data> + <content-type>text/calendar; charset=utf-8</content-type> + <filepath>Resource/CalDAV/sharing/calendars/read-write/8.ics</filepath> + </data> + <verify> + <callback>statusCode</callback> + </verify> + </request> + </test> + <test name='13'> + <description>Sharer sees changed event</description> + <request> + <method>GET</method> + <ruri>$calendarhome1:/shared/2.ics</ruri> + <verify> + <callback>calendarDataMatch</callback> + <arg> + <name>filepath</name> + <value>Resource/CalDAV/sharing/calendars/read-write/8.ics</value> + </arg> + </verify> + </request> + </test> + </test-suite> + + <test-suite name='Default calendar cannot be shared calendar'> + <test name='1'> + <description>Set property on Inbox</description> + <request user="$userid2:" pswd="$pswd2:"> + <method>PROPPATCH</method> + <ruri>$inboxpath2:/</ruri> + <data> + <content-type>text/xml; charset=utf-8</content-type> + <filepath>Resource/CalDAV/sharing/calendars/defaultcalendar/1.xml</filepath> + </data> + <verify> + <callback>propfindItems</callback> + <arg> + <name>badprops</name> + <value>{urn:ietf:params:xml:ns:caldav}schedule-default-calendar-URL</value> + </arg> + </verify> + </request> + </test> + <test name='2'> + <description>Verify property on inbox</description> + <request user="$userid2:" pswd="$pswd2:"> + <method>PROPFIND</method> + <ruri>$inboxpath2:/</ruri> + <header> + <name>Depth</name> + <value>0</value> + </header> + <data> + <content-type>text/xml; charset=utf-8</content-type> + <filepath>Resource/CalDAV/sharing/calendars/defaultcalendar/2.xml</filepath> + </data> + <verify> + <callback>propfindItems</callback> + <arg> + <name>okprops</name> + <value><![CDATA[{urn:ietf:params:xml:ns:caldav}schedule-default-calendar-URL$<href xmlns="DAV:">$calendarpath2:</href>]]></value> + </arg> + </verify> + </request> + </test> + </test-suite> + + <test-suite name='Change to read-only calendar'> + <test name='1'> + <description>POST invitation</description> + <request> + <method>POST</method> + <ruri>$calendarhome1:/shared/</ruri> + <data> + <content-type>text/xml; charset=utf-8</content-type> + <filepath>Resource/CalDAV/sharing/calendars/read-only/1.xml</filepath> + </data> + <verify> + <callback>statusCode</callback> + </verify> + </request> + </test> + <test name='2'> + <description>Check Sharee notification collection</description> + <request user="$userid2:" pswd="$pswd2:"> + <method>WAITCOUNT 1</method> + <ruri>$notificationpath2:/</ruri> + </request> + <request user="$userid2:" pswd="$pswd2:"> + <method>GETNEW</method> + <ruri>$notificationpath2:/</ruri> + <verify> + <callback>xmlDataMatch</callback> + <arg> + <name>filepath</name> + <value>Resource/CalDAV/sharing/calendars/read-only/2.xml</value> + </arg> + <arg> + <name>filter</name> + <value>{http://calendarserver.org/ns/}dtstamp</value> + <value>{http://calendarserver.org/ns/}uid</value> + </arg> + </verify> + <grabelement> + <name>{http://calendarserver.org/ns/}invite-notification/{http://calendarserver.org/ns/}uid</name> + <variable>$inviteuid:</variable> + </grabelement> + </request> + </test> + <test name='3'> + <description>Sharee replies ACCEPTED</description> + <request user="$userid2:" pswd="$pswd2:"> + <method>POST</method> + <ruri>$calendarhome2:/</ruri> + <data> + <content-type>application/xml; charset=utf-8</content-type> + <filepath>Resource/CalDAV/sharing/calendars/read-only/3.xml</filepath> + </data> + <verify> + <callback>statusCode</callback> + </verify> + <grabelement> + <name>{DAV:}href</name> + <variable>$sharedcalendar:</variable> + </grabelement> + </request> + </test> + <test name='4'> + <description>Shared calendar exists</description> + <request user="$userid2:" pswd="$pswd2:"> + <method>PROPFIND</method> + <ruri>$sharedcalendar:/</ruri> + <header> + <name>Depth</name> + <value>0</value> + </header> + <data> + <content-type>text/xml; charset=utf-8</content-type> + <filepath>Resource/CalDAV/sharing/calendars/read-only/4.xml</filepath> + </data> + <verify> + <callback>xmlElementMatch</callback> + <arg> + <name>exists</name> + <value>$verify-property-prefix:/{DAV:}owner/{DAV:}href[=$principaluri1:]</value> + <value>$verify-property-prefix:/{DAV:}resourcetype/{http://calendarserver.org/ns/}shared</value> + <value>$verify-property-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}read</value> + </arg> + <arg> + <name>notexists</name> + <value>$verify-property-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}write</value> + <value>$verify-property-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}bind</value> + <value>$verify-property-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}unbind</value> + <value>$verify-property-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}admin</value> + <value>$verify-property-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}all</value> + </arg> + </verify> + </request> + </test> + <test name='5'> + <description>Create event</description> + <request user="$userid2:" pswd="$pswd2:"> + <method>PUT</method> + <ruri>$sharedcalendar:/3.ics</ruri> + <data> + <content-type>text/calendar; charset=utf-8</content-type> + <filepath>Resource/CalDAV/sharing/calendars/read-only/5.ics</filepath> + </data> + <verify> + <callback>statusCode</callback> + <arg> + <name>status</name> + <value>403</value> + </arg> + </verify> + </request> + </test> + <test name='6'> + <description>Sharer creates event</description> + <request> + <method>PUT</method> + <ruri>$calendarhome1:/shared/4.ics</ruri> + <data> + <content-type>text/calendar; charset=utf-8</content-type> + <filepath>Resource/CalDAV/sharing/calendars/read-only/6.ics</filepath> + </data> + <verify> + <callback>statusCode</callback> + </verify> + </request> + </test> + <test name='7'> + <description>Sharee sees new event</description> + <request user="$userid2:" pswd="$pswd2:"> + <method>GET</method> + <ruri>$sharedcalendar:/4.ics</ruri> + <verify> + <callback>calendarDataMatch</callback> + <arg> + <name>filepath</name> + <value>Resource/CalDAV/sharing/calendars/read-only/6.ics</value> + </arg> + </verify> + </request> + </test> + <test name='8'> + <description>Sharee cannot change event</description> + <request user="$userid2:" pswd="$pswd2:"> + <method>PUT</method> + <ruri>$sharedcalendar:/4.ics</ruri> + <data> + <content-type>text/calendar; charset=utf-8</content-type> + <filepath>Resource/CalDAV/sharing/calendars/read-only/7.ics</filepath> + </data> + <verify> + <callback>statusCode</callback> + <arg> + <name>status</name> + <value>403</value> + </arg> + </verify> + </request> + </test> + </test-suite> + + <end> + <request user="$useradmin:" pswd="$pswdadmin:"> + <method>DELETEALL</method> + <ruri>$notificationpath1:/</ruri> + <ruri>$notificationpath2:/</ruri> + <ruri>$notificationpath3:/</ruri> + <ruri>$notificationpath4:/</ruri> + </request> + </end> + +</caldavtest> 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) { diff --git a/apps/dav/tests/unit/carddav/sharing/plugintest.php b/apps/dav/tests/unit/carddav/sharing/plugintest.php index 19ee075fb4f..f7159c2d22d 100644 --- a/apps/dav/tests/unit/carddav/sharing/plugintest.php +++ b/apps/dav/tests/unit/carddav/sharing/plugintest.php @@ -22,8 +22,8 @@ namespace OCA\DAV\Tests\Unit\CardDAV; -use OCA\DAV\CardDAV\Sharing\IShareableAddressBook; -use OCA\DAV\CardDAV\Sharing\Plugin; +use OCA\DAV\DAV\Sharing\IShareable; +use OCA\DAV\DAV\Sharing\Plugin; use OCA\DAV\Connector\Sabre\Auth; use OCP\IRequest; use Sabre\DAV\Server; @@ -38,7 +38,7 @@ class PluginTest extends TestCase { private $plugin; /** @var Server */ private $server; - /** @var IShareableAddressBook | \PHPUnit_Framework_MockObject_MockObject */ + /** @var IShareable | \PHPUnit_Framework_MockObject_MockObject */ private $book; public function setUp() { @@ -55,7 +55,7 @@ class PluginTest extends TestCase { $root = new SimpleCollection('root'); $this->server = new \Sabre\DAV\Server($root); /** @var SimpleCollection $node */ - $this->book = $this->getMockBuilder('OCA\DAV\CardDAV\Sharing\IShareableAddressBook')->disableOriginalConstructor()->getMock(); + $this->book = $this->getMockBuilder('OCA\DAV\DAV\Sharing\IShareable')->disableOriginalConstructor()->getMock(); $this->book->method('getName')->willReturn('addressbook1.vcf'); $root->addChild($this->book); $this->plugin->initialize($this->server); diff --git a/apps/dav/tests/unit/dav/sharing/plugintest.php b/apps/dav/tests/unit/dav/sharing/plugintest.php new file mode 100644 index 00000000000..ce6c96f1bfc --- /dev/null +++ b/apps/dav/tests/unit/dav/sharing/plugintest.php @@ -0,0 +1,83 @@ +<?php +/** + * @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\Tests\Unit\DAV; + + +use OCA\DAV\DAV\Sharing\IShareable; +use OCA\DAV\DAV\Sharing\Plugin; +use OCA\DAV\Connector\Sabre\Auth; +use OCP\IRequest; +use Sabre\DAV\Server; +use Sabre\DAV\SimpleCollection; +use Sabre\HTTP\Request; +use Sabre\HTTP\Response; +use Test\TestCase; + +class PluginTest extends TestCase { + + /** @var Plugin */ + private $plugin; + /** @var Server */ + private $server; + /** @var IShareable | \PHPUnit_Framework_MockObject_MockObject */ + private $book; + + public function setUp() { + parent::setUp(); + + /** @var Auth | \PHPUnit_Framework_MockObject_MockObject $authBackend */ + $authBackend = $this->getMockBuilder('OCA\DAV\Connector\Sabre\Auth')->disableOriginalConstructor()->getMock(); + $authBackend->method('isDavAuthenticated')->willReturn(true); + + /** @var IRequest $request */ + $request = $this->getMockBuilder('OCP\IRequest')->disableOriginalConstructor()->getMock(); + $this->plugin = new Plugin($authBackend, $request); + + $root = new SimpleCollection('root'); + $this->server = new \Sabre\DAV\Server($root); + /** @var SimpleCollection $node */ + $this->book = $this->getMockBuilder('OCA\DAV\DAV\Sharing\IShareable')-> + disableOriginalConstructor()-> + getMock(); + $this->book->method('getName')->willReturn('addressbook1.vcf'); + $root->addChild($this->book); + $this->plugin->initialize($this->server); + } + + public function testSharing() { + + $this->book->expects($this->once())->method('updateShares')->with([[ + 'href' => 'principal:principals/admin', + 'commonName' => null, + 'summary' => null, + 'readOnly' => false + ]], ['mailto:wilfredo@example.com']); + + // setup request + $request = new Request(); + $request->addHeader('Content-Type', 'application/xml'); + $request->setUrl('addressbook1.vcf'); + $request->setBody('<?xml version="1.0" encoding="utf-8" ?><CS:share xmlns:D="DAV:" xmlns:CS="http://owncloud.org/ns"><CS:set><D:href>principal:principals/admin</D:href><CS:read-write/></CS:set> <CS:remove><D:href>mailto:wilfredo@example.com</D:href></CS:remove></CS:share>'); + $response = new Response(); + $this->plugin->httpPost($request, $response); + } +} diff --git a/apps/dav/tests/unit/servertest.php b/apps/dav/tests/unit/servertest.php new file mode 100644 index 00000000000..63bab482b45 --- /dev/null +++ b/apps/dav/tests/unit/servertest.php @@ -0,0 +1,24 @@ +<?php + +namespace OCA\DAV\Tests\Unit; + +use OCA\DAV\Server; +use OCP\IRequest; + +/** + * Class ServerTest + * + * @group DB + * + * @package OCA\DAV\Tests\Unit + */ +class ServerTest extends \Test\TestCase { + + public function test() { + /** @var IRequest $r */ + $r = $this->getMockBuilder('\OCP\IRequest') + ->disableOriginalConstructor()->getMock(); + $s = new Server($r, '/'); + $this->assertNotNull($s->server); + } +}
\ No newline at end of file diff --git a/apps/files_sharing/api/share20ocs.php b/apps/files_sharing/api/share20ocs.php index c5e7dcff824..a3276c5867a 100644 --- a/apps/files_sharing/api/share20ocs.php +++ b/apps/files_sharing/api/share20ocs.php @@ -20,8 +20,6 @@ */ namespace OCA\Files_Sharing\API; -use OC\Share20\IShare; - use OCP\IGroupManager; use OCP\IUserManager; use OCP\IRequest; @@ -73,36 +71,36 @@ class Share20OCS { /** * Convert an IShare to an array for OCS output * - * @param IShare $share + * @param \OCP\Share\IShare $share * @return array */ - protected function formatShare($share) { + protected function formatShare(\OCP\Share\IShare $share) { $result = [ 'id' => $share->getId(), 'share_type' => $share->getShareType(), 'uid_owner' => $share->getSharedBy()->getUID(), 'displayname_owner' => $share->getSharedBy()->getDisplayName(), 'permissions' => $share->getPermissions(), - 'stime' => $share->getShareTime(), - 'parent' => $share->getParent(), + 'stime' => $share->getShareTime()->getTimestamp(), + 'parent' => null, 'expiration' => null, 'token' => null, 'uid_file_owner' => $share->getShareOwner()->getUID(), 'displayname_file_owner' => $share->getShareOwner()->getDisplayName(), ]; - $path = $share->getPath(); - $result['path'] = $this->rootFolder->getUserFolder($share->getShareOwner()->getUID())->getRelativePath($path->getPath()); - if ($path instanceOf \OCP\Files\Folder) { + $node = $share->getNode(); + $result['path'] = $this->rootFolder->getUserFolder($share->getShareOwner()->getUID())->getRelativePath($node->getPath()); + if ($node instanceOf \OCP\Files\Folder) { $result['item_type'] = 'folder'; } else { $result['item_type'] = 'file'; } - $result['storage_id'] = $path->getStorage()->getId(); - $result['storage'] = $path->getStorage()->getCache()->getNumericStorageId(); - $result['item_source'] = $path->getId(); - $result['file_source'] = $path->getId(); - $result['file_parent'] = $path->getParent()->getId(); + $result['storage_id'] = $node->getStorage()->getId(); + $result['storage'] = $node->getStorage()->getCache()->getNumericStorageId(); + $result['item_source'] = $node->getId(); + $result['file_source'] = $node->getId(); + $result['file_parent'] = $node->getParent()->getId(); $result['file_target'] = $share->getTarget(); if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) { @@ -222,7 +220,7 @@ class Share20OCS { return new \OC_OCS_Result(null, 404, 'wrong path, file/folder doesn\'t exist'); } - $share->setPath($path); + $share->setNode($path); // Parse permissions (if available) $permissions = $this->request->getParam('permissions', null); @@ -272,12 +270,12 @@ class Share20OCS { if ($publicUpload === 'true') { // Check if public upload is allowed if (!$this->shareManager->shareApiLinkAllowPublicUpload()) { - return new \OC_OCS_Result(null, 403, '"public upload disabled by the administrator'); + return new \OC_OCS_Result(null, 403, 'public upload disabled by the administrator'); } // Public upload can only be set for folders if ($path instanceof \OCP\Files\File) { - return new \OC_OCS_Result(null, 404, '"public upload is only possible for public shared folders'); + return new \OC_OCS_Result(null, 404, 'public upload is only possible for public shared folders'); } $share->setPermissions( @@ -290,12 +288,16 @@ class Share20OCS { } // Set password - $share->setPassword($this->request->getParam('password', null)); + $password = $this->request->getParam('password', ''); + + if ($password !== '') { + $share->setPassword($password); + } //Expire date - $expireDate = $this->request->getParam('expireDate', null); + $expireDate = $this->request->getParam('expireDate', ''); - if ($expireDate !== null) { + if ($expireDate !== '') { try { $expireDate = $this->parseDate($expireDate); $share->setExpirationDate($expireDate); @@ -335,7 +337,9 @@ class Share20OCS { $formatted = []; foreach ($shares as $share) { - $formatted[] = $this->formatShare($share); + if ($this->canAccessShare($share)) { + $formatted[] = $this->formatShare($share); + } } return new \OC_OCS_Result($formatted); @@ -351,7 +355,7 @@ class Share20OCS { } $nodes = $folder->getDirectoryListing(); - /** @var IShare[] $shares */ + /** @var \OCP\Share\IShare[] $shares */ $shares = []; foreach ($nodes as $node) { $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $node, false, -1, 0)); @@ -446,7 +450,7 @@ class Share20OCS { } if (!$this->canAccessShare($share)) { - return new \OC_OCS_Result(null, 404, "wrong share Id, share doesn't exist."); + return new \OC_OCS_Result(null, 404, 'wrong share Id, share doesn\'t exist.'); } $permissions = $this->request->getParam('permissions', null); @@ -454,34 +458,74 @@ class Share20OCS { $publicUpload = $this->request->getParam('publicUpload', null); $expireDate = $this->request->getParam('expireDate', null); - if ($permissions === null && $password === null && $publicUpload === null && $expireDate === null) { - return new \OC_OCS_Result(null, 400, 'Wrong or no update parameter given'); - } + /* + * expirationdate, password and publicUpload only make sense for link shares + */ + if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) { + if ($permissions === null && $password === null && $publicUpload === null && $expireDate === null) { + return new \OC_OCS_Result(null, 400, 'Wrong or no update parameter given'); + } - if ($expireDate !== null) { - try { - $expireDate = $this->parseDate($expireDate); - } catch (\Exception $e) { - return new \OC_OCS_Result(null, 400, $e->getMessage()); + $newPermissions = null; + if ($publicUpload === 'true') { + $newPermissions = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE; + } else if ($publicUpload === 'false') { + $newPermissions = \OCP\Constants::PERMISSION_READ; } - $share->setExpirationDate($expireDate); - } - if ($permissions !== null) { - $permissions = (int)$permissions; - $share->setPermissions($permissions); - } + if ($permissions !== null) { + $newPermissions = (int)$permissions; + } - if ($password !== null) { - $share->setPassword($password); - } + if ($newPermissions !== null && + $newPermissions !== \OCP\Constants::PERMISSION_READ && + $newPermissions !== (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE)) { + return new \OC_OCS_Result(null, 400, 'can\'t change permission for public link share'); + } - if ($publicUpload === 'true') { - $share->setPermissions(\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE); - } else if ($publicUpload === 'false') { - $share->setPermissions(\OCP\Constants::PERMISSION_READ); + if ($newPermissions === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE)) { + if (!$this->shareManager->shareApiLinkAllowPublicUpload()) { + return new \OC_OCS_Result(null, 403, 'public upload disabled by the administrator'); + } + + if (!($share->getPath() instanceof \OCP\Files\Folder)) { + return new \OC_OCS_Result(null, 400, "public upload is only possible for public shared folders"); + } + } + + if ($newPermissions !== null) { + $share->setPermissions($newPermissions); + } + + if ($expireDate === '') { + $share->setExpirationDate(null); + } else if ($expireDate !== null) { + try { + $expireDate = $this->parseDate($expireDate); + } catch (\Exception $e) { + return new \OC_OCS_Result(null, 400, $e->getMessage()); + } + $share->setExpirationDate($expireDate); + } + + if ($password === '') { + $share->setPassword(null); + } else if ($password !== null) { + $share->setPassword($password); + } + + } else { + // For other shares only permissions is valid. + if ($permissions === null) { + return new \OC_OCS_Result(null, 400, 'Wrong or no update parameter given'); + } else { + $permissions = (int)$permissions; + $share->setPermissions($permissions); + } } + + try { $share = $this->shareManager->updateShare($share); } catch (\Exception $e) { @@ -491,11 +535,24 @@ class Share20OCS { return new \OC_OCS_Result($this->formatShare($share)); } + public function validatePermissions($permissions) { + if ($permissions < 0 || $permissions > \OCP\Constants::PERMISSION_ALL) { + return false; + } + + + } + /** - * @param IShare $share + * @param \OCP\Share\IShare $share * @return bool */ - protected function canAccessShare(IShare $share) { + protected function canAccessShare(\OCP\Share\IShare $share) { + // A file with permissions 0 can't be accessed by us. So Don't show it + if ($share->getPermissions() === 0) { + return false; + } + // Owner of the file and the sharer of the file can always get share if ($share->getShareOwner() === $this->currentUser || $share->getSharedBy() === $this->currentUser diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 10d1e787922..c44bebbceaf 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -32,228 +32,75 @@ namespace OC\Files\Cache; -use OC\User\NoUserException; +use OC\Files\Cache\Wrapper\CacheJail; use OCP\Files\Cache\ICacheEntry; -use OCP\Share_Backend_Collection; +use OCP\Files\Storage\IStorage; /** * Metadata cache for shared files * * don't use this class directly if you need to get metadata, use \OC\Files\Filesystem::getFileInfo instead */ -class Shared_Cache extends Cache { - - private $storage; - private $files = array(); - +class Shared_Cache extends CacheJail { /** - * @param \OC\Files\Storage\Shared $storage + * @var \OC\Files\Storage\Shared */ - public function __construct($storage) { - parent::__construct($storage); - $this->storage = $storage; - } + private $storage; /** - * Get the source cache of a shared file or folder - * - * @param string $target Shared target file path - * @return \OC\Files\Cache\Cache|false + * @var IStorage */ - private function getSourceCache($target) { - if ($target === false || $target === $this->storage->getMountPoint()) { - $target = ''; - } - $source = \OC_Share_Backend_File::getSource($target, $this->storage->getShare()); - if (isset($source['path']) && isset($source['fileOwner'])) { - try { - \OC\Files\Filesystem::initMountPoints($source['fileOwner']); - } catch(NoUserException $e) { - \OC::$server->getLogger()->logException($e, ['app' => 'files_sharing']); - return false; - } - $mounts = \OC\Files\Filesystem::getMountByNumericId($source['storage']); - if (is_array($mounts) and !empty($mounts)) { - $fullPath = $mounts[0]->getMountPoint() . $source['path']; - list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($fullPath); - if ($storage) { - $this->files[$target] = $internalPath; - $cache = $storage->getCache(); - $this->storageId = $storage->getId(); - $this->numericId = $cache->getNumericStorageId(); - return $cache; - } - } - } - return false; - } - - public function getNumericStorageId() { - if (isset($this->numericId)) { - return $this->numericId; - } else { - return false; - } - } + private $sourceStorage; /** - * get the stored metadata of a file or folder - * - * @param string|int $file - * @return ICacheEntry|false + * @var ICacheEntry */ - public function get($file) { - $mimetypeLoader = \OC::$server->getMimeTypeLoader(); - if (is_string($file)) { - $cache = $this->getSourceCache($file); - if ($cache) { - $data = $cache->get($this->files[$file]); - if ($data) { - $data['displayname_owner'] = \OC_User::getDisplayName($this->storage->getSharedFrom()); - $data['path'] = $file; - if ($file === '') { - $data['is_share_mount_point'] = true; - } - $data['uid_owner'] = $this->storage->getOwner($file); - if (isset($data['permissions'])) { - $data['permissions'] &= $this->storage->getPermissions($file); - } else { - $data['permissions'] = $this->storage->getPermissions($file); - } - } - return $data; - } - } else { - $sourceId = $file; - // if we are at the root of the mount point we want to return the - // cache information for the source item - if (!is_int($sourceId) || $sourceId === 0) { - $sourceId = $this->storage->getSourceId(); - } - $query = \OCP\DB::prepare( - 'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`,' - . ' `size`, `mtime`, `encrypted`, `storage_mtime`, `etag`, `permissions`' - . ' FROM `*PREFIX*filecache` WHERE `fileid` = ?'); - $result = $query->execute(array($sourceId)); - $data = $result->fetchRow(); - $data['fileid'] = (int)$data['fileid']; - $data['mtime'] = (int)$data['mtime']; - $data['storage_mtime'] = (int)$data['storage_mtime']; - $data['encrypted'] = (bool)$data['encrypted']; - $data['mimetype'] = $mimetypeLoader->getMimetypeById($data['mimetype']); - $data['mimepart'] = $mimetypeLoader->getMimetypeById($data['mimepart']); - if ($data['storage_mtime'] === 0) { - $data['storage_mtime'] = $data['mtime']; - } - $data['size'] = (int)$data['size']; - $data['permissions'] = (int)$data['permissions']; - if (!is_int($file) || $file === 0) { - $data['path'] = ''; - $data['name'] = basename($this->storage->getMountPoint()); - $data['is_share_mount_point'] = true; - } - $data['permissions'] &= $this->storage->getPermissions(''); - return $data; - } - return false; - } + private $sourceRootInfo; /** - * get the metadata of all files stored in $folder - * - * @param string $folderId - * @return ICacheEntry[]|false + * @var \OCP\Files\Cache\ICache */ - public function getFolderContentsById($folderId) { - $cache = $this->getSourceCache(''); - if ($cache) { - $owner = $this->storage->getSharedFrom(); - $parentPath = $this->getPathById($folderId); - if ($parentPath !== '') { - $parentPath .= '/'; - } - $sourceFolderContent = $cache->getFolderContentsById($folderId); - foreach ($sourceFolderContent as &$c) { - $c['path'] = ltrim($parentPath . $c['name'], '/'); - $c['uid_owner'] = $owner; - $c['displayname_owner'] = \OC_User::getDisplayName($owner); - $c['permissions'] = $c['permissions'] & $this->storage->getPermissions(false); - } - - return $sourceFolderContent; - } - - return false; - } + private $sourceCache; /** - * store meta data for a file or folder - * - * @param string $file - * @param array $data - * - * @return int|false file id + * @param \OC\Files\Storage\Shared $storage + * @param IStorage $sourceStorage + * @param ICacheEntry $sourceRootInfo */ - public function put($file, array $data) { - $file = ($file === false) ? '' : $file; - if ($cache = $this->getSourceCache($file)) { - return $cache->put($this->files[$file], $data); - } - return false; + public function __construct($storage, IStorage $sourceStorage, ICacheEntry $sourceRootInfo) { + $this->storage = $storage; + $this->sourceStorage = $sourceStorage; + $this->sourceRootInfo = $sourceRootInfo; + $this->sourceCache = $sourceStorage->getCache(); + parent::__construct( + $this->sourceCache, + $this->sourceRootInfo->getPath() + ); } - /** - * get the file id for a file - * - * @param string $file - * @return int - */ - public function getId($file) { - if ($file === false) { - return $this->storage->getSourceId(); - } - $cache = $this->getSourceCache($file); - if ($cache) { - return $cache->getId($this->files[$file]); + public function getNumericStorageId() { + if (isset($this->numericId)) { + return $this->numericId; + } else { + return false; } - return -1; } - /** - * check if a file is available in the cache - * - * @param string $file - * @return bool - */ - public function inCache($file) { - if ($file == '') { - return true; + protected function formatCacheEntry($entry) { + $path = $entry['path']; + $entry = parent::formatCacheEntry($entry); + $sharePermissions = $this->storage->getPermissions($path); + if (isset($entry['permissions'])) { + $entry['permissions'] &= $sharePermissions; + } else { + $entry['permissions'] = $sharePermissions; } - return parent::inCache($file); - } - - /** - * remove a file or folder from the cache - * - * @param string $file - */ - public function remove($file) { - $file = ($file === false) ? '' : $file; - if ($cache = $this->getSourceCache($file)) { - $cache->remove($this->files[$file]); + $entry['uid_owner'] = $this->storage->getOwner($path); + $entry['displayname_owner'] = \OC_User::getDisplayName($entry['uid_owner']); + if ($path === '') { + $entry['is_share_mount_point'] = true; } - } - - /** - * Get the storage id and path needed for a move - * - * @param string $path - * @return array [$storageId, $internalPath] - */ - protected function getMoveInfo($path) { - $cache = $this->getSourceCache($path); - $file = \OC_Share_Backend_File::getSource($path, $this->storage->getShare()); - return [$cache->getNumericStorageId(), $file['path']]; + return $entry; } /** @@ -262,259 +109,4 @@ class Shared_Cache extends Cache { public function clear() { // Not a valid action for Shared Cache } - - /** - * @param string $file - * - * @return int, Cache::NOT_FOUND, Cache::PARTIAL, Cache::SHALLOW or Cache::COMPLETE - */ - public function getStatus($file) { - if ($file == '') { - return self::COMPLETE; - } - if ($cache = $this->getSourceCache($file)) { - return $cache->getStatus($this->files[$file]); - } - return self::NOT_FOUND; - } - - /** - * search for files matching $pattern - * - * @param string $pattern - * @return ICacheEntry[] of file data - */ - public function search($pattern) { - - $pattern = trim($pattern, '%'); - - $normalizedPattern = $this->normalize($pattern); - - $result = array(); - $exploreDirs = array(''); - while (count($exploreDirs) > 0) { - $dir = array_pop($exploreDirs); - $files = $this->getFolderContents($dir); - // no results? - if (!$files) { - // maybe it's a single shared file - $file = $this->get(''); - if ($normalizedPattern === '' || stristr($file['name'], $normalizedPattern) !== false) { - $result[] = $file; - } - continue; - } - foreach ($files as $file) { - if ($normalizedPattern === '' || stristr($file['name'], $normalizedPattern) !== false) { - $result[] = $file; - } - if ($file['mimetype'] === 'httpd/unix-directory') { - $exploreDirs[] = ltrim($dir . '/' . $file['name'], '/'); - } - } - } - return $result; - - } - - /** - * search for files by mimetype - * - * @param string $mimetype - * @return ICacheEntry[] - */ - public function searchByMime($mimetype) { - $mimepart = null; - if (strpos($mimetype, '/') === false) { - $mimepart = $mimetype; - $mimetype = null; - } - - $result = array(); - $exploreDirs = array(''); - while (count($exploreDirs) > 0) { - $dir = array_pop($exploreDirs); - $files = $this->getFolderContents($dir); - // no results? - if (!$files) { - // maybe it's a single shared file - $file = $this->get(''); - if (($mimepart && $file['mimepart'] === $mimepart) || ($mimetype && $file['mimetype'] === $mimetype)) { - $result[] = $file; - } - continue; - } - foreach ($files as $file) { - if ($file['mimetype'] === 'httpd/unix-directory') { - $exploreDirs[] = ltrim($dir . '/' . $file['name'], '/'); - } else if (($mimepart && $file['mimepart'] === $mimepart) || ($mimetype && $file['mimetype'] === $mimetype)) { - $result[] = $file; - } - } - } - return $result; - } - - /** - * Checks whether the given file has the given tag. - * - * @param \OCP\ITags $tagger - * @param array $fileData file data - * @param string $tag tag to check for - * @return boolean true if the given file has the expected tag, - * false otherwise - */ - private function hasTag($tagger, $fileData, $tag) { - $tags = $tagger->getTagsForObjects(array((int)$fileData['fileid'])); - return (!empty($tags) && in_array($tag, current($tags))); - } - - /** - * search for files by tag - * - * @param string|int $tag tag to search for - * @param string $userId owner of the tags - * @return ICacheEntry[] file data - */ - public function searchByTag($tag, $userId) { - // TODO: inject this - $tagger = \OC::$server->getTagManager()->load('files', null, null, $userId); - $result = array(); - $exploreDirs = array(''); - // check if root is tagged - $file = $this->get(''); - if ($this->hasTag($tagger, $file, $tag)) { - $result[] = $file; - } - // FIXME: this is so wrong and unefficient, need to replace with actual DB queries - while (count($exploreDirs) > 0) { - $dir = array_pop($exploreDirs); - $files = $this->getFolderContents($dir); - if (!$files) { - continue; - } - foreach ($files as $file) { - if ($this->hasTag($tagger, $file, $tag)) { - $result[] = $file; - } - if ($file['mimetype'] === 'httpd/unix-directory') { - $exploreDirs[] = ltrim($dir . '/' . $file['name'], '/'); - } - } - } - return $result; - } - - /** - * update the folder size and the size of all parent folders - * - * @param string|boolean $path - * @param array $data (optional) meta data of the folder - */ - public function correctFolderSize($path, $data = null) { - $this->calculateFolderSize($path, $data); - if ($path !== '') { - $parent = dirname($path); - if ($parent === '.' or $parent === '/') { - $parent = ''; - } - $this->correctFolderSize($parent); - } else { - // bubble up to source cache - $sourceCache = $this->getSourceCache($path); - if (isset($this->files[$path])) { - $parent = dirname($this->files[$path]); - if ($sourceCache) { - $sourceCache->correctFolderSize($parent); - } - } - } - } - - /** - * get the size of a folder and set it in the cache - * - * @param string $path - * @param array $entry (optional) meta data of the folder - * @return int - */ - public function calculateFolderSize($path, $entry = null) { - $path = ($path === false) ? '' : $path; - if ($cache = $this->getSourceCache($path)) { - return $cache->calculateFolderSize($this->files[$path]); - } - return 0; - } - - /** - * get all file ids on the files on the storage - * - * @return int[] - */ - public function getAll() { - $ids = \OCP\Share::getItemsSharedWith('file', \OC_Share_Backend_File::FORMAT_GET_ALL); - $folderBackend = \OCP\Share::getBackend('folder'); - if ($folderBackend instanceof Share_Backend_Collection) { - foreach ($ids as $file) { - /** @var $folderBackend Share_Backend_Collection */ - $children = $folderBackend->getChildren($file); - foreach ($children as $child) { - $ids[] = (int)$child['source']; - } - - } - } - - return $ids; - } - - /** - * find a folder in the cache which has not been fully scanned - * - * If multiply incomplete folders are in the cache, the one with the highest id will be returned, - * use the one with the highest id gives the best result with the background scanner, since that is most - * likely the folder where we stopped scanning previously - * - * @return boolean the path of the folder or false when no folder matched - */ - public function getIncomplete() { - return false; - } - - /** - * get the path of a file on this storage relative to the mount point by it's id - * - * @param int $id - * @param string $pathEnd (optional) used internally for recursive calls - * @return string|null - */ - public function getPathById($id, $pathEnd = '') { - // direct shares are easy - if ($id === $this->storage->getSourceId()) { - return ltrim($pathEnd, '/'); - } else { - // if the item is a direct share we try and get the path of the parent and append the name of the item to it - list($parent, $name) = $this->getParentInfo($id); - if ($parent > 0) { - return $this->getPathById($parent, '/' . $name . $pathEnd); - } else { - return null; - } - } - } - - /** - * @param integer $id - * @return array - */ - private function getParentInfo($id) { - $sql = 'SELECT `parent`, `name` FROM `*PREFIX*filecache` WHERE `fileid` = ?'; - $query = \OCP\DB::prepare($sql); - $result = $query->execute(array($id)); - if ($row = $result->fetchRow()) { - return array((int)$row['parent'], $row['name']); - } else { - return array(-1, ''); - } - } } diff --git a/apps/files_sharing/lib/controllers/sharecontroller.php b/apps/files_sharing/lib/controllers/sharecontroller.php index 6f9a8d742cc..9fec57edbdd 100644 --- a/apps/files_sharing/lib/controllers/sharecontroller.php +++ b/apps/files_sharing/lib/controllers/sharecontroller.php @@ -51,7 +51,6 @@ use OCA\Files_Sharing\Helper; use OCP\Util; use OCA\Files_Sharing\Activity; use \OCP\Files\NotFoundException; -use \OC\Share20\IShare; use OCP\Files\IRootFolder; /** @@ -168,11 +167,11 @@ class ShareController extends Controller { * This is a modified version of Helper::authenticate * TODO: Try to merge back eventually with Helper::authenticate * - * @param IShare $share + * @param \OCP\Share\IShare $share * @param string|null $password * @return bool */ - private function linkShareAuth(IShare $share, $password = null) { + private function linkShareAuth(\OCP\Share\IShare $share, $password = null) { if ($password !== null) { if ($this->shareManager->checkPassword($share, $password)) { $this->session->set('public_link_authenticated', (string)$share->getId()); @@ -215,14 +214,14 @@ class ShareController extends Controller { } // We can't get the path of a file share - if ($share->getPath() instanceof \OCP\Files\File && $path !== '') { + if ($share->getNode() instanceof \OCP\Files\File && $path !== '') { throw new NotFoundException(); } $rootFolder = null; - if ($share->getPath() instanceof \OCP\Files\Folder) { + if ($share->getNode() instanceof \OCP\Files\Folder) { /** @var \OCP\Files\Folder $rootFolder */ - $rootFolder = $share->getPath(); + $rootFolder = $share->getNode(); try { $path = $rootFolder->get($path); @@ -234,26 +233,26 @@ class ShareController extends Controller { $shareTmpl = []; $shareTmpl['displayName'] = $share->getShareOwner()->getDisplayName(); $shareTmpl['owner'] = $share->getShareOwner()->getUID(); - $shareTmpl['filename'] = $share->getPath()->getName(); + $shareTmpl['filename'] = $share->getNode()->getName(); $shareTmpl['directory_path'] = $share->getTarget(); - $shareTmpl['mimetype'] = $share->getPath()->getMimetype(); - $shareTmpl['previewSupported'] = $this->previewManager->isMimeSupported($share->getPath()->getMimetype()); + $shareTmpl['mimetype'] = $share->getNode()->getMimetype(); + $shareTmpl['previewSupported'] = $this->previewManager->isMimeSupported($share->getNode()->getMimetype()); $shareTmpl['dirToken'] = $token; $shareTmpl['sharingToken'] = $token; $shareTmpl['server2serversharing'] = Helper::isOutgoingServer2serverShareEnabled(); $shareTmpl['protected'] = $share->getPassword() !== null ? 'true' : 'false'; $shareTmpl['dir'] = ''; - $shareTmpl['nonHumanFileSize'] = $share->getPath()->getSize(); - $shareTmpl['fileSize'] = \OCP\Util::humanFileSize($share->getPath()->getSize()); + $shareTmpl['nonHumanFileSize'] = $share->getNode()->getSize(); + $shareTmpl['fileSize'] = \OCP\Util::humanFileSize($share->getNode()->getSize()); // Show file list - if ($share->getPath() instanceof \OCP\Files\Folder) { + if ($share->getNode() instanceof \OCP\Files\Folder) { $shareTmpl['dir'] = $rootFolder->getRelativePath($path->getPath()); /* * The OC_Util methods require a view. This just uses the node API */ - $freeSpace = $share->getPath()->getStorage()->free_space($share->getPath()->getInternalPath()); + $freeSpace = $share->getNode()->getStorage()->free_space($share->getNode()->getInternalPath()); if ($freeSpace !== \OCP\Files\FileInfo::SPACE_UNKNOWN) { $freeSpace = max($freeSpace, 0); } else { @@ -321,23 +320,23 @@ class ShareController extends Controller { } $userFolder = $this->rootFolder->getUserFolder($share->getShareOwner()->getUID()); - $originalSharePath = $userFolder->getRelativePath($share->getPath()->getPath()); + $originalSharePath = $userFolder->getRelativePath($share->getNode()->getPath()); // Single file share - if ($share->getPath() instanceof \OCP\Files\File) { + if ($share->getNode() instanceof \OCP\Files\File) { // Single file download $event = $this->activityManager->generateEvent(); $event->setApp('files_sharing') ->setType(Activity::TYPE_PUBLIC_LINKS) - ->setSubject(Activity::SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED, [$userFolder->getRelativePath($share->getPath()->getPath())]) + ->setSubject(Activity::SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED, [$userFolder->getRelativePath($share->getNode()->getPath())]) ->setAffectedUser($share->getShareOwner()->getUID()) - ->setObject('files', $share->getPath()->getId(), $userFolder->getRelativePath($share->getPath()->getPath())); + ->setObject('files', $share->getNode()->getId(), $userFolder->getRelativePath($share->getNode()->getPath())); $this->activityManager->publish($event); } // Directory share else { /** @var \OCP\Files\Folder $node */ - $node = $share->getPath(); + $node = $share->getNode(); // Try to get the path if ($path !== '') { diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index 542d0e9e48c..3ae5749ea87 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -32,6 +32,8 @@ namespace OC\Files\Storage; use OC\Files\Filesystem; use OCA\Files_Sharing\ISharedStorage; +use OCP\Files\Cache\ICacheEntry; +use OCP\Files\Storage\IStorage; use OCP\Lock\ILockingProvider; /** @@ -41,7 +43,6 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage { private $share; // the shared resource private $files = array(); - private static $isInitialized = array(); /** * @var \OC\Files\View @@ -55,6 +56,16 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage { private $initialized = false; + /** + * @var ICacheEntry + */ + private $sourceRootInfo; + + /** + * @var IStorage + */ + private $sourceStorage; + public function __construct($arguments) { $this->share = $arguments['share']; $this->ownerView = $arguments['ownerView']; @@ -67,6 +78,9 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage { } $this->initialized = true; Filesystem::initMountPoints($this->share['uid_owner']); + $sourcePath = $this->ownerView->getPath($this->share['file_source']); + list($this->sourceStorage, $sourceInternalPath) = $this->ownerView->resolvePath($sourcePath); + $this->sourceRootInfo = $this->sourceStorage->getCache()->get($sourceInternalPath); } /** @@ -543,7 +557,7 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage { if (!$storage) { $storage = $this; } - return new \OC\Files\Cache\Shared_Cache($storage); + return new \OC\Files\Cache\Shared_Cache($storage, $this->sourceStorage, $this->sourceRootInfo); } public function getScanner($path = '', $storage = null) { @@ -553,13 +567,6 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage { return new \OC\Files\Cache\SharedScanner($storage); } - public function getWatcher($path = '', $storage = null) { - if (!$storage) { - $storage = $this; - } - return new \OC\Files\Cache\Shared_Watcher($storage); - } - public function getPropagator($storage = null) { if (!$storage) { $storage = $this; diff --git a/apps/files_sharing/lib/watcher.php b/apps/files_sharing/lib/watcher.php deleted file mode 100644 index 5b4736c21e1..00000000000 --- a/apps/files_sharing/lib/watcher.php +++ /dev/null @@ -1,81 +0,0 @@ -<?php -/** - * @author Christopher Schäpers <kondou@ts.unde.re> - * @author Michael Gapczynski <GapczynskiM@gmail.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <icewind@owncloud.com> - * @author Vincent Petry <pvince81@owncloud.com> - * - * @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 OC\Files\Cache; -use OCP\Files\Cache\ICacheEntry; - -/** - * check the storage backends for updates and change the cache accordingly - */ -class Shared_Watcher extends Watcher { - /** - * @var \OC\Files\Storage\Shared $storage - */ - protected $storage; - - /** - * Update the cache for changes to $path - * - * @param string $path - * @param ICacheEntry $cachedData - */ - public function update($path, $cachedData) { - parent::update($path, $cachedData); - // since parent::update() has already updated the size of the subdirs, - // only apply the update to the owner's parent dirs - - // find last parent before reaching the shared storage root, - // which is the actual shared dir from the owner - $sepPos = strpos($path, '/'); - if ($sepPos > 0) { - $baseDir = substr($path, 0, $sepPos); - } else { - $baseDir = $path; - } - - // find the path relative to the data dir - $file = $this->storage->getFile($baseDir); - $view = new \OC\Files\View('/' . $file['fileOwner']); - - // find the owner's storage and path - /** @var \OC\Files\Storage\Storage $storage */ - list($storage, $internalPath) = $view->resolvePath($file['path']); - - // update the parent dirs' sizes in the owner's cache - $storage->getCache()->correctFolderSize(dirname($internalPath)); - } - - /** - * remove deleted files in $path from the cache - * - * @param string $path - */ - public function cleanFolder($path) { - if ($path != '') { - parent::cleanFolder($path); - } - } - -} diff --git a/apps/files_sharing/tests/api/share20ocstest.php b/apps/files_sharing/tests/api/share20ocstest.php index f38af988155..0f600a84ca5 100644 --- a/apps/files_sharing/tests/api/share20ocstest.php +++ b/apps/files_sharing/tests/api/share20ocstest.php @@ -20,7 +20,6 @@ */ namespace OCA\Files_Sharing\Tests\API; -use OC\Share20\IShare; use OCA\Files_Sharing\API\Share20OCS; use OCP\IGroupManager; use OCP\IUserManager; @@ -31,19 +30,19 @@ use OCP\Files\IRootFolder; class Share20OCSTest extends \Test\TestCase { - /** @var \OC\Share20\Manager */ + /** @var \OC\Share20\Manager | \PHPUnit_Framework_MockObject_MockObject */ private $shareManager; - /** @var IGroupManager */ + /** @var IGroupManager | \PHPUnit_Framework_MockObject_MockObject */ private $groupManager; - /** @var IUserManager */ + /** @var IUserManager | \PHPUnit_Framework_MockObject_MockObject */ private $userManager; - /** @var IRequest */ + /** @var IRequest | \PHPUnit_Framework_MockObject_MockObject */ private $request; - /** @var IRootFolder */ + /** @var IRootFolder | \PHPUnit_Framework_MockObject_MockObject */ private $rootFolder; /** @var IURLGenerator */ @@ -78,6 +77,20 @@ class Share20OCSTest extends \Test\TestCase { ); } + private function mockFormatShare() { + return $this->getMockBuilder('OCA\Files_Sharing\API\Share20OCS') + ->setConstructorArgs([ + $this->shareManager, + $this->groupManager, + $this->userManager, + $this->request, + $this->rootFolder, + $this->urlGenerator, + $this->currentUser + ])->setMethods(['formatShare']) + ->getMock(); + } + public function testDeleteShareShareNotFound() { $this->shareManager ->expects($this->once()) @@ -90,7 +103,7 @@ class Share20OCSTest extends \Test\TestCase { } public function testDeleteShareCouldNotDelete() { - $share = $this->getMock('OC\Share20\IShare'); + $share = $this->getMock('OCP\Share\IShare'); $share->method('getShareOwner')->willReturn($this->currentUser); $this->shareManager ->expects($this->once()) @@ -109,7 +122,7 @@ class Share20OCSTest extends \Test\TestCase { } public function testDeleteShare() { - $share = $this->getMock('OC\Share20\IShare'); + $share = $this->getMock('OCP\Share\IShare'); $share->method('getSharedBy')->willReturn($this->currentUser); $this->shareManager ->expects($this->once()) @@ -143,17 +156,18 @@ class Share20OCSTest extends \Test\TestCase { public function createShare($id, $shareType, $sharedWith, $sharedBy, $shareOwner, $path, $permissions, $shareTime, $expiration, $parent, $target, $mail_send, $token=null, $password=null) { - $share = $this->getMock('OC\Share20\IShare'); + $share = $this->getMock('OCP\Share\IShare'); $share->method('getId')->willReturn($id); $share->method('getShareType')->willReturn($shareType); $share->method('getSharedWith')->willReturn($sharedWith); $share->method('getSharedBy')->willReturn($sharedBy); $share->method('getShareOwner')->willReturn($shareOwner); - $share->method('getPath')->willReturn($path); + $share->method('getNode')->willReturn($path); $share->method('getPermissions')->willReturn($permissions); - $share->method('getShareTime')->willReturn($shareTime); + $time = new \DateTime(); + $time->setTimestamp($shareTime); + $share->method('getShareTime')->willReturn($time); $share->method('getExpirationDate')->willReturn($expiration); - $share->method('getParent')->willReturn($parent); $share->method('getTarget')->willReturn($target); $share->method('getMailSend')->willReturn($mail_send); $share->method('getToken')->willReturn($token); @@ -243,7 +257,7 @@ class Share20OCSTest extends \Test\TestCase { 'expiration' => null, 'permissions' => 4, 'stime' => 5, - 'parent' => 6, + 'parent' => null, 'storage_id' => 'STORAGE', 'path' => 'file', 'storage' => 101, @@ -284,7 +298,7 @@ class Share20OCSTest extends \Test\TestCase { 'expiration' => null, 'permissions' => 4, 'stime' => 5, - 'parent' => 6, + 'parent' => null, 'storage_id' => 'STORAGE', 'path' => 'folder', 'storage' => 101, @@ -328,7 +342,7 @@ class Share20OCSTest extends \Test\TestCase { 'expiration' => '2000-01-02 00:00:00', 'permissions' => 4, 'stime' => 5, - 'parent' => 6, + 'parent' => null, 'storage_id' => 'STORAGE', 'path' => 'folder', 'storage' => 101, @@ -345,7 +359,7 @@ class Share20OCSTest extends \Test\TestCase { /** * @dataProvider dataGetShare */ - public function testGetShare(\OC\Share20\IShare $share, array $result) { + public function testGetShare(\OCP\Share\IShare $share, array $result) { $ocs = $this->getMockBuilder('OCA\Files_Sharing\API\Share20OCS') ->setConstructorArgs([ $this->shareManager, @@ -384,39 +398,39 @@ class Share20OCSTest extends \Test\TestCase { } public function testCanAccessShare() { - $share = $this->getMock('OC\Share20\IShare'); + $share = $this->getMock('OCP\Share\IShare'); $share->method('getShareOwner')->willReturn($this->currentUser); $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share])); - $share = $this->getMock('OC\Share20\IShare'); + $share = $this->getMock('OCP\Share\IShare'); $share->method('getSharedBy')->willReturn($this->currentUser); $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share])); - $share = $this->getMock('OC\Share20\IShare'); + $share = $this->getMock('OCP\Share\IShare'); $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_USER); $share->method('getSharedWith')->willReturn($this->currentUser); $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share])); - $share = $this->getMock('OC\Share20\IShare'); + $share = $this->getMock('OCP\Share\IShare'); $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_USER); $share->method('getSharedWith')->willReturn($this->getMock('OCP\IUser')); $this->assertFalse($this->invokePrivate($this->ocs, 'canAccessShare', [$share])); - $share = $this->getMock('OC\Share20\IShare'); + $share = $this->getMock('OCP\Share\IShare'); $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_GROUP); $group = $this->getMock('OCP\IGroup'); $group->method('inGroup')->with($this->currentUser)->willReturn(true); $share->method('getSharedWith')->willReturn($group); $this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share])); - $share = $this->getMock('OC\Share20\IShare'); + $share = $this->getMock('OCP\Share\IShare'); $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_GROUP); $group = $this->getMock('OCP\IGroup'); $group->method('inGroup')->with($this->currentUser)->willReturn(false); $share->method('getSharedWith')->willReturn($group); $this->assertFalse($this->invokePrivate($this->ocs, 'canAccessShare', [$share])); - $share = $this->getMock('OC\Share20\IShare'); + $share = $this->getMock('OCP\Share\IShare'); $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_LINK); $this->assertFalse($this->invokePrivate($this->ocs, 'canAccessShare', [$share])); } @@ -457,7 +471,7 @@ class Share20OCSTest extends \Test\TestCase { } public function testCreateShareInvalidPermissions() { - $share = $this->getMock('\OC\Share20\IShare'); + $share = $this->getMock('\OCP\Share\IShare'); $this->shareManager->method('newShare')->willReturn($share); $this->request @@ -488,7 +502,7 @@ class Share20OCSTest extends \Test\TestCase { } public function testCreateShareUserNoShareWith() { - $share = $this->getMock('\OC\Share20\IShare'); + $share = $this->getMock('\OCP\Share\IShare'); $this->shareManager->method('newShare')->willReturn($share); $this->request @@ -520,7 +534,7 @@ class Share20OCSTest extends \Test\TestCase { } public function testCreateShareUserNoValidShareWith() { - $share = $this->getMock('\OC\Share20\IShare'); + $share = $this->getMock('\OCP\Share\IShare'); $this->shareManager->method('newShare')->willReturn($share); $this->request @@ -553,8 +567,9 @@ class Share20OCSTest extends \Test\TestCase { } public function testCreateShareUser() { - $share = $this->getMock('\OC\Share20\IShare'); + $share = $this->getMock('\OCP\Share\IShare'); $this->shareManager->method('newShare')->willReturn($share); + $this->shareManager->method('createShare')->will($this->returnArgument(0)); $ocs = $this->getMockBuilder('OCA\Files_Sharing\API\Share20OCS') ->setConstructorArgs([ @@ -611,8 +626,9 @@ class Share20OCSTest extends \Test\TestCase { } public function testCreateShareGroupNoValidShareWith() { - $share = $this->getMock('\OC\Share20\IShare'); + $share = $this->getMock('\OCP\Share\IShare'); $this->shareManager->method('newShare')->willReturn($share); + $this->shareManager->method('createShare')->will($this->returnArgument(0)); $this->request ->method('getParam') @@ -644,8 +660,9 @@ class Share20OCSTest extends \Test\TestCase { } public function testCreateShareGroup() { - $share = $this->getMock('\OC\Share20\IShare'); + $share = $this->getMock('\OCP\Share\IShare'); $this->shareManager->method('newShare')->willReturn($share); + $this->shareManager->method('createShare')->will($this->returnArgument(0)); $ocs = $this->getMockBuilder('OCA\Files_Sharing\API\Share20OCS') ->setConstructorArgs([ @@ -696,4 +713,650 @@ class Share20OCSTest extends \Test\TestCase { $this->assertEquals($expected->getMeta(), $result->getMeta()); $this->assertEquals($expected->getData(), $result->getData()); } + + public function testCreateShareLinkNoLinksAllowed() { + $this->request + ->method('getParam') + ->will($this->returnValueMap([ + ['path', null, 'valid-path'], + ['shareType', '-1', \OCP\Share::SHARE_TYPE_LINK], + ])); + + $path = $this->getMock('\OCP\Files\Folder'); + $this->rootFolder->method('getUserFolder')->with($this->currentUser->getUID())->will($this->returnSelf()); + $this->rootFolder->method('get')->with('valid-path')->willReturn($path); + + $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare()); + + $expected = new \OC_OCS_Result(null, 404, 'public link sharing is disabled by the administrator'); + $result = $this->ocs->createShare(); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testCreateShareLinkNoPublicUpload() { + $this->request + ->method('getParam') + ->will($this->returnValueMap([ + ['path', null, 'valid-path'], + ['shareType', '-1', \OCP\Share::SHARE_TYPE_LINK], + ['publicUpload', null, 'true'], + ])); + + $path = $this->getMock('\OCP\Files\Folder'); + $this->rootFolder->method('getUserFolder')->with($this->currentUser->getUID())->will($this->returnSelf()); + $this->rootFolder->method('get')->with('valid-path')->willReturn($path); + + $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare()); + $this->shareManager->method('shareApiAllowLinks')->willReturn(true); + + $expected = new \OC_OCS_Result(null, 403, 'public upload disabled by the administrator'); + $result = $this->ocs->createShare(); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testCreateShareLinkPublicUploadFile() { + $this->request + ->method('getParam') + ->will($this->returnValueMap([ + ['path', null, 'valid-path'], + ['shareType', '-1', \OCP\Share::SHARE_TYPE_LINK], + ['publicUpload', null, 'true'], + ])); + + $path = $this->getMock('\OCP\Files\File'); + $this->rootFolder->method('getUserFolder')->with($this->currentUser->getUID())->will($this->returnSelf()); + $this->rootFolder->method('get')->with('valid-path')->willReturn($path); + + $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare()); + $this->shareManager->method('shareApiAllowLinks')->willReturn(true); + $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true); + + $expected = new \OC_OCS_Result(null, 404, 'public upload is only possible for public shared folders'); + $result = $this->ocs->createShare(); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testCreateShareLinkPublicUploadFolder() { + $ocs = $this->mockFormatShare(); + + $this->request + ->method('getParam') + ->will($this->returnValueMap([ + ['path', null, 'valid-path'], + ['shareType', '-1', \OCP\Share::SHARE_TYPE_LINK], + ['publicUpload', null, 'true'], + ['expireDate', '', ''], + ['password', '', ''], + ])); + + $path = $this->getMock('\OCP\Files\Folder'); + $this->rootFolder->method('getUserFolder')->with($this->currentUser->getUID())->will($this->returnSelf()); + $this->rootFolder->method('get')->with('valid-path')->willReturn($path); + + $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare()); + $this->shareManager->method('shareApiAllowLinks')->willReturn(true); + $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true); + + $currentUser = $this->currentUser; + + $this->shareManager->expects($this->once())->method('createShare')->with( + $this->callback(function (IShare $share) use ($path, $currentUser) { + return $share->getPath() === $path && + $share->getShareType() === \OCP\Share::SHARE_TYPE_LINK && + $share->getPermissions() === \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_DELETE && + $share->getSharedBy() === $currentUser && + $share->getPassword() === null && + $share->getExpirationDate() === null; + }) + ); + + $expected = new \OC_OCS_Result(null); + $result = $ocs->createShare(); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testCreateShareLinkPassword() { + $ocs = $this->mockFormatShare(); + + $this->request + ->method('getParam') + ->will($this->returnValueMap([ + ['path', null, 'valid-path'], + ['shareType', '-1', \OCP\Share::SHARE_TYPE_LINK], + ['publicUpload', null, 'false'], + ['expireDate', '', ''], + ['password', '', 'password'], + ])); + + $path = $this->getMock('\OCP\Files\Folder'); + $this->rootFolder->method('getUserFolder')->with($this->currentUser->getUID())->will($this->returnSelf()); + $this->rootFolder->method('get')->with('valid-path')->willReturn($path); + + $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare()); + $this->shareManager->method('shareApiAllowLinks')->willReturn(true); + $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true); + + $currentUser = $this->currentUser; + + $this->shareManager->expects($this->once())->method('createShare')->with( + $this->callback(function (IShare $share) use ($path, $currentUser) { + return $share->getPath() === $path && + $share->getShareType() === \OCP\Share::SHARE_TYPE_LINK && + $share->getPermissions() === \OCP\Constants::PERMISSION_READ && + $share->getSharedBy() === $currentUser && + $share->getPassword() === 'password' && + $share->getExpirationDate() === null; + }) + ); + + $expected = new \OC_OCS_Result(null); + $result = $ocs->createShare(); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testCreateShareValidExpireDate() { + $ocs = $this->mockFormatShare(); + + $this->request + ->method('getParam') + ->will($this->returnValueMap([ + ['path', null, 'valid-path'], + ['shareType', '-1', \OCP\Share::SHARE_TYPE_LINK], + ['publicUpload', null, 'false'], + ['expireDate', '', '2000-01-01'], + ['password', '', ''], + ])); + + $path = $this->getMock('\OCP\Files\Folder'); + $this->rootFolder->method('getUserFolder')->with($this->currentUser->getUID())->will($this->returnSelf()); + $this->rootFolder->method('get')->with('valid-path')->willReturn($path); + + $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare()); + $this->shareManager->method('shareApiAllowLinks')->willReturn(true); + $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true); + + $currentUser = $this->currentUser; + + $this->shareManager->expects($this->once())->method('createShare')->with( + $this->callback(function (IShare $share) use ($path, $currentUser) { + $date = new \DateTime('2000-01-01'); + $date->setTime(0,0,0); + + return $share->getPath() === $path && + $share->getShareType() === \OCP\Share::SHARE_TYPE_LINK && + $share->getPermissions() === \OCP\Constants::PERMISSION_READ && + $share->getSharedBy() === $currentUser && + $share->getPassword() === null && + $share->getExpirationDate() == $date; + }) + ); + + $expected = new \OC_OCS_Result(null); + $result = $ocs->createShare(); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testCreateShareInvalidExpireDate() { + $ocs = $this->mockFormatShare(); + + $this->request + ->method('getParam') + ->will($this->returnValueMap([ + ['path', null, 'valid-path'], + ['shareType', '-1', \OCP\Share::SHARE_TYPE_LINK], + ['publicUpload', null, 'false'], + ['expireDate', '', 'a1b2d3'], + ['password', '', ''], + ])); + + $path = $this->getMock('\OCP\Files\Folder'); + $this->rootFolder->method('getUserFolder')->with($this->currentUser->getUID())->will($this->returnSelf()); + $this->rootFolder->method('get')->with('valid-path')->willReturn($path); + + $this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare()); + $this->shareManager->method('shareApiAllowLinks')->willReturn(true); + $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true); + + $expected = new \OC_OCS_Result(null, 404, 'Invalid Date. Format must be YYYY-MM-DD.'); + $result = $ocs->createShare(); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testUpdateShareCantAccess() { + $share = \OC::$server->getShareManager()->newShare(); + + $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); + + $expected = new \OC_OCS_Result(null, 404, 'wrong share Id, share doesn\'t exist.'); + $result = $this->ocs->updateShare(42); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testUpdateNoParametersLink() { + $share = \OC::$server->getShareManager()->newShare(); + $share->setPermissions(\OCP\Constants::PERMISSION_ALL) + ->setSharedBy($this->currentUser) + ->setShareType(\OCP\Share::SHARE_TYPE_LINK); + + $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); + + $expected = new \OC_OCS_Result(null, 400, 'Wrong or no update parameter given'); + $result = $this->ocs->updateShare(42); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testUpdateNoParametersOther() { + $share = \OC::$server->getShareManager()->newShare(); + $share->setPermissions(\OCP\Constants::PERMISSION_ALL) + ->setSharedBy($this->currentUser) + ->setShareType(\OCP\Share::SHARE_TYPE_GROUP); + + $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); + + $expected = new \OC_OCS_Result(null, 400, 'Wrong or no update parameter given'); + $result = $this->ocs->updateShare(42); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testUpdateLinkShareClear() { + $ocs = $this->mockFormatShare(); + + $share = \OC::$server->getShareManager()->newShare(); + $share->setPermissions(\OCP\Constants::PERMISSION_ALL) + ->setSharedBy($this->currentUser) + ->setShareType(\OCP\Share::SHARE_TYPE_LINK) + ->setPassword('password') + ->setExpirationDate(new \DateTime()) + ->setPermissions(\OCP\Constants::PERMISSION_ALL); + + $this->request + ->method('getParam') + ->will($this->returnValueMap([ + ['publicUpload', null, 'false'], + ['expireDate', null, ''], + ['password', null, ''], + ])); + + $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); + + $this->shareManager->expects($this->once())->method('updateShare')->with( + $this->callback(function (IShare $share) { + return $share->getPermissions() === \OCP\Constants::PERMISSION_READ && + $share->getPassword() === null && + $share->getExpirationDate() === null; + }) + ); + + $expected = new \OC_OCS_Result(null); + $result = $ocs->updateShare(42); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testUpdateLinkShareSet() { + $ocs = $this->mockFormatShare(); + + $folder = $this->getMock('\OCP\Files\Folder'); + + $share = \OC::$server->getShareManager()->newShare(); + $share->setPermissions(\OCP\Constants::PERMISSION_ALL) + ->setSharedBy($this->currentUser) + ->setShareType(\OCP\Share::SHARE_TYPE_LINK) + ->setPath($folder); + + $this->request + ->method('getParam') + ->will($this->returnValueMap([ + ['publicUpload', null, 'true'], + ['expireDate', null, '2000-01-01'], + ['password', null, 'password'], + ])); + + $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); + $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true); + + $this->shareManager->expects($this->once())->method('updateShare')->with( + $this->callback(function (IShare $share) { + $date = new \DateTime('2000-01-01'); + $date->setTime(0,0,0); + + return $share->getPermissions() === \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE && \OCP\Constants::PERMISSION_DELETE && + $share->getPassword() === 'password' && + $share->getExpirationDate() == $date; + }) + ); + + $expected = new \OC_OCS_Result(null); + $result = $ocs->updateShare(42); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testUpdateLinkShareInvalidDate() { + $ocs = $this->mockFormatShare(); + + $folder = $this->getMock('\OCP\Files\Folder'); + + $share = \OC::$server->getShareManager()->newShare(); + $share->setPermissions(\OCP\Constants::PERMISSION_ALL) + ->setSharedBy($this->currentUser) + ->setShareType(\OCP\Share::SHARE_TYPE_LINK) + ->setPath($folder); + + $this->request + ->method('getParam') + ->will($this->returnValueMap([ + ['publicUpload', null, 'true'], + ['expireDate', null, '2000-01-a'], + ['password', null, 'password'], + ])); + + $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); + $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true); + + $expected = new \OC_OCS_Result(null, 400, 'Invalid date. Format must be YYYY-MM-DD'); + $result = $ocs->updateShare(42); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testUpdateLinkSharePublicUploadNotAllowed() { + $ocs = $this->mockFormatShare(); + + $folder = $this->getMock('\OCP\Files\Folder'); + + $share = \OC::$server->getShareManager()->newShare(); + $share->setPermissions(\OCP\Constants::PERMISSION_ALL) + ->setSharedBy($this->currentUser) + ->setShareType(\OCP\Share::SHARE_TYPE_LINK) + ->setPath($folder); + + $this->request + ->method('getParam') + ->will($this->returnValueMap([ + ['publicUpload', null, 'true'], + ['expireDate', '', null], + ['password', '', 'password'], + ])); + + $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); + $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(false); + + $expected = new \OC_OCS_Result(null, 403, 'public upload disabled by the administrator'); + $result = $ocs->updateShare(42); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testUpdateLinkSharePublicUploadOnFile() { + $ocs = $this->mockFormatShare(); + + $file = $this->getMock('\OCP\Files\File'); + + $share = \OC::$server->getShareManager()->newShare(); + $share->setPermissions(\OCP\Constants::PERMISSION_ALL) + ->setSharedBy($this->currentUser) + ->setShareType(\OCP\Share::SHARE_TYPE_LINK) + ->setPath($file); + + $this->request + ->method('getParam') + ->will($this->returnValueMap([ + ['publicUpload', null, 'true'], + ['expireDate', '', ''], + ['password', '', 'password'], + ])); + + $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); + $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true); + + $expected = new \OC_OCS_Result(null, 400, 'public upload is only possible for public shared folders'); + $result = $ocs->updateShare(42); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testUpdateLinkSharePasswordDoesNotChangeOther() { + $ocs = $this->mockFormatShare(); + + $date = new \DateTime('2000-01-01'); + $date->setTime(0,0,0); + + $share = \OC::$server->getShareManager()->newShare(); + $share->setPermissions(\OCP\Constants::PERMISSION_ALL) + ->setSharedBy($this->currentUser) + ->setShareType(\OCP\Share::SHARE_TYPE_LINK) + ->setPassword('password') + ->setExpirationDate($date) + ->setPermissions(\OCP\Constants::PERMISSION_ALL); + + $this->request + ->method('getParam') + ->will($this->returnValueMap([ + ['password', null, 'newpassword'], + ])); + + $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); + + $this->shareManager->expects($this->once())->method('updateShare')->with( + $this->callback(function (IShare $share) use ($date) { + return $share->getPermissions() === \OCP\Constants::PERMISSION_ALL && + $share->getPassword() === 'newpassword' && + $share->getExpirationDate() === $date; + }) + ); + + $expected = new \OC_OCS_Result(null); + $result = $ocs->updateShare(42); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testUpdateLinkShareExpireDateDoesNotChangeOther() { + $ocs = $this->mockFormatShare(); + + $share = \OC::$server->getShareManager()->newShare(); + $share->setPermissions(\OCP\Constants::PERMISSION_ALL) + ->setSharedBy($this->currentUser) + ->setShareType(\OCP\Share::SHARE_TYPE_LINK) + ->setPassword('password') + ->setExpirationDate(new \DateTime()) + ->setPermissions(\OCP\Constants::PERMISSION_ALL); + + $this->request + ->method('getParam') + ->will($this->returnValueMap([ + ['expireDate', null, '2010-12-23'], + ])); + + $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); + + $this->shareManager->expects($this->once())->method('updateShare')->with( + $this->callback(function (IShare $share) { + $date = new \DateTime('2010-12-23'); + $date->setTime(0,0,0); + + return $share->getPermissions() === \OCP\Constants::PERMISSION_ALL && + $share->getPassword() === 'password' && + $share->getExpirationDate() == $date; + }) + ); + + $expected = new \OC_OCS_Result(null); + $result = $ocs->updateShare(42); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testUpdateLinkSharePublicUploadDoesNotChangeOther() { + $ocs = $this->mockFormatShare(); + + $date = new \DateTime('2000-01-01'); + + $folder = $this->getMock('\OCP\Files\Folder'); + + $share = \OC::$server->getShareManager()->newShare(); + $share->setPermissions(\OCP\Constants::PERMISSION_ALL) + ->setSharedBy($this->currentUser) + ->setShareType(\OCP\Share::SHARE_TYPE_LINK) + ->setPassword('password') + ->setExpirationDate($date) + ->setPermissions(\OCP\Constants::PERMISSION_ALL) + ->setPath($folder); + + $this->request + ->method('getParam') + ->will($this->returnValueMap([ + ['publicUpload', null, 'true'], + ])); + + $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); + $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true); + + $this->shareManager->expects($this->once())->method('updateShare')->with( + $this->callback(function (IShare $share) use ($date) { + return $share->getPermissions() === \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_DELETE && + $share->getPassword() === 'password' && + $share->getExpirationDate() === $date; + }) + ); + + $expected = new \OC_OCS_Result(null); + $result = $ocs->updateShare(42); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testUpdateLinkSharePermissions() { + $ocs = $this->mockFormatShare(); + + $date = new \DateTime('2000-01-01'); + + $folder = $this->getMock('\OCP\Files\Folder'); + + $share = \OC::$server->getShareManager()->newShare(); + $share->setPermissions(\OCP\Constants::PERMISSION_ALL) + ->setSharedBy($this->currentUser) + ->setShareType(\OCP\Share::SHARE_TYPE_LINK) + ->setPassword('password') + ->setExpirationDate($date) + ->setPermissions(\OCP\Constants::PERMISSION_ALL) + ->setPath($folder); + + $this->request + ->method('getParam') + ->will($this->returnValueMap([ + ['permissions', null, '7'], + ])); + + $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); + $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true); + + $this->shareManager->expects($this->once())->method('updateShare')->with( + $this->callback(function (IShare $share) use ($date) { + return $share->getPermissions() === \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_DELETE && + $share->getPassword() === 'password' && + $share->getExpirationDate() === $date; + }) + ); + + $expected = new \OC_OCS_Result(null); + $result = $ocs->updateShare(42); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testUpdateLinkShareInvalidPermissions() { + $ocs = $this->mockFormatShare(); + + $date = new \DateTime('2000-01-01'); + + $folder = $this->getMock('\OCP\Files\Folder'); + + $share = \OC::$server->getShareManager()->newShare(); + $share->setPermissions(\OCP\Constants::PERMISSION_ALL) + ->setSharedBy($this->currentUser) + ->setShareType(\OCP\Share::SHARE_TYPE_LINK) + ->setPassword('password') + ->setExpirationDate($date) + ->setPermissions(\OCP\Constants::PERMISSION_ALL) + ->setPath($folder); + + $this->request + ->method('getParam') + ->will($this->returnValueMap([ + ['permissions', null, '31'], + ])); + + $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); + $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true); + + $expected = new \OC_OCS_Result(null, 400, 'can\'t change permission for public link share'); + $result = $ocs->updateShare(42); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testUpdateOtherPermissions() { + $ocs = $this->mockFormatShare(); + + $file = $this->getMock('\OCP\Files\File'); + + $share = \OC::$server->getShareManager()->newShare(); + $share->setPermissions(\OCP\Constants::PERMISSION_ALL) + ->setSharedBy($this->currentUser) + ->setShareType(\OCP\Share::SHARE_TYPE_USER) + ->setPath($file); + + $this->request + ->method('getParam') + ->will($this->returnValueMap([ + ['permissions', null, '31'], + ])); + + $this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share); + $this->shareManager->method('shareApiLinkAllowPublicUpload')->willReturn(true); + + $this->shareManager->expects($this->once())->method('updateShare')->with( + $this->callback(function (IShare $share) { + return $share->getPermissions() === \OCP\Constants::PERMISSION_ALL; + }) + ); + + $expected = new \OC_OCS_Result(null); + $result = $ocs->updateShare(42); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } } diff --git a/apps/files_sharing/tests/controller/sharecontroller.php b/apps/files_sharing/tests/controller/sharecontroller.php index 43db17f5abc..9f1d38f9f23 100644 --- a/apps/files_sharing/tests/controller/sharecontroller.php +++ b/apps/files_sharing/tests/controller/sharecontroller.php @@ -116,7 +116,7 @@ class ShareControllerTest extends \Test\TestCase { } public function testShowAuthenticateNotAuthenticated() { - $share = $this->getMock('\OC\Share20\IShare'); + $share = $this->getMock('\OCP\Share\IShare'); $this->shareManager ->expects($this->once()) @@ -130,7 +130,7 @@ class ShareControllerTest extends \Test\TestCase { } public function testShowAuthenticateAuthenticatedForDifferentShare() { - $share = $this->getMock('\OC\Share20\IShare'); + $share = $this->getMock('\OCP\Share\IShare'); $share->method('getId')->willReturn(1); $this->shareManager @@ -148,7 +148,7 @@ class ShareControllerTest extends \Test\TestCase { } public function testShowAuthenticateCorrectShare() { - $share = $this->getMock('\OC\Share20\IShare'); + $share = $this->getMock('\OCP\Share\IShare'); $share->method('getId')->willReturn(1); $this->shareManager @@ -183,7 +183,7 @@ class ShareControllerTest extends \Test\TestCase { } public function testAuthenticateValidPassword() { - $share = $this->getMock('\OC\Share20\IShare'); + $share = $this->getMock('\OCP\Share\IShare'); $share->method('getId')->willReturn(42); $this->shareManager @@ -214,7 +214,7 @@ class ShareControllerTest extends \Test\TestCase { } public function testAuthenticateInvalidPassword() { - $share = $this->getMock('\OC\Share20\IShare'); + $share = $this->getMock('\OCP\Share\IShare'); $share->method('getId')->willReturn(42); $this->shareManager @@ -252,7 +252,7 @@ class ShareControllerTest extends \Test\TestCase { } public function testShowShareNotAuthenticated() { - $share = $this->getMock('\OC\Share20\IShare'); + $share = $this->getMock('\OCP\Share\IShare'); $share->method('getPassword')->willReturn('password'); $this->shareManager @@ -283,11 +283,11 @@ class ShareControllerTest extends \Test\TestCase { $file->method('getMimetype')->willReturn('text/plain'); $file->method('getSize')->willReturn(33); - $share = $this->getMock('\OC\Share20\IShare'); + $share = $this->getMock('\OCP\Share\IShare'); $share->method('getId')->willReturn('42'); $share->method('getPassword')->willReturn('password'); $share->method('getShareOwner')->willReturn($owner); - $share->method('getPath')->willReturn($file); + $share->method('getNode')->willReturn($file); $share->method('getTarget')->willReturn('/file1.txt'); $this->session->method('exists')->with('public_link_authenticated')->willReturn(true); @@ -340,7 +340,7 @@ class ShareControllerTest extends \Test\TestCase { } public function testDownloadShare() { - $share = $this->getMock('\OC\Share20\IShare'); + $share = $this->getMock('\OCP\Share\IShare'); $share->method('getPassword')->willReturn('password'); $this->shareManager diff --git a/apps/files_sharing/tests/testcase.php b/apps/files_sharing/tests/testcase.php index a9da39f446b..ce0a8beeec8 100644 --- a/apps/files_sharing/tests/testcase.php +++ b/apps/files_sharing/tests/testcase.php @@ -174,9 +174,9 @@ abstract class TestCase extends \Test\TestCase { */ protected static function resetStorage() { $storage = new \ReflectionClass('\OC\Files\Storage\Shared'); - $isInitialized = $storage->getProperty('isInitialized'); + $isInitialized = $storage->getProperty('initialized'); $isInitialized->setAccessible(true); - $isInitialized->setValue(array()); + $isInitialized->setValue($storage, false); $isInitialized->setAccessible(false); } diff --git a/apps/files_versions/tests/versions.php b/apps/files_versions/tests/versions.php index ac922b74b9f..b85877cebd3 100644 --- a/apps/files_versions/tests/versions.php +++ b/apps/files_versions/tests/versions.php @@ -802,9 +802,9 @@ class Test_Files_Versioning extends \Test\TestCase { } $storage = new \ReflectionClass('\OC\Files\Storage\Shared'); - $isInitialized = $storage->getProperty('isInitialized'); + $isInitialized = $storage->getProperty('initialized'); $isInitialized->setAccessible(true); - $isInitialized->setValue(array()); + $isInitialized->setValue($storage, false); $isInitialized->setAccessible(false); \OC_Util::tearDownFS(); diff --git a/core/js/systemtags/systemtagsinputfield.js b/core/js/systemtags/systemtagsinputfield.js index 3e0bfbbc55c..461b52d88e9 100644 --- a/core/js/systemtags/systemtagsinputfield.js +++ b/core/js/systemtags/systemtagsinputfield.js @@ -185,6 +185,12 @@ return false; }, + _addToSelect2Selection: function(selection) { + var data = this.$tagsField.select2('data'); + data.push(selection); + this.$tagsField.select2('data', data); + }, + /** * Event handler whenever a tag is selected. * Also called whenever tag creation is requested through the dummy tag object. @@ -203,10 +209,27 @@ userAssignable: true }, { success: function(model) { - var data = self.$tagsField.select2('data'); - data.push(model.toJSON()); - self.$tagsField.select2('data', data); + self._addToSelect2Selection(model.toJSON()); self.trigger('select', model); + }, + error: function(model, xhr) { + if (xhr.status === 409) { + // re-fetch collection to get the missing tag + self.collection.reset(); + self.collection.fetch({ + success: function(collection) { + // find the tag in the collection + var model = collection.where({name: e.object.name, userVisible: true, userAssignable: true}); + if (model.length) { + model = model[0]; + // the tag already exists or was already assigned, + // add it to the list anyway + self._addToSelect2Selection(model.toJSON()); + self.trigger('select', model); + } + } + }); + } } }); this.$tagsField.select2('close'); diff --git a/core/js/tests/specs/systemtags/systemtagsinputfieldSpec.js b/core/js/tests/specs/systemtags/systemtagsinputfieldSpec.js index a2347eb6893..08470fbdd8a 100644 --- a/core/js/tests/specs/systemtags/systemtagsinputfieldSpec.js +++ b/core/js/tests/specs/systemtags/systemtagsinputfieldSpec.js @@ -158,6 +158,65 @@ describe('OC.SystemTags.SystemTagsInputField tests', function() { expect(selectHandler.calledOnce).toEqual(true); expect(selectHandler.getCall(0).args[0]).toEqual('2'); }); + it('triggers select event and still adds to list even in case of conflict', function() { + var selectHandler = sinon.stub(); + view.on('select', selectHandler); + var fetchStub = sinon.stub(OC.SystemTags.SystemTagsCollection.prototype, 'fetch'); + var createStub = sinon.stub(OC.SystemTags.SystemTagsCollection.prototype, 'create'); + view.$el.find('input').trigger(new $.Event('select2-selecting', { + object: { + id: -1, + name: 'newname', + isNew: true + } + })); + + expect(createStub.calledOnce).toEqual(true); + expect(createStub.getCall(0).args[0]).toEqual({ + name: 'newname', + userVisible: true, + userAssignable: true + }); + + var newModel = new OC.SystemTags.SystemTagModel({ + id: '123', + name: 'newname', + userVisible: true, + userAssignable: true + }); + + // not called yet + expect(selectHandler.notCalled).toEqual(true); + + select2Stub.withArgs('data').returns([{ + id: '1', + name: 'abc' + }]); + + // simulate conflict response for tag creation + createStub.yieldTo('error', view.collection, {status: 409}); + + // at this point it fetches from the server + expect(fetchStub.calledOnce).toEqual(true); + // simulate fetch result by adding model to the collection + view.collection.add(newModel); + fetchStub.yieldTo('success', view.collection); + + expect(select2Stub.lastCall.args[0]).toEqual('data'); + expect(select2Stub.lastCall.args[1]).toEqual([{ + id: '1', + name: 'abc' + }, + newModel.toJSON() + ]); + + // select event still called + expect(selectHandler.calledOnce).toEqual(true); + expect(selectHandler.getCall(0).args[0]).toEqual(newModel); + + createStub.restore(); + fetchStub.restore(); + }); }); describe('tag actions', function() { var opts; diff --git a/lib/base.php b/lib/base.php index 970eabce6af..56ff1cb8962 100644 --- a/lib/base.php +++ b/lib/base.php @@ -473,6 +473,7 @@ class OC { */ public static function setRequiredIniValues() { @ini_set('default_charset', 'UTF-8'); + @ini_set('gd.jpeg_ignore_warning', 1); } public static function init() { diff --git a/lib/private/appframework/dependencyinjection/dicontainer.php b/lib/private/appframework/dependencyinjection/dicontainer.php index 175d6c747e4..61a04482431 100644 --- a/lib/private/appframework/dependencyinjection/dicontainer.php +++ b/lib/private/appframework/dependencyinjection/dicontainer.php @@ -227,6 +227,10 @@ class DIContainer extends SimpleContainer implements IAppContainer { return $this->getServer()->getSecureRandom(); }); + $this->registerService('OCP\\Share\\IManager', function($c) { + return $this->getServer()->getShareManager(); + }); + $this->registerService('OCP\\SystemTag\\ISystemTagManager', function() { return $this->getServer()->getSystemTagManager(); }); diff --git a/lib/private/config.php b/lib/private/config.php index 30baa3fe0e6..368dafd0460 100644 --- a/lib/private/config.php +++ b/lib/private/config.php @@ -184,7 +184,7 @@ class Config { // Include file and merge config foreach ($configFiles as $file) { - $filePointer = @fopen($file, 'r'); + $filePointer = file_exists($file) ? fopen($file, 'r') : false; if($file === $this->configFilePath && $filePointer === false && @!file_exists($this->configFilePath)) { diff --git a/lib/private/files/cache/wrapper/cachejail.php b/lib/private/files/cache/wrapper/cachejail.php index 4d708c2d191..32bd3626fcb 100644 --- a/lib/private/files/cache/wrapper/cachejail.php +++ b/lib/private/files/cache/wrapper/cachejail.php @@ -34,7 +34,7 @@ class CacheJail extends CacheWrapper { protected $root; /** - * @param \OC\Files\Cache\Cache $cache + * @param \OCP\Files\Cache\ICache $cache * @param string $root */ public function __construct($cache, $root) { @@ -113,7 +113,7 @@ class CacheJail extends CacheWrapper { * @param array $data */ public function update($id, array $data) { - $this->cache->update($this->getSourcePath($id), $data); + $this->cache->update($id, $data); } /** diff --git a/lib/private/files/cache/wrapper/cachepermissionsmask.php b/lib/private/files/cache/wrapper/cachepermissionsmask.php index 1eeb3c4783d..b3a7bcb3a73 100644 --- a/lib/private/files/cache/wrapper/cachepermissionsmask.php +++ b/lib/private/files/cache/wrapper/cachepermissionsmask.php @@ -29,7 +29,7 @@ class CachePermissionsMask extends CacheWrapper { protected $mask; /** - * @param \OC\Files\Cache\Cache $cache + * @param \OCP\Files\Cache\ICache $cache * @param int $mask */ public function __construct($cache, $mask) { diff --git a/lib/private/files/cache/wrapper/cachewrapper.php b/lib/private/files/cache/wrapper/cachewrapper.php index 39a6b63205b..1ce4f028c75 100644 --- a/lib/private/files/cache/wrapper/cachewrapper.php +++ b/lib/private/files/cache/wrapper/cachewrapper.php @@ -26,15 +26,16 @@ namespace OC\Files\Cache\Wrapper; use OC\Files\Cache\Cache; use OCP\Files\Cache\ICacheEntry; +use OCP\Files\Cache\ICache; class CacheWrapper extends Cache { /** - * @var \OC\Files\Cache\Cache + * @var \OCP\Files\Cache\ICache */ protected $cache; /** - * @param \OC\Files\Cache\Cache $cache + * @param \OCP\Files\Cache\ICache $cache */ public function __construct($cache) { $this->cache = $cache; @@ -159,6 +160,10 @@ class CacheWrapper extends Cache { $this->cache->move($source, $target); } + public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) { + $this->cache->moveFromCache($sourceCache, $sourcePath, $targetPath); + } + /** * remove all entries for files that are stored on the storage from the cache */ diff --git a/lib/private/files/config/usermountcache.php b/lib/private/files/config/usermountcache.php index e3a494e93a1..7d7b03fbc06 100644 --- a/lib/private/files/config/usermountcache.php +++ b/lib/private/files/config/usermountcache.php @@ -22,9 +22,12 @@ namespace OC\Files\Config; use Doctrine\DBAL\Exception\UniqueConstraintViolationException; +use OC\Files\Filesystem; +use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\Files\Config\ICachedMountInfo; use OCP\Files\Config\IUserMountCache; use OCP\Files\Mount\IMountPoint; +use OCP\Files\NotFoundException; use OCP\ICache; use OCP\IDBConnection; use OCP\ILogger; @@ -53,6 +56,8 @@ class UserMountCache implements IUserMountCache { */ private $logger; + private $cacheInfoCache = []; + /** * UserMountCache constructor. * @@ -133,7 +138,7 @@ class UserMountCache implements IUserMountCache { $query = $builder->update('mounts') ->set('mount_point', $builder->createNamedParameter($mount->getMountPoint())) ->where($builder->expr()->eq('user_id', $builder->createNamedParameter($mount->getUser()->getUID()))) - ->andWhere($builder->expr()->eq('root_id', $builder->createNamedParameter($mount->getRootId(), \PDO::PARAM_INT))); + ->andWhere($builder->expr()->eq('root_id', $builder->createNamedParameter($mount->getRootId(), IQueryBuilder::PARAM_INT))); $query->execute(); } @@ -143,7 +148,7 @@ class UserMountCache implements IUserMountCache { $query = $builder->delete('mounts') ->where($builder->expr()->eq('user_id', $builder->createNamedParameter($mount->getUser()->getUID()))) - ->andWhere($builder->expr()->eq('root_id', $builder->createNamedParameter($mount->getRootId(), \PDO::PARAM_INT))); + ->andWhere($builder->expr()->eq('root_id', $builder->createNamedParameter($mount->getRootId(), IQueryBuilder::PARAM_INT))); $query->execute(); } @@ -178,7 +183,7 @@ class UserMountCache implements IUserMountCache { $builder = $this->connection->getQueryBuilder(); $query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point') ->from('mounts') - ->where($builder->expr()->eq('storage_id', $builder->createPositionalParameter($numericStorageId, \PDO::PARAM_INT))); + ->where($builder->expr()->eq('storage_id', $builder->createPositionalParameter($numericStorageId, IQueryBuilder::PARAM_INT))); $rows = $query->execute()->fetchAll(); @@ -193,7 +198,7 @@ class UserMountCache implements IUserMountCache { $builder = $this->connection->getQueryBuilder(); $query = $builder->select('storage_id', 'root_id', 'user_id', 'mount_point') ->from('mounts') - ->where($builder->expr()->eq('root_id', $builder->createPositionalParameter($rootFileId, \PDO::PARAM_INT))); + ->where($builder->expr()->eq('root_id', $builder->createPositionalParameter($rootFileId, IQueryBuilder::PARAM_INT))); $rows = $query->execute()->fetchAll(); @@ -201,6 +206,60 @@ class UserMountCache implements IUserMountCache { } /** + * @param $fileId + * @return array + * @throws \OCP\Files\NotFoundException + */ + private function getCacheInfoFromFileId($fileId) { + if (!isset($this->cacheInfoCache[$fileId])) { + $builder = $this->connection->getQueryBuilder(); + $query = $builder->select('storage', 'path') + ->from('filecache') + ->where($builder->expr()->eq('fileid', $builder->createNamedParameter($fileId, IQueryBuilder::PARAM_INT))); + + $row = $query->execute()->fetch(); + if (is_array($row)) { + $this->cacheInfoCache[$fileId] = [ + (int)$row['storage'], + $row['path'] + ]; + } else { + throw new NotFoundException('File with id "' . $fileId . '" not found'); + } + } + return $this->cacheInfoCache[$fileId]; + } + + /** + * @param int $fileId + * @return ICachedMountInfo[] + * @since 9.0.0 + */ + public function getMountsForFileId($fileId) { + try { + list($storageId, $internalPath) = $this->getCacheInfoFromFileId($fileId); + } catch (NotFoundException $e) { + return []; + } + $mountsForStorage = $this->getMountsForStorageId($storageId); + + // filter mounts that are from the same storage but a different directory + return array_filter($mountsForStorage, function (ICachedMountInfo $mount) use ($internalPath, $fileId) { + if ($fileId === $mount->getRootId()) { + return true; + } + try { + list(, $internalMountPath) = $this->getCacheInfoFromFileId($mount->getRootId()); + } catch (NotFoundException $e) { + return false; + } + + return $internalMountPath === '' || substr($internalPath, 0, strlen($internalMountPath) + 1) === $internalMountPath . '/'; + }); + + } + + /** * Remove all cached mounts for a user * * @param IUser $user @@ -218,7 +277,7 @@ class UserMountCache implements IUserMountCache { $query = $builder->delete('mounts') ->where($builder->expr()->eq('user_id', $builder->createNamedParameter($userId))) - ->andWhere($builder->expr()->eq('storage_id', $builder->createNamedParameter($storageId, \PDO::PARAM_INT))); + ->andWhere($builder->expr()->eq('storage_id', $builder->createNamedParameter($storageId, IQueryBuilder::PARAM_INT))); $query->execute(); } @@ -226,7 +285,7 @@ class UserMountCache implements IUserMountCache { $builder = $this->connection->getQueryBuilder(); $query = $builder->delete('mounts') - ->where($builder->expr()->eq('storage_id', $builder->createNamedParameter($storageId, \PDO::PARAM_INT))); + ->where($builder->expr()->eq('storage_id', $builder->createNamedParameter($storageId, IQueryBuilder::PARAM_INT))); $query->execute(); } } diff --git a/lib/private/l10n/factory.php b/lib/private/l10n/factory.php index 09496cba410..f4f7d897061 100644 --- a/lib/private/l10n/factory.php +++ b/lib/private/l10n/factory.php @@ -27,6 +27,7 @@ namespace OC\L10N; use OCP\IConfig; use OCP\IRequest; +use OCP\IUserSession; use OCP\L10N\IFactory; /** @@ -59,13 +60,20 @@ class Factory implements IFactory { /** @var IRequest */ protected $request; + /** @var IUserSession */ + protected $userSession; + /** * @param IConfig $config * @param IRequest $request + * @param IUserSession $userSession */ - public function __construct(IConfig $config, IRequest $request) { + public function __construct(IConfig $config, + IRequest $request, + IUserSession $userSession) { $this->config = $config; $this->request = $request; + $this->userSession = $userSession; } /** @@ -107,9 +115,25 @@ class Factory implements IFactory { return $this->requestLanguage; } - $userId = \OC_User::getUser(); // FIXME not available in non-static? + /** + * At this point ownCloud might not yet be installed and thus the lookup + * in the preferences table might fail. For this reason we need to check + * whether the instance has already been installed + * + * @link https://github.com/owncloud/core/issues/21955 + */ + if($this->config->getSystemValue('installed', false)) { + $userId = !is_null($this->userSession->getUser()) ? $this->userSession->getUser()->getUID() : null; + if(!is_null($userId)) { + $userLang = $this->config->getUserValue($userId, 'core', 'lang', null); + } else { + $userLang = null; + } + } else { + $userId = null; + $userLang = null; + } - $userLang = $userId !== false ? $this->config->getUserValue($userId, 'core', 'lang') : null; if ($userLang) { $this->requestLanguage = $userLang; if ($this->languageExists($app, $userLang)) { @@ -124,7 +148,7 @@ class Factory implements IFactory { } $lang = $this->setLanguageFromRequest($app); - if ($userId !== false && $app === null && !$userLang) { + if ($userId !== null && $app === null && !$userLang) { $this->config->setUserValue($userId, 'core', 'lang', $lang); } diff --git a/lib/private/log/owncloud.php b/lib/private/log/owncloud.php index f9ce671aa93..dabf95d7616 100644 --- a/lib/private/log/owncloud.php +++ b/lib/private/log/owncloud.php @@ -43,17 +43,18 @@ class OC_Log_Owncloud { $defaultLogFile = $systemConfig->getValue("datadirectory", OC::$SERVERROOT.'/data').'/owncloud.log'; self::$logFile = $systemConfig->getValue("logfile", $defaultLogFile); - /* - * Fall back to default log file if specified logfile does not exist - * and can not be created. Error suppression is required in order to - * not end up in the error handler which will try to log the error. - * A better solution (compared to error suppression) would be checking - * !is_writable(dirname(self::$logFile)) before touch(), but - * is_writable() on directories used to be pretty unreliable on Windows - * for at least some time. - */ - if (!file_exists(self::$logFile) && !@touch(self::$logFile)) { - self::$logFile = $defaultLogFile; + /** + * Fall back to default log file if specified logfile does not exist + * and can not be created. + */ + if (!file_exists(self::$logFile)) { + if(!is_writable(dirname(self::$logFile))) { + self::$logFile = $defaultLogFile; + } else { + if(!touch(self::$logFile)) { + self::$logFile = $defaultLogFile; + } + } } } diff --git a/lib/private/server.php b/lib/private/server.php index 81929d0c7b3..d453a42d3a0 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -265,7 +265,8 @@ class Server extends ServerContainer implements IServerContainer { $this->registerService('L10NFactory', function (Server $c) { return new \OC\L10N\Factory( $c->getConfig(), - $c->getRequest() + $c->getRequest(), + $c->getUserSession() ); }); $this->registerService('URLGenerator', function (Server $c) { @@ -1255,9 +1256,8 @@ class Server extends ServerContainer implements IServerContainer { return \OC_Mount_Config::$app->getContainer()->query('OCA\\Files_External\\Service\\UserStoragesService'); } - /** - * @return \OC\Share20\Manager + * @return \OCP\Share\IManager */ public function getShareManager() { return $this->query('ShareManager'); diff --git a/lib/private/share20/defaultshareprovider.php b/lib/private/share20/defaultshareprovider.php index fb2acb56a73..baa12d6c933 100644 --- a/lib/private/share20/defaultshareprovider.php +++ b/lib/private/share20/defaultshareprovider.php @@ -20,6 +20,7 @@ */ namespace OC\Share20; +use OCP\Share\IShareProvider; use OC\Share20\Exception\InvalidShare; use OC\Share20\Exception\ProviderException; use OC\Share20\Exception\ShareNotFound; @@ -87,12 +88,12 @@ class DefaultShareProvider implements IShareProvider { /** * Share a path * - * @param IShare $share - * @return IShare The share object + * @param \OCP\Share\IShare $share + * @return \OCP\Share\IShare The share object * @throws ShareNotFound * @throws \Exception */ - public function create(IShare $share) { + public function create(\OCP\Share\IShare $share) { $qb = $this->dbConn->getQueryBuilder(); $qb->insert('share'); @@ -127,15 +128,15 @@ class DefaultShareProvider implements IShareProvider { // Set what is shares $qb->setValue('item_type', $qb->createParameter('itemType')); - if ($share->getPath() instanceof \OCP\Files\File) { + if ($share->getNode() instanceof \OCP\Files\File) { $qb->setParameter('itemType', 'file'); } else { $qb->setParameter('itemType', 'folder'); } // Set the file id - $qb->setValue('item_source', $qb->createNamedParameter($share->getPath()->getId())); - $qb->setValue('file_source', $qb->createNamedParameter($share->getPath()->getId())); + $qb->setValue('item_source', $qb->createNamedParameter($share->getNode()->getId())); + $qb->setValue('file_source', $qb->createNamedParameter($share->getNode()->getId())); // set the permissions $qb->setValue('permissions', $qb->createNamedParameter($share->getPermissions())); @@ -179,10 +180,10 @@ class DefaultShareProvider implements IShareProvider { /** * Update a share * - * @param IShare $share - * @return IShare The share object + * @param \OCP\Share\IShare $share + * @return \OCP\Share\IShare The share object */ - public function update(IShare $share) { + public function update(\OCP\Share\IShare $share) { if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) { /* * We allow updating the recipient on user shares. @@ -194,8 +195,8 @@ class DefaultShareProvider implements IShareProvider { ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()->getUID())) ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()->getUID())) ->set('permissions', $qb->createNamedParameter($share->getPermissions())) - ->set('item_source', $qb->createNamedParameter($share->getPath()->getId())) - ->set('file_source', $qb->createNamedParameter($share->getPath()->getId())) + ->set('item_source', $qb->createNamedParameter($share->getNode()->getId())) + ->set('file_source', $qb->createNamedParameter($share->getNode()->getId())) ->execute(); } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) { $qb = $this->dbConn->getQueryBuilder(); @@ -204,8 +205,8 @@ class DefaultShareProvider implements IShareProvider { ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()->getUID())) ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()->getUID())) ->set('permissions', $qb->createNamedParameter($share->getPermissions())) - ->set('item_source', $qb->createNamedParameter($share->getPath()->getId())) - ->set('file_source', $qb->createNamedParameter($share->getPath()->getId())) + ->set('item_source', $qb->createNamedParameter($share->getNode()->getId())) + ->set('file_source', $qb->createNamedParameter($share->getNode()->getId())) ->execute(); /* @@ -216,8 +217,8 @@ class DefaultShareProvider implements IShareProvider { ->where($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId()))) ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()->getUID())) ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()->getUID())) - ->set('item_source', $qb->createNamedParameter($share->getPath()->getId())) - ->set('file_source', $qb->createNamedParameter($share->getPath()->getId())) + ->set('item_source', $qb->createNamedParameter($share->getNode()->getId())) + ->set('file_source', $qb->createNamedParameter($share->getNode()->getId())) ->execute(); /* @@ -238,8 +239,8 @@ class DefaultShareProvider implements IShareProvider { ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()->getUID())) ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()->getUID())) ->set('permissions', $qb->createNamedParameter($share->getPermissions())) - ->set('item_source', $qb->createNamedParameter($share->getPath()->getId())) - ->set('file_source', $qb->createNamedParameter($share->getPath()->getId())) + ->set('item_source', $qb->createNamedParameter($share->getNode()->getId())) + ->set('file_source', $qb->createNamedParameter($share->getNode()->getId())) ->set('token', $qb->createNamedParameter($share->getToken())) ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE)) ->execute(); @@ -251,10 +252,10 @@ class DefaultShareProvider implements IShareProvider { /** * Get all children of this share * - * @param IShare $parent + * @param \OCP\Share\IShare $parent * @return IShare[] */ - public function getChildren(IShare $parent) { + public function getChildren(\OCP\Share\IShare $parent) { $children = []; $qb = $this->dbConn->getQueryBuilder(); @@ -286,10 +287,10 @@ class DefaultShareProvider implements IShareProvider { /** * Delete a share * - * @param IShare $share + * @param \OCP\Share\IShare $share * @throws BackendError */ - public function delete(IShare $share) { + public function delete(\OCP\Share\IShare $share) { // Fetch share to make sure it exists $share = $this->getShareById($share->getId()); @@ -308,12 +309,12 @@ class DefaultShareProvider implements IShareProvider { * Unshare a share from the recipient. If this is a group share * this means we need a special entry in the share db. * - * @param IShare $share + * @param \OCP\Share\IShare $share * @param IUser $recipient * @throws BackendError * @throws ProviderException */ - public function deleteFromSelf(IShare $share, IUser $recipient) { + public function deleteFromSelf(\OCP\Share\IShare $share, IUser $recipient) { if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) { /** @var IGroup $group */ @@ -341,7 +342,7 @@ class DefaultShareProvider implements IShareProvider { if ($data === false) { $qb = $this->dbConn->getQueryBuilder(); - $type = $share->getPath() instanceof \OCP\Files\File ? 'file' : 'folder'; + $type = $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder'; //Insert new share $qb->insert('share') @@ -352,11 +353,11 @@ class DefaultShareProvider implements IShareProvider { 'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()->getUID()), 'parent' => $qb->createNamedParameter($share->getId()), 'item_type' => $qb->createNamedParameter($type), - 'item_source' => $qb->createNamedParameter($share->getPath()->getId()), - 'file_source' => $qb->createNamedParameter($share->getPath()->getId()), + 'item_source' => $qb->createNamedParameter($share->getNode()->getId()), + 'file_source' => $qb->createNamedParameter($share->getNode()->getId()), 'file_target' => $qb->createNamedParameter($share->getTarget()), 'permissions' => $qb->createNamedParameter(0), - 'stime' => $qb->createNamedParameter($share->getSharetime()), + 'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()), ])->execute(); } else if ($data['permissions'] !== 0) { @@ -450,7 +451,7 @@ class DefaultShareProvider implements IShareProvider { * Get share by id * * @param int $id - * @return IShare + * @return \OCP\Share\IShare * @throws ShareNotFound */ public function getShareById($id) { @@ -649,7 +650,7 @@ class DefaultShareProvider implements IShareProvider { * Create a share object from an database row * * @param mixed[] $data - * @return Share + * @return \OCP\Share\IShare * @throws InvalidShare */ private function createShare($data) { @@ -658,9 +659,12 @@ class DefaultShareProvider implements IShareProvider { ->setShareType((int)$data['share_type']) ->setPermissions((int)$data['permissions']) ->setTarget($data['file_target']) - ->setShareTime((int)$data['stime']) ->setMailSend((bool)$data['mail_send']); + $shareTime = new \DateTime(); + $shareTime->setTimestamp((int)$data['stime']); + $share->setShareTime($shareTime); + if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) { $sharedWith = $this->userManager->get($data['share_with']); if ($sharedWith === null) { @@ -701,7 +705,7 @@ class DefaultShareProvider implements IShareProvider { } $path = $this->getNode($share->getShareOwner(), (int)$data['file_source']); - $share->setPath($path); + $share->setNode($path); if ($data['expiration'] !== null) { $expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']); @@ -760,7 +764,7 @@ class DefaultShareProvider implements IShareProvider { $stmt->closeCursor(); if ($data !== false) { - $share->setPermissions($data['permissions']); + $share->setPermissions((int)$data['permissions']); $share->setTarget($data['file_target']); } diff --git a/lib/private/share20/ishare.php b/lib/private/share20/ishare.php deleted file mode 100644 index 34d1dfa4d3d..00000000000 --- a/lib/private/share20/ishare.php +++ /dev/null @@ -1,233 +0,0 @@ -<?php -/** - * @author Roeland Jago Douma <rullzer@owncloud.com> - * - * @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 OC\Share20; - -use OCP\Files\File; -use OCP\Files\Folder; -use OCP\Files\Node; -use OCP\IUser; -use OCP\IGroup; - -interface IShare { - - /** - * Get the id of the share - * - * @return string - */ - public function getId(); - - /** - * Set the id of the share - * - * @param string $id - * @return IShare The modified share object - */ - public function setId($id); - - /** - * Get the full share id - * - * @return string - */ - public function getFullId(); - - /** - * Set the provider id - * - * @param string $id - * @return IShare The modified share object - */ - public function setProviderId($id); - - /** - * Set the path of this share - * - * @param Node $path - * @return IShare The modified object - */ - public function setPath(Node $path); - - /** - * Get the path of this share for the current user - * - * @return File|Folder - */ - public function getPath(); - - /** - * Set the shareType - * - * @param int $shareType - * @return IShare The modified object - */ - public function setShareType($shareType); - - /** - * Get the shareType - * - * @return int - */ - public function getShareType(); - - /** - * Set the receiver of this share - * - * @param IUser|IGroup|string - * @return IShare The modified object - */ - public function setSharedWith($sharedWith); - - /** - * Get the receiver of this share - * - * @return IUser|IGroup|string - */ - public function getSharedWith(); - - /** - * Set the permissions - * - * @param int $permissions - * @return IShare The modified object - */ - public function setPermissions($permissions); - - /** - * Get the share permissions - * - * @return int - */ - public function getPermissions(); - - /** - * Set the expiration date - * - * @param \DateTime $expireDate - * @return IShare The modified object - */ - public function setExpirationDate($expireDate); - - /** - * Get the share expiration date - * - * @return \DateTime - */ - public function getExpirationDate(); - - /** - * Set the sharer of the path - * - * @param IUser|string $sharedBy - * @return IShare The modified object - */ - public function setSharedBy($sharedBy); - - /** - * Get share sharer - * - * @return IUser|string - */ - public function getSharedBy(); - - /** - * Set the original share owner (who owns the path) - * - * @param IUser|string - * - * @return IShare The modified object - */ - public function setShareOwner($shareOwner); - - /** - * Get the original share owner (who owns the path) - * - * @return IUser|string - */ - public function getShareOwner(); - - /** - * Set the password - * - * @param string $password - * - * @return IShare The modified object - */ - public function setPassword($password); - - /** - * Is a password set for this share - * - * @return string - */ - public function getPassword(); - - /** - * Set the token - * - * @param string $token - * @return IShare The modified object - */ - public function setToken($token); - - /** - * Get the token - * - * @return string - */ - public function getToken(); - - /** - * Get the parent it - * - * @return int - */ - public function getParent(); - - /** - * Set the target of this share - * - * @param string $target - * @return IShare The modified object - */ - public function setTarget($target); - - /** - * Get the target of this share - * - * @return string - */ - public function getTarget(); - - /** - * Get the timestamp this share was created - * - * @return int - */ - public function getSharetime(); - - /** - * Get mailSend - * - * @return bool - */ - public function getMailSend(); -} diff --git a/lib/private/share20/manager.php b/lib/private/share20/manager.php index 673cea9b946..d6245f4beac 100644 --- a/lib/private/share20/manager.php +++ b/lib/private/share20/manager.php @@ -18,11 +18,12 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ -namespace OC\Share20; +namespace OC\Share20; +use OCP\Share\IManager; +use OCP\Share\IProviderFactory; use OC\Share20\Exception\BackendError; -use OC\Share20\Exception\ProviderException; use OCP\IConfig; use OCP\IL10N; use OCP\ILogger; @@ -40,14 +41,11 @@ use OC\HintException; /** * This class is the communication hub for all sharing related operations. */ -class Manager { +class Manager implements IManager { /** @var IProviderFactory */ private $factory; - /** @var array */ - private $type2provider; - /** @var ILogger */ private $logger; @@ -91,9 +89,6 @@ class Manager { IL10N $l, IProviderFactory $factory ) { - $this->providers = []; - $this->type2provider = []; - $this->logger = $logger; $this->config = $config; $this->secureRandom = $secureRandom; @@ -147,10 +142,10 @@ class Manager { /** * Check for generic requirements before creating a share * - * @param IShare $share + * @param \OCP\Share\IShare $share * @throws \Exception */ - protected function generalCreateChecks(IShare $share) { + protected function generalCreateChecks(\OCP\Share\IShare $share) { if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) { // We expect a valid user as sharedWith for user shares if (!($share->getSharedWith() instanceof \OCP\IUser)) { @@ -181,19 +176,19 @@ class Manager { } // The path should be set - if ($share->getPath() === null) { + if ($share->getNode() === null) { throw new \InvalidArgumentException('Path should be set'); } // And it should be a file or a folder - if (!($share->getPath() instanceof \OCP\Files\File) && - !($share->getPath() instanceof \OCP\Files\Folder)) { + if (!($share->getNode() instanceof \OCP\Files\File) && + !($share->getNode() instanceof \OCP\Files\Folder)) { throw new \InvalidArgumentException('Path should be either a file or a folder'); } // Check if we actually have share permissions - if (!$share->getPath()->isShareable()) { - $message_t = $this->l->t('You are not allowed to share %s', [$share->getPath()->getPath()]); + if (!$share->getNode()->isShareable()) { + $message_t = $this->l->t('You are not allowed to share %s', [$share->getNode()->getPath()]); throw new HintException($message_t, $message_t, 404); } @@ -203,8 +198,8 @@ class Manager { } // Check that we do not share with more permissions than we have - if ($share->getPermissions() & ~$share->getPath()->getPermissions()) { - $message_t = $this->l->t('Cannot increase permissions of %s', [$share->getPath()->getPath()]); + if ($share->getPermissions() & ~$share->getNode()->getPermissions()) { + $message_t = $this->l->t('Cannot increase permissions of %s', [$share->getNode()->getPath()]); throw new HintException($message_t, $message_t, 404); } @@ -266,10 +261,10 @@ class Manager { /** * Check for pre share requirements for user shares * - * @param IShare $share + * @param \OCP\Share\IShare $share * @throws \Exception */ - protected function userCreateChecks(IShare $share) { + protected function userCreateChecks(\OCP\Share\IShare $share) { // Check if we can share with group members only if ($this->shareWithGroupMembersOnly()) { // Verify we can share with this user @@ -288,7 +283,7 @@ class Manager { * Also this is not what we want in the future.. then we want to squash identical shares. */ $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_USER); - $existingShares = $provider->getSharesByPath($share->getPath()); + $existingShares = $provider->getSharesByPath($share->getNode()); foreach($existingShares as $existingShare) { // Ignore if it is the same share if ($existingShare->getFullId() === $share->getFullId()) { @@ -312,10 +307,10 @@ class Manager { /** * Check for pre share requirements for group shares * - * @param IShare $share + * @param \OCP\Share\IShare $share * @throws \Exception */ - protected function groupCreateChecks(IShare $share) { + protected function groupCreateChecks(\OCP\Share\IShare $share) { // Verify if the user can share with this group if ($this->shareWithGroupMembersOnly()) { if (!$share->getSharedWith()->inGroup($share->getSharedBy())) { @@ -329,7 +324,7 @@ class Manager { * Also this is not what we want in the future.. then we want to squash identical shares. */ $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP); - $existingShares = $provider->getSharesByPath($share->getPath()); + $existingShares = $provider->getSharesByPath($share->getNode()); foreach($existingShares as $existingShare) { if ($existingShare->getFullId() === $share->getFullId()) { continue; @@ -344,10 +339,10 @@ class Manager { /** * Check for pre share requirements for link shares * - * @param IShare $share + * @param \OCP\Share\IShare $share * @throws \Exception */ - protected function linkCreateChecks(IShare $share) { + protected function linkCreateChecks(\OCP\Share\IShare $share) { // Are link shares allowed? if (!$this->shareApiAllowLinks()) { throw new \Exception('Link sharing not allowed'); @@ -388,15 +383,15 @@ class Manager { /** * Check if the user that is sharing can actually share * - * @param IShare $share + * @param \OCP\Share\IShare $share * @return bool */ - protected function canShare(IShare $share) { + protected function canShare(\OCP\Share\IShare $share) { if (!$this->shareApiEnabled()) { return false; } - if ($this->isSharingDisabledForUser($share->getSharedBy())) { + if ($this->sharingDisabledForUser($share->getSharedBy())) { return false; } @@ -406,13 +401,13 @@ class Manager { /** * Share a path * - * @param IShare $share + * @param \OCP\Share\IShare $share * @return Share The share object * @throws \Exception * * TODO: handle link share permissions or check them */ - public function createShare(IShare $share) { + public function createShare(\OCP\Share\IShare $share) { if (!$this->canShare($share)) { throw new \Exception('The Share API is disabled'); } @@ -452,10 +447,10 @@ class Manager { } // Verify if there are any issues with the path - $this->pathCreateChecks($share->getPath()); + $this->pathCreateChecks($share->getNode()); // On creation of a share the owner is always the owner of the path - $share->setShareOwner($share->getPath()->getOwner()); + $share->setShareOwner($share->getNode()->getOwner()); // Cannot share with the owner if ($share->getSharedWith() === $share->getShareOwner()) { @@ -463,7 +458,7 @@ class Manager { } // Generate the target - $target = $this->config->getSystemValue('share_folder', '/') .'/'. $share->getPath()->getName(); + $target = $this->config->getSystemValue('share_folder', '/') .'/'. $share->getNode()->getName(); $target = \OC\Files\Filesystem::normalizePath($target); $share->setTarget($target); @@ -481,12 +476,12 @@ class Manager { $run = true; $error = ''; $preHookData = [ - 'itemType' => $share->getPath() instanceof \OCP\Files\File ? 'file' : 'folder', - 'itemSource' => $share->getPath()->getId(), + 'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder', + 'itemSource' => $share->getNode()->getId(), 'shareType' => $share->getShareType(), 'uidOwner' => $share->getSharedBy()->getUID(), 'permissions' => $share->getPermissions(), - 'fileSource' => $share->getPath()->getId(), + 'fileSource' => $share->getNode()->getId(), 'expiration' => $share->getExpirationDate(), 'token' => $share->getToken(), 'itemTarget' => $share->getTarget(), @@ -502,16 +497,15 @@ class Manager { $provider = $this->factory->getProviderForType($share->getShareType()); $share = $provider->create($share); - $share->setProviderId($provider->identifier()); // Post share hook $postHookData = [ - 'itemType' => $share->getPath() instanceof \OCP\Files\File ? 'file' : 'folder', - 'itemSource' => $share->getPath()->getId(), + 'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder', + 'itemSource' => $share->getNode()->getId(), 'shareType' => $share->getShareType(), 'uidOwner' => $share->getSharedBy()->getUID(), 'permissions' => $share->getPermissions(), - 'fileSource' => $share->getPath()->getId(), + 'fileSource' => $share->getNode()->getId(), 'expiration' => $share->getExpirationDate(), 'token' => $share->getToken(), 'id' => $share->getId(), @@ -528,10 +522,10 @@ class Manager { /** * Update a share * - * @param IShare $share - * @return IShare The share object + * @param \OCP\Share\IShare $share + * @return \OCP\Share\IShare The share object */ - public function updateShare(IShare $share) { + public function updateShare(\OCP\Share\IShare $share) { $expirationDateUpdated = false; if (!$this->canShare($share)) { @@ -583,7 +577,7 @@ class Manager { } } - $this->pathCreateChecks($share->getPath()); + $this->pathCreateChecks($share->getNode()); // Now update the share! $provider = $this->factory->getProviderForType($share->getShareType()); @@ -591,8 +585,8 @@ class Manager { if ($expirationDateUpdated === true) { \OC_Hook::emit('OCP\Share', 'post_set_expiration_date', [ - 'itemType' => $share->getPath() instanceof \OCP\Files\File ? 'file' : 'folder', - 'itemSource' => $share->getPath()->getId(), + 'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder', + 'itemSource' => $share->getNode()->getId(), 'date' => $share->getExpirationDate(), 'uidOwner' => $share->getSharedBy()->getUID(), ]); @@ -604,10 +598,10 @@ class Manager { /** * Delete all the children of this share * - * @param IShare $share - * @return IShare[] List of deleted shares + * @param \OCP\Share\IShare $share + * @return \OCP\Share\IShare[] List of deleted shares */ - protected function deleteChildren(IShare $share) { + protected function deleteChildren(\OCP\Share\IShare $share) { $deletedShares = []; $provider = $this->factory->getProviderForType($share->getShareType()); @@ -626,16 +620,16 @@ class Manager { /** * Delete a share * - * @param IShare $share + * @param \OCP\Share\IShare $share * @throws ShareNotFound * @throws BackendError * @throws ShareNotFound */ - public function deleteShare(IShare $share) { + public function deleteShare(\OCP\Share\IShare $share) { // Just to make sure we have all the info $share = $this->getShareById($share->getFullId()); - $formatHookParams = function(IShare $share) { + $formatHookParams = function(\OCP\Share\IShare $share) { // Prepare hook $shareType = $share->getShareType(); $sharedWith = ''; @@ -649,13 +643,13 @@ class Manager { $hookParams = [ 'id' => $share->getId(), - 'itemType' => $share->getPath() instanceof \OCP\Files\File ? 'file' : 'folder', - 'itemSource' => $share->getPath()->getId(), + 'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder', + 'itemSource' => $share->getNode()->getId(), 'shareType' => $shareType, 'shareWith' => $sharedWith, 'itemparent' => $share->getParent(), 'uidOwner' => $share->getSharedBy()->getUID(), - 'fileSource' => $share->getPath()->getId(), + 'fileSource' => $share->getNode()->getId(), 'fileTarget' => $share->getTarget() ]; return $hookParams; @@ -694,10 +688,10 @@ class Manager { * the users in a groups deletes that share. But the provider should * handle this. * - * @param IShare $share + * @param \OCP\Share\IShare $share * @param IUser $recipient */ - public function deleteFromSelf(IShare $share, IUser $recipient) { + public function deleteFromSelf(\OCP\Share\IShare $share, IUser $recipient) { list($providerId, $id) = $this->splitFullId($share->getId()); $provider = $this->factory->getProvider($providerId); @@ -713,7 +707,7 @@ class Manager { * @param bool $reshares * @param int $limit The maximum number of returned results, -1 for all results * @param int $offset - * @return IShare[] + * @return \OCP\Share\IShare[] */ public function getSharesBy(IUser $user, $shareType, $path = null, $reshares = false, $limit = 50, $offset = 0) { if ($path !== null && @@ -734,7 +728,7 @@ class Manager { * @param int $shareType * @param int $limit The maximum number of shares returned, -1 for all * @param int $offset - * @return IShare[] + * @return \OCP\Share\IShare[] */ public function getSharedWith(IUser $user, $shareType, $limit = 50, $offset = 0) { $provider = $this->factory->getProviderForType($shareType); @@ -759,7 +753,6 @@ class Manager { $provider = $this->factory->getProvider($providerId); $share = $provider->getShareById($id); - $share->setProviderId($provider->identifier()); return $share; } @@ -797,11 +790,11 @@ class Manager { /** * Verify the password of a public share * - * @param IShare $share + * @param \OCP\Share\IShare $share * @param string $password * @return bool */ - public function checkPassword(IShare $share, $password) { + public function checkPassword(\OCP\Share\IShare $share, $password) { if ($share->getShareType() !== \OCP\Share::SHARE_TYPE_LINK) { //TODO maybe exception? return false; @@ -852,7 +845,7 @@ class Manager { /** * Create a new share - * @return IShare; + * @return \OCP\Share\IShare; */ public function newShare() { return new \OC\Share20\Share(); @@ -938,7 +931,7 @@ class Manager { * @param IUser $user * @return bool */ - public function isSharingDisabledForUser($user) { + public function sharingDisabledForUser(IUser $user) { if ($this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes') { $groupsList = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', ''); $excludedGroups = json_decode($groupsList); diff --git a/lib/private/share20/providerfactory.php b/lib/private/share20/providerfactory.php index 2e5282c1eb4..64147355596 100644 --- a/lib/private/share20/providerfactory.php +++ b/lib/private/share20/providerfactory.php @@ -20,6 +20,7 @@ */ namespace OC\Share20; +use OCP\Share\IProviderFactory; use OC\Share20\Exception\ProviderException; use OCP\IServerContainer; diff --git a/lib/private/share20/share.php b/lib/private/share20/share.php index ee43725d9bc..f9cba10a07a 100644 --- a/lib/private/share20/share.php +++ b/lib/private/share20/share.php @@ -24,7 +24,7 @@ use OCP\Files\Node; use OCP\IUser; use OCP\IGroup; -class Share implements IShare { +class Share implements \OCP\Share\IShare { /** @var string */ private $id; @@ -34,11 +34,11 @@ class Share implements IShare { private $path; /** @var int */ private $shareType; - /** @var IUser|IGroup|string */ + /** @var IUser|IGroup */ private $sharedWith; - /** @var IUser|string */ + /** @var IUser */ private $sharedBy; - /** @var IUser|string */ + /** @var IUser */ private $shareOwner; /** @var int */ private $permissions; @@ -52,16 +52,13 @@ class Share implements IShare { private $parent; /** @var string */ private $target; - /** @var int */ + /** @var \DateTime */ private $shareTime; /** @var bool */ private $mailSend; /** - * Set the id of the share - * - * @param string $id - * @return IShare The modified object + * @inheritdoc */ public function setId($id) { $this->id = $id; @@ -69,9 +66,7 @@ class Share implements IShare { } /** - * Get the id of the share - * - * @return string + * @inheritdoc */ public function getId() { return $this->id; @@ -93,30 +88,22 @@ class Share implements IShare { } /** - * Set the path of this share - * - * @param Node $path - * @return IShare The modified object + * @inheritdoc */ - public function setPath(Node $path) { + public function setNode(Node $path) { $this->path = $path; return $this; } /** - * Get the path of this share for the current user - * - * @return Node + * @inheritdoc */ - public function getPath() { + public function getNode() { return $this->path; } /** - * Set the shareType - * - * @param int $shareType - * @return IShare The modified object + * @inheritdoc */ public function setShareType($shareType) { $this->shareType = $shareType; @@ -124,19 +111,14 @@ class Share implements IShare { } /** - * Get the shareType - * - * @return int + * @inheritdoc */ public function getShareType() { return $this->shareType; } /** - * Set the receiver of this share - * - * @param IUser|IGroup|string - * @return IShare The modified object + * @inheritdoc */ public function setSharedWith($sharedWith) { $this->sharedWith = $sharedWith; @@ -144,19 +126,14 @@ class Share implements IShare { } /** - * Get the receiver of this share - * - * @return IUser|IGroup|string + * @inheritdoc */ public function getSharedWith() { return $this->sharedWith; } /** - * Set the permissions - * - * @param int $permissions - * @return IShare The modified object + * @inheritdoc */ public function setPermissions($permissions) { //TODO checkes @@ -166,19 +143,14 @@ class Share implements IShare { } /** - * Get the share permissions - * - * @return int + * @inheritdoc */ public function getPermissions() { return $this->permissions; } /** - * Set the expiration date - * - * @param \DateTime $expireDate - * @return IShare The modified object + * @inheritdoc */ public function setExpirationDate($expireDate) { //TODO checks @@ -188,19 +160,14 @@ class Share implements IShare { } /** - * Get the share expiration date - * - * @return \DateTime + * @inheritdoc */ public function getExpirationDate() { return $this->expireDate; } /** - * Set the sharer of the path - * - * @param IUser|string $sharedBy - * @return IShare The modified object + * @inheritdoc */ public function setSharedBy($sharedBy) { //TODO checks @@ -210,9 +177,7 @@ class Share implements IShare { } /** - * Get share sharer - * - * @return IUser|string + * @inheritdoc */ public function getSharedBy() { //TODO check if set @@ -220,11 +185,7 @@ class Share implements IShare { } /** - * Set the original share owner (who owns the path) - * - * @param IUser|string - * - * @return IShare The modified object + * @inheritdoc */ public function setShareOwner($shareOwner) { //TODO checks @@ -234,9 +195,7 @@ class Share implements IShare { } /** - * Get the original share owner (who owns the path) - * - * @return IUser|string + * @inheritdoc */ public function getShareOwner() { //TODO check if set @@ -244,33 +203,22 @@ class Share implements IShare { } /** - * Set the password - * - * @param string $password - * - * @return IShare The modified object + * @inheritdoc */ public function setPassword($password) { - //TODO verify - $this->password = $password; return $this; } /** - * Get the password - * - * @return string + * @inheritdoc */ public function getPassword() { return $this->password; } /** - * Set the token - * - * @param string $token - * @return IShare The modified object + * @inheritdoc */ public function setToken($token) { $this->token = $token; @@ -278,19 +226,14 @@ class Share implements IShare { } /** - * Get the token - * - * @return string + * @inheritdoc */ public function getToken() { return $this->token; } /** - * Set the parent id of this share - * - * @param int $parent - * @return IShare The modified object + * @inheritdoc */ public function setParent($parent) { $this->parent = $parent; @@ -298,19 +241,14 @@ class Share implements IShare { } /** - * Get the parent id of this share - * - * @return int + * @inheritdoc */ public function getParent() { return $this->parent; } /** - * Set the target of this share - * - * @param string $target - * @return IShare The modified object + * @inheritdoc */ public function setTarget($target) { $this->target = $target; @@ -318,39 +256,29 @@ class Share implements IShare { } /** - * Get the target of this share - * - * @return string + * @inheritdoc */ public function getTarget() { return $this->target; } /** - * Set the time this share was created - * - * @param int $shareTime - * @return IShare The modified object + * @inheritdoc */ - public function setShareTime($shareTime) { + public function setShareTime(\DateTime $shareTime) { $this->shareTime = $shareTime; return $this; } /** - * Get the timestamp this share was created - * - * @return int + * @inheritdoc */ - public function getSharetime() { + public function getShareTime() { return $this->shareTime; } /** - * Set mailSend - * - * @param bool $mailSend - * @return IShare The modified object + * @inheritdoc */ public function setMailSend($mailSend) { $this->mailSend = $mailSend; @@ -358,9 +286,7 @@ class Share implements IShare { } /** - * Get mailSend - * - * @return bool + * @inheritdoc */ public function getMailSend() { return $this->mailSend; diff --git a/lib/public/files/cache/icache.php b/lib/public/files/cache/icache.php index 07396db4588..3fbf310148d 100644 --- a/lib/public/files/cache/icache.php +++ b/lib/public/files/cache/icache.php @@ -157,13 +157,6 @@ interface ICache { public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath); /** - * remove all entries for files that are stored on the storage from the cache - * - * @since 9.0.0 - */ - public function clear(); - - /** * Get the scan status of a file * * - ICache::NOT_FOUND: File is not in the cache @@ -210,14 +203,6 @@ interface ICache { public function searchByTag($tag, $userId); /** - * get all file ids on the files on the storage - * - * @return int[] - * @since 9.0.0 - */ - public function getAll(); - - /** * find a folder in the cache which has not been fully scanned * * If multiple incomplete folders are in the cache, the one with the highest id will be returned, diff --git a/lib/public/files/config/iusermountcache.php b/lib/public/files/config/iusermountcache.php index f722ad16310..77f58cd8670 100644 --- a/lib/public/files/config/iusermountcache.php +++ b/lib/public/files/config/iusermountcache.php @@ -40,6 +40,8 @@ interface IUserMountCache { public function registerMounts(IUser $user, array $mounts); /** + * Get all cached mounts for a user + * * @param IUser $user * @return ICachedMountInfo[] * @since 9.0.0 @@ -47,6 +49,8 @@ interface IUserMountCache { public function getMountsForUser(IUser $user); /** + * Get all cached mounts by storage + * * @param int $numericStorageId * @return ICachedMountInfo[] * @since 9.0.0 @@ -54,6 +58,8 @@ interface IUserMountCache { public function getMountsForStorageId($numericStorageId); /** + * Get all cached mounts by root + * * @param int $rootFileId * @return ICachedMountInfo[] * @since 9.0.0 @@ -61,6 +67,15 @@ interface IUserMountCache { public function getMountsForRootId($rootFileId); /** + * Get all cached mounts that contain a file + * + * @param int $fileId + * @return ICachedMountInfo[] + * @since 9.0.0 + */ + public function getMountsForFileId($fileId); + + /** * Remove all cached mounts for a user * * @param IUser $user diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php index e21c9fb8e4b..ce1364cc4ea 100644 --- a/lib/public/iservercontainer.php +++ b/lib/public/iservercontainer.php @@ -504,4 +504,12 @@ interface IServerContainer { * @since 9.0.0 */ public function getSystemTagObjectMapper(); + + /** + * Returns the share manager + * + * @return \OCP\Share\IManager + * @since 9.0.0 + */ + public function getShareManager(); } diff --git a/lib/public/share/imanager.php b/lib/public/share/imanager.php new file mode 100644 index 00000000000..6531c14a857 --- /dev/null +++ b/lib/public/share/imanager.php @@ -0,0 +1,212 @@ +<?php +/** + * @author Roeland Jago Douma <rullzer@owncloud.com> + * + * @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 OCP\Share; + +use OCP\IUser; + +use OC\Share20\Exception\ShareNotFound; + +/** + * Interface IManager + * + * @package OCP\Share + * @since 9.0.0 + */ +interface IManager { + + /** + * Create a Share + * + * @param IShare $share + * @return Share The share object + * @since 9.0.0 + */ + public function createShare(IShare $share); + + /** + * Update a share + * + * @param IShare $share + * @return IShare The share object + * @since 9.0.0 + */ + public function updateShare(IShare $share); + + /** + * Delete a share + * + * @param IShare $share + * @throws ShareNotFound + * @since 9.0.0 + */ + public function deleteShare(IShare $share); + + /** + * Unshare a file as the recipient. + * This can be different from a regular delete for example when one of + * the users in a groups deletes that share. But the provider should + * handle this. + * + * @param IShare $share + * @param IUser $recipient + * @since 9.0.0 + */ + public function deleteFromSelf(IShare $share, IUser $recipient); + + /** + * Get shares shared by (initiated) by the provided user. + * + * @param IUser $user + * @param int $shareType + * @param \OCP\Files\File|\OCP\Files\Folder $path + * @param bool $reshares + * @param int $limit The maximum number of returned results, -1 for all results + * @param int $offset + * @return IShare[] + * @since 9.0.0 + */ + public function getSharesBy(IUser $user, $shareType, $path = null, $reshares = false, $limit = 50, $offset = 0); + + /** + * Get shares shared with $user. + * + * @param IUser $user + * @param int $shareType + * @param int $limit The maximum number of shares returned, -1 for all + * @param int $offset + * @return IShare[] + * @since 9.0.0 + */ + public function getSharedWith(IUser $user, $shareType, $limit = 50, $offset = 0); + + /** + * Retrieve a share by the share id + * + * @param string $id + * @return Share + * @throws ShareNotFound + * @since 9.0.0 + */ + public function getShareById($id); + + /** + * Get the share by token possible with password + * + * @param string $token + * @return Share + * @throws ShareNotFound + * @since 9.0.0 + */ + public function getShareByToken($token); + + /** + * Verify the password of a public share + * + * @param IShare $share + * @param string $password + * @return bool + * @since 9.0.0 + */ + public function checkPassword(IShare $share, $password); + + /** + * Instantiates a new share object. This is to be passed to + * createShare. + * + * @return IShare + * @since 9.0.0 + */ + public function newShare(); + + /** + * Is the share API enabled + * + * @return bool + * @since 9.0.0 + */ + public function shareApiEnabled(); + + /** + * Is public link sharing enabled + * + * @return bool + * @since 9.0.0 + */ + public function shareApiAllowLinks(); + + /** + * Is password on public link requires + * + * @return bool + * @since 9.0.0 + */ + public function shareApiLinkEnforcePassword(); + + /** + * Is default expire date enabled + * + * @return bool + * @since 9.0.0 + */ + public function shareApiLinkDefaultExpireDate(); + + /** + * Is default expire date enforced + *` + * @return bool + * @since 9.0.0 + */ + public function shareApiLinkDefaultExpireDateEnforced(); + + /** + * Number of default expire days + * + * @return int + * @since 9.0.0 + */ + public function shareApiLinkDefaultExpireDays(); + + /** + * Allow public upload on link shares + * + * @return bool + * @since 9.0.0 + */ + public function shareApiLinkAllowPublicUpload(); + + /** + * check if user can only share with group members + * @return bool + * @since 9.0.0 + */ + public function shareWithGroupMembersOnly(); + + /** + * Check if sharing is disabled for the given user + * + * @param IUser $user + * @return bool + * @since 9.0.0 + */ + public function sharingDisabledForUser(IUser $user); + +} diff --git a/lib/private/share20/iproviderfactory.php b/lib/public/share/iproviderfactory.php index b38666978db..3a8baccf33b 100644 --- a/lib/private/share20/iproviderfactory.php +++ b/lib/public/share/iproviderfactory.php @@ -18,7 +18,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ -namespace OC\Share20; + +namespace OCP\Share; use OC\Share20\Exception\ProviderException; use OCP\IServerContainer; @@ -34,6 +35,7 @@ interface IProviderFactory { /** * IProviderFactory constructor. * @param IServerContainer $serverContainer + * @since 9.0.0 */ public function __construct(IServerContainer $serverContainer); @@ -41,6 +43,7 @@ interface IProviderFactory { * @param string $id * @return IShareProvider * @throws ProviderException + * @since 9.0.0 */ public function getProvider($id); @@ -48,6 +51,7 @@ interface IProviderFactory { * @param int $shareType * @return IShareProvider * @throws ProviderException + * @since 9.0.0 */ public function getProviderForType($shareType); } diff --git a/lib/public/share/ishare.php b/lib/public/share/ishare.php new file mode 100644 index 00000000000..80e7f7f56ef --- /dev/null +++ b/lib/public/share/ishare.php @@ -0,0 +1,264 @@ +<?php +/** + * @author Roeland Jago Douma <rullzer@owncloud.com> + * + * @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 OCP\Share; + +use OCP\Files\File; +use OCP\Files\Folder; +use OCP\Files\Node; +use OCP\IUser; +use OCP\IGroup; + +/** + * Interface IShare + * + * @package OCP\Share + * @since 9.0.0 + */ +interface IShare { + + /** + * Get the internal id of the share. + * + * @return string + * @since 9.0.0 + */ + public function getId(); + + /** + * Get the full share id. This is the <providerid>:<internalid>. + * The full id is unique in the system. + * + * @return string + * @since 9.0.0 + */ + public function getFullId(); + + /** + * Set the node of the file/folder that is shared + * + * @param File|Folder $path + * @return \OCP\Share\IShare The modified object + * @since 9.0.0 + */ + public function setNode(Node $path); + + /** + * Get the node of the file/folder that is shared + * + * @return File|Folder + * @since 9.0.0 + */ + public function getNode(); + + /** + * Set the shareType + * + * @param int $shareType + * @return \OCP\Share\IShare The modified object + * @since 9.0.0 + */ + public function setShareType($shareType); + + /** + * Get the shareType + * + * @return int + * @since 9.0.0 + */ + public function getShareType(); + + /** + * Set the receiver of this share. + * + * @param IUser|IGroup + * @return \OCP\Share\IShare The modified object + * @since 9.0.0 + */ + public function setSharedWith($sharedWith); + + /** + * Get the receiver of this share. + * + * @return IUser|IGroup + * @since 9.0.0 + */ + public function getSharedWith(); + + /** + * Set the permissions. + * See \OCP\Constants::PERMISSION_* + * + * @param int $permissions + * @return \OCP\Share\IShare The modified object + * @since 9.0.0 + */ + public function setPermissions($permissions); + + /** + * Get the share permissions + * See \OCP\Constants::PERMISSION_* + * + * @return int + * @since 9.0.0 + */ + public function getPermissions(); + + /** + * Set the expiration date + * + * @param \DateTime $expireDate + * @return \OCP\Share\IShare The modified object + * @since 9.0.0 + */ + public function setExpirationDate($expireDate); + + /** + * Get the expiration date + * + * @return \DateTime + * @since 9.0.0 + */ + public function getExpirationDate(); + + /** + * Set the sharer of the path. + * + * @param IUser $sharedBy + * @return \OCP\Share\IShare The modified object + * @since 9.0.0 + */ + public function setSharedBy($sharedBy); + + /** + * Get share sharer + * + * @return IUser + * @since 9.0.0 + */ + public function getSharedBy(); + + /** + * Set the original share owner (who owns the path that is shared) + * + * @param IUser + * @return \OCP\Share\IShare The modified object + * @since 9.0.0 + */ + public function setShareOwner($shareOwner); + + /** + * Get the original share owner (who owns the path that is shared) + * + * @return IUser + * @since 9.0.0 + */ + public function getShareOwner(); + + /** + * Set the password for this share. + * When the share is passed to the share manager to be created + * or updated the password will be hashed. + * + * @param string $password + * @return \OCP\Share\IShare The modified object + * @since 9.0.0 + */ + public function setPassword($password); + + /** + * Get the password of this share. + * If this share is obtained via a shareprovider the password is + * hashed. + * + * @return string + * @since 9.0.0 + */ + public function getPassword(); + + /** + * Set the public link token. + * + * @param string $token + * @return \OCP\Share\IShare The modified object + * @since 9.0.0 + */ + public function setToken($token); + + /** + * Get the public link token. + * + * @return string + * @since 9.0.0 + */ + public function getToken(); + + /** + * Set the target path of this share relative to the recipients user folder. + * + * @param string $target + * @return \OCP\Share\IShare The modified object + * @since 9.0.0 + */ + public function setTarget($target); + + /** + * Get the target path of this share relative to the recipients user folder. + * + * @return string + * @since 9.0.0 + */ + public function getTarget(); + + /** + * Set the time this share was created + * + * @param \DateTime $shareTime + * @return \OCP\Share\IShare The modified object + * @since 9.0.0 + */ + public function setShareTime(\DateTime $shareTime); + + /** + * Get the timestamp this share was created + * + * @return \DateTime + * @since 9.0.0 + */ + public function getShareTime(); + + /** + * Set if the recipient is informed by mail about the share. + * + * @param bool $mailSend + * @return \OCP\Share\IShare The modified object + * @since 9.0.0 + */ + public function setMailSend($mailSend); + + /** + * Get if the recipient informed by mail about the share. + * + * @return bool + * @since 9.0.0 + */ + public function getMailSend(); +} diff --git a/lib/private/share20/ishareprovider.php b/lib/public/share/ishareprovider.php index 17ee4abb9a8..50964c88dd6 100644 --- a/lib/private/share20/ishareprovider.php +++ b/lib/public/share/ishareprovider.php @@ -18,53 +18,65 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ -namespace OC\Share20; + +namespace OCP\Share; use OC\Share20\Exception\ShareNotFound; use OC\Share20\Exception\BackendError; use OCP\IUser; +/** + * Interface IShareProvider + * + * @package OCP\Share + * @since 9.0.0 + */ interface IShareProvider { /** * Return the identifier of this provider. * * @return string Containing only [a-zA-Z0-9] + * @since 9.0.0 */ public function identifier(); /** - * Share a path + * Create a share * - * @param IShare $share - * @return IShare The share object + * @param \OCP\Share\IShare $share + * @return \OCP\Share\IShare The share object + * @since 9.0.0 */ - public function create(IShare $share); + public function create(\OCP\Share\IShare $share); /** * Update a share * - * @param IShare $share - * @return IShare The share object + * @param \OCP\Share\IShare $share + * @return \OCP\Share\IShare The share object + * @since 9.0.0 */ - public function update(IShare $share); + public function update(\OCP\Share\IShare $share); /** * Delete a share * - * @param IShare $share - * @throws BackendError + * @param \OCP\Share\IShare $share + * @since 9.0.0 */ - public function delete(IShare $share); + public function delete(\OCP\Share\IShare $share); /** * Unshare a file from self as recipient. - * This may require special handling. + * This may require special handling. If a user unshares a group + * share from their self then the original group share should still exist. * - * @param IShare $share + * @param \OCP\Share\IShare $share * @param IUser $recipient + * @since 9.0.0 */ - public function deleteFromSelf(IShare $share, IUser $recipient); + public function deleteFromSelf(\OCP\Share\IShare $share, IUser $recipient); /** * Get all shares by the given user @@ -75,7 +87,8 @@ interface IShareProvider { * @param bool $reshares Also get the shares where $user is the owner instead of just the shares where $user is the initiator * @param int $limit The maximum number of shares to be returned, -1 for all shares * @param int $offset - * @return Share[] + * @return \OCP\Share\I Share[] + * @since 9.0.0 */ public function getSharesBy(IUser $user, $shareType, $node, $reshares, $limit, $offset); @@ -83,24 +96,18 @@ interface IShareProvider { * Get share by id * * @param int $id - * @return IShare + * @return \OCP\Share\IShare * @throws ShareNotFound + * @since 9.0.0 */ public function getShareById($id); /** - * Get children - * - * @param IShare $parent - * @return IShare[] - */ - public function getChildren(IShare $parent); - - /** * Get shares for a given path * * @param \OCP\Files\Node $path - * @return IShare[] + * @return \OCP\Share\IShare[] + * @since 9.0.0 */ public function getSharesByPath(\OCP\Files\Node $path); @@ -111,7 +118,8 @@ interface IShareProvider { * @param int $shareType * @param int $limit The max number of entries returned, -1 for all * @param int $offset - * @param Share + * @return \OCP\Share\IShare[] + * @since 9.0.0 */ public function getSharedWith(IUser $user, $shareType, $limit, $offset); @@ -119,8 +127,9 @@ interface IShareProvider { * Get a share by token * * @param string $token - * @return IShare + * @return \OCP\Share\IShare * @throws ShareNotFound + * @since 9.0.0 */ public function getShareByToken($token); } diff --git a/tests/lib/files/config/usermountcache.php b/tests/lib/files/config/usermountcache.php index 26449b5dd23..070c2f6176d 100644 --- a/tests/lib/files/config/usermountcache.php +++ b/tests/lib/files/config/usermountcache.php @@ -8,8 +8,8 @@ namespace Test\Files\Config; +use OC\DB\QueryBuilder\Literal; use OC\Files\Mount\MountPoint; -use OC\Files\Storage\Temporary; use OC\Log; use OC\User\Manager; use OCP\Files\Config\ICachedMountInfo; @@ -37,7 +37,10 @@ class UserMountCache extends TestCase { */ private $cache; + private $fileIds = []; + public function setUp() { + $this->fileIds = []; $this->connection = \OC::$server->getDatabaseConnection(); $this->userManager = new Manager(null); $userBackend = new Dummy(); @@ -51,6 +54,14 @@ class UserMountCache extends TestCase { $builder = $this->connection->getQueryBuilder(); $builder->delete('mounts')->execute(); + + $builder = $this->connection->getQueryBuilder(); + + foreach ($this->fileIds as $fileId) { + $builder->delete('filecache') + ->where($builder->expr()->eq('fileid', new Literal($fileId))) + ->execute(); + } } private function getStorage($storageId, $rootId) { @@ -208,9 +219,7 @@ class UserMountCache extends TestCase { $this->clearCache(); $cachedMounts = $this->cache->getMountsForStorageId(3); - usort($cachedMounts, function (ICachedMountInfo $a, ICachedMountInfo $b) { - return strcmp($a->getUser()->getUID(), $b->getUser()->getUID()); - }); + $this->sortMounts($cachedMounts); $this->assertCount(2, $cachedMounts); @@ -238,9 +247,7 @@ class UserMountCache extends TestCase { $this->clearCache(); $cachedMounts = $this->cache->getMountsForRootId(4); - usort($cachedMounts, function (ICachedMountInfo $a, ICachedMountInfo $b) { - return strcmp($a->getUser()->getUID(), $b->getUser()->getUID()); - }); + $this->sortMounts($cachedMounts); $this->assertCount(2, $cachedMounts); @@ -254,4 +261,115 @@ class UserMountCache extends TestCase { $this->assertEquals(4, $cachedMounts[1]->getRootId()); $this->assertEquals(3, $cachedMounts[1]->getStorageId()); } + + private function sortMounts(&$mounts) { + usort($mounts, function (ICachedMountInfo $a, ICachedMountInfo $b) { + return strcmp($a->getUser()->getUID(), $b->getUser()->getUID()); + }); + } + + private function createCacheEntry($internalPath, $storageId) { + $this->connection->insertIfNotExist('*PREFIX*filecache', [ + 'storage' => $storageId, + 'path' => $internalPath, + 'path_hash' => md5($internalPath), + 'parent' => -1, + 'name' => basename($internalPath), + 'mimetype' => 0, + 'mimepart' => 0, + 'size' => 0, + 'storage_mtime' => 0, + 'encrypted' => 0, + 'unencrypted_size' => 0, + 'etag' => '', + 'permissions' => 31 + ], ['storage', 'path_hash']); + $id = (int)$this->connection->lastInsertId('*PREFIX*filecache'); + $this->fileIds[] = $id; + return $id; + } + + public function testGetMountsForFileIdRootId() { + $user1 = $this->userManager->get('u1'); + + $rootId = $this->createCacheEntry('', 2); + + $mount1 = new MountPoint($this->getStorage(2, $rootId), '/foo/'); + + $this->cache->registerMounts($user1, [$mount1]); + + $this->clearCache(); + + $cachedMounts = $this->cache->getMountsForFileId($rootId); + + $this->assertCount(1, $cachedMounts); + + $this->assertEquals('/foo/', $cachedMounts[0]->getMountPoint()); + $this->assertEquals($user1, $cachedMounts[0]->getUser()); + $this->assertEquals($rootId, $cachedMounts[0]->getRootId()); + $this->assertEquals(2, $cachedMounts[0]->getStorageId()); + } + + public function testGetMountsForFileIdSubFolder() { + $user1 = $this->userManager->get('u1'); + + $rootId = $this->createCacheEntry('', 2); + $fileId = $this->createCacheEntry('/foo/bar', 2); + + $mount1 = new MountPoint($this->getStorage(2, $rootId), '/foo/'); + + $this->cache->registerMounts($user1, [$mount1]); + + $this->clearCache(); + + $cachedMounts = $this->cache->getMountsForFileId($fileId); + + $this->assertCount(1, $cachedMounts); + + $this->assertEquals('/foo/', $cachedMounts[0]->getMountPoint()); + $this->assertEquals($user1, $cachedMounts[0]->getUser()); + $this->assertEquals($rootId, $cachedMounts[0]->getRootId()); + $this->assertEquals(2, $cachedMounts[0]->getStorageId()); + } + + public function testGetMountsForFileIdSubFolderMount() { + $user1 = $this->userManager->get('u1'); + + $this->createCacheEntry('', 2); + $folderId = $this->createCacheEntry('/foo', 2); + $fileId = $this->createCacheEntry('/foo/bar', 2); + + $mount1 = new MountPoint($this->getStorage(2, $folderId), '/foo/'); + + $this->cache->registerMounts($user1, [$mount1]); + + $this->clearCache(); + + $cachedMounts = $this->cache->getMountsForFileId($fileId); + + $this->assertCount(1, $cachedMounts); + + $this->assertEquals('/foo/', $cachedMounts[0]->getMountPoint()); + $this->assertEquals($user1, $cachedMounts[0]->getUser()); + $this->assertEquals($folderId, $cachedMounts[0]->getRootId()); + $this->assertEquals(2, $cachedMounts[0]->getStorageId()); + } + + public function testGetMountsForFileIdSubFolderMountOutside() { + $user1 = $this->userManager->get('u1'); + + $this->createCacheEntry('', 2); + $folderId = $this->createCacheEntry('/foo', 2); + $fileId = $this->createCacheEntry('/bar/asd', 2); + + $mount1 = new MountPoint($this->getStorage(2, $folderId), '/foo/'); + + $this->cache->registerMounts($user1, [$mount1]); + + $this->clearCache(); + + $cachedMounts = $this->cache->getMountsForFileId($fileId); + + $this->assertCount(0, $cachedMounts); + } } diff --git a/tests/lib/l10n/factorytest.php b/tests/lib/l10n/factorytest.php index f632e48e2de..9f5954d0ee1 100644 --- a/tests/lib/l10n/factorytest.php +++ b/tests/lib/l10n/factorytest.php @@ -8,7 +8,6 @@ namespace Test\L10N; - use OC\L10N\Factory; use Test\TestCase; @@ -26,6 +25,9 @@ class FactoryTest extends TestCase { /** @var \OCP\IRequest|\PHPUnit_Framework_MockObject_MockObject */ protected $request; + /** @var \OCP\IUserSession|\PHPUnit_Framework_MockObject_MockObject */ + protected $userSession; + public function setUp() { parent::setUp(); @@ -38,6 +40,8 @@ class FactoryTest extends TestCase { $this->request = $this->getMockBuilder('OCP\IRequest') ->disableOriginalConstructor() ->getMock(); + + $this->userSession = $this->getMock('\OCP\IUserSession'); } /** @@ -50,98 +54,209 @@ class FactoryTest extends TestCase { ->setConstructorArgs([ $this->config, $this->request, + $this->userSession ]) ->setMethods($methods) ->getMock(); } else { - return new Factory($this->config, $this->request); + return new Factory($this->config, $this->request, $this->userSession); } } - public function dataFindLanguage() { + public function dataFindAvailableLanguages() { return [ - [null, false, 1, 'de', true, null, null, null, null, null, 'de'], - [null, 'test', 2, 'de', false, 'ru', true, null, null, null, 'ru'], - [null, 'test', 1, '', null, 'ru', true, null, null, null, 'ru'], - [null, 'test', 3, 'de', false, 'ru', false, 'cz', true, null, 'cz'], - [null, 'test', 2, '', null, 'ru', false, 'cz', true, null, 'cz'], - [null, 'test', 1, '', null, '', null, 'cz', true, null, 'cz'], - [null, 'test', 3, 'de', false, 'ru', false, 'cz', false, 'ar', 'ar'], - [null, 'test', 2, '', null, 'ru', false, 'cz', false, 'ar', 'ar'], - [null, 'test', 1, '', null, '', null, 'cz', false, 'ar', 'ar'], - [null, 'test', 0, '', null, '', null, false, null, 'ar', 'ar'], + [null], + ['files'], ]; } - /** - * @dataProvider dataFindLanguage - * - * @param string|null $app - * @param string|null $user - * @param int $existsCalls - * @param string $storedRequestLang - * @param bool $srlExists - * @param string|null $userLang - * @param bool $ulExists - * @param string|false $defaultLang - * @param bool $dlExists - * @param string|null $requestLang - * @param string $expected - */ - public function testFindLanguage($app, $user, $existsCalls, $storedRequestLang, $srlExists, $userLang, $ulExists, $defaultLang, $dlExists, $requestLang, $expected) { - $factory = $this->getFactory([ - 'languageExists', - 'setLanguageFromRequest', - ]); + public function testFindLanguageWithExistingRequestLanguageAndNoApp() { + $factory = $this->getFactory(['languageExists']); + $this->invokePrivate($factory, 'requestLanguage', ['de']); + $factory->expects($this->once()) + ->method('languageExists') + ->with(null, 'de') + ->willReturn(true); - $session = $this->getMockBuilder('OCP\ISession') - ->disableOriginalConstructor() - ->getMock(); - $session->expects($this->any()) - ->method('get') - ->with('user_id') - ->willReturn($user); - $userSession = $this->getMockBuilder('OC\User\Session') - ->disableOriginalConstructor() - ->getMock(); - $userSession->expects($this->any()) - ->method('getSession') - ->willReturn($session); + $this->assertSame('de', $factory->findLanguage()); + } + + public function testFindLanguageWithExistingRequestLanguageAndApp() { + $factory = $this->getFactory(['languageExists']); + $this->invokePrivate($factory, 'requestLanguage', ['de']); + $factory->expects($this->once()) + ->method('languageExists') + ->with('MyApp', 'de') + ->willReturn(true); - $this->invokePrivate($factory, 'requestLanguage', [$storedRequestLang]); + $this->assertSame('de', $factory->findLanguage('MyApp')); + } - $factory->expects($this->exactly($existsCalls)) - ->method('languageExists') - ->willReturnMap([ - [$app, $storedRequestLang, $srlExists], - [$app, $userLang, $ulExists], - [$app, $defaultLang, $dlExists], - ]); - - $factory->expects($requestLang !== null ? $this->once() : $this->never()) - ->method('setLanguageFromRequest') - ->willReturn($requestLang); - - $this->config->expects($userLang !== null ? $this->any() : $this->never()) - ->method('getUserValue') - ->with($this->anything(), 'core', 'lang') - ->willReturn($userLang); - - $this->config->expects($defaultLang !== null ? $this->once() : $this->never()) + public function testFindLanguageWithNotExistingRequestLanguageAndExistingStoredUserLanguage() { + $factory = $this->getFactory(['languageExists']); + $this->invokePrivate($factory, 'requestLanguage', ['de']); + $factory->expects($this->at(0)) + ->method('languageExists') + ->with('MyApp', 'de') + ->willReturn(false); + $this->config + ->expects($this->once()) ->method('getSystemValue') - ->with('default_language', false) - ->willReturn($defaultLang); + ->with('installed', false) + ->willReturn(true); + $user = $this->getMock('\OCP\IUser'); + $user->expects($this->once()) + ->method('getUID') + ->willReturn('MyUserUid'); + $this->userSession + ->expects($this->exactly(2)) + ->method('getUser') + ->willReturn($user); + $this->config + ->expects($this->once()) + ->method('getUserValue') + ->with('MyUserUid', 'core', 'lang', null) + ->willReturn('jp'); + $factory->expects($this->at(1)) + ->method('languageExists') + ->with('MyApp', 'jp') + ->willReturn(true); + + $this->assertSame('jp', $factory->findLanguage('MyApp')); + } - $this->overwriteService('UserSession', $userSession); - $this->assertSame($expected, $factory->findLanguage($app)); - $this->restoreService('UserSession'); + public function testFindLanguageWithNotExistingRequestLanguageAndNotExistingStoredUserLanguage() { + $factory = $this->getFactory(['languageExists']); + $this->invokePrivate($factory, 'requestLanguage', ['de']); + $factory->expects($this->at(0)) + ->method('languageExists') + ->with('MyApp', 'de') + ->willReturn(false); + $this->config + ->expects($this->at(0)) + ->method('getSystemValue') + ->with('installed', false) + ->willReturn(true); + $user = $this->getMock('\OCP\IUser'); + $user->expects($this->once()) + ->method('getUID') + ->willReturn('MyUserUid'); + $this->userSession + ->expects($this->exactly(2)) + ->method('getUser') + ->willReturn($user); + $this->config + ->expects($this->once()) + ->method('getUserValue') + ->with('MyUserUid', 'core', 'lang', null) + ->willReturn('jp'); + $factory->expects($this->at(1)) + ->method('languageExists') + ->with('MyApp', 'jp') + ->willReturn(false); + $this->config + ->expects($this->at(2)) + ->method('getSystemValue') + ->with('default_language', false) + ->willReturn('es'); + $factory->expects($this->at(2)) + ->method('languageExists') + ->with('MyApp', 'es') + ->willReturn(true); + + $this->assertSame('es', $factory->findLanguage('MyApp')); } - public function dataFindAvailableLanguages() { - return [ - [null], - ['files'], - ]; + public function testFindLanguageWithNotExistingRequestLanguageAndNotExistingStoredUserLanguageAndNotExistingDefault() { + $factory = $this->getFactory(['languageExists']); + $this->invokePrivate($factory, 'requestLanguage', ['de']); + $factory->expects($this->at(0)) + ->method('languageExists') + ->with('MyApp', 'de') + ->willReturn(false); + $this->config + ->expects($this->at(0)) + ->method('getSystemValue') + ->with('installed', false) + ->willReturn(true); + $user = $this->getMock('\OCP\IUser'); + $user->expects($this->once()) + ->method('getUID') + ->willReturn('MyUserUid'); + $this->userSession + ->expects($this->exactly(2)) + ->method('getUser') + ->willReturn($user); + $this->config + ->expects($this->once()) + ->method('getUserValue') + ->with('MyUserUid', 'core', 'lang', null) + ->willReturn('jp'); + $factory->expects($this->at(1)) + ->method('languageExists') + ->with('MyApp', 'jp') + ->willReturn(false); + $this->config + ->expects($this->at(2)) + ->method('getSystemValue') + ->with('default_language', false) + ->willReturn('es'); + $factory->expects($this->at(2)) + ->method('languageExists') + ->with('MyApp', 'es') + ->willReturn(false); + $this->config + ->expects($this->never()) + ->method('setUserValue'); + + $this->assertSame('en', $factory->findLanguage('MyApp')); + } + + public function testFindLanguageWithNotExistingRequestLanguageAndNotExistingStoredUserLanguageAndNotExistingDefaultAndNoAppInScope() { + $factory = $this->getFactory(['languageExists']); + $this->invokePrivate($factory, 'requestLanguage', ['de']); + $factory->expects($this->at(0)) + ->method('languageExists') + ->with('MyApp', 'de') + ->willReturn(false); + $this->config + ->expects($this->at(0)) + ->method('getSystemValue') + ->with('installed', false) + ->willReturn(true); + $user = $this->getMock('\OCP\IUser'); + $user->expects($this->once()) + ->method('getUID') + ->willReturn('MyUserUid'); + $this->userSession + ->expects($this->exactly(2)) + ->method('getUser') + ->willReturn($user); + $this->config + ->expects($this->once()) + ->method('getUserValue') + ->with('MyUserUid', 'core', 'lang', null) + ->willReturn('jp'); + $factory->expects($this->at(1)) + ->method('languageExists') + ->with('MyApp', 'jp') + ->willReturn(false); + $this->config + ->expects($this->at(2)) + ->method('getSystemValue') + ->with('default_language', false) + ->willReturn('es'); + $factory->expects($this->at(2)) + ->method('languageExists') + ->with('MyApp', 'es') + ->willReturn(false); + $this->config + ->expects($this->never()) + ->method('setUserValue') + ->with('MyUserUid', 'core', 'lang', 'en'); + + + $this->assertSame('en', $factory->findLanguage('MyApp')); } /** diff --git a/tests/lib/l10n/l10nlegacytest.php b/tests/lib/l10n/l10nlegacytest.php index ae84968e65d..025f761fe5c 100644 --- a/tests/lib/l10n/l10nlegacytest.php +++ b/tests/lib/l10n/l10nlegacytest.php @@ -124,7 +124,7 @@ class L10nLegacyTest extends \Test\TestCase { } public function testFactoryGetLanguageCode() { - $factory = new \OC\L10N\Factory($this->getMock('OCP\IConfig'), $this->getMock('OCP\IRequest')); + $factory = new \OC\L10N\Factory($this->getMock('OCP\IConfig'), $this->getMock('OCP\IRequest'), $this->getMock('OCP\IUserSession')); $l = $factory->get('lib', 'de'); $this->assertEquals('de', $l->getLanguageCode()); } diff --git a/tests/lib/l10n/l10ntest.php b/tests/lib/l10n/l10ntest.php index 95546b4f788..0d175954bc1 100644 --- a/tests/lib/l10n/l10ntest.php +++ b/tests/lib/l10n/l10ntest.php @@ -12,6 +12,7 @@ namespace Test\L10N; use DateTime; use OC\L10N\Factory; use OC\L10N\L10N; +use OCP\IUserSession; use Test\TestCase; /** @@ -28,7 +29,9 @@ class L10nTest extends TestCase { $config = $this->getMock('OCP\IConfig'); /** @var \OCP\IRequest $request */ $request = $this->getMock('OCP\IRequest'); - return new Factory($config, $request); + /** @var IUserSession $userSession */ + $userSession = $this->getMock('OCP\IUserSession'); + return new Factory($config, $request, $userSession); } public function testGermanPluralTranslations() { diff --git a/tests/lib/server.php b/tests/lib/server.php index 91beea7c2f8..8b2fec1f5a1 100644 --- a/tests/lib/server.php +++ b/tests/lib/server.php @@ -139,6 +139,8 @@ class Server extends \Test\TestCase { ['Search', '\OCP\ISearch'], ['SecureRandom', '\OC\Security\SecureRandom'], ['SecureRandom', '\OCP\Security\ISecureRandom'], + ['ShareManager', '\OC\Share20\Manager'], + ['ShareManager', '\OCP\Share\IManager'], ['SystemConfig', '\OC\SystemConfig'], ['URLGenerator', '\OC\URLGenerator'], diff --git a/tests/lib/share20/defaultshareprovidertest.php b/tests/lib/share20/defaultshareprovidertest.php index 79cc92116be..eb3be0bde14 100644 --- a/tests/lib/share20/defaultshareprovidertest.php +++ b/tests/lib/share20/defaultshareprovidertest.php @@ -172,7 +172,7 @@ class DefaultShareProviderTest extends \Test\TestCase { $this->assertEquals($sharedWith, $share->getSharedWith()); $this->assertEquals($sharedBy, $share->getSharedBy()); $this->assertEquals($shareOwner, $share->getShareOwner()); - $this->assertEquals($ownerPath, $share->getPath()); + $this->assertEquals($ownerPath, $share->getNode()); $this->assertEquals(13, $share->getPermissions()); $this->assertEquals(null, $share->getToken()); $this->assertEquals(null, $share->getExpirationDate()); @@ -240,7 +240,7 @@ class DefaultShareProviderTest extends \Test\TestCase { $this->assertEquals($sharedWith, $share->getSharedWith()); $this->assertEquals($sharedBy, $share->getSharedBy()); $this->assertEquals($shareOwner, $share->getShareOwner()); - $this->assertEquals($ownerPath, $share->getPath()); + $this->assertEquals($ownerPath, $share->getNode()); $this->assertEquals(13, $share->getPermissions()); $this->assertEquals(null, $share->getToken()); $this->assertEquals(null, $share->getExpirationDate()); @@ -303,7 +303,7 @@ class DefaultShareProviderTest extends \Test\TestCase { $this->assertEquals('sharedWith', $share->getPassword()); $this->assertEquals($sharedBy, $share->getSharedBy()); $this->assertEquals($shareOwner, $share->getShareOwner()); - $this->assertEquals($ownerPath, $share->getPath()); + $this->assertEquals($ownerPath, $share->getNode()); $this->assertEquals(13, $share->getPermissions()); $this->assertEquals('token', $share->getToken()); $this->assertEquals(\DateTime::createFromFormat('Y-m-d H:i:s', '2000-01-02 00:00:00'), $share->getExpirationDate()); @@ -326,7 +326,7 @@ class DefaultShareProviderTest extends \Test\TestCase { $id = $qb->getLastInsertId(); - $share = $this->getMock('OC\Share20\IShare'); + $share = $this->getMock('OCP\Share\IShare'); $share->method('getId')->willReturn($id); $provider = $this->getMockBuilder('OC\Share20\DefaultShareProvider') @@ -361,7 +361,7 @@ class DefaultShareProviderTest extends \Test\TestCase { * @expectedException \OC\Share20\Exception\BackendError */ public function testDeleteFails() { - $share = $this->getMock('OC\Share20\IShare'); + $share = $this->getMock('OCP\Share\IShare'); $share ->method('getId') ->willReturn(42); @@ -510,7 +510,7 @@ class DefaultShareProviderTest extends \Test\TestCase { ['group1', $group1] ])); - $share = $this->getMock('\OC\Share20\IShare'); + $share = $this->getMock('\OCP\Share\IShare'); $share->method('getId')->willReturn($id); $children = $this->provider->getChildren($share); @@ -522,7 +522,7 @@ class DefaultShareProviderTest extends \Test\TestCase { $this->assertEquals($user1, $children[0]->getSharedWith()); $this->assertEquals($user2, $children[0]->getSharedBy()); $this->assertEquals($shareOwner, $children[0]->getShareOwner()); - $this->assertEquals($ownerPath, $children[0]->getPath()); + $this->assertEquals($ownerPath, $children[0]->getNode()); $this->assertEquals(2, $children[0]->getPermissions()); $this->assertEquals(null, $children[0]->getToken()); $this->assertEquals(null, $children[0]->getExpirationDate()); @@ -533,7 +533,7 @@ class DefaultShareProviderTest extends \Test\TestCase { $this->assertEquals($group1, $children[1]->getSharedWith()); $this->assertEquals($user3, $children[1]->getSharedBy()); $this->assertEquals($shareOwner, $children[1]->getShareOwner()); - $this->assertEquals($ownerPath, $children[1]->getPath()); + $this->assertEquals($ownerPath, $children[1]->getNode()); $this->assertEquals(4, $children[1]->getPermissions()); $this->assertEquals(null, $children[1]->getToken()); $this->assertEquals(null, $children[1]->getExpirationDate()); @@ -582,7 +582,7 @@ class DefaultShareProviderTest extends \Test\TestCase { $share->setSharedWith($sharedWith); $share->setSharedBy($sharedBy); $share->setShareOwner($shareOwner); - $share->setPath($path); + $share->setNode($path); $share->setPermissions(1); $share->setTarget('/target'); @@ -596,8 +596,8 @@ class DefaultShareProviderTest extends \Test\TestCase { $this->assertSame($shareOwner, $share2->getShareOwner()); $this->assertSame(1, $share2->getPermissions()); $this->assertSame('/target', $share2->getTarget()); - $this->assertLessThanOrEqual(time(), $share2->getSharetime()); - $this->assertSame($path, $share2->getPath()); + $this->assertLessThanOrEqual(new \DateTime(), $share2->getShareTime()); + $this->assertSame($path, $share2->getNode()); } public function testCreateGroupShare() { @@ -645,7 +645,7 @@ class DefaultShareProviderTest extends \Test\TestCase { $share->setSharedWith($sharedWith); $share->setSharedBy($sharedBy); $share->setShareOwner($shareOwner); - $share->setPath($path); + $share->setNode($path); $share->setPermissions(1); $share->setTarget('/target'); @@ -659,8 +659,8 @@ class DefaultShareProviderTest extends \Test\TestCase { $this->assertSame($shareOwner, $share2->getShareOwner()); $this->assertSame(1, $share2->getPermissions()); $this->assertSame('/target', $share2->getTarget()); - $this->assertLessThanOrEqual(time(), $share2->getSharetime()); - $this->assertSame($path, $share2->getPath()); + $this->assertLessThanOrEqual(new \DateTime(), $share2->getShareTime()); + $this->assertSame($path, $share2->getNode()); } public function testCreateLinkShare() { @@ -701,7 +701,7 @@ class DefaultShareProviderTest extends \Test\TestCase { $share->setShareType(\OCP\Share::SHARE_TYPE_LINK); $share->setSharedBy($sharedBy); $share->setShareOwner($shareOwner); - $share->setPath($path); + $share->setNode($path); $share->setPermissions(1); $share->setPassword('password'); $share->setToken('token'); @@ -718,8 +718,8 @@ class DefaultShareProviderTest extends \Test\TestCase { $this->assertSame($shareOwner, $share2->getShareOwner()); $this->assertSame(1, $share2->getPermissions()); $this->assertSame('/target', $share2->getTarget()); - $this->assertLessThanOrEqual(time(), $share2->getSharetime()); - $this->assertSame($path, $share2->getPath()); + $this->assertLessThanOrEqual(new \DateTime(), $share2->getShareTime()); + $this->assertSame($path, $share2->getNode()); $this->assertSame('password', $share2->getPassword()); $this->assertSame('token', $share2->getToken()); $this->assertEquals($expireDate, $share2->getExpirationDate()); @@ -981,13 +981,13 @@ class DefaultShareProviderTest extends \Test\TestCase { $this->assertCount(1, $share); $share = $share[0]; - $this->assertEquals($id, $share->getId()); - $this->assertEquals($group, $share->getSharedWith()); - $this->assertEquals($owner, $share->getShareOwner()); - $this->assertEquals($initiator, $share->getSharedBy()); - $this->assertEquals(\OCP\Share::SHARE_TYPE_GROUP, $share->getShareType()); - $this->assertEquals(0, $share->getPermissions()); - $this->assertEquals('userTarget', $share->getTarget()); + $this->assertSame($id, $share->getId()); + $this->assertSame($group, $share->getSharedWith()); + $this->assertSame($owner, $share->getShareOwner()); + $this->assertSame($initiator, $share->getSharedBy()); + $this->assertSame(\OCP\Share::SHARE_TYPE_GROUP, $share->getShareType()); + $this->assertSame(0, $share->getPermissions()); + $this->assertSame('userTarget', $share->getTarget()); } public function testGetSharesBy() { @@ -1518,7 +1518,7 @@ class DefaultShareProviderTest extends \Test\TestCase { $share->setSharedWith($users['user3']); $share->setSharedBy($users['user4']); $share->setShareOwner($users['user5']); - $share->setPath($file2); + $share->setNode($file2); $share->setPermissions(1); $share2 = $this->provider->update($share); @@ -1567,7 +1567,7 @@ class DefaultShareProviderTest extends \Test\TestCase { $share->setPassword('password'); $share->setSharedBy($users['user4']); $share->setShareOwner($users['user5']); - $share->setPath($file2); + $share->setNode($file2); $share->setPermissions(1); $share2 = $this->provider->update($share); @@ -1616,7 +1616,7 @@ class DefaultShareProviderTest extends \Test\TestCase { $share->setPassword(null); $share->setSharedBy($users['user4']); $share->setShareOwner($users['user5']); - $share->setPath($file2); + $share->setNode($file2); $share->setPermissions(1); $share2 = $this->provider->update($share); @@ -1678,7 +1678,7 @@ class DefaultShareProviderTest extends \Test\TestCase { $share->setSharedWith($groups['group0']); $share->setSharedBy($users['user4']); $share->setShareOwner($users['user5']); - $share->setPath($file2); + $share->setNode($file2); $share->setPermissions(1); $share2 = $this->provider->update($share); @@ -1747,7 +1747,7 @@ class DefaultShareProviderTest extends \Test\TestCase { $share->setSharedWith($groups['group0']); $share->setSharedBy($users['user4']); $share->setShareOwner($users['user5']); - $share->setPath($file2); + $share->setNode($file2); $share->setPermissions(1); $share2 = $this->provider->update($share); diff --git a/tests/lib/share20/managertest.php b/tests/lib/share20/managertest.php index ef602fc8e46..53b1374eade 100644 --- a/tests/lib/share20/managertest.php +++ b/tests/lib/share20/managertest.php @@ -20,8 +20,8 @@ */ namespace Test\Share20; -use OC\Share20\IProviderFactory; -use OC\Share20\IShare; +use OCP\Share\IProviderFactory; +use OCP\Share\IShare; use OC\Share20\Manager; use OC\Share20\Exception; @@ -29,7 +29,7 @@ use OC\Share20\Share; use OCP\IL10N; use OCP\ILogger; use OCP\IConfig; -use OC\Share20\IShareProvider; +use OCP\Share\IShareProvider; use OCP\Security\ISecureRandom; use OCP\Security\IHasher; use OCP\Files\Mount\IMountManager; @@ -102,7 +102,9 @@ class ManagerTest extends \Test\TestCase { $this->factory ); - $this->defaultProvider = $this->getMock('\OC\Share20\IShareProvider'); + $this->defaultProvider = $this->getMockBuilder('\OC\Share20\DefaultShareProvider') + ->disableOriginalConstructor() + ->getMock(); $this->defaultProvider->method('identifier')->willReturn('default'); $this->factory->setProvider($this->defaultProvider); @@ -130,7 +132,7 @@ class ManagerTest extends \Test\TestCase { * @expectedException \OC\Share20\Exception\ShareNotFound */ public function testDeleteNoShareId() { - $share = $this->getMock('\OC\Share20\IShare'); + $share = $this->getMock('\OCP\Share\IShare'); $share ->expects($this->once()) @@ -170,14 +172,14 @@ class ManagerTest extends \Test\TestCase { $path = $this->getMock('\OCP\Files\File'); $path->method('getId')->willReturn(1); - $share = $this->getMock('\OC\Share20\IShare'); - $share->method('getId')->willReturn(42); - $share->method('getFullId')->willReturn('prov:42'); - $share->method('getShareType')->willReturn($shareType); - $share->method('getSharedWith')->willReturn($sharedWith); - $share->method('getSharedBy')->willReturn($sharedBy); - $share->method('getPath')->willReturn($path); - $share->method('getTarget')->willReturn('myTarget'); + $share = $this->manager->newShare(); + $share->setId(42) + ->setProviderId('prov') + ->setShareType($shareType) + ->setSharedWith($sharedWith) + ->setSharedBy($sharedBy) + ->setNode($path) + ->setTarget('myTarget'); $manager->expects($this->once())->method('getShareById')->with('prov:42')->willReturn($share); $manager->expects($this->once())->method('deleteChildren')->with($share); @@ -261,33 +263,33 @@ class ManagerTest extends \Test\TestCase { $path = $this->getMock('\OCP\Files\File'); $path->method('getId')->willReturn(1); - $share1 = $this->getMock('\OC\Share20\IShare'); - $share1->method('getId')->willReturn(42); - $share1->method('getFullId')->willReturn('prov:42'); - $share1->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_USER); - $share1->method('getSharedWith')->willReturn($sharedWith1); - $share1->method('getSharedBy')->willReturn($sharedBy1); - $share1->method('getPath')->willReturn($path); - $share1->method('getTarget')->willReturn('myTarget1'); - - $share2 = $this->getMock('\OC\Share20\IShare'); - $share2->method('getId')->willReturn(43); - $share2->method('getFullId')->willReturn('prov:43'); - $share2->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_GROUP); - $share2->method('getSharedWith')->willReturn($sharedWith2); - $share2->method('getSharedBy')->willReturn($sharedBy2); - $share2->method('getPath')->willReturn($path); - $share2->method('getTarget')->willReturn('myTarget2'); - $share2->method('getParent')->willReturn(42); - - $share3 = $this->getMock('\OC\Share20\IShare'); - $share3->method('getId')->willReturn(44); - $share3->method('getFullId')->willReturn('prov:44'); - $share3->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_LINK); - $share3->method('getSharedBy')->willReturn($sharedBy3); - $share3->method('getPath')->willReturn($path); - $share3->method('getTarget')->willReturn('myTarget3'); - $share3->method('getParent')->willReturn(43); + $share1 = $this->manager->newShare(); + $share1->setId(42) + ->setProviderId('prov') + ->setShareType(\OCP\Share::SHARE_TYPE_USER) + ->setSharedWith($sharedWith1) + ->setSharedBy($sharedBy1) + ->setNode($path) + ->setTarget('myTarget1'); + + $share2 = $this->manager->newShare(); + $share2->setId(43) + ->setProviderId('prov') + ->setShareType(\OCP\Share::SHARE_TYPE_GROUP) + ->setSharedWith($sharedWith2) + ->setSharedBy($sharedBy2) + ->setNode($path) + ->setTarget('myTarget2') + ->setParent(42); + + $share3 = $this->manager->newShare(); + $share3->setId(44) + ->setProviderId('prov') + ->setShareType(\OCP\Share::SHARE_TYPE_LINK) + ->setSharedBy($sharedBy3) + ->setNode($path) + ->setTarget('myTarget3') + ->setParent(43); $manager->expects($this->once())->method('getShareById')->with('prov:42')->willReturn($share1); @@ -383,14 +385,14 @@ class ManagerTest extends \Test\TestCase { ->setMethods(['deleteShare']) ->getMock(); - $share = $this->getMock('\OC\Share20\IShare'); + $share = $this->getMock('\OCP\Share\IShare'); $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_USER); - $child1 = $this->getMock('\OC\Share20\IShare'); + $child1 = $this->getMock('\OCP\Share\IShare'); $child1->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_USER); - $child2 = $this->getMock('\OC\Share20\IShare'); + $child2 = $this->getMock('\OCP\Share\IShare'); $child2->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_USER); - $child3 = $this->getMock('\OC\Share20\IShare'); + $child3 = $this->getMock('\OCP\Share\IShare'); $child3->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_USER); $shares = [ @@ -419,7 +421,7 @@ class ManagerTest extends \Test\TestCase { } public function testGetShareById() { - $share = $this->getMock('\OC\Share20\IShare'); + $share = $this->getMock('\OCP\Share\IShare'); $this->defaultProvider ->expects($this->once()) @@ -487,13 +489,13 @@ class ManagerTest extends \Test\TestCase { public function createShare($id, $type, $path, $sharedWith, $sharedBy, $shareOwner, $permissions, $expireDate = null, $password = null) { - $share = $this->getMock('\OC\Share20\IShare'); + $share = $this->getMock('\OCP\Share\IShare'); $share->method('getShareType')->willReturn($type); $share->method('getSharedWith')->willReturn($sharedWith); $share->method('getSharedBy')->willReturn($sharedBy); $share->method('getSharedOwner')->willReturn($shareOwner); - $share->method('getPath')->willReturn($path); + $share->method('getNode')->willReturn($path); $share->method('getPermissions')->willReturn($permissions); $share->method('getExpirationDate')->willReturn($expireDate); $share->method('getPassword')->willReturn($password); @@ -728,7 +730,7 @@ class ManagerTest extends \Test\TestCase { $share->setSharedBy($sharedBy)->setSharedWith($sharedWith); $path = $this->getMock('\OCP\Files\Node'); - $share->setPath($path); + $share->setNode($path); $this->groupManager ->method('getUserGroupIds') @@ -758,16 +760,16 @@ class ManagerTest extends \Test\TestCase { * @expectedExceptionMessage Path already shared with this user */ public function testUserCreateChecksIdenticalShareExists() { - $share = new \OC\Share20\Share(); - $share2 = new \OC\Share20\Share(); + $share = $this->manager->newShare(); + $share2 = $this->manager->newShare(); $sharedWith = $this->getMock('\OCP\IUser'); $path = $this->getMock('\OCP\Files\Node'); - $share->setSharedWith($sharedWith)->setPath($path) + $share->setSharedWith($sharedWith)->setNode($path) ->setProviderId('foo')->setId('bar'); - $share2->setSharedWith($sharedWith)->setPath($path) + $share2->setSharedWith($sharedWith)->setNode($path) ->setProviderId('foo')->setId('baz'); $this->defaultProvider @@ -783,14 +785,14 @@ class ManagerTest extends \Test\TestCase { * @expectedExceptionMessage Path already shared with this user */ public function testUserCreateChecksIdenticalPathSharedViaGroup() { - $share = new \OC\Share20\Share(); + $share = $this->manager->newShare(); $sharedWith = $this->getMock('\OCP\IUser'); $owner = $this->getMock('\OCP\IUser'); $path = $this->getMock('\OCP\Files\Node'); $share->setSharedWith($sharedWith) - ->setPath($path) + ->setNode($path) ->setShareOwner($owner) ->setProviderId('foo') ->setId('bar'); @@ -823,7 +825,7 @@ class ManagerTest extends \Test\TestCase { $owner = $this->getMock('\OCP\IUser'); $path = $this->getMock('\OCP\Files\Node'); $share->setSharedWith($sharedWith) - ->setPath($path) + ->setNode($path) ->setShareOwner($owner) ->setProviderId('foo') ->setId('bar'); @@ -882,7 +884,7 @@ class ManagerTest extends \Test\TestCase { $sharedWith->method('inGroup')->with($sharedBy)->willReturn(true); $path = $this->getMock('\OCP\Files\Node'); - $share->setPath($path); + $share->setNode($path); $this->defaultProvider->method('getSharesByPath') ->with($path) @@ -902,12 +904,12 @@ class ManagerTest extends \Test\TestCase { * @expectedExceptionMessage Path already shared with this group */ public function testGroupCreateChecksPathAlreadySharedWithSameGroup() { - $share = new \OC\Share20\Share(); + $share = $this->manager->newShare(); $sharedWith = $this->getMock('\OCP\IGroup'); $path = $this->getMock('\OCP\Files\Node'); $share->setSharedWith($sharedWith) - ->setPath($path) + ->setNode($path) ->setProviderId('foo') ->setId('bar'); @@ -930,7 +932,7 @@ class ManagerTest extends \Test\TestCase { $share->setSharedWith($sharedWith); $path = $this->getMock('\OCP\Files\Node'); - $share->setPath($path); + $share->setNode($path); $share2 = new \OC\Share20\Share(); $sharedWith2 = $this->getMock('\OCP\IGroup'); @@ -1143,7 +1145,7 @@ class ManagerTest extends \Test\TestCase { ->with($user) ->willReturn($groupIds); - $res = $this->manager->isSharingDisabledForUser($user); + $res = $this->manager->sharingDisabledForUser($user); $this->assertEquals($expected, $res); } @@ -1176,13 +1178,13 @@ class ManagerTest extends \Test\TestCase { ])); $manager = $this->createManagerMock() - ->setMethods(['isSharingDisabledForUser']) + ->setMethods(['sharingDisabledForUser']) ->getMock(); - $manager->method('isSharingDisabledForUser')->willReturn($disabledForUser); + $manager->method('sharingDisabledForUser')->willReturn($disabledForUser); $user = $this->getMock('\OCP\IUser'); - $share = new \OC\Share20\Share(); + $share = $this->manager->newShare(); $share->setSharedBy($user); $res = $this->invokePrivate($manager, 'canShare', [$share]); @@ -1332,7 +1334,7 @@ class ManagerTest extends \Test\TestCase { $share = new \OC\Share20\Share(); $share->setShareType(\OCP\Share::SHARE_TYPE_LINK) - ->setPath($path) + ->setNode($path) ->setSharedBy($sharedBy) ->setPermissions(\OCP\Constants::PERMISSION_ALL) ->setExpirationDate($date) @@ -1487,7 +1489,7 @@ class ManagerTest extends \Test\TestCase { } public function testGetShareByToken() { - $factory = $this->getMock('\OC\Share20\IProviderFactory'); + $factory = $this->getMock('\OCP\Share\IProviderFactory'); $manager = new Manager( $this->logger, @@ -1500,7 +1502,7 @@ class ManagerTest extends \Test\TestCase { $factory ); - $share = $this->getMock('\OC\Share20\IShare'); + $share = $this->getMock('\OCP\Share\IShare'); $factory->expects($this->once()) ->method('getProviderForType') @@ -1517,13 +1519,13 @@ class ManagerTest extends \Test\TestCase { } public function testCheckPasswordNoLinkShare() { - $share = $this->getMock('\OC\Share20\IShare'); + $share = $this->getMock('\OCP\Share\IShare'); $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_USER); $this->assertFalse($this->manager->checkPassword($share, 'password')); } public function testCheckPasswordNoPassword() { - $share = $this->getMock('\OC\Share20\IShare'); + $share = $this->getMock('\OCP\Share\IShare'); $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_LINK); $this->assertFalse($this->manager->checkPassword($share, 'password')); @@ -1532,7 +1534,7 @@ class ManagerTest extends \Test\TestCase { } public function testCheckPasswordInvalidPassword() { - $share = $this->getMock('\OC\Share20\IShare'); + $share = $this->getMock('\OCP\Share\IShare'); $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_LINK); $share->method('getPassword')->willReturn('password'); @@ -1542,7 +1544,7 @@ class ManagerTest extends \Test\TestCase { } public function testCheckPasswordValidPassword() { - $share = $this->getMock('\OC\Share20\IShare'); + $share = $this->getMock('\OCP\Share\IShare'); $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_LINK); $share->method('getPassword')->willReturn('passwordHash'); @@ -1774,7 +1776,7 @@ class ManagerTest extends \Test\TestCase { ->setShareOwner($user) ->setPassword('password') ->setExpirationDate($tomorrow) - ->setPath($file); + ->setNode($file); $this->defaultProvider->expects($this->once()) ->method('update') |