summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
m---------3rdparty0
-rw-r--r--apps/dav/appinfo/application.php3
-rw-r--r--apps/dav/appinfo/register_command.php3
-rw-r--r--apps/dav/command/createaddressbook.php14
-rw-r--r--apps/dav/command/syncsystemaddressbook.php10
-rw-r--r--apps/dav/lib/carddav/addressbook.php38
-rw-r--r--apps/dav/lib/carddav/card.php8
-rw-r--r--apps/dav/lib/carddav/carddavbackend.php140
-rw-r--r--apps/dav/lib/carddav/sharing/plugin.php6
-rw-r--r--apps/dav/lib/carddav/sharing/xml/sharerequest.php19
-rw-r--r--apps/dav/lib/carddav/syncservice.php4
-rw-r--r--apps/dav/lib/connector/sabre/principal.php35
-rw-r--r--apps/dav/lib/rootcollection.php3
-rw-r--r--apps/dav/tests/travis/caldav/script.sh2
-rw-r--r--apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/sharing/read-write/1.xml8
-rw-r--r--apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/sharing/read-write/4.xml8
-rw-r--r--apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/sharing/read-write/6.vcf11
-rw-r--r--apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/sharing/read-write/7.vcf11
-rw-r--r--apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/sharing/read-write/8.vcf11
-rw-r--r--apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/sharing/read-write/9.vcf11
-rw-r--r--apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/vcurrent-user-principal/1.xml6
-rw-r--r--apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/vreports/put/1.vcf11
-rw-r--r--apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/vreports/put/2.vcf17
-rw-r--r--apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/vreports/put/3.vcf12
-rw-r--r--apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/vreports/sync/1.xml7
-rw-r--r--apps/dav/tests/travis/caldavtest/data/Resource/CardDAV/vreports/sync/2.xml5
-rw-r--r--apps/dav/tests/travis/caldavtest/serverinfo.dtd (renamed from apps/dav/tests/travis/caldavtest/config/serverinfo.dtd)0
-rw-r--r--apps/dav/tests/travis/caldavtest/serverinfo.xml (renamed from apps/dav/tests/travis/caldavtest/config/serverinfo.xml)2
-rw-r--r--apps/dav/tests/travis/caldavtest/tests/CardDAV/sharing-addressbooks.xml246
-rw-r--r--apps/dav/tests/travis/carddav/script.sh9
-rw-r--r--apps/dav/tests/unit/carddav/carddavbackendtest.php14
-rw-r--r--apps/dav/tests/unit/carddav/sharing/plugintest.php2
-rw-r--r--apps/dav/tests/unit/connector/sabre/principal.php24
-rw-r--r--apps/files/tests/js/fileUploadSpec.js4
-rw-r--r--apps/files/tests/js/filelistSpec.js14
-rw-r--r--apps/files/tests/js/filesummarySpec.js12
-rw-r--r--apps/user_ldap/lib/configuration.php1
-rw-r--r--apps/user_ldap/user_ldap.php4
-rw-r--r--build/license.php6
-rw-r--r--core/command/app/disable.php17
-rw-r--r--core/command/app/enable.php41
-rw-r--r--core/command/app/listapps.php20
-rw-r--r--core/js/js.js6
-rw-r--r--core/js/tests/specs/coreSpec.js8
-rw-r--r--core/register_command.php6
-rw-r--r--lib/private/app/dependencyanalyzer.php2
-rw-r--r--lib/private/app/platformrepository.php3
-rw-r--r--lib/private/db/migrator.php2
-rw-r--r--lib/private/defaults.php3
-rw-r--r--lib/private/helper.php2
-rw-r--r--tests/lib/helper.php4
-rw-r--r--tests/settings/controller/EncryptionControllerTest.php3
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