summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/dav/appinfo/application.php39
-rw-r--r--apps/dav/appinfo/register_command.php6
-rw-r--r--apps/dav/appinfo/v1/caldav.php1
-rw-r--r--apps/dav/appinfo/v1/carddav.php1
-rw-r--r--apps/dav/appinfo/v1/webdav.php1
-rw-r--r--apps/dav/command/createaddressbook.php31
-rw-r--r--apps/dav/command/syncbirthdaycalendar.php85
-rw-r--r--apps/dav/command/syncsystemaddressbook.php1
-rw-r--r--apps/dav/lib/caldav/birthdayservice.php187
-rw-r--r--apps/dav/lib/caldav/caldavbackend.php6
-rw-r--r--apps/dav/lib/caldav/calendar.php4
-rw-r--r--apps/dav/lib/carddav/carddavbackend.php34
-rw-r--r--apps/dav/lib/connector/sabre/auth.php37
-rw-r--r--apps/dav/lib/connector/sabre/filesplugin.php12
-rw-r--r--apps/dav/lib/dav/sharing/plugin.php17
-rw-r--r--apps/dav/lib/rootcollection.php5
-rw-r--r--apps/dav/lib/server.php3
-rw-r--r--apps/dav/tests/travis/caldav/script.sh2
-rw-r--r--apps/dav/tests/unit/caldav/calendartest.php6
-rw-r--r--apps/dav/tests/unit/carddav/birthdayservicetest.php171
-rw-r--r--apps/dav/tests/unit/carddav/carddavbackendtest.php12
-rw-r--r--apps/dav/tests/unit/connector/sabre/auth.php107
-rw-r--r--apps/files_external/lib/google.php17
-rw-r--r--core/js/files/client.js5
-rw-r--r--core/js/oc-backbone-webdav.js3
-rw-r--r--issue_template.md7
-rw-r--r--lib/private/api.php3
-rw-r--r--lib/private/files/stream/encryption.php2
-rw-r--r--lib/private/group/dummy.php1
-rw-r--r--lib/private/group/manager.php4
-rw-r--r--lib/private/memcache/factory.php2
-rw-r--r--lib/private/preview.php20
-rw-r--r--lib/public/appframework/utility/icontrollermethodreflector.php1
-rw-r--r--lib/public/search/pagedprovider.php2
34 files changed, 686 insertions, 149 deletions
diff --git a/apps/dav/appinfo/application.php b/apps/dav/appinfo/application.php
index 28b9a833456..7a201e1dd78 100644
--- a/apps/dav/appinfo/application.php
+++ b/apps/dav/appinfo/application.php
@@ -20,6 +20,7 @@
*/
namespace OCA\Dav\AppInfo;
+use OCA\DAV\CalDAV\BirthdayService;
use OCA\DAV\CalDAV\CalDavBackend;
use OCA\DAV\CardDAV\CardDavBackend;
use OCA\DAV\CardDAV\ContactsManager;
@@ -34,6 +35,7 @@ use \OCP\AppFramework\App;
use OCP\AppFramework\IAppContainer;
use OCP\Contacts\IManager;
use OCP\IUser;
+use Symfony\Component\EventDispatcher\GenericEvent;
class Application extends App {
@@ -74,12 +76,12 @@ class Application extends App {
$container->registerService('CardDavBackend', function($c) {
/** @var IAppContainer $c */
$db = $c->getServer()->getDatabaseConnection();
- $logger = $c->getServer()->getLogger();
+ $dispatcher = $c->getServer()->getEventDispatcher();
$principal = new \OCA\DAV\Connector\Sabre\Principal(
$c->getServer()->getUserManager(),
$c->getServer()->getGroupManager()
);
- return new CardDavBackend($db, $principal, $logger);
+ return new CardDavBackend($db, $principal, $dispatcher);
});
$container->registerService('CalDavBackend', function($c) {
@@ -109,6 +111,15 @@ class Application extends App {
$c->query('CalDavBackend')
);
});
+
+ $container->registerService('BirthdayService', function($c) {
+ /** @var IAppContainer $c */
+ return new BirthdayService(
+ $c->query('CalDavBackend'),
+ $c->query('CardDavBackend')
+ );
+
+ });
}
/**
@@ -125,6 +136,30 @@ class Application extends App {
/** @var HookManager $hm */
$hm = $this->getContainer()->query('HookManager');
$hm->setup();
+
+ $listener = function($event) {
+ if ($event instanceof GenericEvent) {
+ $b = $this->getContainer()->query('BirthdayService');
+ $b->onCardChanged(
+ $event->getArgument('addressBookId'),
+ $event->getArgument('cardUri'),
+ $event->getArgument('cardData')
+ );
+ }
+ };
+
+ $dispatcher = $this->getContainer()->getServer()->getEventDispatcher();
+ $dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::createCard', $listener);
+ $dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::updateCard', $listener);
+ $dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::deleteCard', function($event) {
+ if ($event instanceof GenericEvent) {
+ $b = $this->getContainer()->query('BirthdayService');
+ $b->onCardDeleted(
+ $event->getArgument('addressBookId'),
+ $event->getArgument('cardUri')
+ );
+ }
+ });
}
public function getSyncService() {
diff --git a/apps/dav/appinfo/register_command.php b/apps/dav/appinfo/register_command.php
index 4981cab9264..e07f6b4a25b 100644
--- a/apps/dav/appinfo/register_command.php
+++ b/apps/dav/appinfo/register_command.php
@@ -24,21 +24,21 @@ use OCA\DAV\Command\CreateAddressBook;
use OCA\DAV\Command\CreateCalendar;
use OCA\Dav\Command\MigrateAddressbooks;
use OCA\Dav\Command\MigrateCalendars;
+use OCA\DAV\Command\SyncBirthdayCalendar;
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, $groupManager, $dbConnection, $logger));
$application->add(new CreateCalendar($userManager, $groupManager, $dbConnection));
+$application->add(new CreateAddressBook($userManager, $app->getContainer()->query('CardDavBackend')));
$application->add(new SyncSystemAddressBook($app->getSyncService()));
+$application->add(new SyncBirthdayCalendar($userManager, $app->getContainer()->query('BirthdayService')));
// the occ tool is *for now* only available in debug mode for developers to test
if ($config->getSystemValue('debug', false)){
diff --git a/apps/dav/appinfo/v1/caldav.php b/apps/dav/appinfo/v1/caldav.php
index f860ced3877..333e8bbb3c4 100644
--- a/apps/dav/appinfo/v1/caldav.php
+++ b/apps/dav/appinfo/v1/caldav.php
@@ -30,6 +30,7 @@ use Sabre\CalDAV\CalendarRoot;
$authBackend = new Auth(
\OC::$server->getSession(),
\OC::$server->getUserSession(),
+ \OC::$server->getRequest(),
'principals/'
);
$principalBackend = new Principal(
diff --git a/apps/dav/appinfo/v1/carddav.php b/apps/dav/appinfo/v1/carddav.php
index e0c79c75b72..54f0d259bb9 100644
--- a/apps/dav/appinfo/v1/carddav.php
+++ b/apps/dav/appinfo/v1/carddav.php
@@ -32,6 +32,7 @@ use Sabre\CardDAV\Plugin;
$authBackend = new Auth(
\OC::$server->getSession(),
\OC::$server->getUserSession(),
+ \OC::$server->getRequest(),
'principals/'
);
$principalBackend = new Principal(
diff --git a/apps/dav/appinfo/v1/webdav.php b/apps/dav/appinfo/v1/webdav.php
index 3d3e51e84bc..211ffabef84 100644
--- a/apps/dav/appinfo/v1/webdav.php
+++ b/apps/dav/appinfo/v1/webdav.php
@@ -41,6 +41,7 @@ $serverFactory = new \OCA\DAV\Connector\Sabre\ServerFactory(
$authBackend = new \OCA\DAV\Connector\Sabre\Auth(
\OC::$server->getSession(),
\OC::$server->getUserSession(),
+ \OC::$server->getRequest(),
'principals/'
);
$requestUri = \OC::$server->getRequest()->getRequestUri();
diff --git a/apps/dav/command/createaddressbook.php b/apps/dav/command/createaddressbook.php
index 3d99afd4ba3..48302a2b439 100644
--- a/apps/dav/command/createaddressbook.php
+++ b/apps/dav/command/createaddressbook.php
@@ -36,33 +36,21 @@ use Symfony\Component\Console\Output\OutputInterface;
class CreateAddressBook extends Command {
/** @var IUserManager */
- protected $userManager;
+ private $userManager;
- /** @var \OCP\IDBConnection */
- protected $dbConnection;
-
- /** @var ILogger */
- private $logger;
-
- /** @var IGroupManager $groupManager */
- private $groupManager;
+ /** @var CardDavBackend */
+ private $cardDavBackend;
/**
* @param IUserManager $userManager
- * @param IDBConnection $dbConnection
- * @param IConfig $config
- * @param ILogger $logger
+ * @param CardDavBackend $cardDavBackend
*/
function __construct(IUserManager $userManager,
- IGroupManager $groupManager,
- IDBConnection $dbConnection,
- ILogger $logger
+ CardDavBackend $cardDavBackend
) {
parent::__construct();
$this->userManager = $userManager;
- $this->groupManager = $groupManager;
- $this->dbConnection = $dbConnection;
- $this->logger = $logger;
+ $this->cardDavBackend = $cardDavBackend;
}
protected function configure() {
@@ -82,13 +70,8 @@ class CreateAddressBook extends Command {
if (!$this->userManager->userExists($user)) {
throw new \InvalidArgumentException("User <$user> in unknown.");
}
- $principalBackend = new Principal(
- $this->userManager,
- $this->groupManager
- );
$name = $input->getArgument('name');
- $carddav = new CardDavBackend($this->dbConnection, $principalBackend, $this->logger);
- $carddav->createAddressBook("principals/users/$user", $name, []);
+ $this->cardDavBackend->createAddressBook("principals/users/$user", $name, []);
}
}
diff --git a/apps/dav/command/syncbirthdaycalendar.php b/apps/dav/command/syncbirthdaycalendar.php
new file mode 100644
index 00000000000..66ab540b9ad
--- /dev/null
+++ b/apps/dav/command/syncbirthdaycalendar.php
@@ -0,0 +1,85 @@
+<?php
+/**
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+namespace OCA\DAV\Command;
+
+use OCA\DAV\CalDAV\BirthdayService;
+use OCP\IUser;
+use OCP\IUserManager;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Helper\ProgressBar;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class SyncBirthdayCalendar extends Command {
+
+ /** @var BirthdayService */
+ private $birthdayService;
+
+ /** @var IUserManager */
+ private $userManager;
+
+ /**
+ * @param IUserManager $userManager
+ * @param BirthdayService $birthdayService
+ */
+ function __construct(IUserManager $userManager, BirthdayService $birthdayService) {
+ parent::__construct();
+ $this->birthdayService = $birthdayService;
+ $this->userManager = $userManager;
+ }
+
+ protected function configure() {
+ $this
+ ->setName('dav:sync-birthday-calendar')
+ ->setDescription('Synchronizes the birthday calendar')
+ ->addArgument('user',
+ InputArgument::OPTIONAL,
+ 'User for whom the birthday calendar will be synchronized');
+ }
+
+ /**
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ */
+ protected function execute(InputInterface $input, OutputInterface $output) {
+ if ($input->hasArgument('user')) {
+ $user = $input->getArgument('user');
+ if (!$this->userManager->userExists($user)) {
+ throw new \InvalidArgumentException("User <$user> in unknown.");
+ }
+ $output->writeln("Start birthday calendar sync for $user");
+ $this->birthdayService->syncUser($user);
+ return;
+ }
+ $output->writeln("Start birthday calendar sync for all users ...");
+ $p = new ProgressBar($output);
+ $p->start();
+ $this->userManager->callForAllUsers(function($user) use ($p) {
+ $p->advance();
+ /** @var IUser $user */
+ $this->birthdayService->syncUser($user->getUID());
+ });
+
+ $p->finish();
+ $output->writeln('');
+ }
+}
diff --git a/apps/dav/command/syncsystemaddressbook.php b/apps/dav/command/syncsystemaddressbook.php
index b83a37131c3..b62a42d7b90 100644
--- a/apps/dav/command/syncsystemaddressbook.php
+++ b/apps/dav/command/syncsystemaddressbook.php
@@ -34,7 +34,6 @@ class SyncSystemAddressBook extends Command {
private $syncService;
/**
- * @param IUserManager $userManager
* @param SyncService $syncService
*/
function __construct(SyncService $syncService) {
diff --git a/apps/dav/lib/caldav/birthdayservice.php b/apps/dav/lib/caldav/birthdayservice.php
new file mode 100644
index 00000000000..3b0a2a10e1c
--- /dev/null
+++ b/apps/dav/lib/caldav/birthdayservice.php
@@ -0,0 +1,187 @@
+<?php
+/**
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\DAV\CalDAV;
+
+use Exception;
+use OCA\DAV\CardDAV\CardDavBackend;
+use Sabre\VObject\Component\VCalendar;
+use Sabre\VObject\Reader;
+
+class BirthdayService {
+
+ const BIRTHDAY_CALENDAR_URI = 'contact_birthdays';
+
+ /**
+ * BirthdayService constructor.
+ *
+ * @param CalDavBackend $calDavBackEnd
+ * @param CardDavBackend $cardDavBackEnd
+ */
+ public function __construct($calDavBackEnd, $cardDavBackEnd) {
+ $this->calDavBackEnd = $calDavBackEnd;
+ $this->cardDavBackEnd = $cardDavBackEnd;
+ }
+
+ /**
+ * @param int $addressBookId
+ * @param string $cardUri
+ * @param string $cardData
+ */
+ public function onCardChanged($addressBookId, $cardUri, $cardData) {
+
+ $book = $this->cardDavBackEnd->getAddressBookById($addressBookId);
+ $principalUri = $book['principaluri'];
+ $calendarUri = self::BIRTHDAY_CALENDAR_URI;
+ $calendar = $this->ensureCalendarExists($principalUri, $calendarUri, []);
+ $objectUri = $book['uri'] . '-' . $cardUri. '.ics';
+ $calendarData = $this->buildBirthdayFromContact($cardData);
+ $existing = $this->calDavBackEnd->getCalendarObject($calendar['id'], $objectUri);
+ if (is_null($calendarData)) {
+ if (!is_null($existing)) {
+ $this->calDavBackEnd->deleteCalendarObject($calendar['id'], $objectUri);
+ }
+ } else {
+ if (is_null($existing)) {
+ $this->calDavBackEnd->createCalendarObject($calendar['id'], $objectUri, $calendarData->serialize());
+ } else {
+ if ($this->birthdayEvenChanged($existing['calendardata'], $calendarData)) {
+ $this->calDavBackEnd->updateCalendarObject($calendar['id'], $objectUri, $calendarData->serialize());
+ }
+ }
+ }
+ }
+
+ /**
+ * @param int $addressBookId
+ * @param string $cardUri
+ */
+ public function onCardDeleted($addressBookId, $cardUri) {
+ $book = $this->cardDavBackEnd->getAddressBookById($addressBookId);
+ $principalUri = $book['principaluri'];
+ $calendarUri = self::BIRTHDAY_CALENDAR_URI;
+ $calendar = $this->ensureCalendarExists($principalUri, $calendarUri, []);
+ $objectUri = $book['uri'] . '-' . $cardUri. '.ics';
+ $this->calDavBackEnd->deleteCalendarObject($calendar['id'], $objectUri);
+ }
+
+ /**
+ * @param string $principal
+ * @param string $id
+ * @param array $properties
+ * @return array|null
+ * @throws \Sabre\DAV\Exception\BadRequest
+ */
+ public function ensureCalendarExists($principal, $id, $properties) {
+ $book = $this->calDavBackEnd->getCalendarByUri($principal, $id);
+ if (!is_null($book)) {
+ return $book;
+ }
+ $this->calDavBackEnd->createCalendar($principal, $id, $properties);
+
+ return $this->calDavBackEnd->getCalendarByUri($principal, $id);
+ }
+
+ /**
+ * @param string $cardData
+ * @return null|VCalendar
+ */
+ public function buildBirthdayFromContact($cardData) {
+ if (empty($cardData)) {
+ return null;
+ }
+ try {
+ $doc = Reader::read($cardData);
+ } catch (Exception $e) {
+ return null;
+ }
+
+ if (!isset($doc->BDAY)) {
+ return null;
+ }
+ $birthday = $doc->BDAY;
+ if (!(string)$birthday) {
+ return null;
+ }
+ $title = str_replace('{name}',
+ strtr((string)$doc->FN, array('\,' => ',', '\;' => ';')),
+ '{name}\'s Birthday'
+ );
+ try {
+ $date = new \DateTime($birthday);
+ } catch (Exception $e) {
+ return null;
+ }
+ $vCal = new VCalendar();
+ $vCal->VERSION = '2.0';
+ $vEvent = $vCal->createComponent('VEVENT');
+ $vEvent->add('DTSTART');
+ $vEvent->DTSTART->setDateTime(
+ $date
+ );
+ $vEvent->DTSTART['VALUE'] = 'DATE';
+ $vEvent->add('DTEND');
+ $date->add(new \DateInterval('P1D'));
+ $vEvent->DTEND->setDateTime(
+ $date
+ );
+ $vEvent->DTEND['VALUE'] = 'DATE';
+ $vEvent->{'UID'} = $doc->UID;
+ $vEvent->{'RRULE'} = 'FREQ=YEARLY';
+ $vEvent->{'SUMMARY'} = $title . ' (' . $date->format('Y') . ')';
+ $vEvent->{'TRANSP'} = 'TRANSPARENT';
+ $vCal->add($vEvent);
+ return $vCal;
+ }
+
+ /**
+ * @param string $user
+ */
+ public function syncUser($user) {
+ $books = $this->cardDavBackEnd->getAddressBooksForUser('principals/users/'.$user);
+ foreach($books as $book) {
+ $cards = $this->cardDavBackEnd->getCards($book['id']);
+ foreach($cards as $card) {
+ $this->onCardChanged($book['id'], $card['uri'], $card['carddata']);
+ }
+ }
+ }
+
+ /**
+ * @param string $existingCalendarData
+ * @param VCalendar $newCalendarData
+ * @return bool
+ */
+ public function birthdayEvenChanged($existingCalendarData, $newCalendarData) {
+ try {
+ $existingBirthday = Reader::read($existingCalendarData);
+ } catch (Exception $ex) {
+ return true;
+ }
+ if ($newCalendarData->VEVENT->DTSTART->getValue() !== $existingBirthday->VEVENT->DTSTART->getValue() ||
+ $newCalendarData->VEVENT->SUMMARY->getValue() !== $existingBirthday->VEVENT->SUMMARY->getValue()
+ ) {
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/apps/dav/lib/caldav/caldavbackend.php b/apps/dav/lib/caldav/caldavbackend.php
index 775612487f9..c674876598d 100644
--- a/apps/dav/lib/caldav/caldavbackend.php
+++ b/apps/dav/lib/caldav/caldavbackend.php
@@ -235,6 +235,11 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
return array_values($calendars);
}
+ /**
+ * @param string $principal
+ * @param string $uri
+ * @return array|null
+ */
public function getCalendarByUri($principal, $uri) {
$fields = array_values($this->propertyMap);
$fields[] = 'id';
@@ -1367,4 +1372,5 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
public function applyShareAcl($resourceId, $acl) {
return $this->sharingBackend->applyShareAcl($resourceId, $acl);
}
+
}
diff --git a/apps/dav/lib/caldav/calendar.php b/apps/dav/lib/caldav/calendar.php
index 8ed5b6563d0..6b34d570eb3 100644
--- a/apps/dav/lib/caldav/calendar.php
+++ b/apps/dav/lib/caldav/calendar.php
@@ -80,6 +80,10 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IShareable {
}
function delete() {
+ if ($this->getName() === BirthdayService::BIRTHDAY_CALENDAR_URI) {
+ throw new Forbidden();
+ }
+
if (isset($this->calendarInfo['{http://owncloud.org/ns}owner-principal'])) {
$principal = 'principal:' . parent::getOwner();
$shares = $this->getShares();
diff --git a/apps/dav/lib/carddav/carddavbackend.php b/apps/dav/lib/carddav/carddavbackend.php
index 78706ae6bff..56fa652d798 100644
--- a/apps/dav/lib/carddav/carddavbackend.php
+++ b/apps/dav/lib/carddav/carddavbackend.php
@@ -37,6 +37,8 @@ use Sabre\DAV\Exception\BadRequest;
use Sabre\HTTP\URLUtil;
use Sabre\VObject\Component\VCard;
use Sabre\VObject\Reader;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+use Symfony\Component\EventDispatcher\GenericEvent;
class CardDavBackend implements BackendInterface, SyncSupport {
@@ -64,15 +66,22 @@ class CardDavBackend implements BackendInterface, SyncSupport {
const ACCESS_READ_WRITE = 2;
const ACCESS_READ = 3;
+ /** @var EventDispatcherInterface */
+ private $dispatcher;
+
/**
* CardDavBackend constructor.
*
* @param IDBConnection $db
* @param Principal $principalBackend
+ * @param EventDispatcherInterface $dispatcher
*/
- public function __construct(IDBConnection $db, Principal $principalBackend) {
+ public function __construct(IDBConnection $db,
+ Principal $principalBackend,
+ $dispatcher ) {
$this->db = $db;
$this->principalBackend = $principalBackend;
+ $this->dispatcher = $dispatcher;
$this->sharingBackend = new Backend($this->db, $principalBackend, 'addressbook');
}
@@ -492,6 +501,14 @@ class CardDavBackend implements BackendInterface, SyncSupport {
$this->addChange($addressBookId, $cardUri, 1);
$this->updateProperties($addressBookId, $cardUri, $cardData);
+ if (!is_null($this->dispatcher)) {
+ $this->dispatcher->dispatch('\OCA\DAV\CardDAV\CardDavBackend::createCard',
+ new GenericEvent(null, [
+ 'addressBookId' => $addressBookId,
+ 'cardUri' => $cardUri,
+ 'cardData' => $cardData]));
+ }
+
return '"' . $etag . '"';
}
@@ -536,6 +553,14 @@ class CardDavBackend implements BackendInterface, SyncSupport {
$this->addChange($addressBookId, $cardUri, 2);
$this->updateProperties($addressBookId, $cardUri, $cardData);
+ if (!is_null($this->dispatcher)) {
+ $this->dispatcher->dispatch('\OCA\DAV\CardDAV\CardDavBackend::updateCard',
+ new GenericEvent(null, [
+ 'addressBookId' => $addressBookId,
+ 'cardUri' => $cardUri,
+ 'cardData' => $cardData]));
+ }
+
return '"' . $etag . '"';
}
@@ -560,6 +585,13 @@ class CardDavBackend implements BackendInterface, SyncSupport {
$this->addChange($addressBookId, $cardUri, 3);
+ if (!is_null($this->dispatcher)) {
+ $this->dispatcher->dispatch('\OCA\DAV\CardDAV\CardDavBackend::deleteCard',
+ new GenericEvent(null, [
+ 'addressBookId' => $addressBookId,
+ 'cardUri' => $cardUri]));
+ }
+
if ($ret === 1) {
if ($cardId !== null) {
$this->purgeProperties($addressBookId, $cardId);
diff --git a/apps/dav/lib/connector/sabre/auth.php b/apps/dav/lib/connector/sabre/auth.php
index a046e078482..4bb07c5f0ed 100644
--- a/apps/dav/lib/connector/sabre/auth.php
+++ b/apps/dav/lib/connector/sabre/auth.php
@@ -30,6 +30,7 @@
namespace OCA\DAV\Connector\Sabre;
use Exception;
+use OCP\IRequest;
use OCP\ISession;
use OCP\IUserSession;
use Sabre\DAV\Auth\Backend\AbstractBasic;
@@ -45,17 +46,22 @@ class Auth extends AbstractBasic {
private $session;
/** @var IUserSession */
private $userSession;
+ /** @var IRequest */
+ private $request;
/**
* @param ISession $session
* @param IUserSession $userSession
+ * @param IRequest $request
* @param string $principalPrefix
*/
public function __construct(ISession $session,
IUserSession $userSession,
+ IRequest $request,
$principalPrefix = 'principals/users/') {
$this->session = $session;
$this->userSession = $userSession;
+ $this->request = $request;
$this->principalPrefix = $principalPrefix;
}
@@ -107,26 +113,6 @@ class Auth extends AbstractBasic {
}
/**
- * Returns information about the currently logged in username.
- *
- * If nobody is currently logged in, this method should return null.
- *
- * @return string|null
- */
- public function getCurrentUser() {
- $user = $this->userSession->getUser() ? $this->userSession->getUser()->getUID() : null;
- if($user !== null && $this->isDavAuthenticated($user)) {
- return $user;
- }
-
- if($user !== null && is_null($this->session->get(self::DAV_AUTHENTICATED))) {
- return $user;
- }
-
- return null;
- }
-
- /**
* @param RequestInterface $request
* @param ResponseInterface $response
* @return array
@@ -150,8 +136,19 @@ class Auth extends AbstractBasic {
* @param RequestInterface $request
* @param ResponseInterface $response
* @return array
+ * @throws NotAuthenticated
*/
private function auth(RequestInterface $request, ResponseInterface $response) {
+ // If request is not GET and not authenticated via WebDAV a requesttoken is required
+ if($this->userSession->isLoggedIn() &&
+ $this->request->getMethod() !== 'GET' &&
+ !$this->isDavAuthenticated($this->userSession->getUser()->getUID())) {
+ if(!$this->request->passesCSRFCheck()) {
+ $response->setStatus(401);
+ throw new \Sabre\DAV\Exception\NotAuthenticated('CSRF check not passed.');
+ }
+ }
+
if (\OC_User::handleApacheAuth() ||
//Fix for broken webdav clients
($this->userSession->isLoggedIn() && is_null($this->session->get(self::DAV_AUTHENTICATED))) ||
diff --git a/apps/dav/lib/connector/sabre/filesplugin.php b/apps/dav/lib/connector/sabre/filesplugin.php
index 2e913ee1077..eb9116d219b 100644
--- a/apps/dav/lib/connector/sabre/filesplugin.php
+++ b/apps/dav/lib/connector/sabre/filesplugin.php
@@ -193,11 +193,13 @@ class FilesPlugin extends \Sabre\DAV\ServerPlugin {
// adds a 'Content-Disposition: attachment' header
$response->addHeader('Content-Disposition', 'attachment');
- //Add OC-Checksum header
- /** @var $node File */
- $checksum = $node->getChecksum();
- if ($checksum !== null) {
- $response->addHeader('OC-Checksum', $checksum);
+ if ($node instanceof \OCA\DAV\Connector\Sabre\File) {
+ //Add OC-Checksum header
+ /** @var $node File */
+ $checksum = $node->getChecksum();
+ if ($checksum !== null) {
+ $response->addHeader('OC-Checksum', $checksum);
+ }
}
}
diff --git a/apps/dav/lib/dav/sharing/plugin.php b/apps/dav/lib/dav/sharing/plugin.php
index f6e2cceebd9..e6eab3539b3 100644
--- a/apps/dav/lib/dav/sharing/plugin.php
+++ b/apps/dav/lib/dav/sharing/plugin.php
@@ -129,9 +129,6 @@ class Plugin extends ServerPlugin {
return;
}
- // CSRF protection
- $this->protectAgainstCSRF();
-
$requestBody = $request->getBodyAsString();
// If this request handler could not deal with this POST request, it
@@ -201,18 +198,4 @@ class Plugin extends ServerPlugin {
}
}
- private function protectAgainstCSRF() {
- $user = $this->auth->getCurrentUser();
- if ($this->auth->isDavAuthenticated($user)) {
- return true;
- }
-
- if ($this->request->passesCSRFCheck()) {
- return true;
- }
-
- throw new BadRequest();
- }
-
-
}
diff --git a/apps/dav/lib/rootcollection.php b/apps/dav/lib/rootcollection.php
index 2a8f63a2270..b3648e7ba38 100644
--- a/apps/dav/lib/rootcollection.php
+++ b/apps/dav/lib/rootcollection.php
@@ -36,6 +36,7 @@ class RootCollection extends SimpleCollection {
public function __construct() {
$config = \OC::$server->getConfig();
$db = \OC::$server->getDatabaseConnection();
+ $dispatcher = \OC::$server->getEventDispatcher();
$userPrincipalBackend = new Principal(
\OC::$server->getUserManager(),
\OC::$server->getGroupManager()
@@ -79,11 +80,11 @@ class RootCollection extends SimpleCollection {
\OC::$server->getLogger()
);
- $usersCardDavBackend = new CardDavBackend($db, $userPrincipalBackend);
+ $usersCardDavBackend = new CardDavBackend($db, $userPrincipalBackend, $dispatcher);
$usersAddressBookRoot = new AddressBookRoot($userPrincipalBackend, $usersCardDavBackend, 'principals/users');
$usersAddressBookRoot->disableListing = $disableListing;
- $systemCardDavBackend = new CardDavBackend($db, $userPrincipalBackend);
+ $systemCardDavBackend = new CardDavBackend($db, $userPrincipalBackend, $dispatcher);
$systemAddressBookRoot = new AddressBookRoot(new SystemPrincipalBackend(), $systemCardDavBackend, 'principals/system');
$systemAddressBookRoot->disableListing = $disableListing;
diff --git a/apps/dav/lib/server.php b/apps/dav/lib/server.php
index f5f1875a480..ed1ee684049 100644
--- a/apps/dav/lib/server.php
+++ b/apps/dav/lib/server.php
@@ -53,7 +53,8 @@ class Server {
// Backends
$authBackend = new Auth(
\OC::$server->getSession(),
- \OC::$server->getUserSession()
+ \OC::$server->getUserSession(),
+ \OC::$server->getRequest()
);
// Set URL explicitly due to reverse-proxy situations
diff --git a/apps/dav/tests/travis/caldav/script.sh b/apps/dav/tests/travis/caldav/script.sh
index aa5fc732922..7259372567c 100644
--- a/apps/dav/tests/travis/caldav/script.sh
+++ b/apps/dav/tests/travis/caldav/script.sh
@@ -10,6 +10,8 @@ sleep 30
# run the tests
cd "$SCRIPTPATH/CalDAVTester"
PYTHONPATH="$SCRIPTPATH/pycalendar/src" python testcaldav.py --print-details-onfail --basedir "$SCRIPTPATH/../caldavtest/" -o cdt.txt \
+ "CalDAV/current-user-principal.xml" \
+ "CalDAV/sync-report.xml" \
"CalDAV/sharing-calendars.xml"
RESULT=$?
diff --git a/apps/dav/tests/unit/caldav/calendartest.php b/apps/dav/tests/unit/caldav/calendartest.php
index 93b3f4bff8c..4a3c94e8aba 100644
--- a/apps/dav/tests/unit/caldav/calendartest.php
+++ b/apps/dav/tests/unit/caldav/calendartest.php
@@ -37,7 +37,8 @@ class CalendarTest extends TestCase {
$calendarInfo = [
'{http://owncloud.org/ns}owner-principal' => 'user1',
'principaluri' => 'user2',
- 'id' => 666
+ 'id' => 666,
+ 'uri' => 'cal',
];
$c = new Calendar($backend, $calendarInfo);
$c->delete();
@@ -56,7 +57,8 @@ class CalendarTest extends TestCase {
$calendarInfo = [
'{http://owncloud.org/ns}owner-principal' => 'user1',
'principaluri' => 'user2',
- 'id' => 666
+ 'id' => 666,
+ 'uri' => 'cal',
];
$c = new Calendar($backend, $calendarInfo);
$c->delete();
diff --git a/apps/dav/tests/unit/carddav/birthdayservicetest.php b/apps/dav/tests/unit/carddav/birthdayservicetest.php
new file mode 100644
index 00000000000..faf42d9e1b8
--- /dev/null
+++ b/apps/dav/tests/unit/carddav/birthdayservicetest.php
@@ -0,0 +1,171 @@
+<?php
+/**
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ *
+ * @copyright Copyright (c) 2016, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\DAV\Tests\Unit\CardDAV;
+
+use OCA\DAV\CalDAV\BirthdayService;
+use OCA\DAV\CalDAV\CalDavBackend;
+use OCA\DAV\CardDAV\CardDavBackend;
+use Sabre\VObject\Component\VCalendar;
+use Sabre\VObject\Reader;
+use Test\TestCase;
+
+class BirthdayServiceTest extends TestCase {
+
+ /** @var BirthdayService */
+ private $service;
+ /** @var CalDavBackend | \PHPUnit_Framework_MockObject_MockObject */
+ private $calDav;
+ /** @var CardDavBackend | \PHPUnit_Framework_MockObject_MockObject */
+ private $cardDav;
+
+ public function setUp() {
+ parent::setUp();
+
+ $this->calDav = $this->getMockBuilder('OCA\DAV\CalDAV\CalDavBackend')->disableOriginalConstructor()->getMock();
+ $this->cardDav = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend')->disableOriginalConstructor()->getMock();
+
+ $this->service = new BirthdayService($this->calDav, $this->cardDav);
+ }
+
+ /**
+ * @dataProvider providesVCards
+ * @param boolean $nullExpected
+ * @param string | null $data
+ */
+ public function testBuildBirthdayFromContact($nullExpected, $data) {
+ $cal = $this->service->buildBirthdayFromContact($data);
+ if ($nullExpected) {
+ $this->assertNull($cal);
+ } else {
+ $this->assertInstanceOf('Sabre\VObject\Component\VCalendar', $cal);
+ $this->assertTrue(isset($cal->VEVENT));
+ $this->assertEquals('FREQ=YEARLY', $cal->VEVENT->RRULE->getValue());
+ $this->assertEquals('12345\'s Birthday (1900)', $cal->VEVENT->SUMMARY->getValue());
+ $this->assertEquals('TRANSPARENT', $cal->VEVENT->TRANSP->getValue());
+ }
+ }
+
+ public function testOnCardDeleted() {
+ $this->cardDav->expects($this->once())->method('getAddressBookById')
+ ->with(666)
+ ->willReturn([
+ 'principaluri' => 'principals/users/user01',
+ 'uri' => 'default'
+ ]);
+ $this->calDav->expects($this->once())->method('getCalendarByUri')
+ ->with('principals/users/user01', 'contact_birthdays')
+ ->willReturn([
+ 'id' => 1234
+ ]);
+ $this->calDav->expects($this->once())->method('deleteCalendarObject')->with(1234, 'default-gump.vcf.ics');
+
+ $this->service->onCardDeleted(666, 'gump.vcf');
+ }
+
+ /**
+ * @dataProvider providesCardChanges
+ */
+ public function testOnCardChanged($expectedOp) {
+ $this->cardDav->expects($this->once())->method('getAddressBookById')
+ ->with(666)
+ ->willReturn([
+ 'principaluri' => 'principals/users/user01',
+ 'uri' => 'default'
+ ]);
+ $this->calDav->expects($this->once())->method('getCalendarByUri')
+ ->with('principals/users/user01', 'contact_birthdays')
+ ->willReturn([
+ 'id' => 1234
+ ]);
+
+ /** @var BirthdayService | \PHPUnit_Framework_MockObject_MockObject $service */
+ $service = $this->getMock('\OCA\DAV\CalDAV\BirthdayService',
+ ['buildBirthdayFromContact', 'birthdayEvenChanged'], [$this->calDav, $this->cardDav]);
+
+ if ($expectedOp === 'delete') {
+ $this->calDav->expects($this->once())->method('getCalendarObject')->willReturn('');
+ $service->expects($this->once())->method('buildBirthdayFromContact')->willReturn(null);
+ $this->calDav->expects($this->once())->method('deleteCalendarObject')->with(1234, 'default-gump.vcf.ics');
+ }
+ if ($expectedOp === 'create') {
+ $service->expects($this->once())->method('buildBirthdayFromContact')->willReturn(new VCalendar());
+ $this->calDav->expects($this->once())->method('createCalendarObject')->with(1234, 'default-gump.vcf.ics', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nEND:VCALENDAR\r\n");
+ }
+ if ($expectedOp === 'update') {
+ $service->expects($this->once())->method('buildBirthdayFromContact')->willReturn(new VCalendar());
+ $service->expects($this->once())->method('birthdayEvenChanged')->willReturn(true);
+ $this->calDav->expects($this->once())->method('getCalendarObject')->willReturn([
+ 'calendardata' => '']);
+ $this->calDav->expects($this->once())->method('updateCalendarObject')->with(1234, 'default-gump.vcf.ics', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nEND:VCALENDAR\r\n");
+ }
+
+ $service->onCardChanged(666, 'gump.vcf', '');
+ }
+
+ /**
+ * @dataProvider providesBirthday
+ * @param $expected
+ * @param $old
+ * @param $new
+ */
+ public function testBirthdayEvenChanged($expected, $old, $new) {
+ $new = Reader::read($new);
+ $this->assertEquals($expected, $this->service->birthdayEvenChanged($old, $new));
+ }
+
+ public function providesBirthday() {
+ return [
+ [true,
+ '',
+ "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:12345\r\nDTSTAMP:20160218T133704Z\r\nDTSTART;VALUE=DATE:19000101\r\nDTEND;VALUE=DATE:19000102\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:12345's Birthday (1900)\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"],
+ [false,
+ "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:12345\r\nDTSTAMP:20160218T133704Z\r\nDTSTART;VALUE=DATE:19000101\r\nDTEND;VALUE=DATE:19000102\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:12345's Birthday (1900)\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n",
+ "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:12345\r\nDTSTAMP:20160218T133704Z\r\nDTSTART;VALUE=DATE:19000101\r\nDTEND;VALUE=DATE:19000102\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:12345's Birthday (1900)\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"],
+ [true,
+ "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:12345\r\nDTSTAMP:20160218T133704Z\r\nDTSTART;VALUE=DATE:19000101\r\nDTEND;VALUE=DATE:19000102\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:4567's Birthday (1900)\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n",
+ "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:12345\r\nDTSTAMP:20160218T133704Z\r\nDTSTART;VALUE=DATE:19000101\r\nDTEND;VALUE=DATE:19000102\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:12345's Birthday (1900)\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"],
+ [true,
+ "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:12345\r\nDTSTAMP:20160218T133704Z\r\nDTSTART;VALUE=DATE:19000101\r\nDTEND;VALUE=DATE:19000102\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:12345's Birthday (1900)\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n",
+ "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nCALSCALE:GREGORIAN\r\nBEGIN:VEVENT\r\nUID:12345\r\nDTSTAMP:20160218T133704Z\r\nDTSTART;VALUE=DATE:19000102\r\nDTEND;VALUE=DATE:19000102\r\nRRULE:FREQ=YEARLY\r\nSUMMARY:12345's Birthday (1900)\r\nTRANSP:TRANSPARENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"]
+ ];
+ }
+
+ public function providesCardChanges(){
+ return[
+ ['delete'],
+ ['create'],
+ ['update']
+ ];
+ }
+
+ public function providesVCards() {
+ return [
+ [true, null],
+ [true, ''],
+ [true, 'yasfewf'],
+ [true, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nEND:VCARD\r\n", "Dr. Foo Bar"],
+ [true, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:\r\nEND:VCARD\r\n", "Dr. Foo Bar"],
+ [true, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:someday\r\nEND:VCARD\r\n", "Dr. Foo Bar"],
+ [false, "BEGIN:VCARD\r\nVERSION:3.0\r\nPRODID:-//Sabre//Sabre VObject 3.5.0//EN\r\nUID:12345\r\nFN:12345\r\nN:12345;;;;\r\nBDAY:1900-01-01\r\nEND:VCARD\r\n", "Dr. Foo Bar"],
+ ];
+ }
+}
diff --git a/apps/dav/tests/unit/carddav/carddavbackendtest.php b/apps/dav/tests/unit/carddav/carddavbackendtest.php
index 3b5395fb09e..f920eb47b6e 100644
--- a/apps/dav/tests/unit/carddav/carddavbackendtest.php
+++ b/apps/dav/tests/unit/carddav/carddavbackendtest.php
@@ -77,7 +77,7 @@ class CardDavBackendTest extends TestCase {
$this->db = \OC::$server->getDatabaseConnection();
- $this->backend = new CardDavBackend($this->db, $this->principal);
+ $this->backend = new CardDavBackend($this->db, $this->principal, null);
// start every test with a empty cards_properties and cards table
$query = $this->db->getQueryBuilder();
@@ -155,7 +155,7 @@ class CardDavBackendTest extends TestCase {
/** @var CardDavBackend | \PHPUnit_Framework_MockObject_MockObject $backend */
$backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend')
- ->setConstructorArgs([$this->db, $this->principal])
+ ->setConstructorArgs([$this->db, $this->principal, null])
->setMethods(['updateProperties', 'purgeProperties'])->getMock();
// create a new address book
@@ -201,7 +201,7 @@ class CardDavBackendTest extends TestCase {
public function testMultiCard() {
$this->backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend')
- ->setConstructorArgs([$this->db, $this->principal])
+ ->setConstructorArgs([$this->db, $this->principal, null])
->setMethods(['updateProperties'])->getMock();
// create a new address book
@@ -248,7 +248,7 @@ class CardDavBackendTest extends TestCase {
public function testDeleteWithoutCard() {
$this->backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend')
- ->setConstructorArgs([$this->db, $this->principal])
+ ->setConstructorArgs([$this->db, $this->principal, null])
->setMethods([
'getCardId',
'addChange',
@@ -289,7 +289,7 @@ class CardDavBackendTest extends TestCase {
public function testSyncSupport() {
$this->backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend')
- ->setConstructorArgs([$this->db, $this->principal])
+ ->setConstructorArgs([$this->db, $this->principal, null])
->setMethods(['updateProperties'])->getMock();
// create a new address book
@@ -347,7 +347,7 @@ class CardDavBackendTest extends TestCase {
$cardId = 2;
$backend = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend')
- ->setConstructorArgs([$this->db, $this->principal])
+ ->setConstructorArgs([$this->db, $this->principal, null])
->setMethods(['getCardId'])->getMock();
$backend->expects($this->any())->method('getCardId')->willReturn($cardId);
diff --git a/apps/dav/tests/unit/connector/sabre/auth.php b/apps/dav/tests/unit/connector/sabre/auth.php
index 5ff736664f3..57ed44f01c0 100644
--- a/apps/dav/tests/unit/connector/sabre/auth.php
+++ b/apps/dav/tests/unit/connector/sabre/auth.php
@@ -24,6 +24,7 @@
namespace OCA\DAV\Tests\Unit\Connector\Sabre;
+use OCP\IRequest;
use OCP\IUser;
use Test\TestCase;
use OCP\ISession;
@@ -42,6 +43,8 @@ class Auth extends TestCase {
private $auth;
/** @var IUserSession */
private $userSession;
+ /** @var IRequest */
+ private $request;
public function setUp() {
parent::setUp();
@@ -49,7 +52,13 @@ class Auth extends TestCase {
->disableOriginalConstructor()->getMock();
$this->userSession = $this->getMockBuilder('\OCP\IUserSession')
->disableOriginalConstructor()->getMock();
- $this->auth = new \OCA\DAV\Connector\Sabre\Auth($this->session, $this->userSession);
+ $this->request = $this->getMockBuilder('\OCP\IRequest')
+ ->disableOriginalConstructor()->getMock();
+ $this->auth = new \OCA\DAV\Connector\Sabre\Auth(
+ $this->session,
+ $this->userSession,
+ $this->request
+ );
}
public function testIsDavAuthenticatedWithoutDavSession() {
@@ -189,51 +198,57 @@ class Auth extends TestCase {
$this->assertFalse($this->invokePrivate($this->auth, 'validateUserPass', ['MyTestUser', 'MyTestPassword']));
}
- public function testGetCurrentUserWithoutBeingLoggedIn() {
- $this->assertSame(null, $this->auth->getCurrentUser());
- }
-
- public function testGetCurrentUserWithValidDAVLogin() {
+ /**
+ * @expectedException \Sabre\DAV\Exception\NotAuthenticated
+ * @expectedExceptionMessage CSRF check not passed.
+ */
+ public function testAuthenticateAlreadyLoggedInWithoutCsrfTokenForNonGet() {
+ $request = $this->getMockBuilder('Sabre\HTTP\RequestInterface')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $response = $this->getMockBuilder('Sabre\HTTP\ResponseInterface')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->userSession
+ ->expects($this->once())
+ ->method('isLoggedIn')
+ ->will($this->returnValue(true));
+ $this->session
+ ->expects($this->once())
+ ->method('get')
+ ->with('AUTHENTICATED_TO_DAV_BACKEND')
+ ->will($this->returnValue(null));
$user = $this->getMockBuilder('\OCP\IUser')
->disableOriginalConstructor()
->getMock();
$user->expects($this->once())
->method('getUID')
- ->will($this->returnValue('MyTestUser'));
+ ->will($this->returnValue('MyWrongDavUser'));
$this->userSession
- ->expects($this->exactly(2))
+ ->expects($this->once())
->method('getUser')
->will($this->returnValue($user));
- $this->session
- ->expects($this->exactly(2))
- ->method('get')
- ->with('AUTHENTICATED_TO_DAV_BACKEND')
- ->will($this->returnValue('MyTestUser'));
- $this->assertSame('MyTestUser', $this->auth->getCurrentUser());
+ $response = $this->auth->check($request, $response);
+ $this->assertEquals([true, 'principals/users/MyWrongDavUser'], $response);
}
- public function testGetCurrentUserWithoutAnyDAVLogin() {
- $user = $this->getMockBuilder('\OCP\IUser')
+ public function testAuthenticateAlreadyLoggedInWithoutCsrfTokenForGet() {
+ $request = $this->getMockBuilder('Sabre\HTTP\RequestInterface')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $response = $this->getMockBuilder('Sabre\HTTP\ResponseInterface')
->disableOriginalConstructor()
->getMock();
- $user->expects($this->once())
- ->method('getUID')
- ->will($this->returnValue('MyTestUser'));
$this->userSession
->expects($this->exactly(2))
- ->method('getUser')
- ->will($this->returnValue($user));
+ ->method('isLoggedIn')
+ ->will($this->returnValue(true));
$this->session
- ->expects($this->exactly(2))
+ ->expects($this->once())
->method('get')
->with('AUTHENTICATED_TO_DAV_BACKEND')
->will($this->returnValue(null));
-
- $this->assertSame('MyTestUser', $this->auth->getCurrentUser());
- }
-
- public function testGetCurrentUserWithWrongDAVUser() {
$user = $this->getMockBuilder('\OCP\IUser')
->disableOriginalConstructor()
->getMock();
@@ -241,47 +256,49 @@ class Auth extends TestCase {
->method('getUID')
->will($this->returnValue('MyWrongDavUser'));
$this->userSession
- ->expects($this->exactly(2))
+ ->expects($this->once())
->method('getUser')
->will($this->returnValue($user));
- $this->session
- ->expects($this->exactly(3))
- ->method('get')
- ->with('AUTHENTICATED_TO_DAV_BACKEND')
- ->will($this->returnValue('AnotherUser'));
+ $this->request
+ ->expects($this->once())
+ ->method('getMethod')
+ ->willReturn('GET');
- $this->assertSame(null, $this->auth->getCurrentUser());
+ $response = $this->auth->check($request, $response);
+ $this->assertEquals([true, 'principals/users/MyWrongDavUser'], $response);
}
- public function testAuthenticateAlreadyLoggedIn() {
+
+ public function testAuthenticateAlreadyLoggedInWithCsrfTokenForGet() {
$request = $this->getMockBuilder('Sabre\HTTP\RequestInterface')
- ->disableOriginalConstructor()
- ->getMock();
+ ->disableOriginalConstructor()
+ ->getMock();
$response = $this->getMockBuilder('Sabre\HTTP\ResponseInterface')
- ->disableOriginalConstructor()
- ->getMock();
+ ->disableOriginalConstructor()
+ ->getMock();
$this->userSession
- ->expects($this->once())
+ ->expects($this->exactly(2))
->method('isLoggedIn')
->will($this->returnValue(true));
$this->session
- ->expects($this->once())
+ ->expects($this->exactly(2))
->method('get')
->with('AUTHENTICATED_TO_DAV_BACKEND')
->will($this->returnValue(null));
$user = $this->getMockBuilder('\OCP\IUser')
->disableOriginalConstructor()
->getMock();
- $user->expects($this->once())
+ $user->expects($this->exactly(2))
->method('getUID')
->will($this->returnValue('MyWrongDavUser'));
$this->userSession
- ->expects($this->once())
+ ->expects($this->exactly(2))
->method('getUser')
->will($this->returnValue($user));
- $this->session
+ $this->request
->expects($this->once())
- ->method('close');
+ ->method('passesCSRFCheck')
+ ->willReturn(true);
$response = $this->auth->check($request, $response);
$this->assertEquals([true, 'principals/users/MyWrongDavUser'], $response);
diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php
index f496fc77574..ee7a7383615 100644
--- a/apps/files_external/lib/google.php
+++ b/apps/files_external/lib/google.php
@@ -264,7 +264,7 @@ class Google extends \OC\Files\Storage\Common {
foreach ($children->getItems() as $child) {
$name = $child->getTitle();
// Check if this is a Google Doc i.e. no extension in name
- if ($child->getFileExtension() === ''
+ if (empty($child->getFileExtension())
&& $child->getMimeType() !== self::FOLDER
) {
$name .= '.'.$this->getGoogleDocExtension($child->getMimeType());
@@ -368,8 +368,14 @@ class Google extends \OC\Files\Storage\Common {
public function rename($path1, $path2) {
$file = $this->getDriveFile($path1);
if ($file) {
+ $newFile = $this->getDriveFile($path2);
if (dirname($path1) === dirname($path2)) {
- $file->setTitle(basename(($path2)));
+ if ($newFile) {
+ // rename to the name of the target file, could be an office file without extension
+ $file->setTitle($newFile->getTitle());
+ } else {
+ $file->setTitle(basename(($path2)));
+ }
} else {
// Change file parent
$parentFolder2 = $this->getDriveFile(dirname($path2));
@@ -394,8 +400,11 @@ class Google extends \OC\Files\Storage\Common {
if ($result) {
$this->setDriveFile($path1, false);
$this->setDriveFile($path2, $result);
- if ($oldfile) {
- $this->service->files->delete($oldfile->getId());
+ if ($oldfile && $newFile) {
+ // only delete if they have a different id (same id can happen for part files)
+ if ($newFile->getId() !== $oldfile->getId()) {
+ $this->service->files->delete($oldfile->getId());
+ }
}
}
return (bool)$result;
diff --git a/core/js/files/client.js b/core/js/files/client.js
index a7f393d325f..0bf5a69e19c 100644
--- a/core/js/files/client.js
+++ b/core/js/files/client.js
@@ -37,7 +37,10 @@
}
url += options.host + this._root;
- this._defaultHeaders = options.defaultHeaders || {'X-Requested-With': 'XMLHttpRequest'};
+ this._defaultHeaders = options.defaultHeaders || {
+ 'X-Requested-With': 'XMLHttpRequest',
+ 'requesttoken': OC.requestToken
+ };
this._baseUrl = url;
var clientOptions = {
diff --git a/core/js/oc-backbone-webdav.js b/core/js/oc-backbone-webdav.js
index ba678a32fcf..1c1b5c71d81 100644
--- a/core/js/oc-backbone-webdav.js
+++ b/core/js/oc-backbone-webdav.js
@@ -240,7 +240,8 @@
return options.url;
};
var headers = _.extend({
- 'X-Requested-With': 'XMLHttpRequest'
+ 'X-Requested-With': 'XMLHttpRequest',
+ 'requesttoken': OC.requestToken
}, options.headers);
if (options.type === 'PROPFIND') {
return callPropFind(client, options, model, headers);
diff --git a/issue_template.md b/issue_template.md
index 424f6c062a9..e19583977ef 100644
--- a/issue_template.md
+++ b/issue_template.md
@@ -1,3 +1,10 @@
+<!--
+Thanks for reporting issues back to ownCloud! This is the issue tracker of ownCloud, if you have any support question please check out https://owncloud.org/support
+
+This is the bug tracker for the Server component. Find other components at https://github.com/owncloud/core/blob/master/CONTRIBUTING.md#guidelines
+
+To make it possible for us to help you please fill out below information carefully.
+-->
### Steps to reproduce
1.
2.
diff --git a/lib/private/api.php b/lib/private/api.php
index 6c6be233c9d..87f2aa9b118 100644
--- a/lib/private/api.php
+++ b/lib/private/api.php
@@ -188,7 +188,7 @@ class OC_API {
/**
* merge the returned result objects into one response
* @param array $responses
- * @return array|\OC_OCS_Result
+ * @return OC_OCS_Result
*/
public static function mergeResponses($responses) {
// Sort into shipped and third-party
@@ -442,6 +442,7 @@ class OC_API {
/**
* Based on the requested format the response content type is set
+ * @param string $format
*/
public static function setContentType($format = null) {
$format = is_null($format) ? self::requestedFormat() : $format;
diff --git a/lib/private/files/stream/encryption.php b/lib/private/files/stream/encryption.php
index 63949035b5a..37a1d75519d 100644
--- a/lib/private/files/stream/encryption.php
+++ b/lib/private/files/stream/encryption.php
@@ -183,7 +183,7 @@ class Encryption extends Wrapper {
*
* @param resource $source
* @param string $mode
- * @param array $context
+ * @param resource $context
* @param string $protocol
* @param string $class
* @return resource
diff --git a/lib/private/group/dummy.php b/lib/private/group/dummy.php
index c0d206a34e1..97f00385954 100644
--- a/lib/private/group/dummy.php
+++ b/lib/private/group/dummy.php
@@ -114,6 +114,7 @@ class OC_Group_Dummy extends OC_Group_Backend {
if(isset($this->groups[$gid])) {
if(($index=array_search($uid, $this->groups[$gid]))!==false) {
unset($this->groups[$gid][$index]);
+ return true;
}else{
return false;
}
diff --git a/lib/private/group/manager.php b/lib/private/group/manager.php
index 98e5551bcc5..7eca249c701 100644
--- a/lib/private/group/manager.php
+++ b/lib/private/group/manager.php
@@ -150,6 +150,10 @@ class Manager extends PublicEmitter implements IGroupManager {
return $this->getGroupObject($gid);
}
+ /**
+ * @param string $gid
+ * @return \OCP\IGroup
+ */
protected function getGroupObject($gid) {
$backends = array();
foreach ($this->backends as $backend) {
diff --git a/lib/private/memcache/factory.php b/lib/private/memcache/factory.php
index 21149d8b6bf..204ded7d5ab 100644
--- a/lib/private/memcache/factory.php
+++ b/lib/private/memcache/factory.php
@@ -172,7 +172,7 @@ class Factory implements ICacheFactory {
/**
* @see \OC\Memcache\Factory::createLocal()
* @param string $prefix
- * @return \OC\Memcache\Cache|null
+ * @return Cache
*/
public function createLowLatency($prefix = '') {
return $this->createLocal($prefix);
diff --git a/lib/private/preview.php b/lib/private/preview.php
index df6eeceddcb..4fca56dd984 100644
--- a/lib/private/preview.php
+++ b/lib/private/preview.php
@@ -202,7 +202,7 @@ class Preview {
/**
* returns the max width set in ownCloud's config
*
- * @return string
+ * @return integer
*/
public function getConfigMaxX() {
return $this->configMaxWidth;
@@ -211,7 +211,7 @@ class Preview {
/**
* returns the max height set in ownCloud's config
*
- * @return string
+ * @return integer
*/
public function getConfigMaxY() {
return $this->configMaxHeight;
@@ -546,7 +546,7 @@ class Preview {
/**
* Determines the size of the preview we should be looking for in the cache
*
- * @return int[]
+ * @return integer[]
*/
private function simulatePreviewDimensions() {
$askedWidth = $this->getMaxX();
@@ -570,7 +570,7 @@ class Preview {
*
* @param int $originalWidth
* @param int $originalHeight
- * @return \int[]
+ * @return integer[]
*/
private function applyAspectRatio($askedWidth, $askedHeight, $originalWidth = 0, $originalHeight = 0) {
if(!$originalWidth){
@@ -602,7 +602,7 @@ class Preview {
* @param int $askedHeight
* @param int $previewWidth
* @param int $previewHeight
- * @return \int[]
+ * @return integer[]
*/
private function applyCover($askedWidth, $askedHeight, $previewWidth, $previewHeight) {
$originalRatio = $previewWidth / $previewHeight;
@@ -628,7 +628,7 @@ class Preview {
* @param int $askedWidth
* @param int $askedHeight
*
- * @return \int[]
+ * @return integer[]
*/
private function fixSize($askedWidth, $askedHeight) {
if ($this->scalingUp) {
@@ -921,7 +921,7 @@ class Preview {
* @param int $askedWidth
* @param int $askedHeight
* @param int $previewWidth
- * @param null $previewHeight
+ * @param int $previewHeight
*
* @return int[]
*/
@@ -971,7 +971,7 @@ class Preview {
* @param int $askedWidth
* @param int $askedHeight
* @param int $previewWidth
- * @param null $previewHeight
+ * @param int $previewHeight
*/
private function crop($image, $askedWidth, $askedHeight, $previewWidth, $previewHeight = null) {
$cropX = floor(abs($askedWidth - $previewWidth) * 0.5);
@@ -990,7 +990,7 @@ class Preview {
* @param int $askedWidth
* @param int $askedHeight
* @param int $previewWidth
- * @param null $previewHeight
+ * @param int $previewHeight
*/
private function cropAndFill($image, $askedWidth, $askedHeight, $previewWidth, $previewHeight) {
if ($previewWidth > $askedWidth) {
@@ -1218,7 +1218,7 @@ class Preview {
* @param int $maxDim
* @param string $dimName
*
- * @return mixed
+ * @return integer
*/
private function limitMaxDim($dim, $maxDim, $dimName) {
if (!is_null($maxDim)) {
diff --git a/lib/public/appframework/utility/icontrollermethodreflector.php b/lib/public/appframework/utility/icontrollermethodreflector.php
index b2f91fdb170..7bf422aa567 100644
--- a/lib/public/appframework/utility/icontrollermethodreflector.php
+++ b/lib/public/appframework/utility/icontrollermethodreflector.php
@@ -35,6 +35,7 @@ interface IControllerMethodReflector {
/**
* @param object $object an object or classname
* @param string $method the method which we want to inspect
+ * @return void
* @since 8.0.0
*/
public function reflect($object, $method);
diff --git a/lib/public/search/pagedprovider.php b/lib/public/search/pagedprovider.php
index 93289a1bde4..c8530626e59 100644
--- a/lib/public/search/pagedprovider.php
+++ b/lib/public/search/pagedprovider.php
@@ -58,7 +58,7 @@ abstract class PagedProvider extends Provider {
* Search for $query
* @param string $query
* @param int $page pages start at page 1
- * @param int $size, 0 = SIZE_ALL
+ * @param int $size 0 = SIZE_ALL
* @return array An array of OCP\Search\Result's
* @since 8.0.0
*/