diff options
Diffstat (limited to 'apps')
130 files changed, 1816 insertions, 1744 deletions
diff --git a/apps/dav/appinfo/application.php b/apps/dav/appinfo/application.php index 593cd770be5..c3811a40845 100644 --- a/apps/dav/appinfo/application.php +++ b/apps/dav/appinfo/application.php @@ -30,10 +30,6 @@ use OCA\DAV\CardDAV\SyncService; use OCA\DAV\Connector\Sabre\Principal; use OCA\DAV\DAV\GroupPrincipalBackend; use OCA\DAV\HookManager; -use OCA\Dav\Migration\AddressBookAdapter; -use OCA\Dav\Migration\CalendarAdapter; -use OCA\Dav\Migration\MigrateAddressbooks; -use OCA\Dav\Migration\MigrateCalendars; use \OCP\AppFramework\App; use OCP\AppFramework\IAppContainer; use OCP\Contacts\IManager; @@ -98,30 +94,6 @@ class Application extends App { return new CalDavBackend($db, $principal); }); - $container->registerService('MigrateAddressbooks', function($c) { - /** @var IAppContainer $c */ - $db = $c->getServer()->getDatabaseConnection(); - $logger = $c->getServer()->getLogger(); - return new MigrateAddressbooks( - new AddressBookAdapter($db), - $c->query('CardDavBackend'), - $logger, - null - ); - }); - - $container->registerService('MigrateCalendars', function($c) { - /** @var IAppContainer $c */ - $db = $c->getServer()->getDatabaseConnection(); - $logger = $c->getServer()->getLogger(); - return new MigrateCalendars( - new CalendarAdapter($db), - $c->query('CalDavBackend'), - $logger, - null - ); - }); - $container->registerService('BirthdayService', function($c) { /** @var IAppContainer $c */ $g = new GroupPrincipalBackend( @@ -186,38 +158,6 @@ class Application extends App { $jl->add(new SyncJob()); } - public function migrateAddressbooks() { - try { - /** @var MigrateAddressbooks $migration */ - $migration = $this->getContainer()->query('MigrateAddressbooks'); - $migration->setup(); - $userManager = $this->getContainer()->getServer()->getUserManager(); - - $userManager->callForAllUsers(function($user) use($migration) { - /** @var IUser $user */ - $migration->migrateForUser($user->getUID()); - }); - } catch (\Exception $ex) { - $this->getContainer()->getServer()->getLogger()->logException($ex); - } - } - - public function migrateCalendars() { - try { - /** @var MigrateCalendars $migration */ - $migration = $this->getContainer()->query('MigrateCalendars'); - $migration->setup(); - $userManager = $this->getContainer()->getServer()->getUserManager(); - - $userManager->callForAllUsers(function($user) use($migration) { - /** @var IUser $user */ - $migration->migrateForUser($user->getUID()); - }); - } catch (\Exception $ex) { - $this->getContainer()->getServer()->getLogger()->logException($ex); - } - } - public function generateBirthdays() { try { /** @var BirthdayService $migration */ diff --git a/apps/dav/appinfo/install.php b/apps/dav/appinfo/install.php index dc5ae39226e..fbd41d25f49 100644 --- a/apps/dav/appinfo/install.php +++ b/apps/dav/appinfo/install.php @@ -23,6 +23,4 @@ use OCA\Dav\AppInfo\Application; $app = new Application(); $app->setupCron(); -$app->migrateAddressbooks(); -$app->migrateCalendars(); $app->generateBirthdays(); diff --git a/apps/dav/appinfo/register_command.php b/apps/dav/appinfo/register_command.php index 570848f0b23..b3ab25a99e3 100644 --- a/apps/dav/appinfo/register_command.php +++ b/apps/dav/appinfo/register_command.php @@ -21,8 +21,6 @@ use OCA\Dav\AppInfo\Application; 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; @@ -37,5 +35,3 @@ $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'))); -$application->add(new MigrateAddressbooks($userManager, $app->getContainer()->query('MigrateAddressbooks'))); -$application->add(new MigrateCalendars($userManager, $app->getContainer()->query('MigrateCalendars'))); diff --git a/apps/dav/appinfo/v1/publicwebdav.php b/apps/dav/appinfo/v1/publicwebdav.php index b26e9ebe7c8..43fedb19415 100644 --- a/apps/dav/appinfo/v1/publicwebdav.php +++ b/apps/dav/appinfo/v1/publicwebdav.php @@ -30,6 +30,7 @@ $RUNTIME_APPTYPES = ['filesystem', 'authentication', 'logging']; OC_App::loadApps($RUNTIME_APPTYPES); OC_Util::obEnd(); +\OC::$server->getSession()->close(); // Backends $authBackend = new OCA\DAV\Connector\PublicAuth( diff --git a/apps/dav/bin/chunkperf.php b/apps/dav/bin/chunkperf.php new file mode 100644 index 00000000000..a193f001a41 --- /dev/null +++ b/apps/dav/bin/chunkperf.php @@ -0,0 +1,76 @@ +<?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/> + * + */ + +require '../../../../3rdparty/autoload.php'; + +if ($argc !== 6) { + echo "Invalid number of arguments" . PHP_EOL; + exit; +} + +/** + * @param \Sabre\DAV\Client $client + * @param $uploadUrl + * @return mixed + */ +function request($client, $method, $uploadUrl, $data = null, $headers = []) { + echo "$method $uploadUrl ... "; + $t0 = microtime(true); + $result = $client->request($method, $uploadUrl, $data, $headers); + $t1 = microtime(true); + echo $result['statusCode'] . " - " . ($t1 - $t0) . ' seconds' . PHP_EOL; + if (!in_array($result['statusCode'], [200, 201])) { + echo $result['body'] . PHP_EOL; + } + return $result; +} + +$baseUri = $argv[1]; +$userName = $argv[2]; +$password = $argv[3]; +$file = $argv[4]; +$chunkSize = $argv[5] * 1024 * 1024; + +$client = new \Sabre\DAV\Client([ + 'baseUri' => $baseUri, + 'userName' => $userName, + 'password' => $password +]); + +$transfer = uniqid('transfer', true); +$uploadUrl = "$baseUri/uploads/$userName/$transfer"; + +request($client, 'MKCOL', $uploadUrl); + +$size = filesize($file); +$stream = fopen($file, 'r'); + +$index = 0; +while(!feof($stream)) { + request($client, 'PUT', "$uploadUrl/$index", fread($stream, $chunkSize)); + $index++; +} + +$destination = pathinfo($file, PATHINFO_BASENAME); +//echo "Moving $uploadUrl/.file to it's final destination $baseUri/files/$userName/$destination" . PHP_EOL; +request($client, 'MOVE', "$uploadUrl/.file", null, [ + 'Destination' => "$baseUri/files/$userName/$destination" +]); diff --git a/apps/dav/command/migrateaddressbooks.php b/apps/dav/command/migrateaddressbooks.php deleted file mode 100644 index 562f19a2300..00000000000 --- a/apps/dav/command/migrateaddressbooks.php +++ /dev/null @@ -1,86 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OCA\Dav\Command; - -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 MigrateAddressbooks extends Command { - - /** @var IUserManager */ - protected $userManager; - - /** @var \OCA\Dav\Migration\MigrateAddressbooks */ - private $service; - - /** - * @param IUserManager $userManager - * @param \OCA\Dav\Migration\MigrateAddressbooks $service - */ - function __construct(IUserManager $userManager, - \OCA\Dav\Migration\MigrateAddressbooks $service - ) { - parent::__construct(); - $this->userManager = $userManager; - $this->service = $service; - } - - protected function configure() { - $this - ->setName('dav:migrate-addressbooks') - ->setDescription('Migrate addressbooks from the contacts app to core') - ->addArgument('user', - InputArgument::OPTIONAL, - 'User for whom all addressbooks will be migrated'); - } - - protected function execute(InputInterface $input, OutputInterface $output) { - $this->service->setup(); - - $user = $input->getArgument('user'); - if (!is_null($user)) { - if (!$this->userManager->userExists($user)) { - throw new \InvalidArgumentException("User <$user> in unknown."); - } - $output->writeln("Start migration for $user"); - $this->service->migrateForUser($user); - return; - } - $output->writeln("Start migration of all known users ..."); - $p = new ProgressBar($output); - $p->start(); - $this->userManager->callForAllUsers(function($user) use ($p) { - $p->advance(); - /** @var IUser $user */ - $this->service->migrateForUser($user->getUID()); - }); - - $p->finish(); - $output->writeln(''); - } -} diff --git a/apps/dav/command/migratecalendars.php b/apps/dav/command/migratecalendars.php deleted file mode 100644 index d887309ac3e..00000000000 --- a/apps/dav/command/migratecalendars.php +++ /dev/null @@ -1,85 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ -namespace OCA\Dav\Command; - -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 MigrateCalendars extends Command { - - /** @var IUserManager */ - protected $userManager; - - /** @var \OCA\Dav\Migration\MigrateCalendars */ - private $service; - - /** - * @param IUserManager $userManager - * @param \OCA\Dav\Migration\MigrateCalendars $service - */ - function __construct(IUserManager $userManager, - \OCA\Dav\Migration\MigrateCalendars $service - ) { - parent::__construct(); - $this->userManager = $userManager; - $this->service = $service; - } - - protected function configure() { - $this - ->setName('dav:migrate-calendars') - ->setDescription('Migrate calendars from the calendar app to core') - ->addArgument('user', - InputArgument::OPTIONAL, - 'User for whom all calendars will be migrated'); - } - - protected function execute(InputInterface $input, OutputInterface $output) { - $this->service->setup(); - - $user = $input->getArgument('user'); - if (!is_null($user)) { - if (!$this->userManager->userExists($user)) { - throw new \InvalidArgumentException("User <$user> in unknown."); - } - $output->writeln("Start migration for $user"); - $this->service->migrateForUser($user); - return; - } - $output->writeln("Start migration of all known users ..."); - $p = new ProgressBar($output); - $p->start(); - $this->userManager->callForAllUsers(function($user) use ($p) { - $p->advance(); - /** @var IUser $user */ - $this->service->migrateForUser($user->getUID()); - }); - - $p->finish(); - $output->writeln(''); - } -} diff --git a/apps/dav/lib/caldav/birthdayservice.php b/apps/dav/lib/caldav/birthdayservice.php index 1d0b06f03a8..b74116f4083 100644 --- a/apps/dav/lib/caldav/birthdayservice.php +++ b/apps/dav/lib/caldav/birthdayservice.php @@ -204,7 +204,7 @@ class BirthdayService { } /** - * @param $addressBookId + * @param integer $addressBookId * @return mixed */ protected function getAllAffectedPrincipals($addressBookId) { diff --git a/apps/dav/lib/caldav/calendar.php b/apps/dav/lib/caldav/calendar.php index 5072d96107e..6d6c0b5d7a4 100644 --- a/apps/dav/lib/caldav/calendar.php +++ b/apps/dav/lib/caldav/calendar.php @@ -22,17 +22,19 @@ namespace OCA\DAV\CalDAV; use OCA\DAV\DAV\Sharing\IShareable; +use OCP\IL10N; use Sabre\CalDAV\Backend\BackendInterface; use Sabre\DAV\Exception\Forbidden; use Sabre\DAV\PropPatch; class Calendar extends \Sabre\CalDAV\Calendar implements IShareable { - public function __construct(BackendInterface $caldavBackend, $calendarInfo) { + public function __construct(BackendInterface $caldavBackend, $calendarInfo, IL10N $l10n) { parent::__construct($caldavBackend, $calendarInfo); if ($this->getName() === BirthdayService::BIRTHDAY_CALENDAR_URI) { $this->calendarInfo['{http://sabredav.org/ns}read-only'] = true; + $this->calendarInfo['{DAV:}displayname'] = $l10n->t('Contact birthdays'); } } diff --git a/apps/dav/lib/caldav/calendarhome.php b/apps/dav/lib/caldav/calendarhome.php index 87b8d4bb320..a4c485a8983 100644 --- a/apps/dav/lib/caldav/calendarhome.php +++ b/apps/dav/lib/caldav/calendarhome.php @@ -21,6 +21,7 @@ */ namespace OCA\DAV\CalDAV; +use Sabre\CalDAV\Backend\BackendInterface; use Sabre\CalDAV\Backend\NotificationSupport; use Sabre\CalDAV\Backend\SchedulingSupport; use Sabre\CalDAV\Backend\SubscriptionSupport; @@ -31,34 +32,42 @@ use Sabre\DAV\Exception\NotFound; class CalendarHome extends \Sabre\CalDAV\CalendarHome { + /** @var \OCP\IL10N */ + private $l10n; + + public function __construct(BackendInterface $caldavBackend, $principalInfo) { + parent::__construct($caldavBackend, $principalInfo); + $this->l10n = \OC::$server->getL10N('dav'); + } + /** * @inheritdoc */ function getChildren() { $calendars = $this->caldavBackend->getCalendarsForUser($this->principalInfo['uri']); - $objs = []; + $objects = []; foreach ($calendars as $calendar) { - $objs[] = new Calendar($this->caldavBackend, $calendar); + $objects[] = new Calendar($this->caldavBackend, $calendar, $this->l10n); } if ($this->caldavBackend instanceof SchedulingSupport) { - $objs[] = new Inbox($this->caldavBackend, $this->principalInfo['uri']); - $objs[] = new Outbox($this->principalInfo['uri']); + $objects[] = new Inbox($this->caldavBackend, $this->principalInfo['uri']); + $objects[] = new Outbox($this->principalInfo['uri']); } // We're adding a notifications node, if it's supported by the backend. if ($this->caldavBackend instanceof NotificationSupport) { - $objs[] = new \Sabre\CalDAV\Notifications\Collection($this->caldavBackend, $this->principalInfo['uri']); + $objects[] = new \Sabre\CalDAV\Notifications\Collection($this->caldavBackend, $this->principalInfo['uri']); } // If the backend supports subscriptions, we'll add those as well, if ($this->caldavBackend instanceof SubscriptionSupport) { foreach ($this->caldavBackend->getSubscriptionsForUser($this->principalInfo['uri']) as $subscription) { - $objs[] = new Subscription($this->caldavBackend, $subscription); + $objects[] = new Subscription($this->caldavBackend, $subscription); } } - return $objs; + return $objects; } /** @@ -79,7 +88,7 @@ class CalendarHome extends \Sabre\CalDAV\CalendarHome { // Calendars foreach ($this->caldavBackend->getCalendarsForUser($this->principalInfo['uri']) as $calendar) { if ($calendar['uri'] === $name) { - return new Calendar($this->caldavBackend, $calendar); + return new Calendar($this->caldavBackend, $calendar, $this->l10n); } } @@ -94,4 +103,4 @@ class CalendarHome extends \Sabre\CalDAV\CalendarHome { throw new NotFound('Node with name \'' . $name . '\' could not be found'); } -}
\ No newline at end of file +} diff --git a/apps/dav/lib/connector/sabre/file.php b/apps/dav/lib/connector/sabre/file.php index 6b698c6e5a9..943e9150e74 100644 --- a/apps/dav/lib/connector/sabre/file.php +++ b/apps/dav/lib/connector/sabre/file.php @@ -143,7 +143,7 @@ class File extends Node implements IFile { // if content length is sent by client: // double check if the file was fully received // compare expected and actual size - if (isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['REQUEST_METHOD'] !== 'LOCK') { + if (isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['REQUEST_METHOD'] === 'PUT') { $expected = $_SERVER['CONTENT_LENGTH']; if ($count != $expected) { throw new BadRequest('expected filesize ' . $expected . ' got ' . $count); diff --git a/apps/dav/lib/connector/sabre/filesplugin.php b/apps/dav/lib/connector/sabre/filesplugin.php index 8b54291793a..dd4670da5fa 100644 --- a/apps/dav/lib/connector/sabre/filesplugin.php +++ b/apps/dav/lib/connector/sabre/filesplugin.php @@ -28,24 +28,27 @@ namespace OCA\DAV\Connector\Sabre; use OC\Files\View; +use OCA\DAV\Upload\FutureFile; use Sabre\DAV\Exception\Forbidden; use Sabre\DAV\Exception\NotFound; use Sabre\DAV\IFile; use \Sabre\DAV\PropFind; use \Sabre\DAV\PropPatch; +use Sabre\DAV\ServerPlugin; use Sabre\DAV\Tree; use \Sabre\HTTP\RequestInterface; use \Sabre\HTTP\ResponseInterface; use OCP\Files\StorageNotAvailableException; +use OCP\IConfig; -class FilesPlugin extends \Sabre\DAV\ServerPlugin { +class FilesPlugin extends ServerPlugin { // namespace const NS_OWNCLOUD = 'http://owncloud.org/ns'; const FILEID_PROPERTYNAME = '{http://owncloud.org/ns}id'; const INTERNAL_FILEID_PROPERTYNAME = '{http://owncloud.org/ns}fileid'; const PERMISSIONS_PROPERTYNAME = '{http://owncloud.org/ns}permissions'; - const SHARE_PERMISSIONS_PROPERTYNAME = '{http://owncloud.org/ns}share-permissions'; + const SHARE_PERMISSIONS_PROPERTYNAME = '{http://open-collaboration-services.org/ns}share-permissions'; const DOWNLOADURL_PROPERTYNAME = '{http://owncloud.org/ns}downloadURL'; const SIZE_PROPERTYNAME = '{http://owncloud.org/ns}size'; const GETETAG_PROPERTYNAME = '{DAV:}getetag'; @@ -53,6 +56,7 @@ class FilesPlugin extends \Sabre\DAV\ServerPlugin { const OWNER_ID_PROPERTYNAME = '{http://owncloud.org/ns}owner-id'; const OWNER_DISPLAY_NAME_PROPERTYNAME = '{http://owncloud.org/ns}owner-display-name'; const CHECKSUMS_PROPERTYNAME = '{http://owncloud.org/ns}checksums'; + const DATA_FINGERPRINT_PROPERTYNAME = '{http://owncloud.org/ns}data-fingerprint'; /** * Reference to main server object @@ -85,6 +89,11 @@ class FilesPlugin extends \Sabre\DAV\ServerPlugin { private $downloadAttachment; /** + * @var IConfig + */ + private $config; + + /** * @param Tree $tree * @param View $view * @param bool $isPublic @@ -92,10 +101,12 @@ class FilesPlugin extends \Sabre\DAV\ServerPlugin { */ public function __construct(Tree $tree, View $view, + IConfig $config, $isPublic = false, $downloadAttachment = true) { $this->tree = $tree; $this->fileView = $view; + $this->config = $config; $this->isPublic = $isPublic; $this->downloadAttachment = $downloadAttachment; } @@ -123,6 +134,7 @@ class FilesPlugin extends \Sabre\DAV\ServerPlugin { $server->protectedProperties[] = self::OWNER_ID_PROPERTYNAME; $server->protectedProperties[] = self::OWNER_DISPLAY_NAME_PROPERTYNAME; $server->protectedProperties[] = self::CHECKSUMS_PROPERTYNAME; + $server->protectedProperties[] = self::DATA_FINGERPRINT_PROPERTYNAME; // normally these cannot be changed (RFC4918), but we want them modifiable through PROPPATCH $allowedProperties = ['{DAV:}getetag']; @@ -146,11 +158,17 @@ class FilesPlugin extends \Sabre\DAV\ServerPlugin { /** * Plugin that checks if a move can actually be performed. + * * @param string $source source path * @param string $destination destination path * @throws Forbidden + * @throws NotFound */ function checkMove($source, $destination) { + $sourceNode = $this->tree->getNodeForPath($source); + if ($sourceNode instanceof FutureFile) { + return; + } list($sourceDir,) = \Sabre\HTTP\URLUtil::splitPath($source); list($destinationDir,) = \Sabre\HTTP\URLUtil::splitPath($destination); @@ -264,6 +282,18 @@ class FilesPlugin extends \Sabre\DAV\ServerPlugin { $displayName = $owner->getDisplayName(); return $displayName; }); + + $propFind->handle(self::DATA_FINGERPRINT_PROPERTYNAME, function() use ($node) { + if ($node->getPath() === '/') { + return $this->config->getSystemValue('data-fingerprint', ''); + } + }); + } + + if ($node instanceof \OCA\DAV\Files\FilesHome) { + $propFind->handle(self::DATA_FINGERPRINT_PROPERTYNAME, function() use ($node) { + return $this->config->getSystemValue('data-fingerprint', ''); + }); } if ($node instanceof \OCA\DAV\Connector\Sabre\File) { diff --git a/apps/dav/lib/connector/sabre/node.php b/apps/dav/lib/connector/sabre/node.php index 9867fe66cd3..eaba6713992 100644 --- a/apps/dav/lib/connector/sabre/node.php +++ b/apps/dav/lib/connector/sabre/node.php @@ -246,14 +246,6 @@ abstract class Node implements \Sabre\DAV\INode { } /* - * Without sharing permissions there are also no other permissions - */ - if (!($permissions & \OCP\Constants::PERMISSION_SHARE) || - !($permissions & \OCP\Constants::PERMISSION_READ)) { - return 0; - } - - /* * Files can't have create or delete permissions */ if ($this->info->getType() === \OCP\Files\FileInfo::TYPE_FILE) { diff --git a/apps/dav/lib/connector/sabre/serverfactory.php b/apps/dav/lib/connector/sabre/serverfactory.php index cab7a85d19f..5853370778d 100644 --- a/apps/dav/lib/connector/sabre/serverfactory.php +++ b/apps/dav/lib/connector/sabre/serverfactory.php @@ -137,8 +137,15 @@ class ServerFactory { } $objectTree->init($root, $view, $this->mountManager); - $server->addPlugin(new \OCA\DAV\Connector\Sabre\FilesPlugin($objectTree, $view, false, - !$this->config->getSystemValue('debug', false))); + $server->addPlugin( + new \OCA\DAV\Connector\Sabre\FilesPlugin( + $objectTree, + $view, + $this->config, + false, + !$this->config->getSystemValue('debug', false) + ) + ); $server->addPlugin(new \OCA\DAV\Connector\Sabre\QuotaPlugin($view)); if($this->userSession->isLoggedIn()) { diff --git a/apps/dav/lib/hookmanager.php b/apps/dav/lib/hookmanager.php index c3d68a3ee2a..687e6718db3 100644 --- a/apps/dav/lib/hookmanager.php +++ b/apps/dav/lib/hookmanager.php @@ -100,24 +100,26 @@ class HookManager { public function postLogin($params) { $user = $this->userManager->get($params['uid']); - - $principal = 'principals/users/' . $user->getUID(); - $calendars = $this->calDav->getCalendarsForUser($principal); - if (empty($calendars)) { - try { - $this->calDav->createCalendar($principal, 'default', []); - } catch (\Exception $ex) { - \OC::$server->getLogger()->logException($ex); + if (!is_null($user)) { + $principal = 'principals/users/' . $user->getUID(); + $calendars = $this->calDav->getCalendarsForUser($principal); + if (empty($calendars)) { + try { + $this->calDav->createCalendar($principal, 'personal', [ + '{DAV:}displayname' => 'Personal']); + } catch (\Exception $ex) { + \OC::$server->getLogger()->logException($ex); + } } - } - $books = $this->cardDav->getAddressBooksForUser($principal); - if (empty($books)) { - try { - $this->cardDav->createAddressBook($principal, 'default', []); - } catch (\Exception $ex) { - \OC::$server->getLogger()->logException($ex); + $books = $this->cardDav->getAddressBooksForUser($principal); + if (empty($books)) { + try { + $this->cardDav->createAddressBook($principal, 'contacts', [ + '{DAV:}displayname' => 'Contacts']); + } catch (\Exception $ex) { + \OC::$server->getLogger()->logException($ex); + } } } - } } diff --git a/apps/dav/lib/migration/addressbookadapter.php b/apps/dav/lib/migration/addressbookadapter.php deleted file mode 100644 index 5264747a004..00000000000 --- a/apps/dav/lib/migration/addressbookadapter.php +++ /dev/null @@ -1,106 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ -namespace OCA\Dav\Migration; - -use OCP\IDBConnection; -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 AddressBookAdapter { - - /** @var \OCP\IDBConnection */ - protected $dbConnection; - - /** @var string */ - private $sourceBookTable; - - /** @var string */ - private $sourceCardsTable; - - /** - * @param IDBConnection $dbConnection - * @param string $sourceBookTable - * @param string $sourceCardsTable - */ - function __construct(IDBConnection $dbConnection, - $sourceBookTable = 'contacts_addressbooks', - $sourceCardsTable = 'contacts_cards') { - $this->dbConnection = $dbConnection; - $this->sourceBookTable = $sourceBookTable; - $this->sourceCardsTable = $sourceCardsTable; - } - - /** - * @param string $user - * @param \Closure $callBack - */ - public function foreachBook($user, \Closure $callBack) { - // get all addressbooks of that user - $query = $this->dbConnection->getQueryBuilder(); - $stmt = $query->select('*')->from($this->sourceBookTable) - ->where($query->expr()->eq('userid', $query->createNamedParameter($user))) - ->execute(); - - while($row = $stmt->fetch()) { - $callBack($row); - } - } - - public function setup() { - if (!$this->dbConnection->tableExists($this->sourceBookTable)) { - throw new \DomainException('Contacts tables are missing. Nothing to do.'); - } - } - - /** - * @param int $addressBookId - * @param \Closure $callBack - */ - public function foreachCard($addressBookId, \Closure $callBack) { - $query = $this->dbConnection->getQueryBuilder(); - $stmt = $query->select('*')->from($this->sourceCardsTable) - ->where($query->expr()->eq('addressbookid', $query->createNamedParameter($addressBookId))) - ->execute(); - - while($row = $stmt->fetch()) { - $callBack($row); - } - } - - /** - * @param int $addressBookId - * @return array - */ - public function getShares($addressBookId) { - $query = $this->dbConnection->getQueryBuilder(); - $shares = $query->select('*')->from('share') - ->where($query->expr()->eq('item_source', $query->createNamedParameter($addressBookId))) - ->andWhere($query->expr()->eq('item_type', $query->expr()->literal('addressbook'))) - ->andWhere($query->expr()->in('share_type', [ $query->expr()->literal(0), $query->expr()->literal(1)])) - ->execute() - ->fetchAll(); - - return $shares; - } -} diff --git a/apps/dav/lib/migration/calendaradapter.php b/apps/dav/lib/migration/calendaradapter.php deleted file mode 100644 index d02f2256c34..00000000000 --- a/apps/dav/lib/migration/calendaradapter.php +++ /dev/null @@ -1,102 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ -namespace OCA\Dav\Migration; - -use OCP\IDBConnection; - -class CalendarAdapter { - - /** @var \OCP\IDBConnection */ - protected $dbConnection; - - /** @var string */ - private $sourceCalendarTable; - - /** @var string */ - private $sourceCalObjTable; - - /** - * @param IDBConnection $dbConnection - * @param string $sourceCalendarTable - * @param string $sourceCalObjTable - */ - function __construct(IDBConnection $dbConnection, - $sourceCalendarTable = 'clndr_calendars', - $sourceCalObjTable = 'clndr_objects') { - $this->dbConnection = $dbConnection; - $this->sourceCalendarTable = $sourceCalendarTable; - $this->sourceCalObjTable = $sourceCalObjTable; - } - - /** - * @param string $user - * @param \Closure $callBack - */ - public function foreachCalendar($user, \Closure $callBack) { - // get all calendars of that user - $query = $this->dbConnection->getQueryBuilder(); - $stmt = $query->select('*')->from($this->sourceCalendarTable) - ->where($query->expr()->eq('userid', $query->createNamedParameter($user))) - ->execute(); - - while($row = $stmt->fetch()) { - $callBack($row); - } - } - - public function setup() { - if (!$this->dbConnection->tableExists($this->sourceCalendarTable)) { - throw new \DomainException('Calendar tables are missing. Nothing to do.'); - } - } - - /** - * @param int $calendarId - * @param \Closure $callBack - */ - public function foreachCalendarObject($calendarId, \Closure $callBack) { - $query = $this->dbConnection->getQueryBuilder(); - $stmt = $query->select('*')->from($this->sourceCalObjTable) - ->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId))) - ->execute(); - - while($row = $stmt->fetch()) { - $callBack($row); - } - } - - /** - * @param int $addressBookId - * @return array - */ - public function getShares($addressBookId) { - $query = $this->dbConnection->getQueryBuilder(); - $shares = $query->select('*')->from('share') - ->where($query->expr()->eq('item_source', $query->createNamedParameter($addressBookId))) - ->andWhere($query->expr()->eq('item_type', $query->expr()->literal('calendar'))) - ->andWhere($query->expr()->in('share_type', [ $query->expr()->literal(0), $query->expr()->literal(1)])) - ->execute() - ->fetchAll(); - - return $shares; - } -} diff --git a/apps/dav/lib/migration/migrateaddressbooks.php b/apps/dav/lib/migration/migrateaddressbooks.php deleted file mode 100644 index 7e1f47ea75e..00000000000 --- a/apps/dav/lib/migration/migrateaddressbooks.php +++ /dev/null @@ -1,131 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ -namespace OCA\Dav\Migration; - -use OCA\DAV\CardDAV\AddressBook; -use OCA\DAV\CardDAV\CardDavBackend; -use OCP\ILogger; -use Sabre\CardDAV\Plugin; -use Symfony\Component\Console\Output\OutputInterface; - -class MigrateAddressbooks { - - /** @var AddressBookAdapter */ - protected $adapter; - - /** @var CardDavBackend */ - private $backend; - - /** @var ILogger */ - private $logger; - - /** @var OutputInterface */ - private $consoleOutput; - - - /** - * @param AddressBookAdapter $adapter - * @param CardDavBackend $backend - */ - function __construct(AddressBookAdapter $adapter, - CardDavBackend $backend, - ILogger $logger, - OutputInterface $consoleOutput = null - ) { - $this->adapter = $adapter; - $this->backend = $backend; - $this->logger = $logger; - $this->consoleOutput = $consoleOutput; - } - - /** - * @param string $user - */ - public function migrateForUser($user) { - - $this->adapter->foreachBook($user, function($book) use ($user) { - $principal = "principals/users/$user"; - $knownBooks = $this->backend->getAddressBooksByUri($principal, $book['uri']); - if (!is_null($knownBooks)) { - return; - } - - $newId = $this->backend->createAddressBook($principal, $book['uri'], [ - '{DAV:}displayname' => $book['displayname'], - '{' . Plugin::NS_CARDDAV . '}addressbook-description' => $book['description'] - ]); - - $this->migrateBook($book['id'], $newId); - $this->migrateShares($book['id'], $newId); - }); - } - - public function setup() { - $this->adapter->setup(); - } - - /** - * @param int $addressBookId - * @param int $newAddressBookId - */ - private function migrateBook($addressBookId, $newAddressBookId) { - $this->adapter->foreachCard($addressBookId, function($card) use ($newAddressBookId) { - try { - $this->backend->createCard($newAddressBookId, $card['uri'], $card['carddata']); - } catch (\Exception $ex) { - $eventId = $card['id']; - $addressBookId = $card['addressbookid']; - $msg = "One event could not be migrated. (id: $eventId, addressbookid: $addressBookId)"; - $this->logger->logException($ex, ['app' => 'dav', 'message' => $msg]); - if (!is_null($this->consoleOutput)) { - $this->consoleOutput->writeln($msg); - } - } - }); - } - - /** - * @param int $addressBookId - * @param int $newAddressBookId - */ - private function migrateShares($addressBookId, $newAddressBookId) { - $shares =$this->adapter->getShares($addressBookId); - if (empty($shares)) { - return; - } - - $add = array_map(function($s) { - $prefix = 'principal:principals/users/'; - if ((int)$s['share_type'] === 1) { - $prefix = 'principal:principals/groups/'; - } - return [ - 'href' => $prefix . $s['share_with'], - 'readOnly' => !((int)$s['permissions'] === 31) - ]; - }, $shares); - - $newAddressBook = $this->backend->getAddressBookById($newAddressBookId); - $book = new AddressBook($this->backend, $newAddressBook); - $this->backend->updateShares($book, $add, []); - } -} diff --git a/apps/dav/lib/migration/migratecalendars.php b/apps/dav/lib/migration/migratecalendars.php deleted file mode 100644 index 3c1487761c2..00000000000 --- a/apps/dav/lib/migration/migratecalendars.php +++ /dev/null @@ -1,132 +0,0 @@ -<?php -/** - * @author Lukas Reschke <lukas@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ -namespace OCA\Dav\Migration; - -use OCA\DAV\CalDAV\CalDavBackend; -use OCA\DAV\CalDAV\Calendar; -use OCP\ILogger; -use Symfony\Component\Console\Output\OutputInterface; - -class MigrateCalendars { - - /** @var CalendarAdapter */ - protected $adapter; - - /** @var CalDavBackend */ - private $backend; - - /** @var ILogger */ - private $logger; - - /** @var OutputInterface */ - private $consoleOutput; - - /** - * @param CalendarAdapter $adapter - * @param CalDavBackend $backend - */ - function __construct(CalendarAdapter $adapter, - CalDavBackend $backend, - ILogger $logger, - OutputInterface $consoleOutput = null - ) { - $this->adapter = $adapter; - $this->backend = $backend; - $this->logger = $logger; - $this->consoleOutput = $consoleOutput; - } - - /** - * @param string $user - */ - public function migrateForUser($user) { - - $this->adapter->foreachCalendar($user, function($calendar) use ($user) { - $principal = "principals/users/$user"; - $calendarByUri = $this->backend->getCalendarByUri($principal, $calendar['uri']); - if (!is_null($calendarByUri)) { - return; - } - - $newId = $this->backend->createCalendar($principal, $calendar['uri'], [ - '{DAV:}displayname' => $calendar['displayname'], - '{urn:ietf:params:xml:ns:caldav}calendar-description' => $calendar['displayname'], - '{urn:ietf:params:xml:ns:caldav}calendar-timezone' => $calendar['timezone'], - '{http://apple.com/ns/ical/}calendar-order' => $calendar['calendarorder'], - '{http://apple.com/ns/ical/}calendar-color' => $calendar['calendarcolor'], - ]); - - $this->migrateCalendar($calendar['id'], $newId); - $this->migrateShares($calendar['id'], $newId); - }); - } - - public function setup() { - $this->adapter->setup(); - } - - /** - * @param int $calendarId - * @param int $newCalendarId - */ - private function migrateCalendar($calendarId, $newCalendarId) { - $this->adapter->foreachCalendarObject($calendarId, function($calObject) use ($newCalendarId) { - try { - $this->backend->createCalendarObject($newCalendarId, $calObject['uri'], $calObject['calendardata']); - } catch (\Exception $ex) { - $eventId = $calObject['id']; - $calendarId = $calObject['calendarId']; - $msg = "One event could not be migrated. (id: $eventId, calendarid: $calendarId)"; - $this->logger->logException($ex, ['app' => 'dav', 'message' => $msg]); - if (!is_null($this->consoleOutput)) { - $this->consoleOutput->writeln($msg); - } - } - }); - } - - /** - * @param int $calendarId - * @param int $newCalendarId - */ - private function migrateShares($calendarId, $newCalendarId) { - $shares =$this->adapter->getShares($calendarId); - if (empty($shares)) { - return; - } - - $add = array_map(function($s) { - $prefix = 'principal:principals/users/'; - if ((int)$s['share_type'] === 1) { - $prefix = 'principal:principals/groups/'; - } - return [ - 'href' => $prefix . $s['share_with'], - 'readOnly' => !((int)$s['permissions'] === 31) - ]; - }, $shares); - - $newCalendar = $this->backend->getCalendarById($newCalendarId); - $calendar = new Calendar($this->backend, $newCalendar); - $this->backend->updateShares($calendar, $add, []); - } -} diff --git a/apps/dav/lib/rootcollection.php b/apps/dav/lib/rootcollection.php index ea796c09175..b6e1747e990 100644 --- a/apps/dav/lib/rootcollection.php +++ b/apps/dav/lib/rootcollection.php @@ -89,6 +89,9 @@ class RootCollection extends SimpleCollection { $systemAddressBookRoot = new AddressBookRoot(new SystemPrincipalBackend(), $systemCardDavBackend, 'principals/system'); $systemAddressBookRoot->disableListing = $disableListing; + $uploadCollection = new Upload\RootCollection($userPrincipalBackend, 'principals/users'); + $uploadCollection->disableListing = $disableListing; + $children = [ new SimpleCollection('principals', [ $userPrincipals, @@ -102,6 +105,7 @@ class RootCollection extends SimpleCollection { $systemTagCollection, $systemTagRelationsCollection, $commentsCollection, + $uploadCollection, ]; parent::__construct('root', $children); diff --git a/apps/dav/lib/server.php b/apps/dav/lib/server.php index e6668556448..73e24c9a292 100644 --- a/apps/dav/lib/server.php +++ b/apps/dav/lib/server.php @@ -132,8 +132,15 @@ class Server { $user = \OC::$server->getUserSession()->getUser(); if (!is_null($user)) { $view = \OC\Files\Filesystem::getView(); - $this->server->addPlugin(new FilesPlugin($this->server->tree, $view, false, - !\OC::$server->getConfig()->getSystemValue('debug', false))); + $this->server->addPlugin( + new FilesPlugin( + $this->server->tree, + $view, + \OC::$server->getConfig(), + false, + !\OC::$server->getConfig()->getSystemValue('debug', false) + ) + ); $this->server->addPlugin( new \Sabre\DAV\PropertyStorage\Plugin( diff --git a/apps/dav/lib/upload/assemblystream.php b/apps/dav/lib/upload/assemblystream.php new file mode 100644 index 00000000000..4b80a591ce4 --- /dev/null +++ b/apps/dav/lib/upload/assemblystream.php @@ -0,0 +1,234 @@ +<?php + +namespace OCA\DAV\Upload; + +use Sabre\DAV\IFile; + +/** + * Class AssemblyStream + * + * The assembly stream is a virtual stream that wraps multiple chunks. + * Reading from the stream transparently accessed the underlying chunks and + * give a representation as if they were already merged together. + * + * @package OCA\DAV\Upload + */ +class AssemblyStream implements \Icewind\Streams\File { + + /** @var resource */ + private $context; + + /** @var IFile[] */ + private $nodes; + + /** @var int */ + private $pos = 0; + + /** @var array */ + private $sortedNodes; + + /** @var int */ + private $size; + + /** + * @param string $path + * @param string $mode + * @param int $options + * @param string &$opened_path + * @return bool + */ + public function stream_open($path, $mode, $options, &$opened_path) { + $this->loadContext('assembly'); + + // sort the nodes + $nodes = $this->nodes; + // http://stackoverflow.com/a/10985500 + @usort($nodes, function(IFile $a, IFile $b) { + return strcmp($a->getName(), $b->getName()); + }); + $this->nodes = $nodes; + + // build additional information + $this->sortedNodes = []; + $start = 0; + foreach($this->nodes as $node) { + $size = $node->getSize(); + $name = $node->getName(); + $this->sortedNodes[$name] = ['node' => $node, 'start' => $start, 'end' => $start + $size]; + $start += $size; + $this->size = $start; + } + return true; + } + + /** + * @param string $offset + * @param int $whence + * @return bool + */ + public function stream_seek($offset, $whence = SEEK_SET) { + return false; + } + + /** + * @return int + */ + public function stream_tell() { + return $this->pos; + } + + /** + * @param int $count + * @return string + */ + public function stream_read($count) { + + list($node, $posInNode) = $this->getNodeForPosition($this->pos); + if (is_null($node)) { + return null; + } + $stream = $this->getStream($node); + + fseek($stream, $posInNode); + $data = fread($stream, $count); + $read = strlen($data); + + // update position + $this->pos += $read; + return $data; + } + + /** + * @param string $data + * @return int + */ + public function stream_write($data) { + return false; + } + + /** + * @param int $option + * @param int $arg1 + * @param int $arg2 + * @return bool + */ + public function stream_set_option($option, $arg1, $arg2) { + return false; + } + + /** + * @param int $size + * @return bool + */ + public function stream_truncate($size) { + return false; + } + + /** + * @return array + */ + public function stream_stat() { + return []; + } + + /** + * @param int $operation + * @return bool + */ + public function stream_lock($operation) { + return false; + } + + /** + * @return bool + */ + public function stream_flush() { + return false; + } + + /** + * @return bool + */ + public function stream_eof() { + return $this->pos >= $this->size; + } + + /** + * @return bool + */ + public function stream_close() { + return true; + } + + + /** + * Load the source from the stream context and return the context options + * + * @param string $name + * @return array + * @throws \Exception + */ + protected function loadContext($name) { + $context = stream_context_get_options($this->context); + if (isset($context[$name])) { + $context = $context[$name]; + } else { + throw new \BadMethodCallException('Invalid context, "' . $name . '" options not set'); + } + if (isset($context['nodes']) and is_array($context['nodes'])) { + $this->nodes = $context['nodes']; + } else { + throw new \BadMethodCallException('Invalid context, nodes not set'); + } + return $context; + } + + /** + * @param IFile[] $nodes + * @return resource + * + * @throws \BadMethodCallException + */ + public static function wrap(array $nodes) { + $context = stream_context_create([ + 'assembly' => [ + 'nodes' => $nodes] + ]); + stream_wrapper_register('assembly', '\OCA\DAV\Upload\AssemblyStream'); + try { + $wrapped = fopen('assembly://', 'r', null, $context); + } catch (\BadMethodCallException $e) { + stream_wrapper_unregister('assembly'); + throw $e; + } + stream_wrapper_unregister('assembly'); + return $wrapped; + } + + /** + * @param $pos + * @return IFile | null + */ + private function getNodeForPosition($pos) { + foreach($this->sortedNodes as $node) { + if ($pos >= $node['start'] && $pos < $node['end']) { + return [$node['node'], $pos - $node['start']]; + } + } + return null; + } + + /** + * @param IFile $node + * @return resource + */ + private function getStream(IFile $node) { + $data = $node->get(); + if (is_resource($data)) { + return $data; + } + + return fopen('data://text/plain,' . $data,'r'); + } + +} diff --git a/apps/dav/lib/upload/futurefile.php b/apps/dav/lib/upload/futurefile.php new file mode 100644 index 00000000000..aca81afc055 --- /dev/null +++ b/apps/dav/lib/upload/futurefile.php @@ -0,0 +1,103 @@ +<?php + +namespace OCA\DAV\Upload; + +use OCA\DAV\Connector\Sabre\Directory; +use OCA\DAV\Upload\AssemblyStream; +use Sabre\DAV\Exception\Forbidden; +use Sabre\DAV\IFile; + +/** + * Class FutureFile + * + * The FutureFile is a SabreDav IFile which connects the chunked upload directory + * with the AssemblyStream, who does the final assembly job + * + * @package OCA\DAV\Upload + */ +class FutureFile implements \Sabre\DAV\IFile { + + /** @var Directory */ + private $root; + /** @var string */ + private $name; + + /** + * @param Directory $root + * @param string $name + */ + function __construct(Directory $root, $name) { + $this->root = $root; + $this->name = $name; + } + + /** + * @inheritdoc + */ + function put($data) { + throw new Forbidden('Permission denied to put into this file'); + } + + /** + * @inheritdoc + */ + function get() { + $nodes = $this->root->getChildren(); + return AssemblyStream::wrap($nodes); + } + + /** + * @inheritdoc + */ + function getContentType() { + return 'application/octet-stream'; + } + + /** + * @inheritdoc + */ + function getETag() { + return $this->root->getETag(); + } + + /** + * @inheritdoc + */ + function getSize() { + $children = $this->root->getChildren(); + $sizes = array_map(function($node) { + /** @var IFile $node */ + return $node->getSize(); + }, $children); + + return array_sum($sizes); + } + + /** + * @inheritdoc + */ + function delete() { + $this->root->delete(); + } + + /** + * @inheritdoc + */ + function getName() { + return $this->name; + } + + /** + * @inheritdoc + */ + function setName($name) { + throw new Forbidden('Permission denied to rename this file'); + } + + /** + * @inheritdoc + */ + function getLastModified() { + return $this->root->getLastModified(); + } +} diff --git a/apps/dav/lib/upload/rootcollection.php b/apps/dav/lib/upload/rootcollection.php new file mode 100644 index 00000000000..673a3734318 --- /dev/null +++ b/apps/dav/lib/upload/rootcollection.php @@ -0,0 +1,23 @@ +<?php + +namespace OCA\DAV\Upload; + +use Sabre\DAVACL\AbstractPrincipalCollection; + +class RootCollection extends AbstractPrincipalCollection { + + /** + * @inheritdoc + */ + function getChildForPrincipal(array $principalInfo) { + return new UploadHome($principalInfo); + } + + /** + * @inheritdoc + */ + function getName() { + return 'uploads'; + } + +} diff --git a/apps/dav/lib/upload/uploadfolder.php b/apps/dav/lib/upload/uploadfolder.php new file mode 100644 index 00000000000..01fbf1f8dc9 --- /dev/null +++ b/apps/dav/lib/upload/uploadfolder.php @@ -0,0 +1,61 @@ +<?php + +namespace OCA\DAV\Upload; + +use OCA\DAV\Connector\Sabre\Directory; +use Sabre\DAV\Exception\Forbidden; +use Sabre\DAV\ICollection; + +class UploadFolder implements ICollection { + + private $node; + + function __construct(Directory $node) { + $this->node = $node; + } + + function createFile($name, $data = null) { + // TODO: verify name - should be a simple number + $this->node->createFile($name, $data); + } + + function createDirectory($name) { + throw new Forbidden('Permission denied to create file (filename ' . $name . ')'); + } + + function getChild($name) { + if ($name === '.file') { + return new FutureFile($this->node, '.file'); + } + return $this->node->getChild($name); + } + + function getChildren() { + $children = $this->node->getChildren(); + $children[] = new FutureFile($this->node, '.file'); + return $children; + } + + function childExists($name) { + if ($name === '.file') { + return true; + } + return $this->node->childExists($name); + } + + function delete() { + $this->node->delete(); + } + + function getName() { + return $this->node->getName(); + } + + function setName($name) { + throw new Forbidden('Permission denied to rename this folder'); + } + + function getLastModified() { + return $this->node->getLastModified(); + } +} diff --git a/apps/dav/lib/upload/uploadhome.php b/apps/dav/lib/upload/uploadhome.php new file mode 100644 index 00000000000..ae4dcfa4931 --- /dev/null +++ b/apps/dav/lib/upload/uploadhome.php @@ -0,0 +1,74 @@ +<?php + +namespace OCA\DAV\Upload; + +use OC\Files\Filesystem; +use OC\Files\View; +use OCA\DAV\Connector\Sabre\Directory; +use Sabre\DAV\Exception\Forbidden; +use Sabre\DAV\ICollection; + +class UploadHome implements ICollection { + /** + * FilesHome constructor. + * + * @param array $principalInfo + */ + public function __construct($principalInfo) { + $this->principalInfo = $principalInfo; + } + + function createFile($name, $data = null) { + throw new Forbidden('Permission denied to create file (filename ' . $name . ')'); + } + + function createDirectory($name) { + $this->impl()->createDirectory($name); + } + + function getChild($name) { + return new UploadFolder($this->impl()->getChild($name)); + } + + function getChildren() { + return array_map(function($node) { + return new UploadFolder($node); + }, $this->impl()->getChildren()); + } + + function childExists($name) { + return !is_null($this->getChild($name)); + } + + function delete() { + $this->impl()->delete(); + } + + function getName() { + return 'uploads'; + } + + function setName($name) { + throw new Forbidden('Permission denied to rename this folder'); + } + + function getLastModified() { + return $this->impl()->getLastModified(); + } + + /** + * @return Directory + */ + private function impl() { + $rootView = new View(); + $user = \OC::$server->getUserSession()->getUser(); + Filesystem::initMountPoints($user->getUID()); + if (!$rootView->file_exists('/' . $user->getUID() . '/uploads')) { + $rootView->mkdir('/' . $user->getUID() . '/uploads'); + } + $view = new View('/' . $user->getUID() . '/uploads'); + $rootInfo = $view->getFileInfo(''); + $impl = new Directory($view, $rootInfo); + return $impl; + } +} diff --git a/apps/dav/tests/unit/caldav/caldavbackendtest.php b/apps/dav/tests/unit/caldav/caldavbackendtest.php index 87a700a473d..a4a19f5bd3e 100644 --- a/apps/dav/tests/unit/caldav/caldavbackendtest.php +++ b/apps/dav/tests/unit/caldav/caldavbackendtest.php @@ -136,14 +136,23 @@ class CalDavBackendTest extends TestCase { */ public function testCalendarSharing($userCanRead, $userCanWrite, $groupCanRead, $groupCanWrite, $add) { + $l10n = $this->getMockBuilder('\OCP\IL10N') + ->disableOriginalConstructor()->getMock(); + $l10n + ->expects($this->any()) + ->method('t') + ->will($this->returnCallback(function ($text, $parameters = array()) { + return vsprintf($text, $parameters); + })); + $calendarId = $this->createTestCalendar(); $books = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER); $this->assertEquals(1, count($books)); - $calendar = new Calendar($this->backend, $books[0]); + $calendar = new Calendar($this->backend, $books[0], $l10n); $this->backend->updateShares($calendar, $add, []); $books = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER1); $this->assertEquals(1, count($books)); - $calendar = new Calendar($this->backend, $books[0]); + $calendar = new Calendar($this->backend, $books[0], $l10n); $acl = $calendar->getACL(); $this->assertAcl(self::UNIT_TEST_USER, '{DAV:}read', $acl); $this->assertAcl(self::UNIT_TEST_USER, '{DAV:}write', $acl); diff --git a/apps/dav/tests/unit/caldav/calendartest.php b/apps/dav/tests/unit/caldav/calendartest.php index 9e0c3c6c7e4..812e0074d15 100644 --- a/apps/dav/tests/unit/caldav/calendartest.php +++ b/apps/dav/tests/unit/caldav/calendartest.php @@ -23,11 +23,27 @@ namespace OCA\DAV\Tests\Unit\CalDAV; use OCA\DAV\CalDAV\CalDavBackend; use OCA\DAV\CalDAV\Calendar; +use OCP\IL10N; use Sabre\DAV\PropPatch; use Test\TestCase; class CalendarTest extends TestCase { + /** @var IL10N */ + private $l10n; + + public function setUp() { + parent::setUp(); + $this->l10n = $this->getMockBuilder('\OCP\IL10N') + ->disableOriginalConstructor()->getMock(); + $this->l10n + ->expects($this->any()) + ->method('t') + ->will($this->returnCallback(function ($text, $parameters = array()) { + return vsprintf($text, $parameters); + })); + } + public function testDelete() { /** @var \PHPUnit_Framework_MockObject_MockObject | CalDavBackend $backend */ $backend = $this->getMockBuilder('OCA\DAV\CalDAV\CalDavBackend')->disableOriginalConstructor()->getMock(); @@ -41,7 +57,7 @@ class CalendarTest extends TestCase { 'id' => 666, 'uri' => 'cal', ]; - $c = new Calendar($backend, $calendarInfo); + $c = new Calendar($backend, $calendarInfo, $this->l10n); $c->delete(); } @@ -61,7 +77,7 @@ class CalendarTest extends TestCase { 'id' => 666, 'uri' => 'cal', ]; - $c = new Calendar($backend, $calendarInfo); + $c = new Calendar($backend, $calendarInfo, $this->l10n); $c->delete(); } @@ -93,7 +109,7 @@ class CalendarTest extends TestCase { 'id' => 666, 'uri' => 'default' ]; - $c = new Calendar($backend, $calendarInfo); + $c = new Calendar($backend, $calendarInfo, $this->l10n); if ($throws) { $this->setExpectedException('\Sabre\DAV\Exception\Forbidden'); @@ -122,7 +138,7 @@ class CalendarTest extends TestCase { if ($hasOwnerSet) { $calendarInfo['{http://owncloud.org/ns}owner-principal'] = 'user1'; } - $c = new Calendar($backend, $calendarInfo); + $c = new Calendar($backend, $calendarInfo, $this->l10n); $acl = $c->getACL(); $childAcl = $c->getChildACL(); diff --git a/apps/dav/tests/unit/connector/sabre/filesplugin.php b/apps/dav/tests/unit/connector/sabre/filesplugin.php index fb08ee170c4..fb5d658b39c 100644 --- a/apps/dav/tests/unit/connector/sabre/filesplugin.php +++ b/apps/dav/tests/unit/connector/sabre/filesplugin.php @@ -23,6 +23,9 @@ namespace OCA\DAV\Tests\Unit\Connector\Sabre; use OCP\Files\StorageNotAvailableException; +use Sabre\DAV\PropFind; +use Sabre\DAV\PropPatch; +use Test\TestCase; /** * Copyright (c) 2015 Vincent Petry <pvince81@owncloud.com> @@ -30,7 +33,7 @@ use OCP\Files\StorageNotAvailableException; * later. * See the COPYING-README file. */ -class FilesPlugin extends \Test\TestCase { +class FilesPlugin extends TestCase { const GETETAG_PROPERTYNAME = \OCA\DAV\Connector\Sabre\FilesPlugin::GETETAG_PROPERTYNAME; const FILEID_PROPERTYNAME = \OCA\DAV\Connector\Sabre\FilesPlugin::FILEID_PROPERTYNAME; const INTERNAL_FILEID_PROPERTYNAME = \OCA\DAV\Connector\Sabre\FilesPlugin::INTERNAL_FILEID_PROPERTYNAME; @@ -40,14 +43,15 @@ class FilesPlugin extends \Test\TestCase { const DOWNLOADURL_PROPERTYNAME = \OCA\DAV\Connector\Sabre\FilesPlugin::DOWNLOADURL_PROPERTYNAME; const OWNER_ID_PROPERTYNAME = \OCA\DAV\Connector\Sabre\FilesPlugin::OWNER_ID_PROPERTYNAME; const OWNER_DISPLAY_NAME_PROPERTYNAME = \OCA\DAV\Connector\Sabre\FilesPlugin::OWNER_DISPLAY_NAME_PROPERTYNAME; + const DATA_FINGERPRINT_PROPERTYNAME = \OCA\DAV\Connector\Sabre\FilesPlugin::DATA_FINGERPRINT_PROPERTYNAME; /** - * @var \Sabre\DAV\Server + * @var \Sabre\DAV\Server | \PHPUnit_Framework_MockObject_MockObject */ private $server; /** - * @var \Sabre\DAV\Tree + * @var \Sabre\DAV\Tree | \PHPUnit_Framework_MockObject_MockObject */ private $tree; @@ -57,10 +61,15 @@ class FilesPlugin extends \Test\TestCase { private $plugin; /** - * @var \OC\Files\View + * @var \OC\Files\View | \PHPUnit_Framework_MockObject_MockObject */ private $view; + /** + * @var \OCP\IConfig | \PHPUnit_Framework_MockObject_MockObject + */ + private $config; + public function setUp() { parent::setUp(); $this->server = $this->getMockBuilder('\Sabre\DAV\Server') @@ -72,13 +81,22 @@ class FilesPlugin extends \Test\TestCase { $this->view = $this->getMockBuilder('\OC\Files\View') ->disableOriginalConstructor() ->getMock(); - - $this->plugin = new \OCA\DAV\Connector\Sabre\FilesPlugin($this->tree, $this->view); + $this->config = $this->getMock('\OCP\IConfig'); + $this->config->method('getSystemValue') + ->with($this->equalTo('data-fingerprint'), $this->equalTo('')) + ->willReturn('my_fingerprint'); + + $this->plugin = new \OCA\DAV\Connector\Sabre\FilesPlugin( + $this->tree, + $this->view, + $this->config + ); $this->plugin->initialize($this->server); } /** * @param string $class + * @return \PHPUnit_Framework_MockObject_MockObject */ private function createTestNode($class) { $node = $this->getMockBuilder($class) @@ -111,9 +129,10 @@ class FilesPlugin extends \Test\TestCase { } public function testGetPropertiesForFile() { + /** @var \OCA\DAV\Connector\Sabre\File | \PHPUnit_Framework_MockObject_MockObject $node */ $node = $this->createTestNode('\OCA\DAV\Connector\Sabre\File'); - $propFind = new \Sabre\DAV\PropFind( + $propFind = new PropFind( '/dummyPath', array( self::GETETAG_PROPERTYNAME, @@ -123,7 +142,8 @@ class FilesPlugin extends \Test\TestCase { self::PERMISSIONS_PROPERTYNAME, self::DOWNLOADURL_PROPERTYNAME, self::OWNER_ID_PROPERTYNAME, - self::OWNER_DISPLAY_NAME_PROPERTYNAME + self::OWNER_DISPLAY_NAME_PROPERTYNAME, + self::DATA_FINGERPRINT_PROPERTYNAME, ), 0 ); @@ -161,15 +181,16 @@ class FilesPlugin extends \Test\TestCase { $this->assertEquals('http://example.com/', $propFind->get(self::DOWNLOADURL_PROPERTYNAME)); $this->assertEquals('foo', $propFind->get(self::OWNER_ID_PROPERTYNAME)); $this->assertEquals('M. Foo', $propFind->get(self::OWNER_DISPLAY_NAME_PROPERTYNAME)); - $this->assertEquals(array(self::SIZE_PROPERTYNAME), $propFind->get404Properties()); + $this->assertEquals([self::SIZE_PROPERTYNAME, self::DATA_FINGERPRINT_PROPERTYNAME], $propFind->get404Properties()); } public function testGetPropertiesForFileHome() { + /** @var \OCA\DAV\Files\FilesHome | \PHPUnit_Framework_MockObject_MockObject $node */ $node = $this->getMockBuilder('\OCA\DAV\Files\FilesHome') ->disableOriginalConstructor() ->getMock(); - $propFind = new \Sabre\DAV\PropFind( + $propFind = new PropFind( '/dummyPath', array( self::GETETAG_PROPERTYNAME, @@ -179,7 +200,8 @@ class FilesPlugin extends \Test\TestCase { self::PERMISSIONS_PROPERTYNAME, self::DOWNLOADURL_PROPERTYNAME, self::OWNER_ID_PROPERTYNAME, - self::OWNER_DISPLAY_NAME_PROPERTYNAME + self::OWNER_DISPLAY_NAME_PROPERTYNAME, + self::DATA_FINGERPRINT_PROPERTYNAME, ), 0 ); @@ -211,12 +233,14 @@ class FilesPlugin extends \Test\TestCase { '{http://owncloud.org/ns}owner-id', '{http://owncloud.org/ns}owner-display-name' ], $propFind->get404Properties()); + $this->assertEquals('my_fingerprint', $propFind->get(self::DATA_FINGERPRINT_PROPERTYNAME)); } public function testGetPropertiesStorageNotAvailable() { + /** @var \OCA\DAV\Connector\Sabre\File | \PHPUnit_Framework_MockObject_MockObject $node */ $node = $this->createTestNode('\OCA\DAV\Connector\Sabre\File'); - $propFind = new \Sabre\DAV\PropFind( + $propFind = new PropFind( '/dummyPath', array( self::DOWNLOADURL_PROPERTYNAME, @@ -237,10 +261,14 @@ class FilesPlugin extends \Test\TestCase { } public function testGetPublicPermissions() { - $this->plugin = new \OCA\DAV\Connector\Sabre\FilesPlugin($this->tree, $this->view, true); + $this->plugin = new \OCA\DAV\Connector\Sabre\FilesPlugin( + $this->tree, + $this->view, + $this->config, + true); $this->plugin->initialize($this->server); - $propFind = new \Sabre\DAV\PropFind( + $propFind = new PropFind( '/dummyPath', [ self::PERMISSIONS_PROPERTYNAME, @@ -248,6 +276,7 @@ class FilesPlugin extends \Test\TestCase { 0 ); + /** @var \OCA\DAV\Connector\Sabre\File | \PHPUnit_Framework_MockObject_MockObject $node */ $node = $this->createTestNode('\OCA\DAV\Connector\Sabre\File'); $node->expects($this->any()) ->method('getDavPermissions') @@ -262,9 +291,10 @@ class FilesPlugin extends \Test\TestCase { } public function testGetPropertiesForDirectory() { + /** @var \OCA\DAV\Connector\Sabre\Directory | \PHPUnit_Framework_MockObject_MockObject $node */ $node = $this->createTestNode('\OCA\DAV\Connector\Sabre\Directory'); - $propFind = new \Sabre\DAV\PropFind( + $propFind = new PropFind( '/dummyPath', array( self::GETETAG_PROPERTYNAME, @@ -272,6 +302,7 @@ class FilesPlugin extends \Test\TestCase { self::SIZE_PROPERTYNAME, self::PERMISSIONS_PROPERTYNAME, self::DOWNLOADURL_PROPERTYNAME, + self::DATA_FINGERPRINT_PROPERTYNAME, ), 0 ); @@ -290,7 +321,30 @@ class FilesPlugin extends \Test\TestCase { $this->assertEquals(1025, $propFind->get(self::SIZE_PROPERTYNAME)); $this->assertEquals('DWCKMSR', $propFind->get(self::PERMISSIONS_PROPERTYNAME)); $this->assertEquals(null, $propFind->get(self::DOWNLOADURL_PROPERTYNAME)); - $this->assertEquals(array(self::DOWNLOADURL_PROPERTYNAME), $propFind->get404Properties()); + $this->assertEquals([self::DOWNLOADURL_PROPERTYNAME, self::DATA_FINGERPRINT_PROPERTYNAME], $propFind->get404Properties()); + } + + public function testGetPropertiesForRootDirectory() { + /** @var \OCA\DAV\Connector\Sabre\Directory | \PHPUnit_Framework_MockObject_MockObject $node */ + $node = $this->getMockBuilder('\OCA\DAV\Connector\Sabre\Directory') + ->disableOriginalConstructor() + ->getMock(); + $node->method('getPath')->willReturn('/'); + + $propFind = new PropFind( + '/', + [ + self::DATA_FINGERPRINT_PROPERTYNAME, + ], + 0 + ); + + $this->plugin->handleGetProperties( + $propFind, + $node + ); + + $this->assertEquals('my_fingerprint', $propFind->get(self::DATA_FINGERPRINT_PROPERTYNAME)); } public function testUpdateProps() { @@ -308,7 +362,7 @@ class FilesPlugin extends \Test\TestCase { ->will($this->returnValue(true)); // properties to set - $propPatch = new \Sabre\DAV\PropPatch(array( + $propPatch = new PropPatch(array( self::GETETAG_PROPERTYNAME => 'newetag', self::LASTMODIFIED_PROPERTYNAME => $testDate )); @@ -328,9 +382,7 @@ class FilesPlugin extends \Test\TestCase { } public function testUpdatePropsForbidden() { - $node = $this->createTestNode('\OCA\DAV\Connector\Sabre\File'); - - $propPatch = new \Sabre\DAV\PropPatch(array( + $propPatch = new PropPatch(array( self::OWNER_ID_PROPERTYNAME => 'user2', self::OWNER_DISPLAY_NAME_PROPERTYNAME => 'User Two', self::FILEID_PROPERTYNAME => 12345, diff --git a/apps/dav/tests/unit/connector/sabre/filesreportplugin.php b/apps/dav/tests/unit/connector/sabre/filesreportplugin.php index 87973ef0071..ffe1a19ee56 100644 --- a/apps/dav/tests/unit/connector/sabre/filesreportplugin.php +++ b/apps/dav/tests/unit/connector/sabre/filesreportplugin.php @@ -336,7 +336,15 @@ class FilesReportPlugin extends \Test\TestCase { ->method('getSize') ->will($this->returnValue(1024)); - $this->server->addPlugin(new \OCA\DAV\Connector\Sabre\FilesPlugin($this->tree, $this->view)); + $config = $this->getMock('\OCP\IConfig'); + + $this->server->addPlugin( + new \OCA\DAV\Connector\Sabre\FilesPlugin( + $this->tree, + $this->view, + $config + ) + ); $this->plugin->initialize($this->server); $responses = $this->plugin->prepareResponses($requestedProps, [$node1, $node2]); diff --git a/apps/dav/tests/unit/connector/sabre/node.php b/apps/dav/tests/unit/connector/sabre/node.php index cde8e746dc3..6fdf77adc21 100644 --- a/apps/dav/tests/unit/connector/sabre/node.php +++ b/apps/dav/tests/unit/connector/sabre/node.php @@ -66,14 +66,14 @@ class Node extends \Test\TestCase { public function sharePermissionsProvider() { return [ - [\OCP\Files\FileInfo::TYPE_FILE, 1, 0], - [\OCP\Files\FileInfo::TYPE_FILE, 3, 0], - [\OCP\Files\FileInfo::TYPE_FILE, 5, 0], - [\OCP\Files\FileInfo::TYPE_FILE, 7, 0], - [\OCP\Files\FileInfo::TYPE_FILE, 9, 0], - [\OCP\Files\FileInfo::TYPE_FILE, 11, 0], - [\OCP\Files\FileInfo::TYPE_FILE, 13, 0], - [\OCP\Files\FileInfo::TYPE_FILE, 15, 0], + [\OCP\Files\FileInfo::TYPE_FILE, 1, 1], + [\OCP\Files\FileInfo::TYPE_FILE, 3, 3], + [\OCP\Files\FileInfo::TYPE_FILE, 5, 1], + [\OCP\Files\FileInfo::TYPE_FILE, 7, 3], + [\OCP\Files\FileInfo::TYPE_FILE, 9, 1], + [\OCP\Files\FileInfo::TYPE_FILE, 11, 3], + [\OCP\Files\FileInfo::TYPE_FILE, 13, 1], + [\OCP\Files\FileInfo::TYPE_FILE, 15, 3], [\OCP\Files\FileInfo::TYPE_FILE, 17, 17], [\OCP\Files\FileInfo::TYPE_FILE, 19, 19], [\OCP\Files\FileInfo::TYPE_FILE, 21, 17], @@ -81,16 +81,16 @@ class Node extends \Test\TestCase { [\OCP\Files\FileInfo::TYPE_FILE, 25, 17], [\OCP\Files\FileInfo::TYPE_FILE, 27, 19], [\OCP\Files\FileInfo::TYPE_FILE, 29, 17], - [\OCP\Files\FileInfo::TYPE_FILE, 30, 0], + [\OCP\Files\FileInfo::TYPE_FILE, 30, 18], [\OCP\Files\FileInfo::TYPE_FILE, 31, 19], - [\OCP\Files\FileInfo::TYPE_FOLDER, 1, 0], - [\OCP\Files\FileInfo::TYPE_FOLDER, 3, 0], - [\OCP\Files\FileInfo::TYPE_FOLDER, 5, 0], - [\OCP\Files\FileInfo::TYPE_FOLDER, 7, 0], - [\OCP\Files\FileInfo::TYPE_FOLDER, 9, 0], - [\OCP\Files\FileInfo::TYPE_FOLDER, 11, 0], - [\OCP\Files\FileInfo::TYPE_FOLDER, 13, 0], - [\OCP\Files\FileInfo::TYPE_FOLDER, 15, 0], + [\OCP\Files\FileInfo::TYPE_FOLDER, 1, 1], + [\OCP\Files\FileInfo::TYPE_FOLDER, 3, 3], + [\OCP\Files\FileInfo::TYPE_FOLDER, 5, 5], + [\OCP\Files\FileInfo::TYPE_FOLDER, 7, 7], + [\OCP\Files\FileInfo::TYPE_FOLDER, 9, 9], + [\OCP\Files\FileInfo::TYPE_FOLDER, 11, 11], + [\OCP\Files\FileInfo::TYPE_FOLDER, 13, 13], + [\OCP\Files\FileInfo::TYPE_FOLDER, 15, 15], [\OCP\Files\FileInfo::TYPE_FOLDER, 17, 17], [\OCP\Files\FileInfo::TYPE_FOLDER, 19, 19], [\OCP\Files\FileInfo::TYPE_FOLDER, 21, 21], @@ -98,7 +98,7 @@ class Node extends \Test\TestCase { [\OCP\Files\FileInfo::TYPE_FOLDER, 25, 25], [\OCP\Files\FileInfo::TYPE_FOLDER, 27, 27], [\OCP\Files\FileInfo::TYPE_FOLDER, 29, 29], - [\OCP\Files\FileInfo::TYPE_FOLDER, 30, 0], + [\OCP\Files\FileInfo::TYPE_FOLDER, 30, 30], [\OCP\Files\FileInfo::TYPE_FOLDER, 31, 31], ]; } diff --git a/apps/dav/tests/unit/dav/HookManagerTest.php b/apps/dav/tests/unit/dav/HookManagerTest.php new file mode 100644 index 00000000000..bec4c240ce8 --- /dev/null +++ b/apps/dav/tests/unit/dav/HookManagerTest.php @@ -0,0 +1,71 @@ +<?php + +/** + * @author Thomas Müller <thomas.mueller@tmit.eu> + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace OCA\DAV\Tests\Unit\DAV; + +use OCA\DAV\CalDAV\CalDavBackend; +use OCA\DAV\CardDAV\CardDavBackend; +use OCA\DAV\CardDAV\SyncService; +use OCA\DAV\HookManager; +use OCP\IUserManager; +use Test\TestCase; + +class HookManagerTest extends TestCase { + public function test() { + $user = $this->getMockBuilder('\OCP\IUser') + ->disableOriginalConstructor() + ->getMock(); + $user->expects($this->once())->method('getUID')->willReturn('newUser'); + + /** @var IUserManager | \PHPUnit_Framework_MockObject_MockObject $userManager */ + $userManager = $this->getMockBuilder('\OCP\IUserManager') + ->disableOriginalConstructor() + ->getMock(); + $userManager->expects($this->once())->method('get')->willReturn($user); + + /** @var SyncService | \PHPUnit_Framework_MockObject_MockObject $syncService */ + $syncService = $this->getMockBuilder('OCA\DAV\CardDAV\SyncService') + ->disableOriginalConstructor() + ->getMock(); + + /** @var CalDavBackend | \PHPUnit_Framework_MockObject_MockObject $cal */ + $cal = $this->getMockBuilder('OCA\DAV\CalDAV\CalDavBackend') + ->disableOriginalConstructor() + ->getMock(); + $cal->expects($this->once())->method('getCalendarsForUser')->willReturn([]); + $cal->expects($this->once())->method('createCalendar')->with( + 'principals/users/newUser', + 'personal', ['{DAV:}displayname' => 'Personal']); + + /** @var CardDavBackend | \PHPUnit_Framework_MockObject_MockObject $card */ + $card = $this->getMockBuilder('OCA\DAV\CardDAV\CardDavBackend') + ->disableOriginalConstructor() + ->getMock(); + $card->expects($this->once())->method('getAddressBooksForUser')->willReturn([]); + $card->expects($this->once())->method('createAddressBook')->with( + 'principals/users/newUser', + 'contacts', ['{DAV:}displayname' => 'Contacts']); + + $hm = new HookManager($userManager, $syncService, $cal, $card); + $hm->postLogin(['uid' => 'newUser']); + } +} diff --git a/apps/dav/tests/unit/migration/addressbookadaptertest.php b/apps/dav/tests/unit/migration/addressbookadaptertest.php deleted file mode 100644 index e6e57049a93..00000000000 --- a/apps/dav/tests/unit/migration/addressbookadaptertest.php +++ /dev/null @@ -1,129 +0,0 @@ -<?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\Migration; - -use DomainException; -use OCA\Dav\Migration\AddressBookAdapter; -use OCP\IDBConnection; -use Test\TestCase; - -/** - * Class AddressbookAdapterTest - * - * @group DB - * - * @package OCA\DAV\Tests\Unit\Migration - */ -class AddressbookAdapterTest extends TestCase { - - /** @var IDBConnection */ - private $db; - /** @var AddressBookAdapter */ - private $adapter; - /** @var array */ - private $books = []; - /** @var array */ - private $cards = []; - - public function setUp() { - parent::setUp(); - $this->db = \OC::$server->getDatabaseConnection(); - - $manager = new \OC\DB\MDB2SchemaManager($this->db); - $manager->createDbFromStructure(__DIR__ . '/contacts_schema.xml'); - - $this->adapter = new AddressBookAdapter($this->db); - } - - public function tearDown() { - $this->db->dropTable('contacts_addressbooks'); - $this->db->dropTable('contacts_cards'); - parent::tearDown(); - } - - /** - * @expectedException DomainException - */ - public function testOldTablesDoNotExist() { - $adapter = new AddressBookAdapter(\OC::$server->getDatabaseConnection(), 'crazy_table_that_does_no_exist'); - $adapter->setup(); - } - - public function test() { - - // insert test data - $builder = $this->db->getQueryBuilder(); - $builder->insert('contacts_addressbooks') - ->values([ - 'userid' => $builder->createNamedParameter('test-user-666'), - 'displayname' => $builder->createNamedParameter('Display Name'), - 'uri' => $builder->createNamedParameter('contacts'), - 'description' => $builder->createNamedParameter('An address book for testing'), - 'ctag' => $builder->createNamedParameter('112233'), - 'active' => $builder->createNamedParameter('1') - ]) - ->execute(); - $builder = $this->db->getQueryBuilder(); - $builder->insert('contacts_cards') - ->values([ - 'addressbookid' => $builder->createNamedParameter(6666), - 'fullname' => $builder->createNamedParameter('Full Name'), - 'carddata' => $builder->createNamedParameter('datadatadata'), - 'uri' => $builder->createNamedParameter('some-card.vcf'), - 'lastmodified' => $builder->createNamedParameter('112233'), - ]) - ->execute(); - $builder = $this->db->getQueryBuilder(); - $builder->insert('share') - ->values([ - 'share_type' => $builder->createNamedParameter(1), - 'share_with' => $builder->createNamedParameter('user01'), - 'uid_owner' => $builder->createNamedParameter('user02'), - 'item_type' => $builder->createNamedParameter('addressbook'), - 'item_source' => $builder->createNamedParameter(6666), - 'item_target' => $builder->createNamedParameter('Contacts (user02)'), - ]) - ->execute(); - - // test the adapter - $this->adapter->foreachBook('test-user-666', function($row) { - $this->books[] = $row; - }); - $this->assertArrayHasKey('id', $this->books[0]); - $this->assertEquals('test-user-666', $this->books[0]['userid']); - $this->assertEquals('Display Name', $this->books[0]['displayname']); - $this->assertEquals('contacts', $this->books[0]['uri']); - $this->assertEquals('An address book for testing', $this->books[0]['description']); - $this->assertEquals('112233', $this->books[0]['ctag']); - - $this->adapter->foreachCard(6666, function($row) { - $this->cards[]= $row; - }); - $this->assertArrayHasKey('id', $this->cards[0]); - $this->assertEquals(6666, $this->cards[0]['addressbookid']); - - // test getShares - $shares = $this->adapter->getShares(6666); - $this->assertEquals(1, count($shares)); - - } - -} diff --git a/apps/dav/tests/unit/migration/calendar_schema.xml b/apps/dav/tests/unit/migration/calendar_schema.xml deleted file mode 100644 index 6c88b596a3f..00000000000 --- a/apps/dav/tests/unit/migration/calendar_schema.xml +++ /dev/null @@ -1,191 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> -<database> - - <name>*dbname*</name> - <create>true</create> - <overwrite>false</overwrite> - - <charset>utf8</charset> - - <table> - - <name>*dbprefix*clndr_objects</name> - - <declaration> - - <field> - <name>id</name> - <type>integer</type> - <default>0</default> - <notnull>true</notnull> - <autoincrement>1</autoincrement> - <unsigned>true</unsigned> - <length>4</length> - </field> - - <field> - <name>calendarid</name> - <type>integer</type> - <default></default> - <notnull>true</notnull> - <unsigned>true</unsigned> - <length>4</length> - </field> - - <field> - <name>objecttype</name> - <type>text</type> - <default></default> - <notnull>true</notnull> - <length>40</length> - </field> - - <field> - <name>startdate</name> - <type>timestamp</type> - <default>1970-01-01 00:00:00</default> - <notnull>false</notnull> - </field> - - <field> - <name>enddate</name> - <type>timestamp</type> - <default>1970-01-01 00:00:00</default> - <notnull>false</notnull> - </field> - - <field> - <name>repeating</name> - <type>integer</type> - <default></default> - <notnull>false</notnull> - <length>4</length> - </field> - - <field> - <name>summary</name> - <type>text</type> - <default></default> - <notnull>false</notnull> - <length>255</length> - </field> - - <field> - <name>calendardata</name> - <type>clob</type> - <notnull>false</notnull> - </field> - - <field> - <name>uri</name> - <type>text</type> - <default></default> - <notnull>false</notnull> - <length>255</length> - </field> - - <field> - <name>lastmodified</name> - <type>integer</type> - <default></default> - <notnull>false</notnull> - <length>4</length> - </field> - - </declaration> - - </table> - - <table> - - <name>*dbprefix*clndr_calendars</name> - - <declaration> - - <field> - <name>id</name> - <type>integer</type> - <default>0</default> - <notnull>true</notnull> - <autoincrement>1</autoincrement> - <unsigned>true</unsigned> - <length>4</length> - </field> - - <field> - <name>userid</name> - <type>text</type> - <default></default> - <notnull>false</notnull> - <length>255</length> - </field> - - <field> - <name>displayname</name> - <type>text</type> - <default></default> - <notnull>false</notnull> - <length>100</length> - </field> - - <field> - <name>uri</name> - <type>text</type> - <default></default> - <notnull>false</notnull> - <length>255</length> - </field> - - <field> - <name>active</name> - <type>integer</type> - <default>1</default> - <notnull>true</notnull> - <length>4</length> - </field> - - <field> - <name>ctag</name> - <type>integer</type> - <default>0</default> - <notnull>true</notnull> - <unsigned>true</unsigned> - <length>4</length> - </field> - - <field> - <name>calendarorder</name> - <type>integer</type> - <default>0</default> - <notnull>true</notnull> - <unsigned>true</unsigned> - <length>4</length> - </field> - - <field> - <name>calendarcolor</name> - <type>text</type> - <default></default> - <notnull>false</notnull> - <length>10</length> - </field> - - <field> - <name>timezone</name> - <type>clob</type> - <notnull>false</notnull> - </field> - - <field> - <name>components</name> - <type>text</type> - <default></default> - <notnull>false</notnull> - <length>100</length> - </field> - - </declaration> - - </table> - -</database> diff --git a/apps/dav/tests/unit/migration/calendaradaptertest.php b/apps/dav/tests/unit/migration/calendaradaptertest.php deleted file mode 100644 index f92774ef6ad..00000000000 --- a/apps/dav/tests/unit/migration/calendaradaptertest.php +++ /dev/null @@ -1,131 +0,0 @@ -<?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\Migration; - -use DomainException; -use OCA\Dav\Migration\AddressBookAdapter; -use OCA\Dav\Migration\CalendarAdapter; -use OCP\IDBConnection; -use Test\TestCase; - -/** - * Class CalendarAdapterTest - * - * @group DB - * - * @package OCA\DAV\Tests\Unit\Migration - */ -class CalendarAdapterTest extends TestCase { - - /** @var IDBConnection */ - private $db; - /** @var CalendarAdapter */ - private $adapter; - /** @var array */ - private $cals = []; - /** @var array */ - private $calObjs = []; - - public function setUp() { - parent::setUp(); - $this->db = \OC::$server->getDatabaseConnection(); - - $manager = new \OC\DB\MDB2SchemaManager($this->db); - $manager->createDbFromStructure(__DIR__ . '/calendar_schema.xml'); - - $this->adapter = new CalendarAdapter($this->db); - } - - public function tearDown() { - $this->db->dropTable('clndr_calendars'); - $this->db->dropTable('clndr_objects'); - parent::tearDown(); - } - - /** - * @expectedException DomainException - */ - public function testOldTablesDoNotExist() { - $adapter = new AddressBookAdapter(\OC::$server->getDatabaseConnection(), 'crazy_table_that_does_no_exist'); - $adapter->setup(); - } - - public function test() { - - // insert test data - $builder = $this->db->getQueryBuilder(); - $builder->insert('clndr_calendars') - ->values([ - 'userid' => $builder->createNamedParameter('test-user-666'), - 'displayname' => $builder->createNamedParameter('Display Name'), - 'uri' => $builder->createNamedParameter('events'), - 'ctag' => $builder->createNamedParameter('112233'), - 'active' => $builder->createNamedParameter('1') - ]) - ->execute(); - $builder = $this->db->getQueryBuilder(); - $builder->insert('clndr_objects') - ->values([ - 'calendarid' => $builder->createNamedParameter(6666), - 'objecttype' => $builder->createNamedParameter('VEVENT'), - 'startdate' => $builder->createNamedParameter(new \DateTime(), 'datetime'), - 'enddate' => $builder->createNamedParameter(new \DateTime(), 'datetime'), - 'repeating' => $builder->createNamedParameter(0), - 'summary' => $builder->createNamedParameter('Something crazy will happen'), - 'uri' => $builder->createNamedParameter('event.ics'), - 'lastmodified' => $builder->createNamedParameter('112233'), - ]) - ->execute(); - $builder = $this->db->getQueryBuilder(); - $builder->insert('share') - ->values([ - 'share_type' => $builder->createNamedParameter(1), - 'share_with' => $builder->createNamedParameter('user01'), - 'uid_owner' => $builder->createNamedParameter('user02'), - 'item_type' => $builder->createNamedParameter('calendar'), - 'item_source' => $builder->createNamedParameter(6666), - 'item_target' => $builder->createNamedParameter('Contacts (user02)'), - ]) - ->execute(); - - // test the adapter - $this->adapter->foreachCalendar('test-user-666', function($row) { - $this->cals[] = $row; - }); - $this->assertArrayHasKey('id', $this->cals[0]); - $this->assertEquals('test-user-666', $this->cals[0]['userid']); - $this->assertEquals('Display Name', $this->cals[0]['displayname']); - $this->assertEquals('events', $this->cals[0]['uri']); - $this->assertEquals('112233', $this->cals[0]['ctag']); - - $this->adapter->foreachCalendarObject(6666, function($row) { - $this->calObjs[]= $row; - }); - $this->assertArrayHasKey('id', $this->calObjs[0]); - $this->assertEquals(6666, $this->calObjs[0]['calendarid']); - - // test getShares - $shares = $this->adapter->getShares(6666); - $this->assertEquals(1, count($shares)); - - } - -} diff --git a/apps/dav/tests/unit/migration/contacts_schema.xml b/apps/dav/tests/unit/migration/contacts_schema.xml deleted file mode 100644 index 51836a1e0c6..00000000000 --- a/apps/dav/tests/unit/migration/contacts_schema.xml +++ /dev/null @@ -1,151 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> -<database> - - <name>*dbname*</name> - <create>true</create> - <overwrite>false</overwrite> - <charset>utf8</charset> - <table> - - <name>*dbprefix*contacts_addressbooks</name> - - <declaration> - - <field> - <name>id</name> - <type>integer</type> - <default>0</default> - <notnull>true</notnull> - <autoincrement>1</autoincrement> - <unsigned>true</unsigned> - <length>4</length> - </field> - - <field> - <name>userid</name> - <type>text</type> - <default></default> - <notnull>true</notnull> - <length>255</length> - </field> - - <field> - <name>displayname</name> - <type>text</type> - <default></default> - <notnull>false</notnull> - <length>255</length> - </field> - - <field> - <name>uri</name> - <type>text</type> - <default></default> - <notnull>false</notnull> - <length>200</length> - </field> - - <field> - <name>description</name> - <type>text</type> - <notnull>false</notnull> - <length>255</length> - </field> - - <field> - <name>ctag</name> - <type>integer</type> - <default>1</default> - <notnull>true</notnull> - <unsigned>true</unsigned> - <length>4</length> - </field> - - <field> - <name>active</name> - <type>integer</type> - <default>1</default> - <notnull>true</notnull> - <length>4</length> - </field> - - <index> - <name>c_addressbook_userid_index</name> - <field> - <name>userid</name> - <sorting>ascending</sorting> - </field> - </index> - </declaration> - - </table> - - <table> - - <name>*dbprefix*contacts_cards</name> - - <declaration> - - <field> - <name>id</name> - <type>integer</type> - <default>0</default> - <notnull>true</notnull> - <autoincrement>1</autoincrement> - <unsigned>true</unsigned> - <length>4</length> - </field> - - <field> - <name>addressbookid</name> - <type>integer</type> - <default></default> - <notnull>true</notnull> - <unsigned>true</unsigned> - <length>4</length> - </field> - - <field> - <name>fullname</name> - <type>text</type> - <default></default> - <notnull>false</notnull> - <length>255</length> - </field> - - <field> - <name>carddata</name> - <type>clob</type> - <notnull>false</notnull> - </field> - - <field> - <name>uri</name> - <type>text</type> - <default></default> - <notnull>false</notnull> - <length>200</length> - </field> - - <field> - <name>lastmodified</name> - <type>integer</type> - <default></default> - <notnull>false</notnull> - <unsigned>true</unsigned> - <length>4</length> - </field> - - - <index> - <name>c_addressbookid_index</name> - <field> - <name>addressbookid</name> - <sorting>ascending</sorting> - </field> - </index> - </declaration> - - </table> - -</database> diff --git a/apps/dav/tests/unit/migration/migrateaddressbooktest.php b/apps/dav/tests/unit/migration/migrateaddressbooktest.php deleted file mode 100644 index 31cb16265c0..00000000000 --- a/apps/dav/tests/unit/migration/migrateaddressbooktest.php +++ /dev/null @@ -1,81 +0,0 @@ -<?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\Migration; - -use OCA\DAV\CardDAV\CardDavBackend; -use OCA\Dav\Migration\AddressBookAdapter; -use OCP\ILogger; -use Test\TestCase; - -class MigrateAddressbookTest extends TestCase { - - public function testMigration() { - /** @var AddressBookAdapter | \PHPUnit_Framework_MockObject_MockObject $adapter */ - $adapter = $this->mockAdapter([ - ['share_type' => '1', 'share_with' => 'users', 'permissions' => '31'], - ['share_type' => '2', 'share_with' => 'adam', 'permissions' => '1'], - ]); - - /** @var CardDavBackend | \PHPUnit_Framework_MockObject_MockObject $cardDav */ - $cardDav = $this->getMockBuilder('\OCA\Dav\CardDAV\CardDAVBackend')->disableOriginalConstructor()->getMock(); - $cardDav->expects($this->any())->method('createAddressBook')->willReturn(666); - $cardDav->expects($this->any())->method('getAddressBookById')->willReturn([]); - $cardDav->expects($this->once())->method('createAddressBook')->with('principals/users/test01', 'test_contacts'); - $cardDav->expects($this->once())->method('createCard')->with(666, '63f0dd6c-39d5-44be-9d34-34e7a7441fc2.vcf', 'BEGIN:VCARD'); - $cardDav->expects($this->once())->method('updateShares')->with($this->anything(), [ - ['href' => 'principal:principals/groups/users', 'readOnly' => false], - ['href' => 'principal:principals/users/adam', 'readOnly' => true] - ]); - /** @var ILogger $logger */ - $logger = $this->getMockBuilder('\OCP\ILogger')->disableOriginalConstructor()->getMock(); - - $m = new \OCA\Dav\Migration\MigrateAddressbooks($adapter, $cardDav, $logger, null); - $m->migrateForUser('test01'); - } - - /** - * @return \PHPUnit_Framework_MockObject_MockObject - */ - private function mockAdapter($shares = []) { - $adapter = $this->getMockBuilder('\OCA\Dav\Migration\AddressBookAdapter')->disableOriginalConstructor()->getMock(); - $adapter->expects($this->any())->method('foreachBook')->willReturnCallback(function ($user, \Closure $callBack) { - $callBack([ - 'id' => 0, - 'userid' => $user, - 'displayname' => 'Test Contacts', - 'uri' => 'test_contacts', - 'description' => 'Contacts to test with', - 'ctag' => 1234567890, - 'active' => 1 - ]); - }); - $adapter->expects($this->any())->method('foreachCard')->willReturnCallback(function ($addressBookId, \Closure $callBack) { - $callBack([ - 'userid' => $addressBookId, - 'uri' => '63f0dd6c-39d5-44be-9d34-34e7a7441fc2.vcf', - 'carddata' => 'BEGIN:VCARD' - ]); - }); - $adapter->expects($this->any())->method('getShares')->willReturn($shares); - return $adapter; - } - -} diff --git a/apps/dav/tests/unit/migration/migratecalendartest.php b/apps/dav/tests/unit/migration/migratecalendartest.php deleted file mode 100644 index e62970aef34..00000000000 --- a/apps/dav/tests/unit/migration/migratecalendartest.php +++ /dev/null @@ -1,85 +0,0 @@ -<?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\Migration; - -use OCA\DAV\CalDAV\CalDavBackend; -use OCA\Dav\Migration\CalendarAdapter; -use OCP\ILogger; -use Test\TestCase; - -class MigrateCalendarTest extends TestCase { - - public function testMigration() { - /** @var CalendarAdapter | \PHPUnit_Framework_MockObject_MockObject $adapter */ - $adapter = $this->mockAdapter([ - ['share_type' => '1', 'share_with' => 'users', 'permissions' => '31'], - ['share_type' => '2', 'share_with' => 'adam', 'permissions' => '1'], - ]); - - /** @var CalDavBackend | \PHPUnit_Framework_MockObject_MockObject $cardDav */ - $cardDav = $this->getMockBuilder('\OCA\Dav\CalDAV\CalDAVBackend')->disableOriginalConstructor()->getMock(); - $cardDav->expects($this->any())->method('createCalendar')->willReturn(666); - $cardDav->expects($this->once())->method('createCalendar')->with('principals/users/test01', 'test_contacts'); - $cardDav->expects($this->once())->method('createCalendarObject')->with(666, '63f0dd6c-39d5-44be-9d34-34e7a7441fc2.ics', 'BEGIN:VCARD'); - $cardDav->expects($this->once())->method('updateShares')->with($this->anything(), [ - ['href' => 'principal:principals/groups/users', 'readOnly' => false], - ['href' => 'principal:principals/users/adam', 'readOnly' => true] - ]); - /** @var ILogger $logger */ - $logger = $this->getMockBuilder('\OCP\ILogger')->disableOriginalConstructor()->getMock(); - - $m = new \OCA\Dav\Migration\MigrateCalendars($adapter, $cardDav, $logger, null); - $m->migrateForUser('test01'); - } - - /** - * @return \PHPUnit_Framework_MockObject_MockObject - */ - private function mockAdapter($shares = [], $calData = 'BEGIN:VCARD') { - $adapter = $this->getMockBuilder('\OCA\Dav\Migration\CalendarAdapter') - ->disableOriginalConstructor() - ->getMock(); - $adapter->expects($this->any())->method('foreachCalendar')->willReturnCallback(function ($user, \Closure $callBack) { - $callBack([ - // calendarorder | calendarcolor | timezone | components - 'id' => 0, - 'userid' => $user, - 'displayname' => 'Test Contacts', - 'uri' => 'test_contacts', - 'ctag' => 1234567890, - 'active' => 1, - 'calendarorder' => '0', - 'calendarcolor' => '#b3dc6c', - 'timezone' => null, - 'components' => 'VEVENT,VTODO,VJOURNAL' - ]); - }); - $adapter->expects($this->any())->method('foreachCalendarObject')->willReturnCallback(function ($addressBookId, \Closure $callBack) use ($calData) { - $callBack([ - 'userid' => $addressBookId, - 'uri' => '63f0dd6c-39d5-44be-9d34-34e7a7441fc2.ics', - 'calendardata' => $calData - ]); - }); - $adapter->expects($this->any())->method('getShares')->willReturn($shares); - return $adapter; - } -} diff --git a/apps/dav/tests/unit/upload/assemblystreamtest.php b/apps/dav/tests/unit/upload/assemblystreamtest.php new file mode 100644 index 00000000000..373d525a9dd --- /dev/null +++ b/apps/dav/tests/unit/upload/assemblystreamtest.php @@ -0,0 +1,47 @@ +<?php + +class AssemblyStreamTest extends \PHPUnit_Framework_TestCase { + + /** + * @dataProvider providesNodes() + */ + public function testGetContents($expected, $nodes) { + $stream = \OCA\DAV\Upload\AssemblyStream::wrap($nodes); + $content = stream_get_contents($stream); + + $this->assertEquals($expected, $content); + } + + function providesNodes() { + return[ + 'one node only' => ['1234567890', [ + $this->buildNode('0', '1234567890') + ]], + 'two nodes' => ['1234567890', [ + $this->buildNode('1', '67890'), + $this->buildNode('0', '12345') + ]] + ]; + } + + private function buildNode($name, $data) { + $node = $this->getMockBuilder('\Sabre\DAV\File') + ->setMethods(['getName', 'get', 'getSize']) + ->getMockForAbstractClass(); + + $node->expects($this->any()) + ->method('getName') + ->willReturn($name); + + $node->expects($this->any()) + ->method('get') + ->willReturn($data); + + $node->expects($this->any()) + ->method('getSize') + ->willReturn(strlen($data)); + + return $node; + } +} + diff --git a/apps/dav/tests/unit/upload/futurefiletest.php b/apps/dav/tests/unit/upload/futurefiletest.php new file mode 100644 index 00000000000..c0c14bf04d7 --- /dev/null +++ b/apps/dav/tests/unit/upload/futurefiletest.php @@ -0,0 +1,89 @@ +<?php + +class FutureFileTest extends \PHPUnit_Framework_TestCase { + + public function testGetContentType() { + $f = $this->mockFutureFile(); + $this->assertEquals('application/octet-stream', $f->getContentType()); + } + + public function testGetETag() { + $f = $this->mockFutureFile(); + $this->assertEquals('1234567890', $f->getETag()); + } + + public function testGetName() { + $f = $this->mockFutureFile(); + $this->assertEquals('foo.txt', $f->getName()); + } + + public function testGetLastModified() { + $f = $this->mockFutureFile(); + $this->assertEquals(12121212, $f->getLastModified()); + } + + public function testGetSize() { + $f = $this->mockFutureFile(); + $this->assertEquals(0, $f->getSize()); + } + + public function testGet() { + $f = $this->mockFutureFile(); + $stream = $f->get(); + $this->assertTrue(is_resource($stream)); + } + + public function testDelete() { + $d = $this->getMockBuilder('OCA\DAV\Connector\Sabre\Directory') + ->disableOriginalConstructor() + ->setMethods(['delete']) + ->getMock(); + + $d->expects($this->once()) + ->method('delete'); + + $f = new \OCA\DAV\Upload\FutureFile($d, 'foo.txt'); + $f->delete(); + } + + /** + * @expectedException Sabre\DAV\Exception\Forbidden + */ + public function testPut() { + $f = $this->mockFutureFile(); + $f->put(''); + } + + /** + * @expectedException Sabre\DAV\Exception\Forbidden + */ + public function testSetName() { + $f = $this->mockFutureFile(); + $f->setName(''); + } + + /** + * @return \OCA\DAV\Upload\FutureFile + */ + private function mockFutureFile() { + $d = $this->getMockBuilder('OCA\DAV\Connector\Sabre\Directory') + ->disableOriginalConstructor() + ->setMethods(['getETag', 'getLastModified', 'getChildren']) + ->getMock(); + + $d->expects($this->any()) + ->method('getETag') + ->willReturn('1234567890'); + + $d->expects($this->any()) + ->method('getLastModified') + ->willReturn(12121212); + + $d->expects($this->any()) + ->method('getChildren') + ->willReturn([]); + + return new \OCA\DAV\Upload\FutureFile($d, 'foo.txt'); + } +} + diff --git a/apps/encryption/l10n/de_AT.js b/apps/encryption/l10n/de_AT.js new file mode 100644 index 00000000000..164a02092f9 --- /dev/null +++ b/apps/encryption/l10n/de_AT.js @@ -0,0 +1,7 @@ +OC.L10N.register( + "encryption", + { + "The share will expire on %s." : "Die Freigabe wird am %s ablaufen.", + "Cheers!" : "Noch einen schönen Tag!" +}, +"nplurals=2; plural=(n != 1);"); diff --git a/apps/encryption/l10n/de_AT.json b/apps/encryption/l10n/de_AT.json new file mode 100644 index 00000000000..a8313eeb7aa --- /dev/null +++ b/apps/encryption/l10n/de_AT.json @@ -0,0 +1,5 @@ +{ "translations": { + "The share will expire on %s." : "Die Freigabe wird am %s ablaufen.", + "Cheers!" : "Noch einen schönen Tag!" +},"pluralForm" :"nplurals=2; plural=(n != 1);" +}
\ No newline at end of file diff --git a/apps/encryption/lib/crypto/encryption.php b/apps/encryption/lib/crypto/encryption.php index 907a6437f5b..6eff66e72be 100644 --- a/apps/encryption/lib/crypto/encryption.php +++ b/apps/encryption/lib/crypto/encryption.php @@ -547,4 +547,17 @@ class Encryption implements IEncryptionModule { return $path; } + /** + * Check if the module is ready to be used by that specific user. + * In case a module is not ready - because e.g. key pairs have not been generated + * upon login this method can return false before any operation starts and might + * cause issues during operations. + * + * @param string $user + * @return boolean + * @since 9.1.0 + */ + public function isReadyForUser($user) { + return $this->keyManager->userHasKeys($user); + } } diff --git a/apps/encryption/lib/keymanager.php b/apps/encryption/lib/keymanager.php index 12fa5f92bd5..0accfb7900a 100644 --- a/apps/encryption/lib/keymanager.php +++ b/apps/encryption/lib/keymanager.php @@ -493,6 +493,7 @@ class KeyManager { */ public function userHasKeys($userId) { $privateKey = $publicKey = true; + $exception = null; try { $this->getPrivateKey($userId); diff --git a/apps/federatedfilesharing/backgroundjob/unshare.php b/apps/federatedfilesharing/backgroundjob/unshare.php new file mode 100644 index 00000000000..b056db4eac7 --- /dev/null +++ b/apps/federatedfilesharing/backgroundjob/unshare.php @@ -0,0 +1,142 @@ +<?php +/** + * @author Björn Schießle <schiessle@owncloud.com> + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + + +namespace OCA\FederatedFileSharing\BackgroundJob; + + +use OC\BackgroundJob\Job; +use OC\BackgroundJob\JobList; +use OCA\FederatedFileSharing\AddressHandler; +use OCA\FederatedFileSharing\DiscoveryManager; +use OCA\FederatedFileSharing\Notifications; +use OCP\BackgroundJob\IJobList; +use OCP\ILogger; + +/** + * Class UnShare + * + * Background job to re-send the un-share notification to the remote server in + * case the server was not available on the first try + * + * @package OCA\FederatedFileSharing\BackgroundJob + */ +class UnShare extends Job { + + /** @var bool */ + private $retainJob = true; + + /** @var Notifications */ + private $notifications; + + /** @var int max number of attempts to send the un-share request */ + private $maxTry = 10; + + /** @var int how much time should be between two tries (12 hours) */ + private $interval = 43200; + + /** + * UnShare constructor. + * + * @param Notifications $notifications + */ + public function __construct(Notifications $notifications = null) { + if ($notifications) { + $this->notifications = $notifications; + } else { + $addressHandler = new AddressHandler( + \OC::$server->getURLGenerator(), + \OC::$server->getL10N('federatedfilesharing') + ); + $discoveryManager = new DiscoveryManager( + \OC::$server->getMemCacheFactory(), + \OC::$server->getHTTPClientService() + ); + $this->notifications = new Notifications( + $addressHandler, + \OC::$server->getHTTPClientService(), + $discoveryManager, + \OC::$server->getJobList() + ); + } + + } + + /** + * run the job, then remove it from the jobList + * + * @param JobList $jobList + * @param ILogger $logger + */ + public function execute($jobList, ILogger $logger = null) { + + if ($this->shouldRun($this->argument)) { + parent::execute($jobList, $logger); + $jobList->remove($this, $this->argument); + if ($this->retainJob) { + $this->reAddJob($jobList, $this->argument); + } + } + } + + protected function run($argument) { + $remote = $argument['remote']; + $id = (int)$argument['id']; + $token = $argument['token']; + $try = (int)$argument['try'] + 1; + + $result = $this->notifications->sendRemoteUnShare($remote, $id, $token, $try); + + if ($result === true || $try > $this->maxTry) { + $this->retainJob = false; + } + } + + /** + * re-add background job with new arguments + * + * @param IJobList $jobList + * @param array $argument + */ + protected function reAddJob(IJobList $jobList, array $argument) { + $jobList->add('OCA\FederatedFileSharing\BackgroundJob\UnShare', + [ + 'remote' => $argument['remote'], + 'id' => $argument['id'], + 'token' => $argument['token'], + 'try' => (int)$argument['try'] + 1, + 'lastRun' => time() + ] + ); + } + + /** + * test if it is time for the next run + * + * @param array $argument + * @return bool + */ + protected function shouldRun(array $argument) { + $lastRun = (int)$argument['lastRun']; + return ((time() - $lastRun) > $this->interval); + } + +} diff --git a/apps/federatedfilesharing/lib/federatedshareprovider.php b/apps/federatedfilesharing/lib/federatedshareprovider.php index a450b420cf4..78b0b664204 100644 --- a/apps/federatedfilesharing/lib/federatedshareprovider.php +++ b/apps/federatedfilesharing/lib/federatedshareprovider.php @@ -580,4 +580,25 @@ class FederatedShareProvider implements IShareProvider { ->andWhere($qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid))) ->execute(); } + + /** + * This provider does not handle groups + * + * @param string $gid + */ + public function groupDeleted($gid) { + // We don't handle groups here + return; + } + + /** + * This provider does not handle groups + * + * @param string $uid + * @param string $gid + */ + public function userDeletedFromGroup($uid, $gid) { + // We don't handle groups here + return; + } } diff --git a/apps/federatedfilesharing/lib/notifications.php b/apps/federatedfilesharing/lib/notifications.php index 4ec21e81cc7..9cdc7760361 100644 --- a/apps/federatedfilesharing/lib/notifications.php +++ b/apps/federatedfilesharing/lib/notifications.php @@ -23,6 +23,7 @@ namespace OCA\FederatedFileSharing; +use OCP\BackgroundJob\IJobList; use OCP\Http\Client\IClientService; class Notifications { @@ -30,24 +31,32 @@ class Notifications { /** @var AddressHandler */ private $addressHandler; + /** @var IClientService */ private $httpClientService; + /** @var DiscoveryManager */ private $discoveryManager; + /** @var IJobList */ + private $jobList; + /** * @param AddressHandler $addressHandler * @param IClientService $httpClientService * @param DiscoveryManager $discoveryManager + * @param IJobList $jobList */ public function __construct( AddressHandler $addressHandler, IClientService $httpClientService, - DiscoveryManager $discoveryManager + DiscoveryManager $discoveryManager, + IJobList $jobList ) { $this->addressHandler = $addressHandler; $this->httpClientService = $httpClientService; $this->discoveryManager = $discoveryManager; + $this->jobList = $jobList; } /** @@ -97,16 +106,45 @@ class Notifications { * @param string $remote url * @param int $id share id * @param string $token + * @param int $try how often did we already tried to send the un-share request * @return bool */ - public function sendRemoteUnShare($remote, $id, $token) { + public function sendRemoteUnShare($remote, $id, $token, $try = 0) { $url = rtrim($remote, '/'); $fields = array('token' => $token, 'format' => 'json'); $url = $this->addressHandler->removeProtocolFromUrl($url); $result = $this->tryHttpPostToShareEndpoint($url, '/'.$id.'/unshare', $fields); $status = json_decode($result['result'], true); - return ($result['success'] && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200)); + if ($result['success'] && + ($status['ocs']['meta']['statuscode'] === 100 || + $status['ocs']['meta']['statuscode'] === 200 + ) + ) { + return true; + } elseif ($try === 0) { + // only add new job on first try + $this->jobList->add('OCA\FederatedFileSharing\BackgroundJob\UnShare', + [ + 'remote' => $remote, + 'id' => $id, + 'token' => $token, + 'try' => $try, + 'lastRun' => $this->getTimestamp() + ] + ); + } + + return false; + } + + /** + * return current timestamp + * + * @return int + */ + protected function getTimestamp() { + return time(); } /** @@ -117,7 +155,7 @@ class Notifications { * @param array $fields post parameters * @return array */ - private function tryHttpPostToShareEndpoint($remoteDomain, $urlSuffix, array $fields) { + protected function tryHttpPostToShareEndpoint($remoteDomain, $urlSuffix, array $fields) { $client = $this->httpClientService->newClient(); $protocol = 'https://'; $result = [ diff --git a/apps/federatedfilesharing/tests/notificationstest.php b/apps/federatedfilesharing/tests/notificationstest.php new file mode 100644 index 00000000000..bde69a82bad --- /dev/null +++ b/apps/federatedfilesharing/tests/notificationstest.php @@ -0,0 +1,151 @@ +<?php +/** + * @author Björn Schießle <schiessle@owncloud.com> + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + + +namespace OCA\FederatedFileSharing\Tests; + + +use OCA\FederatedFileSharing\AddressHandler; +use OCA\FederatedFileSharing\DiscoveryManager; +use OCA\FederatedFileSharing\Notifications; +use OCP\BackgroundJob\IJobList; +use OCP\Http\Client\IClientService; +use Test\TestCase; + +class NotificationsTest extends TestCase { + + /** @var AddressHandler | \PHPUnit_Framework_MockObject_MockObject */ + private $addressHandler; + + /** @var IClientService | \PHPUnit_Framework_MockObject_MockObject*/ + private $httpClientService; + + /** @var DiscoveryManager | \PHPUnit_Framework_MockObject_MockObject */ + private $discoveryManager; + + /** @var IJobList | \PHPUnit_Framework_MockObject_MockObject */ + private $jobList; + + public function setUp() { + parent::setUp(); + + $this->jobList = $this->getMock('OCP\BackgroundJob\IJobList'); + $this->discoveryManager = $this->getMockBuilder('OCA\FederatedFileSharing\DiscoveryManager') + ->disableOriginalConstructor()->getMock(); + $this->httpClientService = $this->getMock('OCP\Http\Client\IClientService'); + $this->addressHandler = $this->getMockBuilder('OCA\FederatedFileSharing\AddressHandler') + ->disableOriginalConstructor()->getMock(); + + } + + /** + * get instance of Notifications class + * + * @param array $mockedMethods methods which should be mocked + * @return Notifications | \PHPUnit_Framework_MockObject_MockObject + */ + private function getInstance(array $mockedMethods = []) { + if (empty($mockedMethods)) { + $instance = new Notifications( + $this->addressHandler, + $this->httpClientService, + $this->discoveryManager, + $this->jobList + ); + } else { + $instance = $this->getMockBuilder('OCA\FederatedFileSharing\Notifications') + ->setConstructorArgs( + [ + $this->addressHandler, + $this->httpClientService, + $this->discoveryManager, + $this->jobList + ] + )->setMethods($mockedMethods)->getMock(); + } + + return $instance; + } + + /** + * @dataProvider dataTestSendRemoteUnShare + * + * @param int $try + * @param array $httpRequestResult + * @param bool $expected + */ + public function testSendRemoteUnShare($try, $httpRequestResult, $expected) { + $remote = 'remote'; + $id = 42; + $timestamp = 63576; + $token = 'token'; + $instance = $this->getInstance(['tryHttpPostToShareEndpoint', 'getTimestamp']); + + $instance->expects($this->any())->method('getTimestamp')->willReturn($timestamp); + + $instance->expects($this->once())->method('tryHttpPostToShareEndpoint') + ->with($remote, '/'.$id.'/unshare', ['token' => $token, 'format' => 'json']) + ->willReturn($httpRequestResult); + + $this->addressHandler->expects($this->once())->method('removeProtocolFromUrl') + ->with($remote)->willReturn($remote); + + // only add background job on first try + if ($try === 0 && $expected === false) { + $this->jobList->expects($this->once())->method('add') + ->with( + 'OCA\FederatedFileSharing\BackgroundJob\UnShare', + [ + 'remote' => $remote, + 'id' => $id, + 'token' => $token, + 'try' => $try, + 'lastRun' => $timestamp + ] + ); + } else { + $this->jobList->expects($this->never())->method('add'); + } + + $this->assertSame($expected, + $instance->sendRemoteUnShare($remote, $id, $token, $try) + ); + + } + + public function dataTestSendRemoteUnshare() { + return [ + // test if background job is added correctly + [0, ['success' => true, 'result' => json_encode(['ocs' => ['meta' => ['statuscode' => 200]]])], true], + [1, ['success' => true, 'result' => json_encode(['ocs' => ['meta' => ['statuscode' => 200]]])], true], + [0, ['success' => false, 'result' => json_encode(['ocs' => ['meta' => ['statuscode' => 200]]])], false], + [1, ['success' => false, 'result' => json_encode(['ocs' => ['meta' => ['statuscode' => 200]]])], false], + // test all combinations of 'statuscode' and 'success' + [0, ['success' => true, 'result' => json_encode(['ocs' => ['meta' => ['statuscode' => 200]]])], true], + [0, ['success' => true, 'result' => json_encode(['ocs' => ['meta' => ['statuscode' => 100]]])], true], + [0, ['success' => true, 'result' => json_encode(['ocs' => ['meta' => ['statuscode' => 400]]])], false], + [0, ['success' => false, 'result' => json_encode(['ocs' => ['meta' => ['statuscode' => 200]]])], false], + [0, ['success' => false, 'result' => json_encode(['ocs' => ['meta' => ['statuscode' => 100]]])], false], + [0, ['success' => false, 'result' => json_encode(['ocs' => ['meta' => ['statuscode' => 400]]])], false], + ]; + } + +} diff --git a/apps/files/appinfo/application.php b/apps/files/appinfo/application.php index 593e0533c80..2d2decf6288 100644 --- a/apps/files/appinfo/application.php +++ b/apps/files/appinfo/application.php @@ -43,7 +43,8 @@ class Application extends App { $server->getUserSession(), $c->query('TagService'), $server->getPreviewManager(), - $server->getShareManager() + $server->getShareManager(), + $server->getConfig() ); }); diff --git a/apps/files/appinfo/routes.php b/apps/files/appinfo/routes.php index 731c671b60a..6ad938101a2 100644 --- a/apps/files/appinfo/routes.php +++ b/apps/files/appinfo/routes.php @@ -1,6 +1,7 @@ <?php /** * @author Bart Visscher <bartv@thisnet.nl> + * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Lukas Reschke <lukas@owncloud.com> * @author Roeland Jago Douma <rullzer@owncloud.com> * @author Tobias Kaminsky <tobias@kaminsky.me> @@ -48,6 +49,11 @@ $application->registerRoutes( 'verb' => 'GET', 'requirements' => array('tagName' => '.+'), ), + array( + 'name' => 'API#updateFileSorting', + 'url' => '/api/v1/sorting', + 'verb' => 'POST' + ), [ 'name' => 'view#index', 'url' => '/', diff --git a/apps/files/command/transferownership.php b/apps/files/command/transferownership.php index 6bf2fae6bdf..1f46efdde0d 100644 --- a/apps/files/command/transferownership.php +++ b/apps/files/command/transferownership.php @@ -97,6 +97,12 @@ class TransferOwnership extends Command { $output->writeln("<error>Unknown destination user $this->destinationUser</error>"); return; } + + // target user has to be ready + if (!\OC::$server->getEncryptionManager()->isReadyForUser($this->destinationUser)) { + $output->writeln("<error>The target user is not ready to accept files. The user has at least to be logged in once.</error>"); + return; + } $date = date('c'); $this->finalTarget = "$this->destinationUser/files/transferred from $this->sourceUser on $date"; diff --git a/apps/files/controller/apicontroller.php b/apps/files/controller/apicontroller.php index ad286284386..43d426476fe 100644 --- a/apps/files/controller/apicontroller.php +++ b/apps/files/controller/apicontroller.php @@ -1,6 +1,7 @@ <?php /** * @author Joas Schilling <nickvergessen@owncloud.com> + * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Lukas Reschke <lukas@owncloud.com> * @author Morris Jobke <hey@morrisjobke.de> * @author Roeland Jago Douma <rullzer@owncloud.com> @@ -29,13 +30,14 @@ namespace OCA\Files\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Controller; +use OCP\IConfig; use OCP\IRequest; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\DataDisplayResponse; +use OCP\AppFramework\Http\Response; use OCA\Files\Service\TagService; use OCP\IPreview; use OCP\Share\IManager; -use OCP\Files\FileInfo; use OCP\Files\Node; use OCP\IUserSession; @@ -53,6 +55,8 @@ class ApiController extends Controller { private $previewManager; /** IUserSession */ private $userSession; + /** IConfig */ + private $config; /** * @param string $appName @@ -65,12 +69,14 @@ class ApiController extends Controller { IUserSession $userSession, TagService $tagService, IPreview $previewManager, - IManager $shareManager) { + IManager $shareManager, + IConfig $config) { parent::__construct($appName, $request); $this->userSession = $userSession; $this->tagService = $tagService; $this->previewManager = $previewManager; $this->shareManager = $shareManager; + $this->config = $config; } /** @@ -196,4 +202,26 @@ class ApiController extends Controller { return $shareTypes; } + /** + * Change the default sort mode + * + * @NoAdminRequired + * + * @param string $mode + * @param string $direction + * @return Response + */ + public function updateFileSorting($mode, $direction) { + $allowedMode = ['name', 'size', 'mtime']; + $allowedDirection = ['asc', 'desc']; + if (!in_array($mode, $allowedMode) || !in_array($direction, $allowedDirection)) { + $response = new Response(); + $response->setStatus(Http::STATUS_UNPROCESSABLE_ENTITY); + return $response; + } + $this->config->setUserValue($this->userSession->getUser()->getUID(), 'files', 'file_sorting', $mode); + $this->config->setUserValue($this->userSession->getUser()->getUID(), 'files', 'file_sorting_direction', $direction); + return new Response(); + } + } diff --git a/apps/files/controller/viewcontroller.php b/apps/files/controller/viewcontroller.php index 800cf008fa7..6c5f4c6d2a0 100644 --- a/apps/files/controller/viewcontroller.php +++ b/apps/files/controller/viewcontroller.php @@ -1,5 +1,6 @@ <?php /** + * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Lukas Reschke <lukas@owncloud.com> * @author Thomas Müller <thomas.mueller@tmit.eu> * @@ -27,11 +28,12 @@ use OCP\AppFramework\Controller; use OCP\AppFramework\Http\ContentSecurityPolicy; use OCP\AppFramework\Http\RedirectResponse; use OCP\AppFramework\Http\TemplateResponse; +use OCP\IConfig; use OCP\IL10N; use OCP\INavigationManager; use OCP\IRequest; use OCP\IURLGenerator; -use OCP\IConfig; +use OCP\IUserSession; use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** @@ -54,6 +56,8 @@ class ViewController extends Controller { protected $config; /** @var EventDispatcherInterface */ protected $eventDispatcher; + /** @var IUserSession */ + protected $userSession; /** * @param string $appName @@ -70,7 +74,8 @@ class ViewController extends Controller { INavigationManager $navigationManager, IL10N $l10n, IConfig $config, - EventDispatcherInterface $eventDispatcherInterface) { + EventDispatcherInterface $eventDispatcherInterface, + IUserSession $userSession) { parent::__construct($appName, $request); $this->appName = $appName; $this->request = $request; @@ -79,6 +84,7 @@ class ViewController extends Controller { $this->l10n = $l10n; $this->config = $config; $this->eventDispatcher = $eventDispatcherInterface; + $this->userSession = $userSession; } /** @@ -213,6 +219,9 @@ class ViewController extends Controller { $params['mailNotificationEnabled'] = $this->config->getAppValue('core', 'shareapi_allow_mail_notification', 'no'); $params['mailPublicNotificationEnabled'] = $this->config->getAppValue('core', 'shareapi_allow_public_notification', 'no'); $params['allowShareWithLink'] = $this->config->getAppValue('core', 'shareapi_allow_links', 'yes'); + $user = $this->userSession->getUser()->getUID(); + $params['defaultFileSorting'] = $this->config->getUserValue($user, 'files', 'file_sorting', 'name'); + $params['defaultFileSortingDirection'] = $this->config->getUserValue($user, 'files', 'file_sorting_direction', 'asc'); $params['appNavigation'] = $nav; $params['appContents'] = $contentItems; $this->navigationManager->setActiveEntry('files_index'); diff --git a/apps/files/js/app.js b/apps/files/js/app.js index ff505d417f1..4ed805d2681 100644 --- a/apps/files/js/app.js +++ b/apps/files/js/app.js @@ -72,7 +72,11 @@ fileActions: fileActions, allowLegacyActions: true, scrollTo: urlParams.scrollto, - filesClient: OC.Files.getClient() + filesClient: OC.Files.getClient(), + sorting: { + mode: $('#defaultFileSorting').val(), + direction: $('#defaultFileSortingDirection').val() + } } ); this.files.initialize(); diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 71af4a21b9b..7de64f8ade3 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -239,7 +239,11 @@ this.fileSummary = this._createSummary(); - this.setSort('name', 'asc'); + if (options.sorting) { + this.setSort(options.sorting.mode, options.sorting.direction, false, false); + } else { + this.setSort('name', 'asc', false, false); + } var breadcrumbOptions = { onClick: _.bind(this._onClickBreadCrumb, this), @@ -390,6 +394,11 @@ model.toJSON(), {updateSummary: true, silent: false, animate: true} ); + + // restore selection state + var selected = !!self._selectedFiles[$tr.data('id')]; + self._selectFileEl($tr, selected); + $tr.toggleClass('highlighted', highlightState); }); model.on('busy', function(model, state) { @@ -690,14 +699,14 @@ sort = $target.attr('data-sort'); if (sort) { if (this._sort === sort) { - this.setSort(sort, (this._sortDirection === 'desc')?'asc':'desc', true); + this.setSort(sort, (this._sortDirection === 'desc')?'asc':'desc', true, true); } else { if ( sort === 'name' ) { //default sorting of name is opposite to size and mtime - this.setSort(sort, 'asc', true); + this.setSort(sort, 'asc', true, true); } else { - this.setSort(sort, 'desc', true); + this.setSort(sort, 'desc', true, true); } } } @@ -1365,8 +1374,9 @@ * @param sort sort attribute name * @param direction sort direction, one of "asc" or "desc" * @param update true to update the list, false otherwise (default) + * @param persist true to save changes in the database (default) */ - setSort: function(sort, direction, update) { + setSort: function(sort, direction, update, persist) { var comparator = FileList.Comparators[sort] || FileList.Comparators.name; this._sort = sort; this._sortDirection = (direction === 'desc')?'desc':'asc'; @@ -1397,6 +1407,13 @@ this.reload(); } } + + if (persist) { + $.post(OC.generateUrl('/apps/files/api/v1/sorting'), { + mode: sort, + direction: direction + }); + } }, /** diff --git a/apps/files/l10n/de_AT.js b/apps/files/l10n/de_AT.js index 783ff4aaa6b..9100dc4d820 100644 --- a/apps/files/l10n/de_AT.js +++ b/apps/files/l10n/de_AT.js @@ -4,9 +4,11 @@ OC.L10N.register( "Unknown error" : "Unbekannter Fehler", "Files" : "Dateien", "Download" : "Herunterladen", + "Rename" : "Umbenennen", "Delete" : "Löschen", "Unshare" : "Teilung zurücknehmen", "Details" : "Details", + "Name" : "Name", "New folder" : "Neuer Ordner", "Upload" : "Hochladen", "A new file or folder has been <strong>created</strong>" : "Eine neue Datei oder ein neuer Ordner wurde <strong>erstellt</strong>", diff --git a/apps/files/l10n/de_AT.json b/apps/files/l10n/de_AT.json index 2d54751bdf6..cfbffca2b31 100644 --- a/apps/files/l10n/de_AT.json +++ b/apps/files/l10n/de_AT.json @@ -2,9 +2,11 @@ "Unknown error" : "Unbekannter Fehler", "Files" : "Dateien", "Download" : "Herunterladen", + "Rename" : "Umbenennen", "Delete" : "Löschen", "Unshare" : "Teilung zurücknehmen", "Details" : "Details", + "Name" : "Name", "New folder" : "Neuer Ordner", "Upload" : "Hochladen", "A new file or folder has been <strong>created</strong>" : "Eine neue Datei oder ein neuer Ordner wurde <strong>erstellt</strong>", diff --git a/apps/files/l10n/nb_NO.js b/apps/files/l10n/nb_NO.js index b1b83d36c29..086ed3bc144 100644 --- a/apps/files/l10n/nb_NO.js +++ b/apps/files/l10n/nb_NO.js @@ -106,6 +106,7 @@ OC.L10N.register( "Missing permissions to edit from here." : "Manglende rettigheter til å redigere herfra.", "Settings" : "Innstillinger", "WebDAV" : "WebDAV", + "Use this address to <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">access your Files via WebDAV</a>" : "Bruk adressen <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">for å få tilgang til WebDAV</a>", "Cancel upload" : "Avbryt opplasting", "No files in here" : "Ingen filer her", "Upload some content or sync with your devices!" : "Last opp noe innhold eller synkroniser med enhetene dine!", diff --git a/apps/files/l10n/nb_NO.json b/apps/files/l10n/nb_NO.json index fc0958dce74..0f034867f51 100644 --- a/apps/files/l10n/nb_NO.json +++ b/apps/files/l10n/nb_NO.json @@ -104,6 +104,7 @@ "Missing permissions to edit from here." : "Manglende rettigheter til å redigere herfra.", "Settings" : "Innstillinger", "WebDAV" : "WebDAV", + "Use this address to <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">access your Files via WebDAV</a>" : "Bruk adressen <a href=\"%s\" target=\"_blank\" rel=\"noreferrer\">for å få tilgang til WebDAV</a>", "Cancel upload" : "Avbryt opplasting", "No files in here" : "Ingen filer her", "Upload some content or sync with your devices!" : "Last opp noe innhold eller synkroniser med enhetene dine!", diff --git a/apps/files/lib/capabilities.php b/apps/files/lib/capabilities.php index 7d50b51bb97..dc49ca174b3 100644 --- a/apps/files/lib/capabilities.php +++ b/apps/files/lib/capabilities.php @@ -24,6 +24,7 @@ namespace OCA\Files; use OCP\Capabilities\ICapability; +use OCP\IConfig; /** * Class Capabilities @@ -31,6 +32,17 @@ use OCP\Capabilities\ICapability; * @package OCA\Files */ class Capabilities implements ICapability { + /** @var IConfig */ + protected $config; + + /** + * Capabilities constructor. + * + * @param IConfig $config + */ + public function __construct(IConfig $config) { + $this->config = $config; + } /** * Return this classes capabilities @@ -41,6 +53,7 @@ class Capabilities implements ICapability { return [ 'files' => [ 'bigfilechunking' => true, + 'blacklisted_files' => $this->config->getSystemValue('blacklisted_files', ['.htaccess']), ], ]; } diff --git a/apps/files/templates/index.php b/apps/files/templates/index.php index e825c300d31..db464ad2eca 100644 --- a/apps/files/templates/index.php +++ b/apps/files/templates/index.php @@ -18,4 +18,6 @@ <input type="hidden" name="mailNotificationEnabled" id="mailNotificationEnabled" value="<?php p($_['mailNotificationEnabled']) ?>" /> <input type="hidden" name="mailPublicNotificationEnabled" id="mailPublicNotificationEnabled" value="<?php p($_['mailPublicNotificationEnabled']) ?>" /> <input type="hidden" name="allowShareWithLink" id="allowShareWithLink" value="<?php p($_['allowShareWithLink']) ?>" /> +<input type="hidden" name="defaultFileSorting" id="defaultFileSorting" value="<?php p($_['defaultFileSorting']) ?>" /> +<input type="hidden" name="defaultFileSortingDirection" id="defaultFileSortingDirection" value="<?php p($_['defaultFileSortingDirection']) ?>" /> <?php endif; diff --git a/apps/files/tests/controller/ViewControllerTest.php b/apps/files/tests/controller/ViewControllerTest.php index 657ab6cb338..0446cc8982c 100644 --- a/apps/files/tests/controller/ViewControllerTest.php +++ b/apps/files/tests/controller/ViewControllerTest.php @@ -1,5 +1,6 @@ <?php /** + * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Joas Schilling <nickvergessen@owncloud.com> * @author Lukas Reschke <lukas@owncloud.com> * @author Vincent Petry <pvince81@owncloud.com> @@ -33,6 +34,7 @@ use OCP\AppFramework\Http\RedirectResponse; use OCP\INavigationManager; use OCP\IL10N; use OCP\IConfig; +use OCP\IUserSession; use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** @@ -55,6 +57,10 @@ class ViewControllerTest extends TestCase { private $eventDispatcher; /** @var ViewController */ private $viewController; + /** @var IUser */ + private $user; + /** @var IUserSession */ + private $userSession; public function setUp() { parent::setUp(); @@ -64,6 +70,11 @@ class ViewControllerTest extends TestCase { $this->l10n = $this->getMock('\OCP\IL10N'); $this->config = $this->getMock('\OCP\IConfig'); $this->eventDispatcher = $this->getMock('\Symfony\Component\EventDispatcher\EventDispatcherInterface'); + $this->userSession = $this->getMock('\OCP\IUserSession'); + $this->user = $this->getMock('\OCP\IUser'); + $this->userSession->expects($this->any()) + ->method('getUser') + ->will($this->returnValue($this->user)); $this->viewController = $this->getMockBuilder('\OCA\Files\Controller\ViewController') ->setConstructorArgs([ 'files', @@ -72,7 +83,8 @@ class ViewControllerTest extends TestCase { $this->navigationManager, $this->l10n, $this->config, - $this->eventDispatcher + $this->eventDispatcher, + $this->userSession ]) ->setMethods([ 'getStorageInfo', @@ -143,6 +155,12 @@ class ViewControllerTest extends TestCase { 'owner' => 'MyName', 'ownerDisplayName' => 'MyDisplayName', ])); + $this->config->expects($this->exactly(2)) + ->method('getUserValue') + ->will($this->returnValueMap([ + [$this->user->getUID(), 'files', 'file_sorting', 'name', 'name'], + [$this->user->getUID(), 'files', 'file_sorting_direction', 'asc', 'asc'] + ])); $this->config ->expects($this->any()) @@ -224,6 +242,8 @@ class ViewControllerTest extends TestCase { 'owner' => 'MyName', 'ownerDisplayName' => 'MyDisplayName', 'isPublic' => false, + 'defaultFileSorting' => 'name', + 'defaultFileSortingDirection' => 'asc', 'mailNotificationEnabled' => 'no', 'mailPublicNotificationEnabled' => 'no', 'allowShareWithLink' => 'yes', diff --git a/apps/files/tests/controller/apicontrollertest.php b/apps/files/tests/controller/apicontrollertest.php index a9b248a36fe..59f53e8ee81 100644 --- a/apps/files/tests/controller/apicontrollertest.php +++ b/apps/files/tests/controller/apicontrollertest.php @@ -1,5 +1,6 @@ <?php /** + * @author Christoph Wurst <christoph@winzerhof-wurst.at> * @author Lukas Reschke <lukas@owncloud.com> * @author Morris Jobke <hey@morrisjobke.de> * @author Roeland Jago Douma <rullzer@owncloud.com> @@ -43,6 +44,8 @@ use OCP\Image; class ApiControllerTest extends TestCase { /** @var string */ private $appName = 'files'; + /** @var \OCP\IUser */ + private $user; /** @var IRequest */ private $request; /** @var TagService */ @@ -53,19 +56,21 @@ class ApiControllerTest extends TestCase { private $apiController; /** @var \OCP\Share\IManager */ private $shareManager; + /** @var \OCP\IConfig */ + private $config; public function setUp() { $this->request = $this->getMockBuilder('\OCP\IRequest') ->disableOriginalConstructor() ->getMock(); - $user = $this->getMock('\OCP\IUser'); - $user->expects($this->any()) + $this->user = $this->getMock('\OCP\IUser'); + $this->user->expects($this->any()) ->method('getUID') ->will($this->returnValue('user1')); $userSession = $this->getMock('\OCP\IUserSession'); $userSession->expects($this->any()) ->method('getUser') - ->will($this->returnValue($user)); + ->will($this->returnValue($this->user)); $this->tagService = $this->getMockBuilder('\OCA\Files\Service\TagService') ->disableOriginalConstructor() ->getMock(); @@ -75,6 +80,7 @@ class ApiControllerTest extends TestCase { $this->preview = $this->getMockBuilder('\OCP\IPreview') ->disableOriginalConstructor() ->getMock(); + $this->config = $this->getMock('\OCP\IConfig'); $this->apiController = new ApiController( $this->appName, @@ -82,7 +88,8 @@ class ApiControllerTest extends TestCase { $userSession, $this->tagService, $this->preview, - $this->shareManager + $this->shareManager, + $this->config ); } @@ -335,4 +342,44 @@ class ApiControllerTest extends TestCase { $this->assertEquals(Http::STATUS_OK, $ret->getStatus()); } + + public function testUpdateFileSorting() { + $mode = 'mtime'; + $direction = 'desc'; + + $this->config->expects($this->at(0)) + ->method('setUserValue') + ->with($this->user->getUID(), 'files', 'file_sorting', $mode); + $this->config->expects($this->at(1)) + ->method('setUserValue') + ->with($this->user->getUID(), 'files', 'file_sorting_direction', $direction); + + $expected = new HTTP\Response(); + $actual = $this->apiController->updateFileSorting($mode, $direction); + $this->assertEquals($expected, $actual); + } + + public function invalidSortingModeData() { + return [ + ['color', 'asc'], + ['name', 'size'], + ['foo', 'bar'] + ]; + } + + /** + * @dataProvider invalidSortingModeData + */ + public function testUpdateInvalidFileSorting($mode, $direction) { + $this->config->expects($this->never()) + ->method('setUserValue'); + + $expected = new Http\Response(null); + $expected->setStatus(Http::STATUS_UNPROCESSABLE_ENTITY); + + $result = $this->apiController->updateFileSorting($mode, $direction); + + $this->assertEquals($expected, $result); + } + } diff --git a/apps/files/tests/js/filelistSpec.js b/apps/files/tests/js/filelistSpec.js index a83c8c4c0bc..cc3bcd74b46 100644 --- a/apps/files/tests/js/filelistSpec.js +++ b/apps/files/tests/js/filelistSpec.js @@ -2106,6 +2106,8 @@ describe('OCA.Files.FileList tests', function() { it('Toggles the sort indicator when clicking on a column header', function() { var ASC_CLASS = fileList.SORT_INDICATOR_ASC_CLASS; var DESC_CLASS = fileList.SORT_INDICATOR_DESC_CLASS; + var request; + var sortingUrl = OC.generateUrl('/apps/files/api/v1/sorting'); fileList.$el.find('.column-size .columntitle').click(); // moves triangle to size column, check indicator on name is hidden expect( @@ -2118,6 +2120,10 @@ describe('OCA.Files.FileList tests', function() { expect( fileList.$el.find('.column-size .sort-indicator').hasClass(DESC_CLASS) ).toEqual(true); + // check if changes are persisted + expect(fakeServer.requests.length).toEqual(1); + request = fakeServer.requests[0]; + expect(request.url).toEqual(sortingUrl); // click again on size column, reverses direction fileList.$el.find('.column-size .columntitle').click(); @@ -2127,6 +2133,10 @@ describe('OCA.Files.FileList tests', function() { expect( fileList.$el.find('.column-size .sort-indicator').hasClass(ASC_CLASS) ).toEqual(true); + // check if changes are persisted + expect(fakeServer.requests.length).toEqual(2); + request = fakeServer.requests[1]; + expect(request.url).toEqual(sortingUrl); // click again on size column, reverses direction fileList.$el.find('.column-size .columntitle').click(); @@ -2136,6 +2146,9 @@ describe('OCA.Files.FileList tests', function() { expect( fileList.$el.find('.column-size .sort-indicator').hasClass(DESC_CLASS) ).toEqual(true); + expect(fakeServer.requests.length).toEqual(3); + request = fakeServer.requests[2]; + expect(request.url).toEqual(sortingUrl); // click on mtime column, moves indicator there fileList.$el.find('.column-mtime .columntitle').click(); @@ -2148,6 +2161,9 @@ describe('OCA.Files.FileList tests', function() { expect( fileList.$el.find('.column-mtime .sort-indicator').hasClass(DESC_CLASS) ).toEqual(true); + expect(fakeServer.requests.length).toEqual(4); + request = fakeServer.requests[3]; + expect(request.url).toEqual(sortingUrl); }); it('Uses correct sort comparator when inserting files', function() { testFiles.sort(OCA.Files.FileList.Comparators.size); diff --git a/apps/files_external/appinfo/app.php b/apps/files_external/appinfo/app.php index 46a4ecf0793..18f8b2551fa 100644 --- a/apps/files_external/appinfo/app.php +++ b/apps/files_external/appinfo/app.php @@ -26,17 +26,7 @@ * */ -OC::$CLASSPATH['OC\Files\Storage\StreamWrapper'] = 'files_external/lib/streamwrapper.php'; -OC::$CLASSPATH['OC\Files\Storage\FTP'] = 'files_external/lib/ftp.php'; -OC::$CLASSPATH['OC\Files\Storage\OwnCloud'] = 'files_external/lib/owncloud.php'; -OC::$CLASSPATH['OC\Files\Storage\Google'] = 'files_external/lib/google.php'; -OC::$CLASSPATH['OC\Files\Storage\Swift'] = 'files_external/lib/swift.php'; -OC::$CLASSPATH['OC\Files\Storage\SMB'] = 'files_external/lib/smb.php'; -OC::$CLASSPATH['OC\Files\Storage\AmazonS3'] = 'files_external/lib/amazons3.php'; -OC::$CLASSPATH['OC\Files\Storage\Dropbox'] = 'files_external/lib/dropbox.php'; -OC::$CLASSPATH['OC\Files\Storage\SFTP'] = 'files_external/lib/sftp.php'; OC::$CLASSPATH['OC_Mount_Config'] = 'files_external/lib/config.php'; -OC::$CLASSPATH['OCA\Files\External\Api'] = 'files_external/lib/api.php'; require_once __DIR__ . '/../3rdparty/autoload.php'; diff --git a/apps/files_external/appinfo/routes.php b/apps/files_external/appinfo/routes.php index 2d2e6ddf607..e2f55e652a8 100644 --- a/apps/files_external/appinfo/routes.php +++ b/apps/files_external/appinfo/routes.php @@ -61,6 +61,6 @@ $this->create('files_external_list_applicable', '/applicable') \OCP\API::register('get', '/apps/files_external/api/v1/mounts', - array('\OCA\Files\External\Api', 'getUserMounts'), + array('\OCA\Files_External\Lib\Api', 'getUserMounts'), 'files_external'); diff --git a/apps/files_external/l10n/de_AT.js b/apps/files_external/l10n/de_AT.js index 417e514c605..e151ec8ad1b 100644 --- a/apps/files_external/l10n/de_AT.js +++ b/apps/files_external/l10n/de_AT.js @@ -9,6 +9,7 @@ OC.L10N.register( "Host" : "Host", "Location" : "Ort", "Share" : "Freigeben", + "Name" : "Name", "Folder name" : "Ordner Name", "Delete" : "Löschen" }, diff --git a/apps/files_external/l10n/de_AT.json b/apps/files_external/l10n/de_AT.json index 6367f7d3b09..53a670e106d 100644 --- a/apps/files_external/l10n/de_AT.json +++ b/apps/files_external/l10n/de_AT.json @@ -7,6 +7,7 @@ "Host" : "Host", "Location" : "Ort", "Share" : "Freigeben", + "Name" : "Name", "Folder name" : "Ordner Name", "Delete" : "Löschen" },"pluralForm" :"nplurals=2; plural=(n != 1);" diff --git a/apps/files_external/l10n/sl.js b/apps/files_external/l10n/sl.js index 454f142f2f1..8ce2cd450f6 100644 --- a/apps/files_external/l10n/sl.js +++ b/apps/files_external/l10n/sl.js @@ -10,6 +10,7 @@ OC.L10N.register( "Storage with id \"%i\" not found" : "Shrambe z ID \"%i\" ni mogoče najti.", "Invalid backend or authentication mechanism class" : "Neveljaven ozadnji program oziroma razred mehanizma overitve", "Invalid mount point" : "Neveljavna priklopna točka", + "Objectstore forbidden" : "Shranjevanje predmeta je prepovedano", "Invalid storage backend \"%s\"" : "Neveljaven ozadnji program shrambe \"%s\"", "Not permitted to use backend \"%s\"" : "Uporaba ozadnjega programa \"%s\" ni dovoljena.", "Not permitted to use authentication mechanism \"%s\"" : "Uporaba načina overitve \"%s\" ni dovoljena.", @@ -30,6 +31,7 @@ OC.L10N.register( "Admin defined" : "Skrbnik je določen", "Saved" : "Shranjeno", "Empty response from the server" : "S strežnika je prejet odziv brez vsebine.", + "Couldn't get the information from the ownCloud server: {code} {type}" : "Ni mogoče pridobiti podrobnosti s strežnika ownCloud:{koda} {vrsta}", "Couldn't get the list of external mount points: {type}" : "Ni mogoče pridobiti seznama zunanjih priklopnih točk: {type}", "There was an error with message: " : "Prišlo je do napake s sporočilom:", "External mount error" : "Notranja napaka priklopa", diff --git a/apps/files_external/l10n/sl.json b/apps/files_external/l10n/sl.json index 05ec6314a71..753a401d536 100644 --- a/apps/files_external/l10n/sl.json +++ b/apps/files_external/l10n/sl.json @@ -8,6 +8,7 @@ "Storage with id \"%i\" not found" : "Shrambe z ID \"%i\" ni mogoče najti.", "Invalid backend or authentication mechanism class" : "Neveljaven ozadnji program oziroma razred mehanizma overitve", "Invalid mount point" : "Neveljavna priklopna točka", + "Objectstore forbidden" : "Shranjevanje predmeta je prepovedano", "Invalid storage backend \"%s\"" : "Neveljaven ozadnji program shrambe \"%s\"", "Not permitted to use backend \"%s\"" : "Uporaba ozadnjega programa \"%s\" ni dovoljena.", "Not permitted to use authentication mechanism \"%s\"" : "Uporaba načina overitve \"%s\" ni dovoljena.", @@ -28,6 +29,7 @@ "Admin defined" : "Skrbnik je določen", "Saved" : "Shranjeno", "Empty response from the server" : "S strežnika je prejet odziv brez vsebine.", + "Couldn't get the information from the ownCloud server: {code} {type}" : "Ni mogoče pridobiti podrobnosti s strežnika ownCloud:{koda} {vrsta}", "Couldn't get the list of external mount points: {type}" : "Ni mogoče pridobiti seznama zunanjih priklopnih točk: {type}", "There was an error with message: " : "Prišlo je do napake s sporočilom:", "External mount error" : "Notranja napaka priklopa", diff --git a/apps/files_external/lib/api.php b/apps/files_external/lib/api.php index 50a2f38c65b..589317dcf98 100644 --- a/apps/files_external/lib/api.php +++ b/apps/files_external/lib/api.php @@ -23,7 +23,7 @@ * */ -namespace OCA\Files\External; +namespace OCA\Files_External\Lib; class Api { diff --git a/apps/files_external/lib/backend/amazons3.php b/apps/files_external/lib/backend/amazons3.php index b2dedc10e4a..449b6c0379d 100644 --- a/apps/files_external/lib/backend/amazons3.php +++ b/apps/files_external/lib/backend/amazons3.php @@ -38,7 +38,7 @@ class AmazonS3 extends Backend { $this ->setIdentifier('amazons3') ->addIdentifierAlias('\OC\Files\Storage\AmazonS3') // legacy compat - ->setStorageClass('\OC\Files\Storage\AmazonS3') + ->setStorageClass('\OCA\Files_External\Lib\Storage\AmazonS3') ->setText($l->t('Amazon S3')) ->addParameters([ (new DefinitionParameter('bucket', $l->t('Bucket'))), diff --git a/apps/files_external/lib/backend/dropbox.php b/apps/files_external/lib/backend/dropbox.php index 7a414731192..f9156082515 100644 --- a/apps/files_external/lib/backend/dropbox.php +++ b/apps/files_external/lib/backend/dropbox.php @@ -38,7 +38,7 @@ class Dropbox extends Backend { $this ->setIdentifier('dropbox') ->addIdentifierAlias('\OC\Files\Storage\Dropbox') // legacy compat - ->setStorageClass('\OC\Files\Storage\Dropbox') + ->setStorageClass('\OCA\Files_External\Lib\Storage\Dropbox') ->setText($l->t('Dropbox')) ->addParameters([ // all parameters handled in OAuth1 mechanism diff --git a/apps/files_external/lib/backend/ftp.php b/apps/files_external/lib/backend/ftp.php index b2b83a27405..3960592d0bc 100644 --- a/apps/files_external/lib/backend/ftp.php +++ b/apps/files_external/lib/backend/ftp.php @@ -38,7 +38,7 @@ class FTP extends Backend { $this ->setIdentifier('ftp') ->addIdentifierAlias('\OC\Files\Storage\FTP') // legacy compat - ->setStorageClass('\OC\Files\Storage\FTP') + ->setStorageClass('\OCA\Files_External\Lib\Storage\FTP') ->setText($l->t('FTP')) ->addParameters([ (new DefinitionParameter('host', $l->t('Host'))), diff --git a/apps/files_external/lib/backend/google.php b/apps/files_external/lib/backend/google.php index 93a8cd2177d..b2b48a0e402 100644 --- a/apps/files_external/lib/backend/google.php +++ b/apps/files_external/lib/backend/google.php @@ -38,7 +38,7 @@ class Google extends Backend { $this ->setIdentifier('googledrive') ->addIdentifierAlias('\OC\Files\Storage\Google') // legacy compat - ->setStorageClass('\OC\Files\Storage\Google') + ->setStorageClass('\OCA\Files_External\Lib\Storage\Google') ->setText($l->t('Google Drive')) ->addParameters([ // all parameters handled in OAuth2 mechanism diff --git a/apps/files_external/lib/backend/owncloud.php b/apps/files_external/lib/backend/owncloud.php index e7da328c5f1..e92288b1354 100644 --- a/apps/files_external/lib/backend/owncloud.php +++ b/apps/files_external/lib/backend/owncloud.php @@ -35,7 +35,7 @@ class OwnCloud extends Backend { $this ->setIdentifier('owncloud') ->addIdentifierAlias('\OC\Files\Storage\OwnCloud') // legacy compat - ->setStorageClass('\OC\Files\Storage\OwnCloud') + ->setStorageClass('\OCA\Files_External\Lib\Storage\OwnCloud') ->setText($l->t('ownCloud')) ->addParameters([ (new DefinitionParameter('host', $l->t('URL'))), diff --git a/apps/files_external/lib/backend/sftp.php b/apps/files_external/lib/backend/sftp.php index 3e5ecb90131..fa33caeb576 100644 --- a/apps/files_external/lib/backend/sftp.php +++ b/apps/files_external/lib/backend/sftp.php @@ -35,7 +35,7 @@ class SFTP extends Backend { $this ->setIdentifier('sftp') ->addIdentifierAlias('\OC\Files\Storage\SFTP') // legacy compat - ->setStorageClass('\OC\Files\Storage\SFTP') + ->setStorageClass('\OCA\Files_External\Lib\Storage\SFTP') ->setText($l->t('SFTP')) ->addParameters([ (new DefinitionParameter('host', $l->t('Host'))), diff --git a/apps/files_external/lib/backend/sftp_key.php b/apps/files_external/lib/backend/sftp_key.php index 58dddedf784..838cf6c52b2 100644 --- a/apps/files_external/lib/backend/sftp_key.php +++ b/apps/files_external/lib/backend/sftp_key.php @@ -34,7 +34,7 @@ class SFTP_Key extends Backend { public function __construct(IL10N $l, RSA $legacyAuth, SFTP $sftpBackend) { $this ->setIdentifier('\OC\Files\Storage\SFTP_Key') - ->setStorageClass('\OC\Files\Storage\SFTP') + ->setStorageClass('\OCA\Files_External\Lib\Storage\SFTP') ->setText($l->t('SFTP with secret key login')) ->addParameters([ (new DefinitionParameter('host', $l->t('Host'))), diff --git a/apps/files_external/lib/backend/smb.php b/apps/files_external/lib/backend/smb.php index 9b71636936a..7ea30dd11bd 100644 --- a/apps/files_external/lib/backend/smb.php +++ b/apps/files_external/lib/backend/smb.php @@ -40,7 +40,7 @@ class SMB extends Backend { $this ->setIdentifier('smb') ->addIdentifierAlias('\OC\Files\Storage\SMB') // legacy compat - ->setStorageClass('\OC\Files\Storage\SMB') + ->setStorageClass('\OCA\Files_External\Lib\Storage\SMB') ->setText($l->t('SMB / CIFS')) ->addParameters([ (new DefinitionParameter('host', $l->t('Host'))), diff --git a/apps/files_external/lib/backend/smb_oc.php b/apps/files_external/lib/backend/smb_oc.php index ba38754ce5a..c543a19bdd8 100644 --- a/apps/files_external/lib/backend/smb_oc.php +++ b/apps/files_external/lib/backend/smb_oc.php @@ -42,7 +42,7 @@ class SMB_OC extends Backend { public function __construct(IL10N $l, SessionCredentials $legacyAuth, SMB $smbBackend) { $this ->setIdentifier('\OC\Files\Storage\SMB_OC') - ->setStorageClass('\OC\Files\Storage\SMB') + ->setStorageClass('\OCA\Files_External\Lib\Storage\SMB') ->setText($l->t('SMB / CIFS using OC login')) ->addParameters([ (new DefinitionParameter('host', $l->t('Host'))), diff --git a/apps/files_external/lib/backend/swift.php b/apps/files_external/lib/backend/swift.php index d6e4ac12f9a..58677575f52 100644 --- a/apps/files_external/lib/backend/swift.php +++ b/apps/files_external/lib/backend/swift.php @@ -38,7 +38,7 @@ class Swift extends Backend { $this ->setIdentifier('swift') ->addIdentifierAlias('\OC\Files\Storage\Swift') // legacy compat - ->setStorageClass('\OC\Files\Storage\Swift') + ->setStorageClass('\OCA\Files_External\Lib\Storage\Swift') ->setText($l->t('OpenStack Object Storage')) ->addParameters([ (new DefinitionParameter('service_name', $l->t('Service name'))) diff --git a/apps/files_external/lib/amazons3.php b/apps/files_external/lib/storage/amazons3.php index cb2082ee38b..42df1deffb0 100644 --- a/apps/files_external/lib/amazons3.php +++ b/apps/files_external/lib/storage/amazons3.php @@ -33,7 +33,7 @@ * */ -namespace OC\Files\Storage; +namespace OCA\Files_External\Lib\Storage; set_include_path(get_include_path() . PATH_SEPARATOR . \OC_App::getAppPath('files_external') . '/3rdparty/aws-sdk-php'); diff --git a/apps/files_external/lib/dropbox.php b/apps/files_external/lib/storage/dropbox.php index 8381ccbae59..55ae7146572 100644 --- a/apps/files_external/lib/dropbox.php +++ b/apps/files_external/lib/storage/dropbox.php @@ -27,13 +27,13 @@ * */ -namespace OC\Files\Storage; +namespace OCA\Files_External\Lib\Storage; use GuzzleHttp\Exception\RequestException; use Icewind\Streams\IteratorDirectory; use Icewind\Streams\RetryWrapper; -require_once __DIR__ . '/../3rdparty/Dropbox/autoload.php'; +require_once __DIR__ . '/../../3rdparty/Dropbox/autoload.php'; class Dropbox extends \OC\Files\Storage\Common { @@ -59,7 +59,7 @@ class Dropbox extends \OC\Files\Storage\Common { // note: Dropbox_API connection is lazy $this->dropbox = new \Dropbox_API($this->oauth, 'auto'); } else { - throw new \Exception('Creating \OC\Files\Storage\Dropbox storage failed'); + throw new \Exception('Creating Dropbox storage failed'); } } diff --git a/apps/files_external/lib/ftp.php b/apps/files_external/lib/storage/ftp.php index 7249aeceb5d..051c1873009 100644 --- a/apps/files_external/lib/ftp.php +++ b/apps/files_external/lib/storage/ftp.php @@ -28,11 +28,11 @@ * */ -namespace OC\Files\Storage; +namespace OCA\Files_External\Lib\Storage; use Icewind\Streams\RetryWrapper; -class FTP extends \OC\Files\Storage\StreamWrapper{ +class FTP extends StreamWrapper{ private $password; private $user; private $host; @@ -59,7 +59,7 @@ class FTP extends \OC\Files\Storage\StreamWrapper{ $this->root .= '/'; } } else { - throw new \Exception('Creating \OC\Files\Storage\FTP storage failed'); + throw new \Exception('Creating FTP storage failed'); } } diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/storage/google.php index 62d264dfeef..8d1fe808130 100644 --- a/apps/files_external/lib/google.php +++ b/apps/files_external/lib/storage/google.php @@ -31,7 +31,7 @@ * */ -namespace OC\Files\Storage; +namespace OCA\Files_External\Lib\Storage; use GuzzleHttp\Exception\RequestException; use Icewind\Streams\IteratorDirectory; @@ -79,7 +79,7 @@ class Google extends \OC\Files\Storage\Common { $token = json_decode($params['token'], true); $this->id = 'google::'.substr($params['client_id'], 0, 30).$token['created']; } else { - throw new \Exception('Creating \OC\Files\Storage\Google storage failed'); + throw new \Exception('Creating Google storage failed'); } } diff --git a/apps/files_external/lib/owncloud.php b/apps/files_external/lib/storage/owncloud.php index c4824e6bd14..22ecb4c806a 100644 --- a/apps/files_external/lib/owncloud.php +++ b/apps/files_external/lib/storage/owncloud.php @@ -21,7 +21,7 @@ * */ -namespace OC\Files\Storage; +namespace OCA\Files_External\Lib\Storage; /** * ownCloud backend for external storage based on DAV backend. diff --git a/apps/files_external/lib/sftp.php b/apps/files_external/lib/storage/sftp.php index a6984f3b4e0..2375f84dcda 100644 --- a/apps/files_external/lib/sftp.php +++ b/apps/files_external/lib/storage/sftp.php @@ -29,7 +29,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/> * */ -namespace OC\Files\Storage; +namespace OCA\Files_External\Lib\Storage; use Icewind\Streams\IteratorDirectory; use Icewind\Streams\RetryWrapper; diff --git a/apps/files_external/lib/smb.php b/apps/files_external/lib/storage/smb.php index 08c4b25a088..4249d13168c 100644 --- a/apps/files_external/lib/smb.php +++ b/apps/files_external/lib/storage/smb.php @@ -28,7 +28,7 @@ * */ -namespace OC\Files\Storage; +namespace OCA\Files_External\Lib\Storage; use Icewind\SMB\Exception\ConnectException; use Icewind\SMB\Exception\Exception; @@ -42,7 +42,7 @@ use OC\Cache\CappedMemoryCache; use OC\Files\Filesystem; use OCP\Files\StorageNotAvailableException; -class SMB extends Common { +class SMB extends \OC\Files\Storage\Common { /** * @var \Icewind\SMB\Server */ diff --git a/apps/files_external/lib/streamwrapper.php b/apps/files_external/lib/storage/streamwrapper.php index efb51f32ba4..0b4dff78c4f 100644 --- a/apps/files_external/lib/streamwrapper.php +++ b/apps/files_external/lib/storage/streamwrapper.php @@ -24,9 +24,9 @@ * */ -namespace OC\Files\Storage; +namespace OCA\Files_External\Lib\Storage; -abstract class StreamWrapper extends Common { +abstract class StreamWrapper extends \OC\Files\Storage\Common { /** * @param string $path diff --git a/apps/files_external/lib/swift.php b/apps/files_external/lib/storage/swift.php index 9282fe28669..4578cd9a5c7 100644 --- a/apps/files_external/lib/swift.php +++ b/apps/files_external/lib/storage/swift.php @@ -32,7 +32,7 @@ * */ -namespace OC\Files\Storage; +namespace OCA\Files_External\Lib\Storage; use Guzzle\Http\Url; use Guzzle\Http\Exception\ClientErrorResponseException; diff --git a/apps/files_external/tests/amazons3migration.php b/apps/files_external/tests/amazons3migration.php index d4ea9e2c261..614d6ca33df 100644 --- a/apps/files_external/tests/amazons3migration.php +++ b/apps/files_external/tests/amazons3migration.php @@ -24,14 +24,16 @@ */ -namespace Test\Files\Storage; +namespace OCA\Files_External\Tests; + +use OCA\Files_External\Lib\Storage\AmazonS3; /** * Class AmazonS3Migration * * @group DB * - * @package Test\Files\Storage + * @package OCA\Files_External\Tests */ class AmazonS3Migration extends \Test\TestCase { @@ -77,7 +79,7 @@ class AmazonS3Migration extends \Test\TestCase { $fileId = $oldCache->put('foobar', array('size' => 0, 'mtime' => time(), 'mimetype' => 'httpd/directory')); try { - $this->instance = new \OC\Files\Storage\AmazonS3($this->params); + $this->instance = new AmazonS3($this->params); } catch (\Exception $e) { //ignore } @@ -103,7 +105,7 @@ class AmazonS3Migration extends \Test\TestCase { $fileId = $oldCache->put('/', array('size' => 0, 'mtime' => time(), 'mimetype' => 'httpd/directory')); try { - $this->instance = new \OC\Files\Storage\AmazonS3($this->params); + $this->instance = new AmazonS3($this->params); } catch (\Exception $e) { //ignore } diff --git a/apps/files_external/tests/controller/storagescontrollertest.php b/apps/files_external/tests/controller/storagescontrollertest.php index 5854cb00fee..4c3c62d5d6f 100644 --- a/apps/files_external/tests/controller/storagescontrollertest.php +++ b/apps/files_external/tests/controller/storagescontrollertest.php @@ -51,7 +51,7 @@ abstract class StoragesControllerTest extends \Test\TestCase { /** * @return \OCA\Files_External\Lib\Backend\Backend */ - protected function getBackendMock($class = '\OCA\Files_External\Lib\Backend\SMB', $storageClass = '\OC\Files\Storage\SMB') { + protected function getBackendMock($class = '\OCA\Files_External\Lib\Backend\SMB', $storageClass = '\OCA\Files_External\Lib\Storage\SMB') { $backend = $this->getMockBuilder('\OCA\Files_External\Lib\Backend\Backend') ->disableOriginalConstructor() ->getMock(); @@ -104,7 +104,7 @@ abstract class StoragesControllerTest extends \Test\TestCase { $response = $this->controller->create( 'mount', - '\OC\Files\Storage\SMB', + '\OCA\Files_External\Lib\Storage\SMB', '\OCA\Files_External\Lib\Auth\NullMechanism', array(), [], @@ -146,7 +146,7 @@ abstract class StoragesControllerTest extends \Test\TestCase { $response = $this->controller->update( 1, 'mount', - '\OC\Files\Storage\SMB', + '\OCA\Files_External\Lib\Storage\SMB', '\OCA\Files_External\Lib\Auth\NullMechanism', array(), [], @@ -188,7 +188,7 @@ abstract class StoragesControllerTest extends \Test\TestCase { $response = $this->controller->create( $mountPoint, - '\OC\Files\Storage\SMB', + '\OCA\Files_External\Lib\Storage\SMB', '\OCA\Files_External\Lib\Auth\NullMechanism', array(), [], @@ -202,7 +202,7 @@ abstract class StoragesControllerTest extends \Test\TestCase { $response = $this->controller->update( 1, $mountPoint, - '\OC\Files\Storage\SMB', + '\OCA\Files_External\Lib\Storage\SMB', '\OCA\Files_External\Lib\Auth\NullMechanism', array(), [], @@ -279,7 +279,7 @@ abstract class StoragesControllerTest extends \Test\TestCase { $response = $this->controller->update( 255, 'mount', - '\OC\Files\Storage\SMB', + '\OCA\Files_External\Lib\Storage\SMB', '\OCA\Files_External\Lib\Auth\NullMechanism', array(), [], @@ -375,7 +375,7 @@ abstract class StoragesControllerTest extends \Test\TestCase { $response = $this->controller->create( 'mount', - '\OC\Files\Storage\SMB', + '\OCA\Files_External\Lib\Storage\SMB', '\OCA\Files_External\Lib\Auth\NullMechanism', array(), [], diff --git a/apps/files_external/tests/controller/userstoragescontrollertest.php b/apps/files_external/tests/controller/userstoragescontrollertest.php index a7e854471b5..804b752b6af 100644 --- a/apps/files_external/tests/controller/userstoragescontrollertest.php +++ b/apps/files_external/tests/controller/userstoragescontrollertest.php @@ -78,7 +78,7 @@ class UserStoragesControllerTest extends StoragesControllerTest { $response = $this->controller->create( 'mount', - '\OC\Files\Storage\SMB', + '\OCA\Files_External\Lib\Storage\SMB', '\Auth\Mechanism', array(), [], @@ -92,7 +92,7 @@ class UserStoragesControllerTest extends StoragesControllerTest { $response = $this->controller->update( 1, 'mount', - '\OC\Files\Storage\SMB', + '\OCA\Files_External\Lib\Storage\SMB', '\Auth\Mechanism', array(), [], diff --git a/apps/files_external/tests/owncloudfunctions.php b/apps/files_external/tests/owncloudfunctions.php index 019f988275e..25aaa90d178 100644 --- a/apps/files_external/tests/owncloudfunctions.php +++ b/apps/files_external/tests/owncloudfunctions.php @@ -23,14 +23,14 @@ * */ -namespace Test\Files\Storage; +namespace OCA\Files_External\Tests; /** * Class OwnCloudFunctions * * @group DB * - * @package Test\Files\Storage + * @package OCA\Files_External\Tests */ class OwnCloudFunctions extends \Test\TestCase { @@ -109,7 +109,7 @@ class OwnCloudFunctions extends \Test\TestCase { public function testConfig($config, $expectedUri) { $config['user'] = 'someuser'; $config['password'] = 'somepassword'; - $instance = new \OC\Files\Storage\OwnCloud($config); + $instance = new \OCA\Files_External\Lib\Storage\OwnCloud($config); $this->assertEquals($expectedUri, $instance->createBaseUri()); } } diff --git a/apps/files_external/tests/service/storagesservicetest.php b/apps/files_external/tests/service/storagesservicetest.php index 3fbe3b755e1..f93c0134814 100644 --- a/apps/files_external/tests/service/storagesservicetest.php +++ b/apps/files_external/tests/service/storagesservicetest.php @@ -121,9 +121,9 @@ abstract class StoragesServiceTest extends \Test\TestCase { $this->backendService->method('getAuthMechanisms') ->will($this->returnValue($authMechanisms)); - $sftpBackend = $this->getBackendMock('\OCA\Files_External\Lib\Backend\SFTP', '\OC\Files\Storage\SFTP'); + $sftpBackend = $this->getBackendMock('\OCA\Files_External\Lib\Backend\SFTP', '\OCA\Files_External\Lib\Storage\SFTP'); $backends = [ - 'identifier:\OCA\Files_External\Lib\Backend\SMB' => $this->getBackendMock('\OCA\Files_External\Lib\Backend\SMB', '\OC\Files\Storage\SMB'), + 'identifier:\OCA\Files_External\Lib\Backend\SMB' => $this->getBackendMock('\OCA\Files_External\Lib\Backend\SMB', '\OCA\Files_External\Lib\Storage\SMB'), 'identifier:\OCA\Files_External\Lib\Backend\SFTP' => $sftpBackend, 'identifier:sftp_alias' => $sftpBackend, ]; @@ -171,7 +171,7 @@ abstract class StoragesServiceTest extends \Test\TestCase { } } - protected function getBackendMock($class = '\OCA\Files_External\Lib\Backend\SMB', $storageClass = '\OC\Files\Storage\SMB') { + protected function getBackendMock($class = '\OCA\Files_External\Lib\Backend\SMB', $storageClass = '\OCA\Files_External\Lib\Storage\SMB') { $backend = $this->getMockBuilder('\OCA\Files_External\Lib\Backend\Backend') ->disableOriginalConstructor() ->getMock(); diff --git a/apps/files_external/tests/backends/amazons3.php b/apps/files_external/tests/storage/amazons3test.php index 3b43f81a926..eb0e410764c 100644 --- a/apps/files_external/tests/backends/amazons3.php +++ b/apps/files_external/tests/storage/amazons3test.php @@ -24,16 +24,18 @@ * */ -namespace Test\Files\Storage; +namespace OCA\Files_External\Tests\Storage; + +use \OCA\Files_External\Lib\Storage\AmazonS3; /** - * Class AmazonS3 + * Class AmazonS3Test * * @group DB * - * @package Test\Files\Storage + * @package OCA\Files_External\Tests\Storage */ -class AmazonS3 extends Storage { +class AmazonS3Test extends \Test\Files\Storage\Storage { private $config; @@ -44,7 +46,7 @@ class AmazonS3 extends Storage { if ( ! is_array($this->config) or ! $this->config['run']) { $this->markTestSkipped('AmazonS3 backend not configured'); } - $this->instance = new \OC\Files\Storage\AmazonS3($this->config); + $this->instance = new AmazonS3($this->config); } protected function tearDown() { diff --git a/apps/files_external/tests/backends/dropbox.php b/apps/files_external/tests/storage/dropboxtest.php index 1bf8b4171fb..d466d4b1b44 100644 --- a/apps/files_external/tests/backends/dropbox.php +++ b/apps/files_external/tests/storage/dropboxtest.php @@ -24,16 +24,18 @@ * */ -namespace Test\Files\Storage; +namespace OCA\Files_External\Tests\Storage; + +use \OCA\Files_External\Lib\Storage\Dropbox; /** - * Class Dropbox + * Class DropboxTest * * @group DB * - * @package Test\Files\Storage + * @package OCA\Files_External\Tests\Storage */ -class Dropbox extends Storage { +class DropboxTest extends \Test\Files\Storage\Storage { private $config; protected function setUp() { @@ -45,7 +47,7 @@ class Dropbox extends Storage { $this->markTestSkipped('Dropbox backend not configured'); } $this->config['dropbox']['root'] .= '/' . $id; //make sure we have an new empty folder to work in - $this->instance = new \OC\Files\Storage\Dropbox($this->config['dropbox']); + $this->instance = new Dropbox($this->config['dropbox']); } protected function tearDown() { diff --git a/apps/files_external/tests/backends/ftp.php b/apps/files_external/tests/storage/ftptest.php index 868a022d38f..9af9ccff012 100644 --- a/apps/files_external/tests/backends/ftp.php +++ b/apps/files_external/tests/storage/ftptest.php @@ -24,16 +24,18 @@ * */ -namespace Test\Files\Storage; +namespace OCA\Files_External\Tests\Storage; + +use \OCA\Files_External\Lib\Storage\FTP; /** - * Class FTP + * Class FTPTest * * @group DB * - * @package Test\Files\Storage + * @package OCA\Files_External\Tests\Storage */ -class FTP extends Storage { +class FTPTest extends \Test\Files\Storage\Storage { private $config; protected function setUp() { @@ -45,7 +47,7 @@ class FTP extends Storage { $this->markTestSkipped('FTP backend not configured'); } $this->config['root'] .= '/' . $id; //make sure we have an new empty folder to work in - $this->instance = new \OC\Files\Storage\FTP($this->config); + $this->instance = new FTP($this->config); $this->instance->mkdir('/'); } @@ -63,31 +65,31 @@ class FTP extends Storage { 'password' => 'ftp', 'root' => '/', 'secure' => false ); - $instance = new \OC\Files\Storage\FTP($config); + $instance = new FTP($config); $this->assertEquals('ftp://ftp:ftp@localhost/', $instance->constructUrl('')); $config['secure'] = true; - $instance = new \OC\Files\Storage\FTP($config); + $instance = new FTP($config); $this->assertEquals('ftps://ftp:ftp@localhost/', $instance->constructUrl('')); $config['secure'] = 'false'; - $instance = new \OC\Files\Storage\FTP($config); + $instance = new FTP($config); $this->assertEquals('ftp://ftp:ftp@localhost/', $instance->constructUrl('')); $config['secure'] = 'true'; - $instance = new \OC\Files\Storage\FTP($config); + $instance = new FTP($config); $this->assertEquals('ftps://ftp:ftp@localhost/', $instance->constructUrl('')); $config['root'] = ''; - $instance = new \OC\Files\Storage\FTP($config); + $instance = new FTP($config); $this->assertEquals('ftps://ftp:ftp@localhost/somefile.txt', $instance->constructUrl('somefile.txt')); $config['root'] = '/abc'; - $instance = new \OC\Files\Storage\FTP($config); + $instance = new FTP($config); $this->assertEquals('ftps://ftp:ftp@localhost/abc/somefile.txt', $instance->constructUrl('somefile.txt')); $config['root'] = '/abc/'; - $instance = new \OC\Files\Storage\FTP($config); + $instance = new FTP($config); $this->assertEquals('ftps://ftp:ftp@localhost/abc/somefile.txt', $instance->constructUrl('somefile.txt')); } } diff --git a/apps/files_external/tests/backends/google.php b/apps/files_external/tests/storage/googletest.php index 7622f796407..46aa4555b12 100644 --- a/apps/files_external/tests/backends/google.php +++ b/apps/files_external/tests/storage/googletest.php @@ -25,18 +25,18 @@ * */ -namespace Test\Files\Storage; +namespace OCA\Files_External\Tests\Storage; -require_once 'files_external/lib/google.php'; +use \OCA\Files_External\Lib\Storage\Google; /** - * Class Google + * Class GoogleTest * * @group DB * - * @package Test\Files\Storage + * @package OCA\Files_External\Tests\Storage */ -class Google extends Storage { +class GoogleTest extends \Test\Files\Storage\Storage { private $config; @@ -49,7 +49,7 @@ class Google extends Storage { ) { $this->markTestSkipped('Google Drive backend not configured'); } - $this->instance = new \OC\Files\Storage\Google($this->config['google']); + $this->instance = new Google($this->config['google']); } protected function tearDown() { diff --git a/apps/files_external/tests/backends/owncloud.php b/apps/files_external/tests/storage/owncloudtest.php index a56e9b2a186..cbc25e46fa0 100644 --- a/apps/files_external/tests/backends/owncloud.php +++ b/apps/files_external/tests/storage/owncloudtest.php @@ -22,16 +22,18 @@ * */ -namespace Test\Files\Storage; +namespace OCA\Files_External\Tests\Storage; + +use \OCA\Files_External\Lib\Storage\OwnCloud; /** - * Class OwnCloud + * Class OwnCloudTest * * @group DB * - * @package Test\Files\Storage + * @package OCA\Files_External\Tests\Storage */ -class OwnCloud extends Storage { +class OwnCloudTest extends \Test\Files\Storage\Storage { private $config; @@ -44,7 +46,7 @@ class OwnCloud extends Storage { $this->markTestSkipped('ownCloud backend not configured'); } $this->config['owncloud']['root'] .= '/' . $id; //make sure we have an new empty folder to work in - $this->instance = new \OC\Files\Storage\OwnCloud($this->config['owncloud']); + $this->instance = new OwnCloud($this->config['owncloud']); $this->instance->mkdir('/'); } diff --git a/apps/files_external/tests/backends/sftp_key.php b/apps/files_external/tests/storage/sftp_keytest.php index 73c6a0b6432..b974f88555f 100644 --- a/apps/files_external/tests/backends/sftp_key.php +++ b/apps/files_external/tests/storage/sftp_keytest.php @@ -22,16 +22,18 @@ * */ -namespace Test\Files\Storage; +namespace OCA\Files_External\Tests\Storage; + +use \OCA\Files_External\Lib\Storage\SFTP_Key; /** - * Class SFTP_Key + * Class SFTP_KeyTest * * @group DB * - * @package Test\Files\Storage + * @package OCA\Files_External\Tests\Storage */ -class SFTP_Key extends Storage { +class SFTP_KeyTest extends \Test\Files\Storage\Storage { private $config; protected function setUp() { @@ -44,7 +46,7 @@ class SFTP_Key extends Storage { } // Make sure we have an new empty folder to work in $this->config['sftp_key']['root'] .= '/' . $id; - $this->instance = new \OC\Files\Storage\SFTP_Key($this->config['sftp_key']); + $this->instance = new SFTP_Key($this->config['sftp_key']); $this->instance->mkdir('/'); } diff --git a/apps/files_external/tests/backends/sftp.php b/apps/files_external/tests/storage/sftptest.php index 608982adbc4..329e93819fc 100644 --- a/apps/files_external/tests/backends/sftp.php +++ b/apps/files_external/tests/storage/sftptest.php @@ -24,18 +24,20 @@ * */ -namespace Test\Files\Storage; +namespace OCA\Files_External\Tests\Storage; + +use \OCA\Files_External\Lib\Storage\SFTP; /** - * Class SFTP + * Class SFTPTest * * @group DB * - * @package Test\Files\Storage + * @package OCA\Files_External\Tests\Storage */ -class SFTP extends Storage { +class SFTPTest extends \Test\Files\Storage\Storage { /** - * @var \OC\Files\Storage\SFTP instance + * @var SFTP instance */ protected $instance; @@ -50,7 +52,7 @@ class SFTP extends Storage { $this->markTestSkipped('SFTP backend not configured'); } $this->config['root'] .= '/' . $id; //make sure we have an new empty folder to work in - $this->instance = new \OC\Files\Storage\SFTP($this->config); + $this->instance = new SFTP($this->config); $this->instance->mkdir('/'); } @@ -66,7 +68,7 @@ class SFTP extends Storage { * @dataProvider configProvider */ public function testStorageId($config, $expectedStorageId) { - $instance = new \OC\Files\Storage\SFTP($config); + $instance = new SFTP($config); $this->assertEquals($expectedStorageId, $instance->getId()); } diff --git a/apps/files_external/tests/backends/smb.php b/apps/files_external/tests/storage/smbtest.php index f9a377c271b..fc2795702c6 100644 --- a/apps/files_external/tests/backends/smb.php +++ b/apps/files_external/tests/storage/smbtest.php @@ -23,16 +23,18 @@ * */ -namespace Test\Files\Storage; +namespace OCA\Files_External\Tests\Storage; + +use \OCA\Files_External\Lib\Storage\SMB; /** - * Class SMB + * Class SMBTest * * @group DB * - * @package Test\Files\Storage + * @package OCA\Files_External\Tests\Storage */ -class SMB extends Storage { +class SMBTest extends \Test\Files\Storage\Storage { protected function setUp() { parent::setUp(); @@ -46,7 +48,7 @@ class SMB extends Storage { $config['root'] .= '/'; } $config['root'] .= $id; //make sure we have an new empty folder to work in - $this->instance = new \OC\Files\Storage\SMB($config); + $this->instance = new SMB($config); $this->instance->mkdir('/'); } @@ -71,7 +73,7 @@ class SMB extends Storage { } public function testStorageId() { - $this->instance = new \OC\Files\Storage\SMB([ + $this->instance = new SMB([ 'host' => 'testhost', 'user' => 'testuser', 'password' => 'somepass', diff --git a/apps/files_external/tests/backends/swift.php b/apps/files_external/tests/storage/swifttest.php index 9bdcd48ee68..1bcbb815067 100644 --- a/apps/files_external/tests/backends/swift.php +++ b/apps/files_external/tests/storage/swifttest.php @@ -24,16 +24,18 @@ * */ -namespace Test\Files\Storage; +namespace OCA\Files_External\Tests\Storage; + +use \OCA\Files_External\Lib\Storage\Swift; /** - * Class Swift + * Class SwiftTest * * @group DB * - * @package Test\Files\Storage + * @package OCA\Files_External\Tests\Storage */ -class Swift extends Storage { +class SwiftTest extends \Test\Files\Storage\Storage { private $config; @@ -44,7 +46,7 @@ class Swift extends Storage { if (!is_array($this->config) or !$this->config['run']) { $this->markTestSkipped('OpenStack Object Storage backend not configured'); } - $this->instance = new \OC\Files\Storage\Swift($this->config); + $this->instance = new Swift($this->config); } protected function tearDown() { diff --git a/apps/files_external/tests/backends/webdav.php b/apps/files_external/tests/storage/webdavtest.php index e1a710c94b4..f8c5b19e04f 100644 --- a/apps/files_external/tests/backends/webdav.php +++ b/apps/files_external/tests/storage/webdavtest.php @@ -23,16 +23,18 @@ * */ -namespace Test\Files\Storage; +namespace OCA\Files_External\Tests\Storage; + +use \OC\Files\Storage\DAV; /** - * Class DAV + * Class WebDAVTest * * @group DB * - * @package Test\Files\Storage + * @package OCA\Files_External\Tests\Storage */ -class DAV extends Storage { +class WebDAVTest extends \Test\Files\Storage\Storage { protected function setUp() { parent::setUp(); @@ -46,7 +48,7 @@ class DAV extends Storage { $this->waitDelay = $config['wait']; } $config['root'] .= '/' . $id; //make sure we have an new empty folder to work in - $this->instance = new \OC\Files\Storage\DAV($config); + $this->instance = new DAV($config); $this->instance->mkdir('/'); } diff --git a/apps/files_sharing/ajax/shareinfo.php b/apps/files_sharing/ajax/shareinfo.php index e531e84ebbc..e15e12fd287 100644 --- a/apps/files_sharing/ajax/shareinfo.php +++ b/apps/files_sharing/ajax/shareinfo.php @@ -71,12 +71,12 @@ function getChildInfo($dir, $view) { $children = $view->getDirectoryContent($dir->getPath()); $result = array(); foreach ($children as $child) { - $formated = \OCA\Files\Helper::formatFileInfo($child); + $formatted = \OCA\Files\Helper::formatFileInfo($child); if ($child->getType() === 'dir') { - $formated['children'] = getChildInfo($child, $view); + $formatted['children'] = getChildInfo($child, $view); } - $formated['mtime'] = $formated['mtime'] / 1000; - $result[] = $formated; + $formatted['mtime'] = $formatted['mtime'] / 1000; + $result[] = $formatted; } return $result; } diff --git a/apps/files_sharing/js/share.js b/apps/files_sharing/js/share.js index 5bfc8e1d4a2..07ec5f766a1 100644 --- a/apps/files_sharing/js/share.js +++ b/apps/files_sharing/js/share.js @@ -38,7 +38,7 @@ var tr = oldCreateRow.apply(this, arguments); var sharePermissions = fileData.permissions; if (fileData.mountType && fileData.mountType === "external-root"){ - // for external storages we cant use the permissions of the mountpoint + // for external storages we can't use the permissions of the mountpoint // instead we show all permissions and only use the share permissions from the mountpoint to handle resharing sharePermissions = sharePermissions | (OC.PERMISSION_ALL & ~OC.PERMISSION_SHARE); } diff --git a/apps/files_sharing/l10n/de_AT.js b/apps/files_sharing/l10n/de_AT.js index fdbbbee12f0..4f3c622fcce 100644 --- a/apps/files_sharing/l10n/de_AT.js +++ b/apps/files_sharing/l10n/de_AT.js @@ -9,6 +9,7 @@ OC.L10N.register( "%2$s shared %1$s with you" : "%2$s hat %1$s mit dir geteilt", "Shares" : "teilt", "Password" : "Passwort", + "Name" : "Name", "Download" : "Herunterladen" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_sharing/l10n/de_AT.json b/apps/files_sharing/l10n/de_AT.json index 5cda52d6358..c6e2724f33d 100644 --- a/apps/files_sharing/l10n/de_AT.json +++ b/apps/files_sharing/l10n/de_AT.json @@ -7,6 +7,7 @@ "%2$s shared %1$s with you" : "%2$s hat %1$s mit dir geteilt", "Shares" : "teilt", "Password" : "Passwort", + "Name" : "Name", "Download" : "Herunterladen" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/files_sharing/lib/external/manager.php b/apps/files_sharing/lib/external/manager.php index 71d6788cb52..7dc9f66f114 100644 --- a/apps/files_sharing/lib/external/manager.php +++ b/apps/files_sharing/lib/external/manager.php @@ -384,7 +384,7 @@ class Manager { } /** - * return a list of shares wich are accepted by the user + * return a list of shares which are accepted by the user * * @return array list of accepted server-to-server shares */ diff --git a/apps/files_sharing/lib/mountprovider.php b/apps/files_sharing/lib/mountprovider.php index 4a60e44bb26..6c8bbb62ee7 100644 --- a/apps/files_sharing/lib/mountprovider.php +++ b/apps/files_sharing/lib/mountprovider.php @@ -55,19 +55,20 @@ class MountProvider implements IMountProvider { $shares = array_filter($shares, function ($share) { return $share['permissions'] > 0; }); - $shares = array_map(function ($share) use ($user, $storageFactory) { - - return new SharedMount( + $mounts = []; + foreach ($shares as $share) { + $mounts[] = new SharedMount( '\OC\Files\Storage\Shared', - '/' . $user->getUID() . '/' . $share['file_target'], - array( + $mounts, + [ 'share' => $share, 'user' => $user->getUID() - ), + ], $storageFactory ); - }, $shares); + } + // array_filter removes the null values from the array - return array_filter($shares); + return array_filter($mounts); } } diff --git a/apps/files_sharing/lib/sharedmount.php b/apps/files_sharing/lib/sharedmount.php index 1e554cc5948..311e81269db 100644 --- a/apps/files_sharing/lib/sharedmount.php +++ b/apps/files_sharing/lib/sharedmount.php @@ -25,6 +25,7 @@ namespace OCA\Files_Sharing; +use OC\Files\Filesystem; use OC\Files\Mount\MountPoint; use OC\Files\Mount\MoveableMount; use OC\Files\View; @@ -50,14 +51,14 @@ class SharedMount extends MountPoint implements MoveableMount { /** * @param string $storage - * @param string $mountpoint + * @param SharedMount[] $mountpoints * @param array|null $arguments * @param \OCP\Files\Storage\IStorageFactory $loader */ - public function __construct($storage, $mountpoint, $arguments = null, $loader = null) { + public function __construct($storage, array $mountpoints, $arguments = null, $loader = null) { $this->user = $arguments['user']; $this->recipientView = new View('/' . $this->user . '/files'); - $newMountPoint = $this->verifyMountPoint($arguments['share']); + $newMountPoint = $this->verifyMountPoint($arguments['share'], $mountpoints); $absMountPoint = '/' . $this->user . '/files' . $newMountPoint; $arguments['ownerView'] = new View('/' . $arguments['share']['uid_owner'] . '/files'); parent::__construct($storage, $absMountPoint, $arguments, $loader); @@ -67,9 +68,10 @@ class SharedMount extends MountPoint implements MoveableMount { * check if the parent folder exists otherwise move the mount point up * * @param array $share + * @param SharedMount[] $mountpoints * @return string */ - private function verifyMountPoint(&$share) { + private function verifyMountPoint(&$share, array $mountpoints) { $mountPoint = basename($share['file_target']); $parent = dirname($share['file_target']); @@ -78,10 +80,10 @@ class SharedMount extends MountPoint implements MoveableMount { $parent = Helper::getShareFolder(); } - $newMountPoint = \OCA\Files_Sharing\Helper::generateUniqueTarget( + $newMountPoint = $this->generateUniqueTarget( \OC\Files\Filesystem::normalizePath($parent . '/' . $mountPoint), - [], - $this->recipientView + $this->recipientView, + $mountpoints ); if ($newMountPoint !== $share['file_target']) { @@ -94,6 +96,37 @@ class SharedMount extends MountPoint implements MoveableMount { } /** + * @param string $path + * @param View $view + * @param SharedMount[] $mountpoints + * @return mixed + */ + private function generateUniqueTarget($path, $view, array $mountpoints) { + $pathinfo = pathinfo($path); + $ext = (isset($pathinfo['extension'])) ? '.'.$pathinfo['extension'] : ''; + $name = $pathinfo['filename']; + $dir = $pathinfo['dirname']; + + // Helper function to find existing mount points + $mountpointExists = function($path) use ($mountpoints) { + foreach ($mountpoints as $mountpoint) { + if ($mountpoint->getShare()['file_target'] === $path) { + return true; + } + } + return false; + }; + + $i = 2; + while ($view->file_exists($path) || $mountpointExists($path)) { + $path = Filesystem::normalizePath($dir . '/' . $name . ' ('.$i.')' . $ext); + $i++; + } + + return $path; + } + + /** * update fileTarget in the database if the mount point changed * * @param string $newPath diff --git a/apps/files_sharing/tests/cache.php b/apps/files_sharing/tests/cache.php index c137ba0728d..fcc5a343a03 100644 --- a/apps/files_sharing/tests/cache.php +++ b/apps/files_sharing/tests/cache.php @@ -193,7 +193,7 @@ class Test_Files_Sharing_Cache extends TestCase { array('name' => 'shareddir', 'path' => ''), ) ), - array('%nonexistant%', + array('%nonexistent%', array( ) ), diff --git a/apps/files_trashbin/l10n/de_AT.js b/apps/files_trashbin/l10n/de_AT.js index 5d1a6cec445..8212e5210a9 100644 --- a/apps/files_trashbin/l10n/de_AT.js +++ b/apps/files_trashbin/l10n/de_AT.js @@ -2,6 +2,7 @@ OC.L10N.register( "files_trashbin", { "Delete" : "Löschen", - "Error" : "Fehler" + "Error" : "Fehler", + "Name" : "Name" }, "nplurals=2; plural=(n != 1);"); diff --git a/apps/files_trashbin/l10n/de_AT.json b/apps/files_trashbin/l10n/de_AT.json index 5452cc8972a..d15a7c583ac 100644 --- a/apps/files_trashbin/l10n/de_AT.json +++ b/apps/files_trashbin/l10n/de_AT.json @@ -1,5 +1,6 @@ { "translations": { "Delete" : "Löschen", - "Error" : "Fehler" + "Error" : "Fehler", + "Name" : "Name" },"pluralForm" :"nplurals=2; plural=(n != 1);" }
\ No newline at end of file diff --git a/apps/files_versions/tests/versions.php b/apps/files_versions/tests/versions.php index f6658e092bd..9d0ffb87946 100644 --- a/apps/files_versions/tests/versions.php +++ b/apps/files_versions/tests/versions.php @@ -224,7 +224,7 @@ class Test_Files_Versioning extends \Test\TestCase { ), 11 // size of all deleted files (every file has the size 1) ), - // third set of versions, with some gaps inbetween + // third set of versions, with some gaps between array( array( // first slice (10sec) keep one version every 2 seconds @@ -605,7 +605,7 @@ class Test_Files_Versioning extends \Test\TestCase { /** * @param string $hookName name of hook called - * @param string $params variable to recieve parameters provided by hook + * @param string $params variable to receive parameters provided by hook */ private function connectMockHooks($hookName, &$params) { if ($hookName === null) { diff --git a/apps/systemtags/l10n/de_AT.js b/apps/systemtags/l10n/de_AT.js new file mode 100644 index 00000000000..25ab44ecb4f --- /dev/null +++ b/apps/systemtags/l10n/de_AT.js @@ -0,0 +1,6 @@ +OC.L10N.register( + "systemtags", + { + "Name" : "Name" +}, +"nplurals=2; plural=(n != 1);"); diff --git a/apps/systemtags/l10n/de_AT.json b/apps/systemtags/l10n/de_AT.json new file mode 100644 index 00000000000..d00289bba5c --- /dev/null +++ b/apps/systemtags/l10n/de_AT.json @@ -0,0 +1,4 @@ +{ "translations": { + "Name" : "Name" +},"pluralForm" :"nplurals=2; plural=(n != 1);" +}
\ No newline at end of file diff --git a/apps/updatenotification/appinfo/app.php b/apps/updatenotification/appinfo/app.php index f257cba6974..a88861c0942 100644 --- a/apps/updatenotification/appinfo/app.php +++ b/apps/updatenotification/appinfo/app.php @@ -20,10 +20,9 @@ */ if(\OC::$server->getConfig()->getSystemValue('updatechecker', true) === true) { - $updater = new \OC\Updater( - \OC::$server->getHTTPHelper(), - \OC::$server->getConfig(), - \OC::$server->getIntegrityCodeChecker() + $updater = new \OC\Updater\VersionCheck( + \OC::$server->getHTTPClientService(), + \OC::$server->getConfig() ); $updateChecker = new \OCA\UpdateNotification\UpdateChecker( $updater diff --git a/apps/updatenotification/appinfo/application.php b/apps/updatenotification/appinfo/application.php index 24c0a11af69..08ff4abf766 100644 --- a/apps/updatenotification/appinfo/application.php +++ b/apps/updatenotification/appinfo/application.php @@ -34,10 +34,9 @@ class Application extends App { $container = $this->getContainer(); $container->registerService('AdminController', function(IAppContainer $c) { - $updater = new \OC\Updater( - \OC::$server->getHTTPHelper(), - \OC::$server->getConfig(), - \OC::$server->getIntegrityCodeChecker() + $updater = new \OC\Updater\VersionCheck( + \OC::$server->getHTTPClientService(), + \OC::$server->getConfig() ); return new AdminController( $c->query('AppName'), diff --git a/apps/updatenotification/lib/updatechecker.php b/apps/updatenotification/lib/updatechecker.php index 965e21617e7..bf653c23b8f 100644 --- a/apps/updatenotification/lib/updatechecker.php +++ b/apps/updatenotification/lib/updatechecker.php @@ -21,16 +21,16 @@ namespace OCA\UpdateNotification; -use OC\Updater; +use OC\Updater\VersionCheck; class UpdateChecker { - /** @var Updater */ + /** @var VersionCheck */ private $updater; /** - * @param Updater $updater + * @param VersionCheck $updater */ - public function __construct(Updater $updater) { + public function __construct(VersionCheck $updater) { $this->updater = $updater; } diff --git a/apps/updatenotification/tests/UpdateCheckerTest.php b/apps/updatenotification/tests/UpdateCheckerTest.php index 9591758c4c9..5865284a48e 100644 --- a/apps/updatenotification/tests/UpdateCheckerTest.php +++ b/apps/updatenotification/tests/UpdateCheckerTest.php @@ -34,7 +34,7 @@ class UpdateCheckerTest extends TestCase { public function setUp() { parent::setUp(); - $this->updater = $this->getMockBuilder('\OC\Updater') + $this->updater = $this->getMockBuilder('\OC\Updater\VersionCheck') ->disableOriginalConstructor()->getMock(); $this->updateChecker = new UpdateChecker($this->updater); } diff --git a/apps/user_ldap/l10n/de_AT.js b/apps/user_ldap/l10n/de_AT.js index 5695ad9c987..1c13871cd0f 100644 --- a/apps/user_ldap/l10n/de_AT.js +++ b/apps/user_ldap/l10n/de_AT.js @@ -22,6 +22,7 @@ OC.L10N.register( "Could not find the desired feature" : "Funktion konnte nicht gefunden werden", "Invalid Host" : "Ungültiger Host", "Server" : "Server", + "Users" : "Benutzer", "Test Configuration" : "Konfiguration testen", "Help" : "Hilfe", "Groups meeting these criteria are available in %s:" : "Gruppen die den Kriterien entsprechen sind verfügbar unter %s:", diff --git a/apps/user_ldap/l10n/de_AT.json b/apps/user_ldap/l10n/de_AT.json index f9aabf1e4d4..f26797280bf 100644 --- a/apps/user_ldap/l10n/de_AT.json +++ b/apps/user_ldap/l10n/de_AT.json @@ -20,6 +20,7 @@ "Could not find the desired feature" : "Funktion konnte nicht gefunden werden", "Invalid Host" : "Ungültiger Host", "Server" : "Server", + "Users" : "Benutzer", "Test Configuration" : "Konfiguration testen", "Help" : "Hilfe", "Groups meeting these criteria are available in %s:" : "Gruppen die den Kriterien entsprechen sind verfügbar unter %s:", diff --git a/apps/user_ldap/l10n/sl.js b/apps/user_ldap/l10n/sl.js index 57b80dc1345..6a8e8e5f273 100644 --- a/apps/user_ldap/l10n/sl.js +++ b/apps/user_ldap/l10n/sl.js @@ -20,11 +20,14 @@ OC.L10N.register( "Select object classes" : "Izbor razredov predmeta", "Please check the credentials, they seem to be wrong." : "Preverite poverila! Najverjetneje so napačna.", "Base DN could not be auto-detected, please revise credentials, host and port." : "Osnovnega enoznačnega imena (DN) ni mogoče samodejno zaznati. Preverite poverila ter nastavitve gostitelja in vrat.", + "Could not detect Base DN, please enter it manually." : "Ni mogoče zaznati osnovnega enoznačnega imena (DN). Vnesti ga bo treba ročno.", "{nthServer}. Server" : "{nthServer}. strežnik", "No object found in the given Base DN. Please revise." : "Ni najdenega predmeta v osnovnem enoznačnem imenu (DN). Preverite nastavitve.", "More than 1,000 directory entries available." : "Na voljo je več kot 1000 vnosov imenika", "Do you really want to delete the current Server Configuration?" : "Ali res želite izbrisati trenutne nastavitve strežnika?", "Confirm Deletion" : "Potrdi brisanje", + "Mappings cleared successfully!" : "Preslikave so uspešno počiščene!", + "Error while clearing the mappings." : "Napaka pri čiščenju preslikav.", "Mode switch" : "Preklop načina", "Select attributes" : "Izbor atributov", "User found and settings verified." : "Uporabnik je najden in nastavitve so overjene.", @@ -48,6 +51,7 @@ OC.L10N.register( "Edit LDAP Query" : "Uredi poizvedbo LDAP", "LDAP Filter:" : "Filter LDAP:", "The filter specifies which LDAP groups shall have access to the %s instance." : "Filter določa, katere skupine LDAP bodo imele dostop do %s.", + "Verify settings and count groups" : "Preveri nastavitve in preštej skupine", "LDAP / AD Username:" : "Uporabniško ime LDAP / AD:", "Allows login against the LDAP / AD username, which is either uid or samaccountname and will be detected." : "Omogoča prijavo prek LDAP / AD, ki je ali UID ali ime računa, ki bo zaznano.", "LDAP / AD Email Address:" : "Elektronski naslov LDAP / AD:", @@ -57,6 +61,7 @@ OC.L10N.register( "Verify settings" : "Preveri nastavitve", "1. Server" : "1. strežnik", "%s. Server:" : "%s. strežnik:", + "Add a new and blank configuration" : "In nova, privzeta nastavitev", "Host" : "Gostitelj", "You can omit the protocol, except you require SSL. Then start with ldaps://" : "Protokol je lahko izpuščen, če ni posebej zahtevan SSL. V tem primeru se mora naslov začeti z ldaps://", "Port" : "Vrata", diff --git a/apps/user_ldap/l10n/sl.json b/apps/user_ldap/l10n/sl.json index 39a8fae8cdb..f4622c44fa7 100644 --- a/apps/user_ldap/l10n/sl.json +++ b/apps/user_ldap/l10n/sl.json @@ -18,11 +18,14 @@ "Select object classes" : "Izbor razredov predmeta", "Please check the credentials, they seem to be wrong." : "Preverite poverila! Najverjetneje so napačna.", "Base DN could not be auto-detected, please revise credentials, host and port." : "Osnovnega enoznačnega imena (DN) ni mogoče samodejno zaznati. Preverite poverila ter nastavitve gostitelja in vrat.", + "Could not detect Base DN, please enter it manually." : "Ni mogoče zaznati osnovnega enoznačnega imena (DN). Vnesti ga bo treba ročno.", "{nthServer}. Server" : "{nthServer}. strežnik", "No object found in the given Base DN. Please revise." : "Ni najdenega predmeta v osnovnem enoznačnem imenu (DN). Preverite nastavitve.", "More than 1,000 directory entries available." : "Na voljo je več kot 1000 vnosov imenika", "Do you really want to delete the current Server Configuration?" : "Ali res želite izbrisati trenutne nastavitve strežnika?", "Confirm Deletion" : "Potrdi brisanje", + "Mappings cleared successfully!" : "Preslikave so uspešno počiščene!", + "Error while clearing the mappings." : "Napaka pri čiščenju preslikav.", "Mode switch" : "Preklop načina", "Select attributes" : "Izbor atributov", "User found and settings verified." : "Uporabnik je najden in nastavitve so overjene.", @@ -46,6 +49,7 @@ "Edit LDAP Query" : "Uredi poizvedbo LDAP", "LDAP Filter:" : "Filter LDAP:", "The filter specifies which LDAP groups shall have access to the %s instance." : "Filter določa, katere skupine LDAP bodo imele dostop do %s.", + "Verify settings and count groups" : "Preveri nastavitve in preštej skupine", "LDAP / AD Username:" : "Uporabniško ime LDAP / AD:", "Allows login against the LDAP / AD username, which is either uid or samaccountname and will be detected." : "Omogoča prijavo prek LDAP / AD, ki je ali UID ali ime računa, ki bo zaznano.", "LDAP / AD Email Address:" : "Elektronski naslov LDAP / AD:", @@ -55,6 +59,7 @@ "Verify settings" : "Preveri nastavitve", "1. Server" : "1. strežnik", "%s. Server:" : "%s. strežnik:", + "Add a new and blank configuration" : "In nova, privzeta nastavitev", "Host" : "Gostitelj", "You can omit the protocol, except you require SSL. Then start with ldaps://" : "Protokol je lahko izpuščen, če ni posebej zahtevan SSL. V tem primeru se mora naslov začeti z ldaps://", "Port" : "Vrata", diff --git a/apps/user_ldap/lib/configuration.php b/apps/user_ldap/lib/configuration.php index daec2bed13a..418a2bfc015 100644 --- a/apps/user_ldap/lib/configuration.php +++ b/apps/user_ldap/lib/configuration.php @@ -28,6 +28,9 @@ namespace OCA\user_ldap\lib; +/** + * @property int ldapPagingSize holds an integer + */ class Configuration { protected $configPrefix = null; diff --git a/apps/user_ldap/lib/connection.php b/apps/user_ldap/lib/connection.php index c485ac74395..53c9b3790a7 100644 --- a/apps/user_ldap/lib/connection.php +++ b/apps/user_ldap/lib/connection.php @@ -85,11 +85,12 @@ class Connection extends LDAPUtility { if($memcache->isAvailable()) { $this->cache = $memcache->create(); } - $this->hasPagedResultSupport = - $this->ldap->hasPagedResultSupport(); $helper = new Helper(); $this->doNotValidate = !in_array($this->configPrefix, $helper->getServerConfigurationPrefixes()); + $this->hasPagedResultSupport = + intval($this->configuration->ldapPagingSize) !== 0 + || $this->ldap->hasPagedResultSupport(); } public function __destruct() { diff --git a/apps/user_ldap/lib/wizard.php b/apps/user_ldap/lib/wizard.php index 5235011fb96..0b475ee7143 100644 --- a/apps/user_ldap/lib/wizard.php +++ b/apps/user_ldap/lib/wizard.php @@ -221,7 +221,7 @@ class Wizard extends LDAPUtility { $count = intval($this->countUsersWithAttribute($attr, true)); if($count > 0) { //no change, but we sent it back to make sure the user interface - //is still correct, even if the ajax call was cancelled inbetween + //is still correct, even if the ajax call was cancelled meanwhile $this->result->addChange('ldap_display_name', $attr); return $this->result; } diff --git a/apps/user_ldap/tests/mapping/abstractmappingtest.php b/apps/user_ldap/tests/mapping/abstractmappingtest.php index c6427be516b..a931a07a44c 100644 --- a/apps/user_ldap/tests/mapping/abstractmappingtest.php +++ b/apps/user_ldap/tests/mapping/abstractmappingtest.php @@ -112,7 +112,7 @@ abstract class AbstractMappingTest extends \Test\TestCase { } /** - * tests unmap() for both successfuly and not successful removing of + * tests unmap() for both successful and unsuccessful removing of * mapping entries */ public function testUnmap() { |