diff options
52 files changed, 701 insertions, 157 deletions
diff --git a/3rdparty b/3rdparty -Subproject 89f00bfa2457ba8609f362084a830b7085c186d +Subproject 177daad35de835dafacc6e84f09e6335cc229a7 diff --git a/apps/dav/appinfo/application.php b/apps/dav/appinfo/application.php index 41d064c2d83..2a27dbeb016 100644 --- a/apps/dav/appinfo/application.php +++ b/apps/dav/appinfo/application.php @@ -68,7 +68,8 @@ class Application extends App { $db = $c->getServer()->getDatabaseConnection(); $logger = $c->getServer()->getLogger(); $principal = new \OCA\DAV\Connector\Sabre\Principal( - $c->getServer()->getUserManager() + $c->getServer()->getUserManager(), + $c->getServer()->getGroupManager() ); return new \OCA\DAV\CardDAV\CardDavBackend($db, $principal, $logger); }); diff --git a/apps/dav/appinfo/register_command.php b/apps/dav/appinfo/register_command.php index 3152712b7c0..8ef1979aa08 100644 --- a/apps/dav/appinfo/register_command.php +++ b/apps/dav/appinfo/register_command.php @@ -27,12 +27,13 @@ use OCA\DAV\Command\SyncSystemAddressBook; $config = \OC::$server->getConfig(); $dbConnection = \OC::$server->getDatabaseConnection(); $userManager = OC::$server->getUserManager(); +$groupManager = OC::$server->getGroupManager(); $config = \OC::$server->getConfig(); $logger = \OC::$server->getLogger(); $app = new Application(); /** @var Symfony\Component\Console\Application $application */ -$application->add(new CreateAddressBook($userManager, $dbConnection, $config, $logger)); +$application->add(new CreateAddressBook($userManager, $groupManager, $dbConnection, $logger)); $application->add(new CreateCalendar($userManager, $dbConnection)); $application->add(new SyncSystemAddressBook($app->getSyncService())); diff --git a/apps/dav/command/createaddressbook.php b/apps/dav/command/createaddressbook.php index 0e396074704..201101d17f4 100644 --- a/apps/dav/command/createaddressbook.php +++ b/apps/dav/command/createaddressbook.php @@ -25,6 +25,7 @@ use OCA\DAV\CardDAV\CardDavBackend; use OCA\DAV\Connector\Sabre\Principal; use OCP\IConfig; use OCP\IDBConnection; +use OCP\IGroupManager; use OCP\ILogger; use OCP\IUserManager; use Symfony\Component\Console\Command\Command; @@ -40,12 +41,12 @@ class CreateAddressBook extends Command { /** @var \OCP\IDBConnection */ protected $dbConnection; - /** @var IConfig */ - private $config; - /** @var ILogger */ private $logger; + /** @var IGroupManager $groupManager */ + private $groupManager; + /** * @param IUserManager $userManager * @param IDBConnection $dbConnection @@ -53,14 +54,14 @@ class CreateAddressBook extends Command { * @param ILogger $logger */ function __construct(IUserManager $userManager, + IGroupManager $groupManager, IDBConnection $dbConnection, - IConfig $config, ILogger $logger ) { parent::__construct(); $this->userManager = $userManager; + $this->groupManager = $groupManager; $this->dbConnection = $dbConnection; - $this->config = $config; $this->logger = $logger; } @@ -82,7 +83,8 @@ class CreateAddressBook extends Command { throw new \InvalidArgumentException("User <$user> in unknown."); } $principalBackend = new Principal( - $this->userManager + $this->userManager, + $this->groupManager ); $name = $input->getArgument('name'); diff --git a/apps/dav/command/syncsystemaddressbook.php b/apps/dav/command/syncsystemaddressbook.php index c7401107480..50f570ec93e 100644 --- a/apps/dav/command/syncsystemaddressbook.php +++ b/apps/dav/command/syncsystemaddressbook.php @@ -20,18 +20,8 @@ */ namespace OCA\DAV\Command; -use OCA\DAV\CardDAV\CardDavBackend; -use OCA\DAV\CardDAV\Converter; use OCA\DAV\CardDAV\SyncService; -use OCA\DAV\Connector\Sabre\Principal; -use OCP\IConfig; -use OCP\IDBConnection; -use OCP\IUser; use OCP\IUserManager; -use Sabre\CardDAV\Plugin; -use Sabre\VObject\Component\VCard; -use Sabre\VObject\Property\Text; -use Sabre\VObject\Reader; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\Console\Input\InputArgument; diff --git a/apps/dav/lib/carddav/addressbook.php b/apps/dav/lib/carddav/addressbook.php index 3e3e751828e..2cfaa7b708c 100644 --- a/apps/dav/lib/carddav/addressbook.php +++ b/apps/dav/lib/carddav/addressbook.php @@ -50,7 +50,7 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareableAddres function updateShares(array $add, array $remove) { /** @var CardDavBackend $carddavBackend */ $carddavBackend = $this->carddavBackend; - $carddavBackend->updateShares($this->getName(), $add, $remove); + $carddavBackend->updateShares($this, $add, $remove); } /** @@ -68,7 +68,7 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareableAddres function getShares() { /** @var CardDavBackend $carddavBackend */ $carddavBackend = $this->carddavBackend; - $carddavBackend->getShares($this->getName()); + return $carddavBackend->getShares($this->getBookId()); } function getACL() { @@ -81,7 +81,26 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareableAddres ]; } - return $acl; + // 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']; + $acl[] = [ + 'privilege' => '{DAV:}read', + 'principal' => $owner, + 'protected' => true, + ]; + if ($this->addressBookInfo['{' . \OCA\DAV\CardDAV\Sharing\Plugin::NS_OWNCLOUD . '}read-only']) { + $acl[] = [ + 'privilege' => '{DAV:}write', + 'principal' => $owner, + 'protected' => true, + ]; + } + } + + /** @var CardDavBackend $carddavBackend */ + $carddavBackend = $this->carddavBackend; + return $carddavBackend->applyShareAcl($this->getBookId(), $acl); } function getChildACL() { @@ -94,15 +113,24 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareableAddres ]; } - return $acl; + /** @var CardDavBackend $carddavBackend */ + $carddavBackend = $this->carddavBackend; + return $carddavBackend->applyShareAcl($this->getBookId(), $acl); } function getChild($name) { - $obj = $this->carddavBackend->getCard($this->addressBookInfo['id'], $name); + $obj = $this->carddavBackend->getCard($this->getBookId(), $name); if (!$obj) { throw new NotFound('Card not found'); } return new Card($this->carddavBackend, $this->addressBookInfo, $obj); } + /** + * @return int + */ + public function getBookId() { + return $this->addressBookInfo['id']; + } + } diff --git a/apps/dav/lib/carddav/card.php b/apps/dav/lib/carddav/card.php index 5ec9a7e93a9..d848f2e28ec 100644 --- a/apps/dav/lib/carddav/card.php +++ b/apps/dav/lib/carddav/card.php @@ -33,7 +33,13 @@ class Card extends \Sabre\CardDAV\Card { ]; } - return $acl; + /** @var CardDavBackend $carddavBackend */ + $carddavBackend = $this->carddavBackend; + return $carddavBackend->applyShareAcl($this->getBookId(), $acl); + } + + private function getBookId() { + return $this->addressBookInfo['id']; } } diff --git a/apps/dav/lib/carddav/carddavbackend.php b/apps/dav/lib/carddav/carddavbackend.php index 7deda07497f..7b8c43958b6 100644 --- a/apps/dav/lib/carddav/carddavbackend.php +++ b/apps/dav/lib/carddav/carddavbackend.php @@ -26,7 +26,6 @@ namespace OCA\DAV\CardDAV; use OCA\DAV\Connector\Sabre\Principal; use OCP\IDBConnection; -use OCP\ILogger; use Sabre\CardDAV\Backend\BackendInterface; use Sabre\CardDAV\Backend\SyncSupport; use Sabre\CardDAV\Plugin; @@ -53,6 +52,10 @@ class CardDavBackend implements BackendInterface, SyncSupport { 'BDAY', 'UID', 'N', 'FN', 'TITLE', 'ROLE', 'NOTE', 'NICKNAME', 'ORG', 'CATEGORIES', 'EMAIL', 'TEL', 'IMPP', 'ADR', 'URL', 'GEO', 'CLOUD'); + const ACCESS_OWNER = 1; + const ACCESS_READ_WRITE = 2; + const ACCESS_READ = 3; + /** * CardDavBackend constructor. * @@ -65,7 +68,7 @@ class CardDavBackend implements BackendInterface, SyncSupport { } /** - * Returns the list of addressbooks for a specific user. + * Returns the list of address books for a specific user. * * Every addressbook should have the following properties: * id - an arbitrary unique id @@ -105,28 +108,30 @@ class CardDavBackend implements BackendInterface, SyncSupport { $result->closeCursor(); // query for shared calendars + $principals = $this->principalBackend->getGroupMembership($principalUri); + $principals[]= $principalUri; + $query = $this->db->getQueryBuilder(); - $query2 = $this->db->getQueryBuilder(); - $query2->select(['resourceid']) - ->from('dav_shares') - ->where($query2->expr()->eq('principaluri', $query2->createParameter('principaluri'))) - ->andWhere($query2->expr()->eq('type', $query2->createParameter('type'))); - $result = $query->select(['id', 'uri', 'displayname', 'principaluri', 'description', 'synctoken']) - ->from('addressbooks') - ->where($query->expr()->in('id', $query->createFunction($query2->getSQL()))) + $result = $query->select(['a.id', 'a.uri', 'a.displayname', 'a.principaluri', 'a.description', 'a.synctoken', 's.uri', 's.access']) + ->from('dav_shares', 's') + ->join('s', 'addressbooks', 'a', $query->expr()->eq('s.resourceid', 'a.id')) + ->where($query->expr()->in('s.principaluri', $query->createParameter('principaluri'))) + ->andWhere($query->expr()->eq('s.type', $query->createParameter('type'))) ->setParameter('type', 'addressbook') - ->setParameter('principaluri', $principalUri) + ->setParameter('principaluri', $principals, \Doctrine\DBAL\Connection::PARAM_STR_ARRAY) ->execute(); while($row = $result->fetch()) { $addressBooks[] = [ 'id' => $row['id'], 'uri' => $row['uri'], - 'principaluri' => $row['principaluri'], + 'principaluri' => $principalUri, '{DAV:}displayname' => $row['displayname'], '{' . 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, ]; } $result->closeCursor(); @@ -134,11 +139,43 @@ class CardDavBackend implements BackendInterface, SyncSupport { return $addressBooks; } - public function getAddressBooksByUri($addressBookUri) { + /** + * @param int $addressBookId + */ + public function getAddressBookById($addressBookId) { + $query = $this->db->getQueryBuilder(); + $result = $query->select(['id', 'uri', 'displayname', 'principaluri', 'description', 'synctoken']) + ->from('addressbooks') + ->where($query->expr()->eq('id', $query->createNamedParameter($addressBookId))) + ->execute(); + + $row = $result->fetch(); + $result->closeCursor(); + if ($row === false) { + return null; + } + + return [ + 'id' => $row['id'], + 'uri' => $row['uri'], + 'principaluri' => $row['principaluri'], + '{DAV:}displayname' => $row['displayname'], + '{' . 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', + ]; + } + + /** + * @param $addressBookUri + * @return array|null + */ + public function getAddressBooksByUri($principal, $addressBookUri) { $query = $this->db->getQueryBuilder(); $result = $query->select(['id', 'uri', 'displayname', 'principaluri', 'description', 'synctoken']) ->from('addressbooks') ->where($query->expr()->eq('uri', $query->createNamedParameter($addressBookUri))) + ->andWhere($query->expr()->eq('principaluri', $query->createNamedParameter($principal))) ->setMaxResults(1) ->execute(); @@ -217,6 +254,7 @@ class CardDavBackend implements BackendInterface, SyncSupport { * @param string $principalUri * @param string $url Just the 'basename' of the url. * @param array $properties + * @return int * @throws BadRequest */ function createAddressBook($principalUri, $url, array $properties) { @@ -260,6 +298,8 @@ class CardDavBackend implements BackendInterface, SyncSupport { ]) ->setParameters($values) ->execute(); + + return $query->getLastInsertId(); } /** @@ -663,16 +703,16 @@ class CardDavBackend implements BackendInterface, SyncSupport { } /** - * @param string $path + * @param AddressBook $book * @param string[] $add * @param string[] $remove */ - public function updateShares($path, $add, $remove) { + public function updateShares($book, $add, $remove) { foreach($add as $element) { - $this->shareWith($path, $element); + $this->shareWith($book, $element); } foreach($remove as $element) { - $this->unshare($path, $element); + $this->unshare($book->getBookId(), $element); } } @@ -758,10 +798,10 @@ class CardDavBackend implements BackendInterface, SyncSupport { /** - * @param string $addressBookUri + * @param AddressBook $addressBook * @param string $element */ - private function shareWith($addressBookUri, $element) { + private function shareWith($addressBook, $element) { $user = $element['href']; $parts = explode(':', $user, 2); if ($parts[0] !== 'principal') { @@ -772,31 +812,31 @@ class CardDavBackend implements BackendInterface, SyncSupport { return; } - $addressBook = $this->getAddressBooksByUri($addressBookUri); - if (is_null($addressBook)) { - return; - } - // remove the share if it already exists - $this->unshare($addressBookUri, $element['href']); + $this->unshare($addressBook->getBookId(), $element['href']); + $access = self::ACCESS_READ; + if (isset($element['readOnly'])) { + $access = $element['readOnly'] ? self::ACCESS_READ : self::ACCESS_READ_WRITE; + } + $newUri = sha1($addressBook->getName() . $addressBook->getOwner()); $query = $this->db->getQueryBuilder(); $query->insert('dav_shares') ->values([ 'principaluri' => $query->createNamedParameter($parts[1]), - 'uri' => $query->createNamedParameter($addressBookUri), + 'uri' => $query->createNamedParameter($newUri), 'type' => $query->createNamedParameter('addressbook'), - 'access' => $query->createNamedParameter(0), - 'resourceid' => $query->createNamedParameter($addressBook['id']) + 'access' => $query->createNamedParameter($access), + 'resourceid' => $query->createNamedParameter($addressBook->getBookId()) ]); $query->execute(); } /** - * @param string $addressBookUri + * @param int $addressBookId * @param string $element */ - private function unshare($addressBookUri, $element) { + private function unshare($addressBookId, $element) { $parts = explode(':', $element, 2); if ($parts[0] !== 'principal') { return; @@ -806,14 +846,9 @@ class CardDavBackend implements BackendInterface, SyncSupport { return; } - $addressBook = $this->getAddressBooksByUri($addressBookUri); - if (is_null($addressBook)) { - return; - } - $query = $this->db->getQueryBuilder(); $query->delete('dav_shares') - ->where($query->expr()->eq('resourceid', $query->createNamedParameter($addressBook['id']))) + ->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]))) ; @@ -832,11 +867,11 @@ class CardDavBackend implements BackendInterface, SyncSupport { * * @return array */ - public function getShares($addressBookUri) { + public function getShares($addressBookId) { $query = $this->db->getQueryBuilder(); $result = $query->select(['principaluri', 'access']) ->from('dav_shares') - ->where($query->expr()->eq('uri', $query->createNamedParameter($addressBookUri))) + ->where($query->expr()->eq('resourceid', $query->createNamedParameter($addressBookId))) ->andWhere($query->expr()->eq('type', $query->createNamedParameter('addressbook'))) ->execute(); @@ -847,7 +882,8 @@ class CardDavBackend implements BackendInterface, SyncSupport { 'href' => "principal:${p['uri']}", 'commonName' => isset($p['{DAV:}displayname']) ? $p['{DAV:}displayname'] : '', 'status' => 1, - 'readOnly' => ($row['access'] === 1) + 'readOnly' => ($row['access'] === self::ACCESS_READ), + '{'.\OCA\DAV\CardDAV\Sharing\Plugin::NS_OWNCLOUD.'}principal' => $p['uri'] ]; } @@ -942,4 +978,30 @@ class CardDavBackend implements BackendInterface, SyncSupport { return (int)$cardIds['id']; } + + /** + * For shared address books the sharee is set in the ACL of the address book + * @param $addressBookId + * @param $acl + * @return array + */ + public function applyShareAcl($addressBookId, $acl) { + + $shares = $this->getShares($addressBookId); + foreach ($shares as $share) { + $acl[] = [ + 'privilege' => '{DAV:}read', + 'principal' => $share['{' . \OCA\DAV\CardDAV\Sharing\Plugin::NS_OWNCLOUD . '}principal'], + 'protected' => true, + ]; + if (!$share['readOnly']) { + $acl[] = [ + 'privilege' => '{DAV:}write', + 'principal' => $share['{' . \OCA\DAV\CardDAV\Sharing\Plugin::NS_OWNCLOUD . '}principal'], + 'protected' => true, + ]; + } + } + return $acl; + } } diff --git a/apps/dav/lib/carddav/sharing/plugin.php b/apps/dav/lib/carddav/sharing/plugin.php index 7ad3f43dca8..d25b84d01f3 100644 --- a/apps/dav/lib/carddav/sharing/plugin.php +++ b/apps/dav/lib/carddav/sharing/plugin.php @@ -34,6 +34,8 @@ use Sabre\HTTP\ResponseInterface; class Plugin extends ServerPlugin { + const NS_OWNCLOUD = 'http://owncloud.org/ns'; + /** @var Auth */ private $auth; @@ -100,7 +102,7 @@ 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['{' . \Sabre\CardDAV\Plugin::NS_CARDDAV . '}share'] = 'OCA\\DAV\\CardDAV\\Sharing\\Xml\\ShareRequest'; + $this->server->xml->elementMap['{' . Plugin::NS_OWNCLOUD . '}share'] = 'OCA\\DAV\\CardDAV\\Sharing\\Xml\\ShareRequest'; $this->server->on('method:POST', [$this, 'httpPost']); } @@ -148,7 +150,7 @@ class Plugin extends ServerPlugin { // Dealing with the 'share' document, which modified invitees on a // calendar. - case '{' . \Sabre\CardDAV\Plugin::NS_CARDDAV . '}share' : + case '{' . self::NS_OWNCLOUD . '}share' : // We can only deal with IShareableCalendar objects if (!$node instanceof IShareableAddressBook) { diff --git a/apps/dav/lib/carddav/sharing/xml/sharerequest.php b/apps/dav/lib/carddav/sharing/xml/sharerequest.php index 6be6bd795a1..bd55dd4073e 100644 --- a/apps/dav/lib/carddav/sharing/xml/sharerequest.php +++ b/apps/dav/lib/carddav/sharing/xml/sharerequest.php @@ -20,6 +20,7 @@ */ namespace OCA\DAV\CardDAV\Sharing\Xml; +use OCA\DAV\CardDAV\Sharing\Plugin; use Sabre\Xml\Reader; use Sabre\Xml\XmlDeserializable; @@ -44,32 +45,32 @@ class ShareRequest implements XmlDeserializable { static function xmlDeserialize(Reader $reader) { - $elems = $reader->parseInnerTree([ - '{' . \Sabre\CardDAV\Plugin::NS_CARDDAV. '}set' => 'Sabre\\Xml\\Element\\KeyValue', - '{' . \Sabre\CardDAV\Plugin::NS_CARDDAV . '}remove' => 'Sabre\\Xml\\Element\\KeyValue', + $elements = $reader->parseInnerTree([ + '{' . Plugin::NS_OWNCLOUD. '}set' => 'Sabre\\Xml\\Element\\KeyValue', + '{' . Plugin::NS_OWNCLOUD . '}remove' => 'Sabre\\Xml\\Element\\KeyValue', ]); $set = []; $remove = []; - foreach ($elems as $elem) { + foreach ($elements as $elem) { switch ($elem['name']) { - case '{' . \Sabre\CardDAV\Plugin::NS_CARDDAV . '}set' : + case '{' . Plugin::NS_OWNCLOUD . '}set' : $sharee = $elem['value']; - $sumElem = '{' . \Sabre\CardDAV\Plugin::NS_CARDDAV . '}summary'; - $commonName = '{' . \Sabre\CardDAV\Plugin::NS_CARDDAV . '}common-name'; + $sumElem = '{' . Plugin::NS_OWNCLOUD . '}summary'; + $commonName = '{' . Plugin::NS_OWNCLOUD . '}common-name'; $set[] = [ 'href' => $sharee['{DAV:}href'], 'commonName' => isset($sharee[$commonName]) ? $sharee[$commonName] : null, 'summary' => isset($sharee[$sumElem]) ? $sharee[$sumElem] : null, - 'readOnly' => !array_key_exists('{' . \Sabre\CardDAV\Plugin::NS_CARDDAV . '}read-write', $sharee), + 'readOnly' => !array_key_exists('{' . Plugin::NS_OWNCLOUD . '}read-write', $sharee), ]; break; - case '{' . \Sabre\CardDAV\Plugin::NS_CARDDAV . '}remove' : + case '{' . Plugin::NS_OWNCLOUD . '}remove' : $remove[] = $elem['value']['{DAV:}href']; break; diff --git a/apps/dav/lib/carddav/syncservice.php b/apps/dav/lib/carddav/syncservice.php index 6412a01b428..4b5907620e6 100644 --- a/apps/dav/lib/carddav/syncservice.php +++ b/apps/dav/lib/carddav/syncservice.php @@ -90,13 +90,13 @@ class SyncService { * @throws \Sabre\DAV\Exception\BadRequest */ public function ensureSystemAddressBookExists($principal, $id, $properties) { - $book = $this->backend->getAddressBooksByUri($id); + $book = $this->backend->getAddressBooksByUri($principal, $id); if (!is_null($book)) { return $book; } $this->backend->createAddressBook($principal, $id, $properties); - return $this->backend->getAddressBooksByUri($id); + return $this->backend->getAddressBooksByUri($principal, $id); } /** diff --git a/apps/dav/lib/connector/sabre/principal.php b/apps/dav/lib/connector/sabre/principal.php index ece799c7019..5f02d1271df 100644 --- a/apps/dav/lib/connector/sabre/principal.php +++ b/apps/dav/lib/connector/sabre/principal.php @@ -29,9 +29,10 @@ namespace OCA\DAV\Connector\Sabre; +use OCP\IGroup; +use OCP\IGroupManager; use OCP\IUser; use OCP\IUserManager; -use OCP\IConfig; use Sabre\DAV\Exception; use \Sabre\DAV\PropPatch; use Sabre\DAVACL\PrincipalBackend\BackendInterface; @@ -42,11 +43,15 @@ class Principal implements BackendInterface { /** @var IUserManager */ private $userManager; + /** @var IGroupManager */ + private $groupManager; + /** * @param IUserManager $userManager */ - public function __construct(IUserManager $userManager) { + public function __construct(IUserManager $userManager, IGroupManager $groupManager) { $this->userManager = $userManager; + $this->groupManager = $groupManager; } /** @@ -127,24 +132,23 @@ class Principal implements BackendInterface { public function getGroupMembership($principal) { list($prefix, $name) = URLUtil::splitPath($principal); - $group_membership = array(); if ($prefix === 'principals/users') { - $principal = $this->getPrincipalByPath($principal); - if (!$principal) { + $user = $this->userManager->get($name); + if (!$user) { throw new Exception('Principal not found'); } - // TODO: for now the user principal has only its own groups - return array( - 'principals/users/'.$name.'/calendar-proxy-read', - 'principals/users/'.$name.'/calendar-proxy-write', - // The addressbook groups are not supported in Sabre, - // see http://groups.google.com/group/sabredav-discuss/browse_thread/thread/ef2fa9759d55f8c#msg_5720afc11602e753 - //'principals/'.$name.'/addressbook-proxy-read', - //'principals/'.$name.'/addressbook-proxy-write', - ); + $groups = $this->groupManager->getUserGroups($user); + $groups = array_map(function($group) { + /** @var IGroup $group */ + return 'principals/groups/' . $group->getGID(); + }, $groups); + + $groups[]= 'principals/users/'.$name.'/calendar-proxy-read'; + $groups[]= 'principals/users/'.$name.'/calendar-proxy-write'; + return $groups; } - return $group_membership; + return []; } /** @@ -207,4 +211,5 @@ class Principal implements BackendInterface { } return $principal; } + } diff --git a/apps/dav/lib/rootcollection.php b/apps/dav/lib/rootcollection.php index 8e0e0c6b86f..0afde97a9e7 100644 --- a/apps/dav/lib/rootcollection.php +++ b/apps/dav/lib/rootcollection.php @@ -37,7 +37,8 @@ class RootCollection extends SimpleCollection { $config = \OC::$server->getConfig(); $db = \OC::$server->getDatabaseConnection(); $userPrincipalBackend = new Principal( - \OC::$server->getUserManager() + \OC::$server->getUserManager(), + \OC::$server->getGroupManager() ); $groupPrincipalBackend = new GroupPrincipalBackend( \OC::$server->getGroupManager() diff --git a/apps/dav/tests/travis/caldav/script.sh b/apps/dav/tests/travis/caldav/script.sh index 9a818b553f7..a295c83ad94 100644 --- a/apps/dav/tests/travis/caldav/script.sh +++ b/apps/dav/tests/travis/caldav/script.sh @@ -9,7 +9,7 @@ sleep 30 # run the tests cd "$SCRIPTPATH/CalDAVTester" -PYTHONPATH="$SCRIPTPATH/pycalendar/src" python testcaldav.py --print-details-onfail -s "$SCRIPTPATH/../caldavtest/config/serverinfo.xml" -o cdt.txt \ +PYTHONPATH="$SCRIPTPATH/pycalendar/src" python testcaldav.py --print-details-onfail -s "$SCRIPTPATH/../caldavtest/serverinfo.xml" -o cdt.txt \ "$SCRIPTPATH/../caldavtest/tests/CalDAV/current-user-principal.xml" RESULT=$? diff --git a/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/sharing/read-write/1.xml b/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/sharing/read-write/1.xml new file mode 100644 index 00000000000..20d2ebf4cfc --- /dev/null +++ b/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/sharing/read-write/1.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" ?> +<CS:share xmlns:D="DAV:" xmlns:CS="http://owncloud.org/ns"> + <CS:set> + <D:href>principal:principals/users/user02</D:href> + <CS:summary>My Shared Calendar</CS:summary> + <CS:read-write/> + </CS:set> +</CS:share> diff --git a/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/sharing/read-write/4.xml b/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/sharing/read-write/4.xml new file mode 100644 index 00000000000..fd0f248bb31 --- /dev/null +++ b/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/sharing/read-write/4.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" ?> +<D:propfind xmlns:D="DAV:"> +<D:prop> +<D:resourcetype/> +<D:owner/> +<D:current-user-privilege-set/> +</D:prop> +</D:propfind> diff --git a/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/sharing/read-write/6.vcf b/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/sharing/read-write/6.vcf new file mode 100644 index 00000000000..6b53f8ba3bf --- /dev/null +++ b/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/sharing/read-write/6.vcf @@ -0,0 +1,11 @@ +BEGIN:VCARD +VERSION:3.0 +N:Thompson;Default;;; +FN:Default Thompson +EMAIL;TYPE=INTERNET,WORK,pref:lthompson@example.com +TEL;TYPE=WORK,pref:1-555-555-5555 +TEL;TYPE=CELL:1-555-555-5555 +ITEM1.ADR;TYPE=WORK,pref:;;2 Lag;Elk Forest;California;99999;USA +ITEM1.X-ABADR:us +UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson +END:VCARD diff --git a/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/sharing/read-write/7.vcf b/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/sharing/read-write/7.vcf new file mode 100644 index 00000000000..27fdb9fae5f --- /dev/null +++ b/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/sharing/read-write/7.vcf @@ -0,0 +1,11 @@ +BEGIN:VCARD +VERSION:3.0 +N:Thompson;Default;;; +FN:Default Thompson +EMAIL;TYPE=INTERNET,WORK,pref:lthompson@example.net +TEL;TYPE=WORK,pref:1-555-555-5555 +TEL;TYPE=CELL:1-555-555-6666 +ITEM1.ADR;TYPE=WORK,pref:;;2 Lag;Elk Forest;California;99999;USA +ITEM1.X-ABADR:us +UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson +END:VCARD diff --git a/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/sharing/read-write/8.vcf b/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/sharing/read-write/8.vcf new file mode 100644 index 00000000000..9188fdd913c --- /dev/null +++ b/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/sharing/read-write/8.vcf @@ -0,0 +1,11 @@ +BEGIN:VCARD +VERSION:3.0 +N:Miller;Default;;; +FN:Default Miller +EMAIL;TYPE=INTERNET,WORK,pref:lthompson@example.com +TEL;TYPE=WORK,pref:1-555-555-5555 +TEL;TYPE=CELL:1-555-555-5555 +ITEM1.ADR;TYPE=WORK,pref:;;2 Lag;Elk Forest;California;99999;USA +ITEM1.X-ABADR:us +UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson +END:VCARD diff --git a/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/sharing/read-write/9.vcf b/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/sharing/read-write/9.vcf new file mode 100644 index 00000000000..1ca0a36ca4c --- /dev/null +++ b/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/sharing/read-write/9.vcf @@ -0,0 +1,11 @@ +BEGIN:VCARD +VERSION:3.0 +N:Smith;Default;;; +FN:Default Smith +EMAIL;TYPE=INTERNET,WORK,pref:lthompson@example.com +TEL;TYPE=WORK,pref:1-555-555-5555 +TEL;TYPE=CELL:1-555-555-5555 +ITEM1.ADR;TYPE=WORK,pref:;;2 Lag;Elk Forest;California;99999;USA +ITEM1.X-ABADR:us +UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson +END:VCARD diff --git a/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/vcurrent-user-principal/1.xml b/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/vcurrent-user-principal/1.xml new file mode 100644 index 00000000000..dffedc6880d --- /dev/null +++ b/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/vcurrent-user-principal/1.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" ?> +<D:propfind xmlns:D="DAV:"> +<D:prop> +<D:current-user-principal/> +</D:prop> +</D:propfind> diff --git a/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/vreports/put/1.vcf b/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/vreports/put/1.vcf new file mode 100644 index 00000000000..2121c65f1f4 --- /dev/null +++ b/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/vreports/put/1.vcf @@ -0,0 +1,11 @@ +BEGIN:VCARD +VERSION:3.0 +N:Thompson;Default;;; +FN:Default Thompson +EMAIL;type=INTERNET;type=WORK;type=pref:lthompson@example.com +TEL;type=WORK;type=pref:1-555-555-5555 +TEL;type=CELL:1-555-555-5555 +item1.ADR;type=WORK;type=pref:;;2 Lag;Elk Forest;California;99999;USA +item1.X-ABADR:us +UID:ED7A5AEC-AB19-4CE0-AD6A-2923A3E5C4E1:ABPerson +END:VCARD diff --git a/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/vreports/put/2.vcf b/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/vreports/put/2.vcf new file mode 100644 index 00000000000..390a3d8ae69 --- /dev/null +++ b/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/vreports/put/2.vcf @@ -0,0 +1,17 @@ +BEGIN:VCARD +VERSION:3.0 +N:Contact;Mulberry;;; +FN:Mulberry Contact +NICKNAME:mulberry +ORG:Apple Inc.; +EMAIL;type=INTERNET;type=WORK;type=pref:mulberry_contact@example.com +TEL;type=HOME;type=pref:555-555-5555 +TEL;type=WORK:555-555-5555 +TEL;type=WORK;type=FAX:555-555-5555 +item1.ADR;type=WORK;type=pref:;;1 Infinite Circle;Exampletino\, CA 99999;USA;; +item1.X-ABADR:us +NOTE:This is a contact created in Mulberry. +item2.URL;type=pref:http://www.example.com/~magic +item2.X-ABLabel:_$!<HomePage>!$_ +UID:782DAAF92CB1ED1BC155CDB3@D76FAF7B10D9E8D2D41F779D +END:VCARD diff --git a/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/vreports/put/3.vcf b/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/vreports/put/3.vcf new file mode 100644 index 00000000000..37c3b81bdcf --- /dev/null +++ b/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/vreports/put/3.vcf @@ -0,0 +1,12 @@ +BEGIN:VCARD +VERSION:3.0 +N:Kawado;Saeko;;; +FN:Snow Leopard +ORG:Snow Leopard; +EMAIL;type=INTERNET;type=WORK;type=pref:snowleopard_apple@example.com +TEL;type=WORK;type=pref:555-555-5555 +item1.ADR;type=WORK;type=pref:;;2 Fidel Ave. Suite 1;Mountain Top;CA;99999;USA +item1.X-ABADR:us +X-ABShowAs:COMPANY +UID:FCBA0FA3-00B2-4C95-B4EC-4CCC4843F8B1:ABPerson +END:VCARD diff --git a/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/vreports/sync/1.xml b/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/vreports/sync/1.xml new file mode 100644 index 00000000000..7f454b38900 --- /dev/null +++ b/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/vreports/sync/1.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8" ?> +<D:propfind xmlns:D="DAV:"> +<D:prop> +<D:supported-report-set/> +<D:sync-token/> +</D:prop> +</D:propfind> diff --git a/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/vreports/sync/2.xml b/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/vreports/sync/2.xml new file mode 100644 index 00000000000..99ee3dbb0e0 --- /dev/null +++ b/apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/vreports/sync/2.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8" ?> +<D:sync-collection xmlns:D="DAV:"> +<D:sync-token/> +<D:prop/> +</D:sync-collection> diff --git a/apps/dav/tests/travis/caldavtest/config/serverinfo.dtd b/apps/dav/tests/travis/caldavtest/serverinfo.dtd index d642f4f90cd..d642f4f90cd 100644 --- a/apps/dav/tests/travis/caldavtest/config/serverinfo.dtd +++ b/apps/dav/tests/travis/caldavtest/serverinfo.dtd diff --git a/apps/dav/tests/travis/caldavtest/config/serverinfo.xml b/apps/dav/tests/travis/caldavtest/serverinfo.xml index c80e47f9481..dea8f5af0f3 100644 --- a/apps/dav/tests/travis/caldavtest/config/serverinfo.xml +++ b/apps/dav/tests/travis/caldavtest/serverinfo.xml @@ -1,7 +1,7 @@ <?xml version="1.0" standalone="no"?> <!DOCTYPE serverinfo SYSTEM - "/home/deepdiver/Development/ownCloud/master/apps/dav/tests/travis/caldavtest/config/serverinfo.dtd"> + "/home/deepdiver/Development/ownCloud/master/apps/dav/tests/travis/caldavtest/serverinfo.dtd"> <!-- Copyright (c) 2006-2015 Apple Inc. All rights reserved. diff --git a/apps/dav/tests/travis/caldavtest/tests/CardDAV/sharing-addressbooks.xml b/apps/dav/tests/travis/caldavtest/tests/CardDAV/sharing-addressbooks.xml new file mode 100644 index 00000000000..046c3d59dbd --- /dev/null +++ b/apps/dav/tests/travis/caldavtest/tests/CardDAV/sharing-addressbooks.xml @@ -0,0 +1,246 @@ +<?xml version="1.0" standalone="no"?> + +<!DOCTYPE caldavtest SYSTEM "caldavtest.dtd"> + +<caldavtest> + <description>Test addressbook sharing</description> + + <require-feature> + <feature>carddav</feature> + </require-feature> + + <start> + </start> + + <test-suite name='Read-write addressbook'> + <test name='1'> + <description>POST invitation</description> + <request> + <method>POST</method> + <ruri>$addressbookpath1:</ruri> + <data> + <content-type>text/xml; charset=utf-8</content-type> + <filepath>Resource/CardDAV/sharing/read-write/1.xml</filepath> + </data> + <verify> + <callback>statusCode</callback> + </verify> + </request> + </test> + <test name='4'> + <description>Shared addressbook exists</description> + <request user="$userid2:" pswd="$pswd2:"> + <method>PROPFIND</method> + <ruri>$addressbookpath1:/</ruri> + <header> + <name>Depth</name> + <value>0</value> + </header> + <data> + <content-type>text/xml; charset=utf-8</content-type> + <filepath>Resource/CardDAV/sharing/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:carddav}addressbook</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> + </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>$addressbookhome2:/</ruri> + <header> + <name>Depth</name> + <value>1</value> + </header> + <data> + <content-type>text/xml; charset=utf-8</content-type> + <filepath>Resource/CardDAV/sharing/read-write/4.xml</filepath> + </data> + <verify> + <callback>xmlElementMatch</callback> + <arg> + <name>parent</name> + <value>$multistatus-response-prefix:[^{DAV:}href=$addressbookhome2:/ade1a55d408167e8ff77611c0eebe8f80579b549/]</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:carddav}addressbook</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> + </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='5'> + <description>Original calendar unchanged</description> + <request> + <method>PROPFIND</method> + <ruri>$addressbookpath1:</ruri> + <header> + <name>Depth</name> + <value>0</value> + </header> + <data> + <content-type>text/xml; charset=utf-8</content-type> + <filepath>Resource/CardDAV/sharing/read-write/4.xml</filepath> + </data> + <verify> + <callback>xmlElementMatch</callback> + <arg> + <name>exists</name> + <value>$verify-property-prefix:/{DAV:}owner/{DAV:}href[=$principaluri1:]</value> + </arg> + </verify> + </request> + </test> + + <test name='6'> + <description>Sharee creates contact</description> + <request user="$userid2:" pswd="$pswd2:"> + <method>PUT</method> + <ruri>$addressbookpath1:/1.vcf</ruri> + <data> + <content-type>text/vcard; charset=utf-8</content-type> + <filepath>Resource/CardDAV/sharing/read-write/6.vcf</filepath> + </data> + <verify> + <callback>statusCode</callback> + </verify> + </request> + </test> + + <test name='7'> + <description>Sharer sees contact</description> + <request> + <method>GET</method> + <ruri>$addressbookpath1:/1.vcf</ruri> + <verify> + <callback>addressDataMatch</callback> + <arg> + <name>filepath</name> + <value>Resource/CardDAV/sharing/read-write/6.vcf</value> + </arg> + </verify> + </request> + </test> + + <test name='8'> + <description>Sharer changes contact</description> + <request> + <method>PUT</method> + <ruri>$addressbookpath1:/1.vcf</ruri> + <data> + <content-type>text/vcard; charset=utf-8</content-type> + <filepath>Resource/CardDAV/sharing/read-write/7.vcf</filepath> + </data> + <verify> + <callback>statusCode</callback> + </verify> + </request> + </test> + + <test name='9'> + <description>Sharee sees changed contact</description> + <request user="$userid2:" pswd="$pswd2:"> + <method>GET</method> + <ruri>$addressbookpath1:/1.vcf</ruri> + <verify> + <callback>addressDataMatch</callback> + <arg> + <name>filepath</name> + <value>Resource/CardDAV/sharing/read-write/7.vcf</value> + </arg> + </verify> + </request> + </test> + + <test name='10'> + <description>Sharer creates event</description> + <request> + <method>PUT</method> + <ruri>$addressbookpath1:/2.vcf</ruri> + <data> + <content-type>text/vcard; charset=utf-8</content-type> + <filepath>Resource/CardDAV/sharing/read-write/8.vcf</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>$addressbookpath1:/2.vcf</ruri> + <verify> + <callback>addressDataMatch</callback> + <arg> + <name>filepath</name> + <value>Resource/CardDAV/sharing/read-write/8.vcf</value> + </arg> + </verify> + </request> + </test> + <test name='12'> + <description>Sharee changes event</description> + <request user="$userid2:" pswd="$pswd2:"> + <method>PUT</method> + <ruri>$addressbookpath1:/2.vcf</ruri> + <data> + <content-type>text/vcard; charset=utf-8</content-type> + <filepath>Resource/CardDAV/sharing/read-write/9.vcf</filepath> + </data> + <verify> + <callback>statusCode</callback> + </verify> + </request> + </test> + <test name='13'> + <description>Sharer sees changed event</description> + <request> + <method>GET</method> + <ruri>$addressbookpath1:/2.vcf</ruri> + <verify> + <callback>addressDataMatch</callback> + <arg> + <name>filepath</name> + <value>Resource/CardDAV/sharing/read-write/9.vcf</value> + </arg> + </verify> + </request> + </test> + </test-suite> + + <end> + </end> + +</caldavtest> diff --git a/apps/dav/tests/travis/carddav/script.sh b/apps/dav/tests/travis/carddav/script.sh index 46a6a98e273..a8bd9f11b38 100644 --- a/apps/dav/tests/travis/carddav/script.sh +++ b/apps/dav/tests/travis/carddav/script.sh @@ -9,9 +9,12 @@ sleep 30 # run the tests cd "$SCRIPTPATH/CalDAVTester" -PYTHONPATH="$SCRIPTPATH/pycalendar/src" python testcaldav.py --print-details-onfail -s "$SCRIPTPATH/../caldavtest/config/serverinfo.xml" -o cdt.txt \ - "$SCRIPTPATH/../caldavtest/tests/CardDAV/current-user-principal.xml" \ - "$SCRIPTPATH/../caldavtest/tests/CardDAV/sync-report.xml" +PYTHONPATH="$SCRIPTPATH/pycalendar/src" python testcaldav.py --print-details-onfail --basedir "$SCRIPTPATH/../caldavtest/" -o cdt.txt \ + "CardDAV/current-user-principal.xml" \ + "CardDAV/sync-report.xml" \ + "CardDAV/sharing-addressbooks.xml" + + RESULT=$? tail "$/../../../../../data-autotest/owncloud.log" diff --git a/apps/dav/tests/unit/carddav/carddavbackendtest.php b/apps/dav/tests/unit/carddav/carddavbackendtest.php index 3841d1904ab..3291314ec40 100644 --- a/apps/dav/tests/unit/carddav/carddavbackendtest.php +++ b/apps/dav/tests/unit/carddav/carddavbackendtest.php @@ -23,6 +23,7 @@ namespace OCA\DAV\Tests\Unit\CardDAV; use InvalidArgumentException; +use OCA\DAV\CardDAV\AddressBook; use OCA\DAV\CardDAV\CardDavBackend; use OCA\DAV\Connector\Sabre\Principal; use OCP\IDBConnection; @@ -247,23 +248,24 @@ class CardDavBackendTest extends TestCase { $books = $this->backend->getAddressBooksForUser(self::UNIT_TEST_USER); $this->assertEquals(1, count($books)); - $this->backend->updateShares('Example', [['href' => 'principal:principals/best-friend']], []); + $exampleBook = new AddressBook($this->backend, $books[0]); + $this->backend->updateShares($exampleBook, [['href' => 'principal:principals/best-friend']], []); - $shares = $this->backend->getShares('Example'); + $shares = $this->backend->getShares($exampleBook->getBookId()); $this->assertEquals(1, count($shares)); // adding the same sharee again has no effect - $this->backend->updateShares('Example', [['href' => 'principal:principals/best-friend']], []); + $this->backend->updateShares($exampleBook, [['href' => 'principal:principals/best-friend']], []); - $shares = $this->backend->getShares('Example'); + $shares = $this->backend->getShares($exampleBook->getBookId()); $this->assertEquals(1, count($shares)); $books = $this->backend->getAddressBooksForUser('principals/best-friend'); $this->assertEquals(1, count($books)); - $this->backend->updateShares('Example', [], ['principal:principals/best-friend']); + $this->backend->updateShares($exampleBook, [], ['principal:principals/best-friend']); - $shares = $this->backend->getShares('Example'); + $shares = $this->backend->getShares($exampleBook->getBookId()); $this->assertEquals(0, count($shares)); $books = $this->backend->getAddressBooksForUser('principals/best-friend'); diff --git a/apps/dav/tests/unit/carddav/sharing/plugintest.php b/apps/dav/tests/unit/carddav/sharing/plugintest.php index 3dce0fb6083..19ee075fb4f 100644 --- a/apps/dav/tests/unit/carddav/sharing/plugintest.php +++ b/apps/dav/tests/unit/carddav/sharing/plugintest.php @@ -74,7 +74,7 @@ class PluginTest extends TestCase { $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="urn:ietf:params:xml:ns:carddav"><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>'); + $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/connector/sabre/principal.php b/apps/dav/tests/unit/connector/sabre/principal.php index e0b459495b6..d6bc7cd405f 100644 --- a/apps/dav/tests/unit/connector/sabre/principal.php +++ b/apps/dav/tests/unit/connector/sabre/principal.php @@ -23,21 +23,28 @@ namespace OCA\DAV\Tests\Unit\Connector\Sabre; +use OCP\IGroupManager; use \Sabre\DAV\PropPatch; use OCP\IUserManager; -use OCP\IConfig; +use Test\TestCase; -class Principal extends \Test\TestCase { - /** @var IUserManager */ +class Principal extends TestCase { + /** @var IUserManager | \PHPUnit_Framework_MockObject_MockObject */ private $userManager; /** @var \OCA\DAV\Connector\Sabre\Principal */ private $connector; + /** @var IGroupManager | \PHPUnit_Framework_MockObject_MockObject */ + private $groupManager; public function setUp() { $this->userManager = $this->getMockBuilder('\OCP\IUserManager') ->disableOriginalConstructor()->getMock(); + $this->groupManager = $this->getMockBuilder('\OCP\IGroupManager') + ->disableOriginalConstructor()->getMock(); - $this->connector = new \OCA\DAV\Connector\Sabre\Principal($this->userManager); + $this->connector = new \OCA\DAV\Connector\Sabre\Principal( + $this->userManager, + $this->groupManager); parent::setUp(); } @@ -195,15 +202,14 @@ class Principal extends \Test\TestCase { public function testGetGroupMembership() { $fooUser = $this->getMockBuilder('\OC\User\User') ->disableOriginalConstructor()->getMock(); - $fooUser - ->expects($this->exactly(1)) - ->method('getUID') - ->will($this->returnValue('foo')); $this->userManager ->expects($this->once()) ->method('get') ->with('foo') - ->will($this->returnValue($fooUser)); + ->willReturn($fooUser); + $this->groupManager + ->method('getUserGroups') + ->willReturn([]); $expectedResponse = [ 'principals/users/foo/calendar-proxy-read', diff --git a/apps/files/tests/js/fileUploadSpec.js b/apps/files/tests/js/fileUploadSpec.js index 8a0d6b01952..0483d4649d4 100644 --- a/apps/files/tests/js/fileUploadSpec.js +++ b/apps/files/tests/js/fileUploadSpec.js @@ -102,7 +102,7 @@ describe('OC.Upload tests', function() { expect(failStub.calledOnce).toEqual(true); expect(failStub.getCall(0).args[1].textStatus).toEqual('sizeexceedlimit'); expect(failStub.getCall(0).args[1].errorThrown).toEqual( - 'Total file size 5 kB exceeds upload limit 1000 B' + 'Total file size 5 KB exceeds upload limit 1000 B' ); }); it('does not add file if it exceeds free space', function() { @@ -115,7 +115,7 @@ describe('OC.Upload tests', function() { expect(failStub.calledOnce).toEqual(true); expect(failStub.getCall(0).args[1].textStatus).toEqual('notenoughspace'); expect(failStub.getCall(0).args[1].errorThrown).toEqual( - 'Not enough free space, you are uploading 5 kB but only 1000 B is left' + 'Not enough free space, you are uploading 5 KB but only 1000 B is left' ); }); }); diff --git a/apps/files/tests/js/filelistSpec.js b/apps/files/tests/js/filelistSpec.js index e6046f2197e..9cd6bc90e88 100644 --- a/apps/files/tests/js/filelistSpec.js +++ b/apps/files/tests/js/filelistSpec.js @@ -213,7 +213,7 @@ describe('OCA.Files.FileList tests', function() { .toEqual(OC.webroot + '/remote.php/webdav/subdir/testName.txt'); expect($tr.find('.nametext').text().trim()).toEqual('testName.txt'); - expect($tr.find('.filesize').text()).toEqual('1 kB'); + expect($tr.find('.filesize').text()).toEqual('1 KB'); expect($tr.find('.date').text()).not.toEqual('?'); expect(fileList.findFileEl('testName.txt')[0]).toEqual($tr[0]); }); @@ -239,7 +239,7 @@ describe('OCA.Files.FileList tests', function() { expect($tr.attr('data-mime')).toEqual('httpd/unix-directory'); expect($tr.attr('data-mtime')).toEqual('123456'); - expect($tr.find('.filesize').text()).toEqual('1 kB'); + expect($tr.find('.filesize').text()).toEqual('1 KB'); expect($tr.find('.date').text()).not.toEqual('?'); expect(fileList.findFileEl('testFolder')[0]).toEqual($tr[0]); @@ -296,7 +296,7 @@ describe('OCA.Files.FileList tests', function() { size: '0' }; var $tr = fileList.add(fileData); - expect($tr.find('.filesize').text()).toEqual('0 kB'); + expect($tr.find('.filesize').text()).toEqual('0 KB'); }); it('generates file element with unknown date when mtime invalid', function() { var fileData = { @@ -424,7 +424,7 @@ describe('OCA.Files.FileList tests', function() { expect($summary.find('.info').text()).toEqual('1 folder and 2 files'); expect($summary.find('.dirinfo').hasClass('hidden')).toEqual(false); expect($summary.find('.fileinfo').hasClass('hidden')).toEqual(false); - expect($summary.find('.filesize').text()).toEqual('69 kB'); + expect($summary.find('.filesize').text()).toEqual('69 KB'); expect(fileList.isEmpty).toEqual(false); }); it('Shows empty content when removing last file', function() { @@ -479,7 +479,7 @@ describe('OCA.Files.FileList tests', function() { expect($summary.find('.info').text()).toEqual('1 folder and 1 file'); expect($summary.find('.dirinfo').hasClass('hidden')).toEqual(false); expect($summary.find('.fileinfo').hasClass('hidden')).toEqual(false); - expect($summary.find('.filesize').text()).toEqual('57 kB'); + expect($summary.find('.filesize').text()).toEqual('57 KB'); expect(fileList.isEmpty).toEqual(false); expect($('#filestable thead th').hasClass('hidden')).toEqual(false); expect($('#emptycontent').hasClass('hidden')).toEqual(true); @@ -777,7 +777,7 @@ describe('OCA.Files.FileList tests', function() { // folder size has increased expect(fileList.findFileEl('somedir').data('size')).toEqual(12311); - expect(fileList.findFileEl('somedir').find('.filesize').text()).toEqual('12 kB'); + expect(fileList.findFileEl('somedir').find('.filesize').text()).toEqual('12 KB'); expect(notificationStub.notCalled).toEqual(true); }); @@ -843,7 +843,7 @@ describe('OCA.Files.FileList tests', function() { $summary = $('#filestable .summary'); expect($summary.hasClass('hidden')).toEqual(false); expect($summary.find('.info').text()).toEqual('1 folder and 3 files'); - expect($summary.find('.filesize').text()).toEqual('69 kB'); + expect($summary.find('.filesize').text()).toEqual('69 KB'); }); it('shows headers, summary and hide empty content message after setting files', function(){ fileList.setFiles(testFiles); diff --git a/apps/files/tests/js/filesummarySpec.js b/apps/files/tests/js/filesummarySpec.js index ae5ff95fc0c..ec94c28acb6 100644 --- a/apps/files/tests/js/filesummarySpec.js +++ b/apps/files/tests/js/filesummarySpec.js @@ -40,7 +40,7 @@ describe('OCA.Files.FileSummary tests', function() { }); expect($container.hasClass('hidden')).toEqual(false); expect($container.find('.info').text()).toEqual('5 folders and 2 files'); - expect($container.find('.filesize').text()).toEqual('250 kB'); + expect($container.find('.filesize').text()).toEqual('250 KB'); }); it('hides summary when no files or folders', function() { var s = new FileSummary($container); @@ -63,7 +63,7 @@ describe('OCA.Files.FileSummary tests', function() { s.update(); expect($container.hasClass('hidden')).toEqual(false); expect($container.find('.info').text()).toEqual('6 folders and 3 files'); - expect($container.find('.filesize').text()).toEqual('500 kB'); + expect($container.find('.filesize').text()).toEqual('500 KB'); expect(s.summary.totalDirs).toEqual(6); expect(s.summary.totalFiles).toEqual(3); expect(s.summary.totalSize).toEqual(512100); @@ -80,7 +80,7 @@ describe('OCA.Files.FileSummary tests', function() { s.update(); expect($container.hasClass('hidden')).toEqual(false); expect($container.find('.info').text()).toEqual('4 folders and 1 file'); - expect($container.find('.filesize').text()).toEqual('125 kB'); + expect($container.find('.filesize').text()).toEqual('125 KB'); expect(s.summary.totalDirs).toEqual(4); expect(s.summary.totalFiles).toEqual(1); expect(s.summary.totalSize).toEqual(127900); @@ -96,7 +96,7 @@ describe('OCA.Files.FileSummary tests', function() { }); expect($container.hasClass('hidden')).toEqual(false); expect($container.find('.info').text()).toEqual('5 folders and 2 files match \'foo\''); - expect($container.find('.filesize').text()).toEqual('250 kB'); + expect($container.find('.filesize').text()).toEqual('250 KB'); }); it('hides filtered summary when no files or folders', function() { var s = new FileSummary($container); @@ -123,7 +123,7 @@ describe('OCA.Files.FileSummary tests', function() { s.update(); expect($container.hasClass('hidden')).toEqual(false); expect($container.find('.info').text()).toEqual('6 folders and 3 files match \'foo\''); - expect($container.find('.filesize').text()).toEqual('500 kB'); + expect($container.find('.filesize').text()).toEqual('500 KB'); expect(s.summary.totalDirs).toEqual(6); expect(s.summary.totalFiles).toEqual(3); expect(s.summary.totalSize).toEqual(512103); @@ -143,7 +143,7 @@ describe('OCA.Files.FileSummary tests', function() { s.update(); expect($container.hasClass('hidden')).toEqual(false); expect($container.find('.info').text()).toEqual('4 folders and 1 file match \'foo\''); - expect($container.find('.filesize').text()).toEqual('125 kB'); + expect($container.find('.filesize').text()).toEqual('125 KB'); expect(s.summary.totalDirs).toEqual(4); expect(s.summary.totalFiles).toEqual(1); expect(s.summary.totalSize).toEqual(127903); diff --git a/apps/user_ldap/lib/configuration.php b/apps/user_ldap/lib/configuration.php index e810fb835d4..75d244255c6 100644 --- a/apps/user_ldap/lib/configuration.php +++ b/apps/user_ldap/lib/configuration.php @@ -281,7 +281,6 @@ class Configuration { * * @param string $varName name of config-key * @param array|string $value to set - * @param boolean $trim Trim value? (default: false) */ protected function setMultiLine($varName, $value) { if(empty($value)) { diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php index 8ebb5ab30e8..87c857a844a 100644 --- a/apps/user_ldap/user_ldap.php +++ b/apps/user_ldap/user_ldap.php @@ -152,8 +152,8 @@ class USER_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserIn * Get a list of all users * * @param string $search - * @param null|int $limit - * @param null|int $offset + * @param integer $limit + * @param integer $offset * @return string[] an array of all uids */ public function getUsers($search = '', $limit = 10, $offset = 0) { diff --git a/build/license.php b/build/license.php index 738ace8b1ad..ce6fceb8160 100644 --- a/build/license.php +++ b/build/license.php @@ -118,6 +118,9 @@ With help from many libraries and frameworks including: echo "License updated: $path" . PHP_EOL; } + /** + * @param string $source + */ private function isMITLicensed($source) { $lines = explode(PHP_EOL, $source); while(!empty($lines)) { @@ -131,6 +134,9 @@ With help from many libraries and frameworks including: return false; } + /** + * @param string $source + */ private function eatOldLicense($source) { $lines = explode(PHP_EOL, $source); while(!empty($lines)) { diff --git a/core/command/app/disable.php b/core/command/app/disable.php index b5e776d7e03..b3157faf32e 100644 --- a/core/command/app/disable.php +++ b/core/command/app/disable.php @@ -23,12 +23,25 @@ namespace OC\Core\Command\App; +use OCP\App\IAppManager; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; class Disable extends Command { + + /** @var IAppManager */ + protected $manager; + + /** + * @param IAppManager $manager + */ + public function __construct(IAppManager $manager) { + parent::__construct(); + $this->manager = $manager; + } + protected function configure() { $this ->setName('app:disable') @@ -42,9 +55,9 @@ class Disable extends Command { protected function execute(InputInterface $input, OutputInterface $output) { $appId = $input->getArgument('app-id'); - if (\OC_App::isEnabled($appId)) { + if ($this->manager->isInstalled($appId)) { try { - \OC_App::disable($appId); + $this->manager->disableApp($appId); $output->writeln($appId . ' disabled'); } catch(\Exception $e) { $output->writeln($e->getMessage()); diff --git a/core/command/app/enable.php b/core/command/app/enable.php index d50b1c4773e..4315972bae2 100644 --- a/core/command/app/enable.php +++ b/core/command/app/enable.php @@ -23,12 +23,26 @@ namespace OC\Core\Command\App; +use OCP\App\IAppManager; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; class Enable extends Command { + + /** @var IAppManager */ + protected $manager; + + /** + * @param IAppManager $manager + */ + public function __construct(IAppManager $manager) { + parent::__construct(); + $this->manager = $manager; + } + protected function configure() { $this ->setName('app:enable') @@ -37,19 +51,36 @@ class Enable extends Command { 'app-id', InputArgument::REQUIRED, 'enable the specified app' - ); + ) + ->addOption( + 'groups', + 'g', + InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, + 'enable the app only for a list of groups' + ) + ; } protected function execute(InputInterface $input, OutputInterface $output) { $appId = $input->getArgument('app-id'); - if (\OC_App::isEnabled($appId)) { - $output->writeln($appId . ' is already enabled'); - } else if (!\OC_App::getAppPath($appId)) { + + if (!\OC_App::getAppPath($appId)) { $output->writeln($appId . ' not found'); return 1; - } else { + } + + $groups = $input->getOption('groups'); + if ($this->manager->isInstalled($appId) && empty($groups)) { + $output->writeln($appId . ' is already enabled'); + } + + if (empty($groups)) { \OC_App::enable($appId); $output->writeln($appId . ' enabled'); + } else { + \OC_App::enable($appId, $groups); + $output->writeln($appId . ' enabled for groups: ' . implode(', ', $groups)); } + return 0; } } diff --git a/core/command/app/listapps.php b/core/command/app/listapps.php index 504944dd707..d7546b3c0c7 100644 --- a/core/command/app/listapps.php +++ b/core/command/app/listapps.php @@ -25,11 +25,24 @@ namespace OC\Core\Command\App; use OC\Core\Command\Base; +use OCP\App\IAppManager; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; class ListApps extends Base { + + /** @var IAppManager */ + protected $manager; + + /** + * @param IAppManager $manager + */ + public function __construct(IAppManager $manager) { + parent::__construct(); + $this->manager = $manager; + } + protected function configure() { parent::configure(); @@ -47,10 +60,9 @@ class ListApps extends Base { protected function execute(InputInterface $input, OutputInterface $output) { if ($input->getOption('shipped') === 'true' || $input->getOption('shipped') === 'false'){ - $shouldFilterShipped = true; $shippedFilter = $input->getOption('shipped') === 'true'; } else { - $shouldFilterShipped = false; + $shippedFilter = null; } $apps = \OC_App::getAllApps(); @@ -59,10 +71,10 @@ class ListApps extends Base { //sort enabled apps above disabled apps foreach ($apps as $app) { - if ($shouldFilterShipped && \OC_App::isShipped($app) !== $shippedFilter){ + if ($shippedFilter !== null && \OC_App::isShipped($app) !== $shippedFilter){ continue; } - if (\OC_App::isEnabled($app)) { + if ($this->manager->isInstalled($app)) { $enabledApps[] = $app; } else { $disabledApps[] = $app; diff --git a/core/js/js.js b/core/js/js.js index 2937d3f6eb1..d24a46fc0bb 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -1449,7 +1449,7 @@ $.fn.filterAttr = function(attr_name, attr_value) { * @return {string} */ function humanFileSize(size, skipSmallSizes) { - var humanList = ['B', 'kB', 'MB', 'GB', 'TB']; + var humanList = ['B', 'KB', 'MB', 'GB', 'TB']; // Calculate Log with base 1024: size = 1024 ** order var order = size > 0 ? Math.floor(Math.log(size) / Math.log(1024)) : 0; // Stay in range of the byte sizes that are defined @@ -1458,9 +1458,9 @@ function humanFileSize(size, skipSmallSizes) { var relativeSize = (size / Math.pow(1024, order)).toFixed(1); if(skipSmallSizes === true && order === 0) { if(relativeSize !== "0.0"){ - return '< 1 kB'; + return '< 1 KB'; } else { - return '0 kB'; + return '0 KB'; } } if(order < 2){ diff --git a/core/js/tests/specs/coreSpec.js b/core/js/tests/specs/coreSpec.js index f653fc88637..2e970f7e707 100644 --- a/core/js/tests/specs/coreSpec.js +++ b/core/js/tests/specs/coreSpec.js @@ -524,7 +524,7 @@ describe('Core base tests', function() { ["0", '0 B'], ["A", 'NaN B'], [125, '125 B'], - [128000, '125 kB'], + [128000, '125 KB'], [128000000, '122.1 MB'], [128000000000, '119.2 GB'], [128000000000000, '116.4 TB'] @@ -535,9 +535,9 @@ describe('Core base tests', function() { }); it('renders file sizes with the correct unit for small sizes', function() { var data = [ - [0, '0 kB'], - [125, '< 1 kB'], - [128000, '125 kB'], + [0, '0 KB'], + [125, '< 1 KB'], + [128000, '125 KB'], [128000000, '122.1 MB'], [128000000000, '119.2 GB'], [128000000000000, '116.4 TB'] diff --git a/core/register_command.php b/core/register_command.php index a7dd7414790..e43994530b9 100644 --- a/core/register_command.php +++ b/core/register_command.php @@ -44,10 +44,10 @@ $application->add(new \OC\Core\Command\Integrity\SignCore( )); if (\OC::$server->getConfig()->getSystemValue('installed', false)) { - $application->add(new OC\Core\Command\App\Disable()); - $application->add(new OC\Core\Command\App\Enable()); + $application->add(new OC\Core\Command\App\Disable(\OC::$server->getAppManager())); + $application->add(new OC\Core\Command\App\Enable(\OC::$server->getAppManager())); $application->add(new OC\Core\Command\App\GetPath()); - $application->add(new OC\Core\Command\App\ListApps()); + $application->add(new OC\Core\Command\App\ListApps(\OC::$server->getAppManager())); $application->add(new OC\Core\Command\Background\Cron(\OC::$server->getConfig())); $application->add(new OC\Core\Command\Background\WebCron(\OC::$server->getConfig())); diff --git a/lib/private/app/dependencyanalyzer.php b/lib/private/app/dependencyanalyzer.php index ba2479ae7aa..0cf4bc72161 100644 --- a/lib/private/app/dependencyanalyzer.php +++ b/lib/private/app/dependencyanalyzer.php @@ -73,7 +73,7 @@ class DependencyAnalyzer { * 5.2.6.5 and 5.1 will be turned into 5.2 and 5.1 * @param string $first * @param string $second - * @return array first element is the first version, second element is the + * @return string[] first element is the first version, second element is the * second version */ private function normalizeVersions($first, $second) { diff --git a/lib/private/app/platformrepository.php b/lib/private/app/platformrepository.php index 730c67f45ee..7363b2a44b1 100644 --- a/lib/private/app/platformrepository.php +++ b/lib/private/app/platformrepository.php @@ -206,6 +206,9 @@ class PlatformRepository { throw new \UnexpectedValueException('Invalid version string "' . $version . '"' . $extraMessage); } + /** + * @param string $stability + */ private function expandStability($stability) { $stability = strtolower($stability); switch ($stability) { diff --git a/lib/private/db/migrator.php b/lib/private/db/migrator.php index cd310bb75a5..7ca3f981358 100644 --- a/lib/private/db/migrator.php +++ b/lib/private/db/migrator.php @@ -52,7 +52,7 @@ class Migrator { protected $config; /** - * @param \Doctrine\DBAL\Connection $connection + * @param Connection $connection * @param ISecureRandom $random * @param IConfig $config */ diff --git a/lib/private/defaults.php b/lib/private/defaults.php index 1fa8352edc1..43e8c8082cc 100644 --- a/lib/private/defaults.php +++ b/lib/private/defaults.php @@ -261,6 +261,9 @@ class OC_Defaults { return $footer; } + /** + * @param string $key + */ public function buildDocLinkToKey($key) { if ($this->themeExist('buildDocLinkToKey')) { return $this->theme->buildDocLinkToKey($key); diff --git a/lib/private/helper.php b/lib/private/helper.php index 3590eaee612..c387cd40a24 100644 --- a/lib/private/helper.php +++ b/lib/private/helper.php @@ -112,7 +112,7 @@ class OC_Helper { } $bytes = round($bytes / 1024, 0); if ($bytes < 1024) { - return "$bytes kB"; + return "$bytes KB"; } $bytes = round($bytes / 1024, 1); if ($bytes < 1024) { diff --git a/tests/lib/helper.php b/tests/lib/helper.php index c2620896157..89a981e6e23 100644 --- a/tests/lib/helper.php +++ b/tests/lib/helper.php @@ -21,7 +21,7 @@ class Test_Helper extends \Test\TestCase { { return array( array('0 B', 0), - array('1 kB', 1024), + array('1 KB', 1024), array('9.5 MB', 10000000), array('1.3 GB', 1395864371), array('465.7 GB', 500000000000), @@ -63,7 +63,7 @@ class Test_Helper extends \Test\TestCase { function providesComputerFileSize(){ return [ [0.0, "0 B"], - [1024.0, "1 kB"], + [1024.0, "1 KB"], [1395864371.0, '1.3 GB'], [9961472.0, "9.5 MB"], [500041567437.0, "465.7 GB"], diff --git a/tests/settings/controller/EncryptionControllerTest.php b/tests/settings/controller/EncryptionControllerTest.php index 2446b8c7b9e..a3bb4c45a27 100644 --- a/tests/settings/controller/EncryptionControllerTest.php +++ b/tests/settings/controller/EncryptionControllerTest.php @@ -90,6 +90,9 @@ class EncryptionControllerTest extends TestCase { } public function testStartMigrationSuccessful() { + // we need to be able to autoload the class we're mocking + \OC::$loader->addValidRoot(\OC_App::getAppPath('encryption')); + $migration = $this->getMockBuilder('\\OCA\\Encryption\\Migration') ->disableOriginalConstructor()->getMock(); $this->encryptionController |