aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTING.md4
-rw-r--r--apps/files/js/file-upload.js12
-rw-r--r--apps/files/l10n/es.js1
-rw-r--r--apps/files/l10n/es.json1
-rw-r--r--apps/files/l10n/fr.js1
-rw-r--r--apps/files/l10n/fr.json1
-rw-r--r--apps/files/tests/js/fileUploadSpec.js59
-rw-r--r--apps/files_sharing/appinfo/app.php37
-rw-r--r--apps/files_sharing/appinfo/application.php124
-rw-r--r--apps/files_sharing/appinfo/routes.php1
-rw-r--r--apps/files_sharing/application.php115
-rw-r--r--apps/files_sharing/lib/helper.php2
-rw-r--r--apps/files_sharing/lib/mountprovider.php72
-rw-r--r--apps/files_sharing/lib/propagation/changewatcher.php76
-rw-r--r--apps/files_sharing/lib/propagation/propagationmanager.php112
-rw-r--r--apps/files_sharing/lib/propagation/recipientpropagator.php118
-rw-r--r--apps/files_sharing/lib/sharedmount.php21
-rw-r--r--apps/files_sharing/lib/sharedstorage.php50
-rw-r--r--apps/files_sharing/lib/updater.php39
-rw-r--r--apps/files_sharing/tests/cache.php4
-rw-r--r--apps/files_sharing/tests/controller/sharecontroller.php2
-rw-r--r--apps/files_sharing/tests/etagpropagation.php345
-rw-r--r--apps/files_sharing/tests/permissions.php4
-rw-r--r--apps/files_sharing/tests/sharedstorage.php5
-rw-r--r--apps/files_sharing/tests/sizepropagation.php (renamed from apps/files_sharing/tests/propagation.php)4
-rw-r--r--apps/files_sharing/tests/testcase.php9
-rw-r--r--apps/files_sharing/tests/watcher.php4
-rw-r--r--apps/files_trashbin/tests/trashbin.php4
-rw-r--r--apps/files_versions/tests/versions.php4
-rw-r--r--apps/user_ldap/ajax/getNewServerConfigPrefix.php4
-rw-r--r--apps/user_ldap/js/wizard/wizardTabElementary.js34
-rwxr-xr-xautotest-external.sh5
-rw-r--r--lib/private/connector/sabre/file.php1
-rw-r--r--lib/private/files/cache/changepropagator.php5
-rw-r--r--lib/private/files/cache/updater.php4
-rw-r--r--lib/private/files/view.php4
-rw-r--r--lib/private/helper.php9
-rw-r--r--lib/private/server.php2
-rw-r--r--lib/private/share/share.php52
-rw-r--r--lib/public/iservercontainer.php2
-rw-r--r--lib/public/share.php6
-rw-r--r--settings/l10n/fr.js2
-rw-r--r--settings/l10n/fr.json2
-rw-r--r--settings/l10n/gl.js2
-rw-r--r--settings/l10n/gl.json2
-rw-r--r--tests/lib/connector/sabre/file.php1
-rw-r--r--tests/lib/files/etagtest.php4
47 files changed, 1110 insertions, 262 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index d76bf8d2c22..3bf6c0882d1 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -2,9 +2,9 @@
If you have questions about how to install or use ownCloud, please direct these to the [mailing list][mailinglist] or our [forum][forum]. We are also available on [IRC][irc].
-### TL;DR
+### Short version
- * The [**issue template can be found here**][template] but be aware of the different repositories! See list below.
+ * The [**issue template can be found here**][template] but be aware of the different repositories! See list below. Please always use the issue template when reporting issues.
### Guidelines
* Please search the existing issues first, it's likely that your issue was already reported or even fixed.
diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js
index ce8127c9887..6b6acdb5e01 100644
--- a/apps/files/js/file-upload.js
+++ b/apps/files/js/file-upload.js
@@ -611,7 +611,7 @@ OC.Upload = {
var lastPos;
var checkInput = function () {
var filename = input.val();
- if (Files.isFileNameValid(filename)) {
+ if (!Files.isFileNameValid(filename)) {
// Files.isFileNameValid(filename) throws an exception itself
} else if (FileList.inList(filename)) {
throw t('files', '{new_name} already exists', {new_name: filename});
@@ -651,12 +651,6 @@ OC.Upload = {
FileList.lastAction();
}
var name = FileList.getUniqueName(newname);
- if (newname !== name) {
- FileList.checkName(name, newname, true);
- var hidden = true;
- } else {
- var hidden = false;
- }
switch(type) {
case 'file':
$.post(
@@ -667,7 +661,7 @@ OC.Upload = {
},
function(result) {
if (result.status === 'success') {
- FileList.add(result.data, {hidden: hidden, animate: true, scrollTo: true});
+ FileList.add(result.data, {animate: true, scrollTo: true});
} else {
OC.dialogs.alert(result.data.message, t('core', 'Could not create file'));
}
@@ -683,7 +677,7 @@ OC.Upload = {
},
function(result) {
if (result.status === 'success') {
- FileList.add(result.data, {hidden: hidden, animate: true, scrollTo: true});
+ FileList.add(result.data, {animate: true, scrollTo: true});
} else {
OC.dialogs.alert(result.data.message, t('core', 'Could not create folder'));
}
diff --git a/apps/files/l10n/es.js b/apps/files/l10n/es.js
index 90562ff52f5..bd3a645c693 100644
--- a/apps/files/l10n/es.js
+++ b/apps/files/l10n/es.js
@@ -42,6 +42,7 @@ OC.L10N.register(
"Delete" : "Eliminar",
"Disconnect storage" : "Desconectar almacenamiento",
"Unshare" : "Dejar de compartir",
+ "No permission to delete" : "Ninguna autorización a borrar",
"Download" : "Descargar",
"Select" : "Seleccionar",
"Pending" : "Pendiente",
diff --git a/apps/files/l10n/es.json b/apps/files/l10n/es.json
index 62ed9b2defe..010430d9b3b 100644
--- a/apps/files/l10n/es.json
+++ b/apps/files/l10n/es.json
@@ -40,6 +40,7 @@
"Delete" : "Eliminar",
"Disconnect storage" : "Desconectar almacenamiento",
"Unshare" : "Dejar de compartir",
+ "No permission to delete" : "Ninguna autorización a borrar",
"Download" : "Descargar",
"Select" : "Seleccionar",
"Pending" : "Pendiente",
diff --git a/apps/files/l10n/fr.js b/apps/files/l10n/fr.js
index 1c42ce7649c..f155c4c5556 100644
--- a/apps/files/l10n/fr.js
+++ b/apps/files/l10n/fr.js
@@ -42,6 +42,7 @@ OC.L10N.register(
"Delete" : "Supprimer",
"Disconnect storage" : "Déconnecter ce support de stockage",
"Unshare" : "Ne plus partager",
+ "No permission to delete" : "Pas de permission de suppression",
"Download" : "Télécharger",
"Select" : "Sélectionner",
"Pending" : "En attente",
diff --git a/apps/files/l10n/fr.json b/apps/files/l10n/fr.json
index c04ba115e8b..2cecba687d8 100644
--- a/apps/files/l10n/fr.json
+++ b/apps/files/l10n/fr.json
@@ -40,6 +40,7 @@
"Delete" : "Supprimer",
"Disconnect storage" : "Déconnecter ce support de stockage",
"Unshare" : "Ne plus partager",
+ "No permission to delete" : "Pas de permission de suppression",
"Download" : "Télécharger",
"Select" : "Sélectionner",
"Pending" : "En attente",
diff --git a/apps/files/tests/js/fileUploadSpec.js b/apps/files/tests/js/fileUploadSpec.js
index 49b7265ced1..817654c4fa9 100644
--- a/apps/files/tests/js/fileUploadSpec.js
+++ b/apps/files/tests/js/fileUploadSpec.js
@@ -35,7 +35,14 @@ describe('OC.Upload tests', function() {
$('#testArea').append(
'<input type="file" id="file_upload_start" name="files[]" multiple="multiple">' +
'<input type="hidden" id="upload_limit" name="upload_limit" value="10000000">' + // 10 MB
- '<input type="hidden" id="free_space" name="free_space" value="50000000">' // 50 MB
+ '<input type="hidden" id="free_space" name="free_space" value="50000000">' + // 50 MB
+ // TODO: handlebars!
+ '<div id="new">' +
+ '<a>New</a>' +
+ '<ul>' +
+ '<li data-type="file" data-newname="New text file.txt"><p>Text file</p></li>' +
+ '</ul>' +
+ '</div>'
);
$dummyUploader = $('#file_upload_start');
});
@@ -111,4 +118,54 @@ describe('OC.Upload tests', function() {
);
});
});
+ describe('New file', function() {
+ var $input;
+ var currentDirStub;
+
+ beforeEach(function() {
+ OC.Upload.init();
+ $('#new>a').click();
+ $('#new li[data-type=file]').click();
+ $input = $('#new input[type=text]');
+
+ currentDirStub = sinon.stub(FileList, 'getCurrentDirectory');
+ currentDirStub.returns('testdir');
+ });
+ afterEach(function() {
+ currentDirStub.restore();
+ });
+ it('sets default text in field', function() {
+ expect($input.length).toEqual(1);
+ expect($input.val()).toEqual('New text file.txt');
+ });
+ it('creates file when enter is pressed', function() {
+ $input.val('somefile.txt');
+ $input.trigger(new $.Event('keyup', {keyCode: 13}));
+ $input.parent('form').submit();
+ expect(fakeServer.requests.length).toEqual(2);
+
+ var request = fakeServer.requests[1];
+ expect(request.method).toEqual('POST');
+ expect(request.url).toEqual(OC.webroot + '/index.php/apps/files/ajax/newfile.php');
+ var query = OC.parseQueryString(request.requestBody);
+ expect(query).toEqual({
+ dir: 'testdir',
+ filename: 'somefile.txt'
+ });
+ });
+ it('prevents entering invalid file names', function() {
+ $input.val('..');
+ $input.trigger(new $.Event('keyup', {keyCode: 13}));
+ $input.parent('form').submit();
+ expect(fakeServer.requests.length).toEqual(1);
+ });
+ it('prevents entering file names that already exist', function() {
+ var inListStub = sinon.stub(FileList, 'inList').returns(true);
+ $input.val('existing.txt');
+ $input.trigger(new $.Event('keyup', {keyCode: 13}));
+ $input.parent('form').submit();
+ expect(fakeServer.requests.length).toEqual(1);
+ inListStub.restore();
+ });
+ });
});
diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php
index d009fbca3b9..19d3b6cd9cc 100644
--- a/apps/files_sharing/appinfo/app.php
+++ b/apps/files_sharing/appinfo/app.php
@@ -25,31 +25,38 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
+
+namespace OCA\Files_Sharing\Appinfo;
+
$l = \OC::$server->getL10N('files_sharing');
-OC::$CLASSPATH['OC_Share_Backend_File'] = 'files_sharing/lib/share/file.php';
-OC::$CLASSPATH['OC_Share_Backend_Folder'] = 'files_sharing/lib/share/folder.php';
-OC::$CLASSPATH['OC\Files\Storage\Shared'] = 'files_sharing/lib/sharedstorage.php';
-OC::$CLASSPATH['OC\Files\Cache\SharedScanner'] = 'files_sharing/lib/scanner.php';
-OC::$CLASSPATH['OC\Files\Cache\Shared_Cache'] = 'files_sharing/lib/cache.php';
-OC::$CLASSPATH['OC\Files\Cache\Shared_Permissions'] = 'files_sharing/lib/permissions.php';
-OC::$CLASSPATH['OC\Files\Cache\Shared_Updater'] = 'files_sharing/lib/updater.php';
-OC::$CLASSPATH['OC\Files\Cache\Shared_Watcher'] = 'files_sharing/lib/watcher.php';
-OC::$CLASSPATH['OCA\Files\Share\Maintainer'] = 'files_sharing/lib/maintainer.php';
-OC::$CLASSPATH['OCA\Files\Share\Proxy'] = 'files_sharing/lib/proxy.php';
+\OC::$CLASSPATH['OC_Share_Backend_File'] = 'files_sharing/lib/share/file.php';
+\OC::$CLASSPATH['OC_Share_Backend_Folder'] = 'files_sharing/lib/share/folder.php';
+\OC::$CLASSPATH['OC\Files\Storage\Shared'] = 'files_sharing/lib/sharedstorage.php';
+\OC::$CLASSPATH['OC\Files\Cache\SharedScanner'] = 'files_sharing/lib/scanner.php';
+\OC::$CLASSPATH['OC\Files\Cache\Shared_Cache'] = 'files_sharing/lib/cache.php';
+\OC::$CLASSPATH['OC\Files\Cache\Shared_Permissions'] = 'files_sharing/lib/permissions.php';
+\OC::$CLASSPATH['OC\Files\Cache\Shared_Updater'] = 'files_sharing/lib/updater.php';
+\OC::$CLASSPATH['OC\Files\Cache\Shared_Watcher'] = 'files_sharing/lib/watcher.php';
+\OC::$CLASSPATH['OCA\Files\Share\Maintainer'] = 'files_sharing/lib/maintainer.php';
+\OC::$CLASSPATH['OCA\Files\Share\Proxy'] = 'files_sharing/lib/proxy.php';
// Exceptions
-OC::$CLASSPATH['OCA\Files_Sharing\Exceptions\BrokenPath'] = 'files_sharing/lib/exceptions.php';
+\OC::$CLASSPATH['OCA\Files_Sharing\Exceptions\BrokenPath'] = 'files_sharing/lib/exceptions.php';
+
+$application = new Application();
+$application->registerMountProviders();
+$application->setupPropagation();
\OCP\App::registerAdmin('files_sharing', 'settings-admin');
\OCA\Files_Sharing\Helper::registerHooks();
-OCP\Share::registerBackend('file', 'OC_Share_Backend_File');
-OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file');
+\OCP\Share::registerBackend('file', 'OC_Share_Backend_File');
+\OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file');
-OCP\Util::addScript('files_sharing', 'share');
-OCP\Util::addScript('files_sharing', 'external');
+\OCP\Util::addScript('files_sharing', 'share');
+\OCP\Util::addScript('files_sharing', 'external');
// FIXME: registering a job here will cause additional useless SQL queries
// when the route is not cron.php, needs a better way
diff --git a/apps/files_sharing/appinfo/application.php b/apps/files_sharing/appinfo/application.php
new file mode 100644
index 00000000000..0eb20945070
--- /dev/null
+++ b/apps/files_sharing/appinfo/application.php
@@ -0,0 +1,124 @@
+<?php
+/**
+ * Copyright (c) 2015 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCA\Files_Sharing\Appinfo;
+
+use OCA\Files_Sharing\Helper;
+use OCA\Files_Sharing\MountProvider;
+use OCA\Files_Sharing\Propagation\PropagationManager;
+use OCP\AppFramework\App;
+use OC\AppFramework\Utility\SimpleContainer;
+use OCA\Files_Sharing\Controllers\ExternalSharesController;
+use OCA\Files_Sharing\Controllers\ShareController;
+use OCA\Files_Sharing\Middleware\SharingCheckMiddleware;
+use \OCP\IContainer;
+
+class Application extends App {
+ public function __construct(array $urlParams = array()) {
+ parent::__construct('files_sharing', $urlParams);
+
+ $container = $this->getContainer();
+ $server = $container->getServer();
+
+ /**
+ * Controllers
+ */
+ $container->registerService('ShareController', function (SimpleContainer $c) use ($server) {
+ return new ShareController(
+ $c->query('AppName'),
+ $c->query('Request'),
+ $c->query('UserSession'),
+ $server->getAppConfig(),
+ $server->getConfig(),
+ $c->query('URLGenerator'),
+ $c->query('UserManager'),
+ $server->getLogger(),
+ $server->getActivityManager()
+ );
+ });
+ $container->registerService('ExternalSharesController', function (SimpleContainer $c) {
+ return new ExternalSharesController(
+ $c->query('AppName'),
+ $c->query('Request'),
+ $c->query('IsIncomingShareEnabled'),
+ $c->query('ExternalManager')
+ );
+ });
+
+ /**
+ * Core class wrappers
+ */
+ $container->registerService('UserSession', function (SimpleContainer $c) use ($server) {
+ return $server->getUserSession();
+ });
+ $container->registerService('URLGenerator', function (SimpleContainer $c) use ($server) {
+ return $server->getUrlGenerator();
+ });
+ $container->registerService('UserManager', function (SimpleContainer $c) use ($server) {
+ return $server->getUserManager();
+ });
+ $container->registerService('IsIncomingShareEnabled', function (SimpleContainer $c) {
+ return Helper::isIncomingServer2serverShareEnabled();
+ });
+ $container->registerService('ExternalManager', function (SimpleContainer $c) use ($server) {
+ $user = $server->getUserSession()->getUser();
+ $uid = $user ? $user->getUID() : null;
+ return new \OCA\Files_Sharing\External\Manager(
+ $server->getDatabaseConnection(),
+ \OC\Files\Filesystem::getMountManager(),
+ \OC\Files\Filesystem::getLoader(),
+ $server->getHTTPHelper(),
+ $uid
+ );
+ });
+
+ /**
+ * Middleware
+ */
+ $container->registerService('SharingCheckMiddleware', function (SimpleContainer $c) use ($server) {
+ return new SharingCheckMiddleware(
+ $c->query('AppName'),
+ $server->getConfig(),
+ $server->getAppManager()
+ );
+ });
+
+ // Execute middlewares
+ $container->registerMiddleware('SharingCheckMiddleware');
+
+ $container->registerService('MountProvider', function (IContainer $c) {
+ /** @var \OCP\IServerContainer $server */
+ $server = $c->query('ServerContainer');
+ return new MountProvider(
+ $server->getConfig(),
+ $c->query('PropagationManager')
+ );
+ });
+
+ $container->registerService('PropagationManager', function (IContainer $c) {
+ /** @var \OCP\IServerContainer $server */
+ $server = $c->query('ServerContainer');
+ return new PropagationManager(
+ $server->getUserSession(),
+ $server->getConfig()
+ );
+ });
+ }
+
+ public function registerMountProviders() {
+ /** @var \OCP\IServerContainer $server */
+ $server = $this->getContainer()->query('ServerContainer');
+ $mountProviderCollection = $server->getMountProviderCollection();
+ $mountProviderCollection->registerProvider($this->getContainer()->query('MountProvider'));
+ }
+
+ public function setupPropagation() {
+ $propagationManager = $this->getContainer()->query('PropagationManager');
+ \OCP\Util::connectHook('OC_Filesystem', 'setup', $propagationManager, 'globalSetup');
+ }
+}
diff --git a/apps/files_sharing/appinfo/routes.php b/apps/files_sharing/appinfo/routes.php
index 9ac3a1f731a..78fa138f5b5 100644
--- a/apps/files_sharing/appinfo/routes.php
+++ b/apps/files_sharing/appinfo/routes.php
@@ -25,7 +25,6 @@
*/
namespace OCA\Files_Sharing\AppInfo;
-use OCA\Files_Sharing\Application;
use OCP\API;
$application = new Application();
diff --git a/apps/files_sharing/application.php b/apps/files_sharing/application.php
deleted file mode 100644
index 62c07ffe404..00000000000
--- a/apps/files_sharing/application.php
+++ /dev/null
@@ -1,115 +0,0 @@
-<?php
-/**
- * @author Björn Schießle <schiessle@owncloud.com>
- * @author Lukas Reschke <lukas@owncloud.com>
- * @author Morris Jobke <hey@morrisjobke.de>
- * @author Thomas Müller <thomas.mueller@tmit.eu>
- *
- * @copyright Copyright (c) 2015, 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\Files_Sharing;
-
-use OC\AppFramework\Utility\SimpleContainer;
-use OCA\Files_Sharing\Controllers\ExternalSharesController;
-use OCA\Files_Sharing\Controllers\ShareController;
-use OCA\Files_Sharing\Middleware\SharingCheckMiddleware;
-use \OCP\AppFramework\App;
-
-/**
- * @package OCA\Files_Sharing
- */
-class Application extends App {
-
-
- /**
- * @param array $urlParams
- */
- public function __construct(array $urlParams=array()){
- parent::__construct('files_sharing', $urlParams);
-
- $container = $this->getContainer();
- $server = $container->getServer();
-
- /**
- * Controllers
- */
- $container->registerService('ShareController', function(SimpleContainer $c) use ($server) {
- return new ShareController(
- $c->query('AppName'),
- $c->query('Request'),
- $c->query('UserSession'),
- $server->getAppConfig(),
- $server->getConfig(),
- $c->query('URLGenerator'),
- $c->query('UserManager'),
- $server->getLogger(),
- $server->getActivityManager()
- );
- });
- $container->registerService('ExternalSharesController', function(SimpleContainer $c) {
- return new ExternalSharesController(
- $c->query('AppName'),
- $c->query('Request'),
- $c->query('IsIncomingShareEnabled'),
- $c->query('ExternalManager')
- );
- });
-
- /**
- * Core class wrappers
- */
- $container->registerService('UserSession', function(SimpleContainer $c) use ($server) {
- return $server->getUserSession();
- });
- $container->registerService('URLGenerator', function(SimpleContainer $c) use ($server){
- return $server->getUrlGenerator();
- });
- $container->registerService('UserManager', function(SimpleContainer $c) use ($server){
- return $server->getUserManager();
- });
- $container->registerService('IsIncomingShareEnabled', function(SimpleContainer $c) {
- return Helper::isIncomingServer2serverShareEnabled();
- });
- $container->registerService('ExternalManager', function(SimpleContainer $c) use ($server){
- $user = $server->getUserSession()->getUser();
- $uid = $user ? $user->getUID() : null;
- return new \OCA\Files_Sharing\External\Manager(
- $server->getDatabaseConnection(),
- \OC\Files\Filesystem::getMountManager(),
- \OC\Files\Filesystem::getLoader(),
- $server->getHTTPHelper(),
- $uid
- );
- });
-
- /**
- * Middleware
- */
- $container->registerService('SharingCheckMiddleware', function(SimpleContainer $c) use ($server){
- return new SharingCheckMiddleware(
- $c->query('AppName'),
- $server->getConfig(),
- $server->getAppManager()
- );
- });
-
- // Execute middlewares
- $container->registerMiddleware('SharingCheckMiddleware');
- }
-
-}
diff --git a/apps/files_sharing/lib/helper.php b/apps/files_sharing/lib/helper.php
index 5b5525e244f..05b0352ca1f 100644
--- a/apps/files_sharing/lib/helper.php
+++ b/apps/files_sharing/lib/helper.php
@@ -30,9 +30,7 @@ namespace OCA\Files_Sharing;
class Helper {
public static function registerHooks() {
- \OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup');
\OCP\Util::connectHook('OC_Filesystem', 'setup', '\OCA\Files_Sharing\External\Manager', 'setup');
- \OCP\Util::connectHook('OC_Filesystem', 'post_write', '\OC\Files\Cache\Shared_Updater', 'writeHook');
\OCP\Util::connectHook('OC_Filesystem', 'delete', '\OC\Files\Cache\Shared_Updater', 'deleteHook');
\OCP\Util::connectHook('OC_Filesystem', 'post_rename', '\OC\Files\Cache\Shared_Updater', 'renameHook');
\OCP\Util::connectHook('OC_Filesystem', 'post_delete', '\OCA\Files_Sharing\Hooks', 'unshareChildren');
diff --git a/apps/files_sharing/lib/mountprovider.php b/apps/files_sharing/lib/mountprovider.php
new file mode 100644
index 00000000000..94fb473883d
--- /dev/null
+++ b/apps/files_sharing/lib/mountprovider.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Copyright (c) 2015 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCA\Files_Sharing;
+
+use OC\Files\Filesystem;
+use OCA\Files_Sharing\Propagation\PropagationManager;
+use OCP\Files\Config\IMountProvider;
+use OCP\Files\Storage\IStorageFactory;
+use OCP\IConfig;
+use OCP\IUser;
+
+class MountProvider implements IMountProvider {
+ /**
+ * @var \OCP\IConfig
+ */
+ protected $config;
+
+ /**
+ * @var \OCA\Files_Sharing\Propagation\PropagationManager
+ */
+ protected $propagationManager;
+
+ /**
+ * @param \OCP\IConfig $config
+ * @param \OCA\Files_Sharing\Propagation\PropagationManager $propagationManager
+ */
+ public function __construct(IConfig $config, PropagationManager $propagationManager) {
+ $this->config = $config;
+ $this->propagationManager = $propagationManager;
+ }
+
+
+ /**
+ * Get all mountpoints applicable for the user and check for shares where we need to update the etags
+ *
+ * @param \OCP\IUser $user
+ * @param \OCP\Files\Storage\IStorageFactory $storageFactory
+ * @return \OCP\Files\Mount\IMountPoint[]
+ */
+ public function getMountsForUser(IUser $user, IStorageFactory $storageFactory) {
+ $shares = \OCP\Share::getItemsSharedWithUser('file', $user->getUID());
+ $propagator = $this->propagationManager->getSharePropagator($user->getUID());
+ $propagator->propagateDirtyMountPoints($shares);
+ $shares = array_filter($shares, function ($share) {
+ return $share['permissions'] > 0;
+ });
+ return array_map(function ($share) use ($user, $storageFactory) {
+ Filesystem::initMountPoints($share['uid_owner']);
+ // for updating etags for the share owner when we make changes to this share.
+ $ownerPropagator = $this->propagationManager->getChangePropagator($share['uid_owner']);
+
+ // for updating our etags when changes are made to the share from the owners side (probably indirectly by us trough another share)
+ $this->propagationManager->listenToOwnerChanges($share['uid_owner'], $user->getUID());
+ return new SharedMount(
+ '\OC\Files\Storage\Shared',
+ '/' . $user->getUID() . '/' . $share['file_target'],
+ array(
+ 'propagator' => $ownerPropagator,
+ 'share' => $share,
+ 'user' => $user->getUID()
+ ),
+ $storageFactory
+ );
+ }, $shares);
+ }
+}
diff --git a/apps/files_sharing/lib/propagation/changewatcher.php b/apps/files_sharing/lib/propagation/changewatcher.php
new file mode 100644
index 00000000000..483f436e289
--- /dev/null
+++ b/apps/files_sharing/lib/propagation/changewatcher.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Copyright (c) 2015 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCA\Files_Sharing\Propagation;
+
+use OC\Files\Cache\ChangePropagator;
+use OC\Files\Filesystem;
+use OC\Files\View;
+use OCA\Files_Sharing\SharedMount;
+
+/**
+ * Watch for changes made in a shared mount and propagate the changes to the share owner
+ */
+class ChangeWatcher {
+ /**
+ * The user view for the logged in user
+ *
+ * @var \OC\Files\View
+ */
+ private $baseView;
+
+ /**
+ * @param \OC\Files\View $baseView the view for the logged in user
+ */
+ public function __construct(View $baseView) {
+ $this->baseView = $baseView;
+ }
+
+
+ public function writeHook($params) {
+ $path = $params['path'];
+ $fullPath = $this->baseView->getAbsolutePath($path);
+ $mount = $this->baseView->getMount($path);
+ if ($mount instanceof SharedMount) {
+ $this->propagateForOwner($mount->getShare(), $mount->getInternalPath($fullPath), $mount->getOwnerPropagator());
+ }
+ }
+
+ public function renameHook($params) {
+ $path1 = $params['oldpath'];
+ $path2 = $params['newpath'];
+ $fullPath1 = $this->baseView->getAbsolutePath($path1);
+ $fullPath2 = $this->baseView->getAbsolutePath($path2);
+ $mount1 = $this->baseView->getMount($path1);
+ $mount2 = $this->baseView->getMount($path2);
+ if ($mount1 instanceof SharedMount and $mount1->getInternalPath($fullPath1) !== '') {
+ $this->propagateForOwner($mount1->getShare(), $mount1->getInternalPath($fullPath1), $mount1->getOwnerPropagator());
+ }
+ if ($mount1 !== $mount2 and $mount2 instanceof SharedMount and $mount2->getInternalPath($fullPath2) !== '') {
+ $this->propagateForOwner($mount2->getShare(), $mount2->getInternalPath($fullPath2), $mount2->getOwnerPropagator());
+ }
+ }
+
+ /**
+ * @param array $share
+ * @param string $internalPath
+ * @param \OC\Files\Cache\ChangePropagator $propagator
+ */
+ private function propagateForOwner($share, $internalPath, ChangePropagator $propagator) {
+ // note that we have already set up the filesystem for the owner when mounting the share
+ $view = new View('/' . $share['uid_owner'] . '/files');
+
+ $shareRootPath = $view->getPath($share['item_source']);
+ if (!is_null($shareRootPath)) {
+ $path = $shareRootPath . '/' . $internalPath;
+ $path = Filesystem::normalizePath($path);
+ $propagator->addChange($path);
+ $propagator->propagateChanges();
+ }
+ }
+}
diff --git a/apps/files_sharing/lib/propagation/propagationmanager.php b/apps/files_sharing/lib/propagation/propagationmanager.php
new file mode 100644
index 00000000000..fa073be7f60
--- /dev/null
+++ b/apps/files_sharing/lib/propagation/propagationmanager.php
@@ -0,0 +1,112 @@
+<?php
+/**
+ * Copyright (c) 2015 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCA\Files_Sharing\Propagation;
+
+use OC\Files\Filesystem;
+use OC\Files\View;
+use OCP\IConfig;
+use OCP\IUserSession;
+
+
+/**
+ * Keep track of all change and share propagators by owner
+ */
+class PropagationManager {
+ /**
+ * @var \OCP\IUserSession
+ */
+ private $userSession;
+
+ /**
+ * @var \OCP\IConfig
+ */
+ private $config;
+
+ /**
+ * Change propagators for share owner
+ *
+ * @var \OC\Files\Cache\ChangePropagator[]
+ */
+ private $changePropagators = [];
+
+ /**
+ * Recipient propagators
+ *
+ * @var \OCA\Files_Sharing\Propagation\RecipientPropagator[]
+ */
+ private $sharePropagators = [];
+
+ public function __construct(IUserSession $userSession, IConfig $config) {
+ $this->userSession = $userSession;
+ $this->config = $config;
+ }
+
+ /**
+ * @param string $user
+ * @return \OC\Files\Cache\ChangePropagator
+ */
+ public function getChangePropagator($user) {
+ $activeUser = $this->userSession->getUser();
+
+ // for the local user we want to propagator from the active view, not any cached one
+ if ($activeUser && $activeUser->getUID() === $user && Filesystem::getView() instanceof View) {
+ // it's important that we take the existing propagator here to make sure we can listen to external changes
+ $this->changePropagators[$user] = Filesystem::getView()->getUpdater()->getPropagator();
+ }
+ if (isset($this->changePropagators[$user])) {
+ return $this->changePropagators[$user];
+ }
+ $view = new View('/' . $user . '/files');
+ $this->changePropagators[$user] = $view->getUpdater()->getPropagator();
+ return $this->changePropagators[$user];
+ }
+
+ /**
+ * @param string $user
+ * @return \OCA\Files_Sharing\Propagation\RecipientPropagator
+ */
+ public function getSharePropagator($user) {
+ if (isset($this->sharePropagators[$user])) {
+ return $this->sharePropagators[$user];
+ }
+ $this->sharePropagators[$user] = new RecipientPropagator($user, $this->getChangePropagator($user), $this->config);
+ return $this->sharePropagators[$user];
+ }
+
+ /**
+ * Attach the recipient propagator for $user to the change propagator of a share owner to mark shares as dirty when the owner makes a change to a share
+ *
+ * @param string $shareOwner
+ * @param string $user
+ */
+ public function listenToOwnerChanges($shareOwner, $user) {
+ $sharePropagator = $this->getSharePropagator($user);
+ $ownerPropagator = $this->getChangePropagator($shareOwner);
+ $sharePropagator->attachToPropagator($ownerPropagator, $shareOwner);
+ }
+
+ /**
+ * To be called from setupFS trough a hook
+ *
+ * Sets up listening to changes made to shares owned by the current user
+ */
+ public function globalSetup() {
+ $user = $this->userSession->getUser();
+ if (!$user) {
+ return;
+ }
+ $watcher = new ChangeWatcher(Filesystem::getView());
+
+ // for marking shares owned by the active user as dirty when a file inside them changes
+ $this->listenToOwnerChanges($user->getUID(), $user->getUID());
+ \OC_Hook::connect('OC_Filesystem', 'post_write', $watcher, 'writeHook');
+ \OC_Hook::connect('OC_Filesystem', 'post_delete', $watcher, 'writeHook');
+ \OC_Hook::connect('OC_Filesystem', 'post_rename', $watcher, 'renameHook');
+ }
+}
diff --git a/apps/files_sharing/lib/propagation/recipientpropagator.php b/apps/files_sharing/lib/propagation/recipientpropagator.php
new file mode 100644
index 00000000000..5b7651f2ce7
--- /dev/null
+++ b/apps/files_sharing/lib/propagation/recipientpropagator.php
@@ -0,0 +1,118 @@
+<?php
+/**
+ * Copyright (c) 2015 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCA\Files_Sharing\Propagation;
+
+use OC\Files\Cache\ChangePropagator;
+use OC\Files\View;
+use OC\Share\Share;
+
+/**
+ * Propagate etags for share recipients
+ */
+class RecipientPropagator {
+ /**
+ * @var string
+ */
+ protected $userId;
+
+ /**
+ * @var \OC\Files\Cache\ChangePropagator
+ */
+ protected $changePropagator;
+
+ /**
+ * @var \OCP\IConfig
+ */
+ protected $config;
+
+ /**
+ * @param string $userId current user, must match the propagator's
+ * user
+ * @param \OC\Files\Cache\ChangePropagator $changePropagator change propagator
+ * initialized with a view for $user
+ * @param \OCP\IConfig $config
+ */
+ public function __construct($userId, $changePropagator, $config) {
+ $this->userId = $userId;
+ $this->changePropagator = $changePropagator;
+ $this->config = $config;
+ }
+
+ /**
+ * Propagate the etag changes for all shares marked as dirty and mark the shares as clean
+ *
+ * @param array $shares the shares for the users
+ * @param int $time
+ */
+ public function propagateDirtyMountPoints(array $shares, $time = null) {
+ if ($time === null) {
+ $time = microtime(true);
+ }
+ $dirtyShares = $this->getDirtyShares($shares);
+ foreach ($dirtyShares as $share) {
+ $this->changePropagator->addChange($share['file_target']);
+ }
+ if (count($dirtyShares)) {
+ $this->config->setUserValue($this->userId, 'files_sharing', 'last_propagate', $time);
+ $this->changePropagator->propagateChanges(floor($time));
+ }
+ }
+
+ /**
+ * Get all shares we need to update the etag for
+ *
+ * @param array $shares the shares for the users
+ * @return string[]
+ */
+ protected function getDirtyShares($shares) {
+ $dirty = [];
+ $userTime = $this->config->getUserValue($this->userId, 'files_sharing', 'last_propagate', 0);
+ foreach ($shares as $share) {
+ $updateTime = $this->config->getAppValue('files_sharing', $share['id'], 0);
+ if ($updateTime >= $userTime) {
+ $dirty[] = $share;
+ }
+ }
+ return $dirty;
+ }
+
+ /**
+ * @param array $share
+ * @param int $time
+ */
+ public function markDirty($share, $time = null) {
+ if ($time === null) {
+ $time = microtime(true);
+ }
+ $this->config->setAppValue('files_sharing', $share['id'], $time);
+ }
+
+ /**
+ * Listen on the propagator for updates made to shares owned by a user
+ *
+ * @param \OC\Files\Cache\ChangePropagator $propagator
+ * @param string $owner
+ */
+ public function attachToPropagator(ChangePropagator $propagator, $owner) {
+ $propagator->listen('\OC\Files', 'propagate', function ($path, $entry) use ($owner) {
+ $shares = Share::getAllSharesForFileId($entry['fileid']);
+ foreach ($shares as $share) {
+ // propagate down the share tree
+ $this->markDirty($share, microtime(true));
+
+ // propagate up the share tree
+ $user = $share['uid_owner'];
+ $view = new View('/' . $user . '/files');
+ $path = $view->getPath($share['file_source']);
+ $watcher = new ChangeWatcher($view);
+ $watcher->writeHook(['path' => $path]);
+ }
+ });
+ }
+}
diff --git a/apps/files_sharing/lib/sharedmount.php b/apps/files_sharing/lib/sharedmount.php
index da00549541b..15aea0aa52a 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\Mount\MountPoint;
use OC\Files\Mount\MoveableMount;
+use OC\Files\View;
/**
* Shared mount points can be moved by the user
@@ -35,8 +36,14 @@ class SharedMount extends MountPoint implements MoveableMount {
*/
protected $storage = null;
+ /**
+ * @var \OC\Files\Cache\ChangePropagator
+ */
+ protected $ownerPropagator;
+
public function __construct($storage, $mountpoint, $arguments = null, $loader = null) {
// first update the mount point before creating the parent
+ $this->ownerPropagator = $arguments['propagator'];
$newMountPoint = $this->verifyMountPoint($arguments['share'], $arguments['user']);
$absMountPoint = '/' . $arguments['user'] . '/files' . $newMountPoint;
parent::__construct($storage, $absMountPoint, $arguments, $loader);
@@ -49,8 +56,9 @@ class SharedMount extends MountPoint implements MoveableMount {
$mountPoint = basename($share['file_target']);
$parent = dirname($share['file_target']);
+ $view = new View('/' . $user . '/files');
- if (!\OC\Files\Filesystem::is_dir($parent)) {
+ if (!$view->is_dir($parent)) {
$parent = Helper::getShareFolder();
}
@@ -174,4 +182,15 @@ class SharedMount extends MountPoint implements MoveableMount {
return $result;
}
+
+ public function getShare() {
+ return $this->getStorage()->getShare();
+ }
+
+ /**
+ * @return \OC\Files\Cache\ChangePropagator
+ */
+ public function getOwnerPropagator() {
+ return $this->ownerPropagator;
+ }
}
diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php
index 8c2f03b1419..bc01465cb4a 100644
--- a/apps/files_sharing/lib/sharedstorage.php
+++ b/apps/files_sharing/lib/sharedstorage.php
@@ -28,8 +28,12 @@
*/
namespace OC\Files\Storage;
+
+use OC\Files\Cache\ChangePropagator;
use OC\Files\Filesystem;
+use OC\Files\View;
use OCA\Files_Sharing\ISharedStorage;
+use OCA\Files_Sharing\Propagator;
use OCA\Files_Sharing\SharedMount;
/**
@@ -47,6 +51,7 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
/**
* get id of the mount point
+ *
* @return string
*/
public function getId() {
@@ -55,14 +60,16 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
/**
* get file cache of the shared item source
+ *
* @return int
*/
public function getSourceId() {
- return (int) $this->share['file_source'];
+ return (int)$this->share['file_source'];
}
/**
* Get the source file path, permissions, and owner for a shared file
+ *
* @param string $target Shared target file path
* @return Returns array with the keys path, permissions, and owner or false if not found
*/
@@ -86,6 +93,7 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
/**
* Get the source file path for a shared file
+ *
* @param string $target Shared target file path
* @return string|false source file path or false if not found
*/
@@ -109,6 +117,7 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
/**
* Get the permissions granted for a shared file
+ *
* @param string $target Shared target file path
* @return int CRUDS permissions granted
*/
@@ -138,13 +147,14 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
/**
* Delete the directory if DELETE permission is granted
+ *
* @param string $path
* @return boolean
*/
public function rmdir($path) {
// never delete a share mount point
- if(empty($path)) {
+ if (empty($path)) {
return false;
}
@@ -277,6 +287,7 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
/**
* Delete the file if DELETE permission is granted
+ *
* @param string $path
* @return boolean
*/
@@ -426,37 +437,6 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
return false;
}
- public static function setup($options) {
- $user = $options['user'];
- $shares = \OCP\Share::getItemsSharedWithUser('file', $user);
- $manager = Filesystem::getMountManager();
- $loader = Filesystem::getLoader();
- if (
- !isset(self::$isInitialized[$user]) && (
- !\OCP\User::isLoggedIn()
- || \OCP\User::getUser() != $options['user']
- || $shares
- )
- ) {
- foreach ($shares as $share) {
- // don't mount shares where we have no permissions
- if ($share['permissions'] > 0) {
- $mount = new SharedMount(
- '\OC\Files\Storage\Shared',
- $options['user_dir'] . '/' . $share['file_target'],
- array(
- 'share' => $share,
- 'user' => $user
- ),
- $loader
- );
- $manager->addMount($mount);
- }
- }
- }
- self::$isInitialized[$user] = true;
- }
-
/**
* return mount point of share, relative to data/user/files
*
@@ -476,6 +456,7 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
/**
* does the group share already has a user specific unique name
+ *
* @return bool
*/
public function uniqueNameSet() {
@@ -493,6 +474,7 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
/**
* get share ID
+ *
* @return integer unique share ID
*/
public function getShareId() {
@@ -501,6 +483,7 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
/**
* get the user who shared the file
+ *
* @return string
*/
public function getSharedFrom() {
@@ -516,6 +499,7 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage {
/**
* return share type, can be "file" or "folder"
+ *
* @return string
*/
public function getItemType() {
diff --git a/apps/files_sharing/lib/updater.php b/apps/files_sharing/lib/updater.php
index 322c031f2f1..45cf662d148 100644
--- a/apps/files_sharing/lib/updater.php
+++ b/apps/files_sharing/lib/updater.php
@@ -50,47 +50,9 @@ class Shared_Updater {
}
/**
- * Correct the parent folders' ETags for all users shared the file at $target
- *
- * @param string $target
- */
- static public function correctFolders($target) {
-
- // ignore part files
- if (pathinfo($target, PATHINFO_EXTENSION) === 'part') {
- return false;
- }
-
- // Correct Shared folders of other users shared with
- $shares = \OCA\Files_Sharing\Helper::getSharesFromItem($target);
-
- foreach ($shares as $share) {
- if ((int)$share['share_type'] === \OCP\Share::SHARE_TYPE_USER) {
- self::correctUsersFolder($share['share_with'], $share['file_target']);
- } elseif ((int)$share['share_type'] === \OCP\Share::SHARE_TYPE_GROUP) {
- $users = \OC_Group::usersInGroup($share['share_with']);
- foreach ($users as $user) {
- self::correctUsersFolder($user, $share['file_target']);
- }
- } else { //unique name for group share
- self::correctUsersFolder($share['share_with'], $share['file_target']);
- }
- }
- }
-
- /**
- * @param array $params
- */
- static public function writeHook($params) {
- self::correctFolders($params['path']);
- }
-
- /**
* @param array $params
*/
static public function renameHook($params) {
- self::correctFolders($params['newpath']);
- self::correctFolders(pathinfo($params['oldpath'], PATHINFO_DIRNAME));
self::renameChildren($params['oldpath'], $params['newpath']);
}
@@ -99,7 +61,6 @@ class Shared_Updater {
*/
static public function deleteHook($params) {
$path = $params['path'];
- self::correctFolders($path);
}
/**
diff --git a/apps/files_sharing/tests/cache.php b/apps/files_sharing/tests/cache.php
index 882c8afadc3..7e7e5ee26d5 100644
--- a/apps/files_sharing/tests/cache.php
+++ b/apps/files_sharing/tests/cache.php
@@ -113,7 +113,9 @@ class Test_Files_Sharing_Cache extends TestCase {
}
protected function tearDown() {
- $this->sharedCache->clear();
+ if($this->sharedCache) {
+ $this->sharedCache->clear();
+ }
self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
diff --git a/apps/files_sharing/tests/controller/sharecontroller.php b/apps/files_sharing/tests/controller/sharecontroller.php
index c3bd41b0402..64ee5b8ce51 100644
--- a/apps/files_sharing/tests/controller/sharecontroller.php
+++ b/apps/files_sharing/tests/controller/sharecontroller.php
@@ -26,7 +26,7 @@
namespace OCA\Files_Sharing\Controllers;
use OC\Files\Filesystem;
-use OCA\Files_Sharing\Application;
+use OCA\Files_Sharing\AppInfo\Application;
use OCP\AppFramework\Http\NotFoundResponse;
use OCP\AppFramework\IAppContainer;
use OCP\Files;
diff --git a/apps/files_sharing/tests/etagpropagation.php b/apps/files_sharing/tests/etagpropagation.php
new file mode 100644
index 00000000000..041ed34ce11
--- /dev/null
+++ b/apps/files_sharing/tests/etagpropagation.php
@@ -0,0 +1,345 @@
+<?php
+/**
+ * @author Vincent Petry <pvince81@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, 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\Files_sharing\Tests;
+
+use OC\Files\Filesystem;
+use OC\Files\View;
+
+class EtagPropagation extends TestCase {
+ /**
+ * @var \OC\Files\View
+ */
+ private $rootView;
+ protected $fileIds = []; // [$user=>[$path=>$id]]
+ protected $fileEtags = []; // [$id=>$etag]
+
+ protected function setUp() {
+ parent::setUp();
+ $this->setUpShares();
+ }
+
+ protected function tearDown() {
+ \OC_Hook::clear('OC_Filesystem', 'post_write');
+ \OC_Hook::clear('OC_Filesystem', 'post_delete');
+ \OC_Hook::clear('OC_Filesystem', 'post_rename');
+ parent::tearDown();
+ }
+
+ /**
+ * "user1" is the admin who shares a folder "sub1/sub2/folder" with "user2" and "user3"
+ * "user2" receives the folder and puts it in "sub1/sub2/folder"
+ * "user3" receives the folder and puts it in "sub1/sub2/folder"
+ * "user2" reshares the subdir "sub1/sub2/folder/inside" with "user4"
+ * "user4" puts the received "inside" folder into "sub1/sub2/inside" (this is to check if it propagates across multiple subfolders)
+ */
+ private function setUpShares() {
+ $this->fileIds[self::TEST_FILES_SHARING_API_USER1] = [];
+ $this->fileIds[self::TEST_FILES_SHARING_API_USER2] = [];
+ $this->fileIds[self::TEST_FILES_SHARING_API_USER3] = [];
+ $this->fileIds[self::TEST_FILES_SHARING_API_USER4] = [];
+
+ $this->rootView = new View('');
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
+ $view1 = new View('/' . self::TEST_FILES_SHARING_API_USER1 . '/files');
+ $view1->mkdir('/sub1/sub2/folder/inside');
+ $view1->mkdir('/directReshare');
+ $view1->mkdir('/sub1/sub2/folder/other');
+ $view1->mkdir('/sub1/sub2/folder/other');
+ $view1->file_put_contents('/sub1/sub2/folder/file.txt', 'foobar');
+ $view1->file_put_contents('/sub1/sub2/folder/inside/file.txt', 'foobar');
+ $folderInfo = $view1->getFileInfo('/sub1/sub2/folder');
+ \OCP\Share::shareItem('folder', $folderInfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 31);
+ \OCP\Share::shareItem('folder', $folderInfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER3, 31);
+ $folderInfo = $view1->getFileInfo('/directReshare');
+ \OCP\Share::shareItem('folder', $folderInfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 31);
+ $this->fileIds[self::TEST_FILES_SHARING_API_USER1][''] = $view1->getFileInfo('')->getId();
+ $this->fileIds[self::TEST_FILES_SHARING_API_USER1]['sub1'] = $view1->getFileInfo('sub1')->getId();
+ $this->fileIds[self::TEST_FILES_SHARING_API_USER1]['sub1/sub2'] = $view1->getFileInfo('sub1/sub2')->getId();
+
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
+ $view2 = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files');
+ $view2->mkdir('/sub1/sub2');
+ $view2->rename('/folder', '/sub1/sub2/folder');
+ $insideInfo = $view2->getFileInfo('/sub1/sub2/folder/inside');
+ \OCP\Share::shareItem('folder', $insideInfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER4, 31);
+ $folderInfo = $view2->getFileInfo('/directReshare');
+ \OCP\Share::shareItem('folder', $folderInfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER4, 31);
+ $this->fileIds[self::TEST_FILES_SHARING_API_USER2][''] = $view2->getFileInfo('')->getId();
+ $this->fileIds[self::TEST_FILES_SHARING_API_USER2]['sub1'] = $view2->getFileInfo('sub1')->getId();
+ $this->fileIds[self::TEST_FILES_SHARING_API_USER2]['sub1/sub2'] = $view2->getFileInfo('sub1/sub2')->getId();
+
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER3);
+ $view3 = new View('/' . self::TEST_FILES_SHARING_API_USER3 . '/files');
+ $view3->mkdir('/sub1/sub2');
+ $view3->rename('/folder', '/sub1/sub2/folder');
+ $this->fileIds[self::TEST_FILES_SHARING_API_USER3][''] = $view3->getFileInfo('')->getId();
+ $this->fileIds[self::TEST_FILES_SHARING_API_USER3]['sub1'] = $view3->getFileInfo('sub1')->getId();
+ $this->fileIds[self::TEST_FILES_SHARING_API_USER3]['sub1/sub2'] = $view3->getFileInfo('sub1/sub2')->getId();
+
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER4);
+ $view4 = new View('/' . self::TEST_FILES_SHARING_API_USER4 . '/files');
+ $view4->mkdir('/sub1/sub2');
+ $view4->rename('/inside', '/sub1/sub2/inside');
+ $this->fileIds[self::TEST_FILES_SHARING_API_USER4][''] = $view4->getFileInfo('')->getId();
+ $this->fileIds[self::TEST_FILES_SHARING_API_USER4]['sub1'] = $view4->getFileInfo('sub1')->getId();
+ $this->fileIds[self::TEST_FILES_SHARING_API_USER4]['sub1/sub2'] = $view4->getFileInfo('sub1/sub2')->getId();
+
+ foreach ($this->fileIds as $user => $ids) {
+ $this->loginAsUser($user);
+ foreach ($ids as $id) {
+ $path = $this->rootView->getPath($id);
+ $this->fileEtags[$id] = $this->rootView->getFileInfo($path)->getEtag();
+ }
+ }
+ }
+
+ /**
+ * @param string[] $users
+ * @param string $subPath
+ */
+ private function assertEtagsChanged($users, $subPath = '') {
+ $oldUser = \OC::$server->getUserSession()->getUser();
+ foreach ($users as $user) {
+ $this->loginAsUser($user);
+ $id = $this->fileIds[$user][$subPath];
+ $path = $this->rootView->getPath($id);
+ $etag = $this->rootView->getFileInfo($path)->getEtag();
+ $this->assertNotEquals($this->fileEtags[$id], $etag, 'Failed asserting that the etag for "' . $subPath . '" of user ' . $user . ' has changed');
+ $this->fileEtags[$id] = $etag;
+ }
+ $this->loginAsUser($oldUser->getUID());
+ }
+
+ /**
+ * @param string[] $users
+ * @param string $subPath
+ */
+ private function assertEtagsNotChanged($users, $subPath = '') {
+ $oldUser = \OC::$server->getUserSession()->getUser();
+ foreach ($users as $user) {
+ $this->loginAsUser($user);
+ $id = $this->fileIds[$user][$subPath];
+ $path = $this->rootView->getPath($id);
+ $etag = $this->rootView->getFileInfo($path)->getEtag();
+ $this->assertEquals($this->fileEtags[$id], $etag, 'Failed asserting that the etag for "' . $subPath . '" of user ' . $user . ' has not changed');
+ $this->fileEtags[$id] = $etag;
+ }
+ $this->loginAsUser($oldUser->getUID());
+ }
+
+ /**
+ * Assert that the etags for the root, /sub1 and /sub1/sub2 have changed
+ *
+ * @param string[] $users
+ */
+ private function assertEtagsForFoldersChanged($users) {
+ $this->assertEtagsChanged($users);
+
+ $this->assertEtagsChanged($users, 'sub1');
+ $this->assertEtagsChanged($users, 'sub1/sub2');
+ }
+
+ private function assertAllUnchaged() {
+ $users = [self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4];
+ $this->assertEtagsNotChanged($users);
+ }
+
+ public function testOwnerWritesToShare() {
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
+ Filesystem::file_put_contents('/sub1/sub2/folder/asd.txt', 'bar');
+ $this->assertEtagsNotChanged([self::TEST_FILES_SHARING_API_USER4]);
+ $this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER3]);
+
+ $this->assertAllUnchaged();
+ }
+
+ public function testOwnerWritesToShareWithReshare() {
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
+ Filesystem::file_put_contents('/sub1/sub2/folder/inside/bar.txt', 'bar');
+ $this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
+
+ $this->assertAllUnchaged();
+ }
+
+ public function testOwnerRenameInShare() {
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
+ $this->assertEtagsNotChanged([self::TEST_FILES_SHARING_API_USER4]);
+ Filesystem::rename('/sub1/sub2/folder/file.txt', '/sub1/sub2/folder/renamed.txt');
+ $this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER3]);
+
+ $this->assertAllUnchaged();
+ }
+
+ public function testOwnerRenameInReShare() {
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
+ Filesystem::rename('/sub1/sub2/folder/inside/file.txt', '/sub1/sub2/folder/inside/renamed.txt');
+ $this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
+
+ $this->assertAllUnchaged();
+ }
+
+ public function testOwnerRenameIntoReShare() {
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
+ Filesystem::rename('/sub1/sub2/folder/file.txt', '/sub1/sub2/folder/inside/renamed.txt');
+ $this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
+
+ $this->assertAllUnchaged();
+ }
+
+ public function testOwnerRenameOutOfReShare() {
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
+ Filesystem::rename('/sub1/sub2/folder/inside/file.txt', '/sub1/sub2/folder/renamed.txt');
+ $this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
+
+ $this->assertAllUnchaged();
+ }
+
+ public function testOwnerDeleteInShare() {
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
+ Filesystem::unlink('/sub1/sub2/folder/file.txt');
+ $this->assertEtagsNotChanged([self::TEST_FILES_SHARING_API_USER4]);
+ $this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER3]);
+
+ $this->assertAllUnchaged();
+ }
+
+ public function testOwnerDeleteInReShare() {
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
+ Filesystem::unlink('/sub1/sub2/folder/inside/file.txt');
+ $this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
+
+ $this->assertAllUnchaged();
+ }
+
+ public function testRecipientWritesToShare() {
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
+ Filesystem::file_put_contents('/sub1/sub2/folder/asd.txt', 'bar');
+ $this->assertEtagsNotChanged([self::TEST_FILES_SHARING_API_USER4]);
+ $this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER3]);
+
+ $this->assertAllUnchaged();
+ }
+
+ public function testRecipientWritesToReshare() {
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
+ Filesystem::file_put_contents('/sub1/sub2/folder/inside/asd.txt', 'bar');
+ $this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
+
+ $this->assertAllUnchaged();
+ }
+
+ public function testRecipientWritesToOtherRecipientsReshare() {
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER3);
+ Filesystem::file_put_contents('/sub1/sub2/folder/inside/asd.txt', 'bar');
+ $this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
+
+ $this->assertAllUnchaged();
+ }
+
+ public function testRecipientRenameInShare() {
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
+ Filesystem::rename('/sub1/sub2/folder/file.txt', '/sub1/sub2/folder/renamed.txt');
+ $this->assertEtagsNotChanged([self::TEST_FILES_SHARING_API_USER4]);
+ $this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER3]);
+
+ $this->assertAllUnchaged();
+ }
+
+ public function testRecipientRenameInReShare() {
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
+ Filesystem::rename('/sub1/sub2/folder/inside/file.txt', '/sub1/sub2/folder/inside/renamed.txt');
+ $this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
+
+ $this->assertAllUnchaged();
+ }
+
+ public function testRecipientRenameResharedFolder() {
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
+ Filesystem::rename('/directReshare', '/sub1/directReshare');
+ $this->assertEtagsNotChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
+ $this->assertEtagsChanged([self::TEST_FILES_SHARING_API_USER2]);
+
+ $this->assertEtagsChanged([self::TEST_FILES_SHARING_API_USER2], 'sub1');
+
+ $this->assertAllUnchaged();
+ }
+
+ public function testRecipientDeleteInShare() {
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
+ Filesystem::unlink('/sub1/sub2/folder/file.txt');
+ $this->assertEtagsNotChanged([self::TEST_FILES_SHARING_API_USER4]);
+ $this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER3]);
+
+ $this->assertAllUnchaged();
+ }
+
+ public function testRecipientDeleteInReShare() {
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER2);
+ Filesystem::unlink('/sub1/sub2/folder/inside/file.txt');
+ $this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
+
+ $this->assertAllUnchaged();
+ }
+
+ public function testReshareRecipientWritesToReshare() {
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER4);
+ Filesystem::file_put_contents('/sub1/sub2/inside/asd.txt', 'bar');
+ $this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
+
+ $this->assertAllUnchaged();
+ }
+
+ public function testReshareRecipientRenameInReShare() {
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER4);
+ Filesystem::rename('/sub1/sub2/inside/file.txt', '/sub1/sub2/inside/renamed.txt');
+ $this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
+
+ $this->assertAllUnchaged();
+ }
+
+ public function testReshareRecipientDeleteInReShare() {
+ $this->loginAsUser(self::TEST_FILES_SHARING_API_USER4);
+ Filesystem::unlink('/sub1/sub2/inside/file.txt');
+ $this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2,
+ self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER4]);
+
+ $this->assertAllUnchaged();
+ }
+}
diff --git a/apps/files_sharing/tests/permissions.php b/apps/files_sharing/tests/permissions.php
index 92703f4a905..91f0347163a 100644
--- a/apps/files_sharing/tests/permissions.php
+++ b/apps/files_sharing/tests/permissions.php
@@ -103,7 +103,9 @@ class Test_Files_Sharing_Permissions extends OCA\Files_sharing\Tests\TestCase {
}
protected function tearDown() {
- $this->sharedCache->clear();
+ if ($this->sharedCache) {
+ $this->sharedCache->clear();
+ }
self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
diff --git a/apps/files_sharing/tests/sharedstorage.php b/apps/files_sharing/tests/sharedstorage.php
index a1469a74687..7c28d0431e1 100644
--- a/apps/files_sharing/tests/sharedstorage.php
+++ b/apps/files_sharing/tests/sharedstorage.php
@@ -368,7 +368,10 @@ class Test_Files_Sharing_Storage extends OCA\Files_sharing\Tests\TestCase {
self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
$this->assertTrue($rootView->file_exists('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/' . $this->folder));
- OC_Hook::emit('OC_Filesystem', 'setup', array('user' => self::TEST_FILES_SHARING_API_USER3, 'user_dir' => \OC_User::getHome(self::TEST_FILES_SHARING_API_USER3)));
+
+ $mountConfigManager = \OC::$server->getMountProviderCollection();
+ $mounts = $mountConfigManager->getMountsForUser(\OC::$server->getUserManager()->get(self::TEST_FILES_SHARING_API_USER3));
+ array_walk($mounts, array(\OC\Files\Filesystem::getMountManager(), 'addMount'));
$this->assertTrue($rootView->file_exists('/' . self::TEST_FILES_SHARING_API_USER3 . '/files/' . $this->filename));
diff --git a/apps/files_sharing/tests/propagation.php b/apps/files_sharing/tests/sizepropagation.php
index 546f67556f2..4ab3475ccfc 100644
--- a/apps/files_sharing/tests/propagation.php
+++ b/apps/files_sharing/tests/sizepropagation.php
@@ -19,11 +19,11 @@
*
*/
-namespace OCA\Files_Sharing\Tests;
+namespace OCA\Files_sharing\Tests;
use OC\Files\View;
-class Propagation extends TestCase {
+class SizePropagation extends TestCase {
public function testSizePropagationWhenOwnerChangesFile() {
$this->loginHelper(self::TEST_FILES_SHARING_API_USER1);
diff --git a/apps/files_sharing/tests/testcase.php b/apps/files_sharing/tests/testcase.php
index b9f8658a69e..b9e9f077201 100644
--- a/apps/files_sharing/tests/testcase.php
+++ b/apps/files_sharing/tests/testcase.php
@@ -31,6 +31,7 @@ namespace OCA\Files_Sharing\Tests;
use OC\Files\Filesystem;
use OCA\Files\Share;
+use OCA\Files_Sharing\Appinfo\Application;
/**
* Class Test_Files_Sharing_Base
@@ -42,6 +43,7 @@ abstract class TestCase extends \Test\TestCase {
const TEST_FILES_SHARING_API_USER1 = "test-share-user1";
const TEST_FILES_SHARING_API_USER2 = "test-share-user2";
const TEST_FILES_SHARING_API_USER3 = "test-share-user3";
+ const TEST_FILES_SHARING_API_USER4 = "test-share-user4";
const TEST_FILES_SHARING_API_GROUP1 = "test-share-group1";
@@ -57,6 +59,10 @@ abstract class TestCase extends \Test\TestCase {
public static function setUpBeforeClass() {
parent::setUpBeforeClass();
+ $application = new Application();
+ $application->registerMountProviders();
+ $application->setupPropagation();
+
// reset backend
\OC_User::clearBackends();
\OC_Group::clearBackends();
@@ -64,7 +70,6 @@ abstract class TestCase extends \Test\TestCase {
// clear share hooks
\OC_Hook::clear('OCP\\Share');
\OC::registerShareHooks();
- \OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup');
// create users
$backend = new \OC_User_Dummy();
@@ -72,6 +77,7 @@ abstract class TestCase extends \Test\TestCase {
$backend->createUser(self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER1);
$backend->createUser(self::TEST_FILES_SHARING_API_USER2, self::TEST_FILES_SHARING_API_USER2);
$backend->createUser(self::TEST_FILES_SHARING_API_USER3, self::TEST_FILES_SHARING_API_USER3);
+ $backend->createUser(self::TEST_FILES_SHARING_API_USER4, self::TEST_FILES_SHARING_API_USER4);
// create group
$groupBackend = new \OC_Group_Dummy();
@@ -147,6 +153,7 @@ abstract class TestCase extends \Test\TestCase {
\OC::$server->getUserSession()->setUser(null);
\OC\Files\Filesystem::tearDown();
\OC::$server->getUserSession()->login($user, $password);
+
\OC_Util::setupFS($user);
}
diff --git a/apps/files_sharing/tests/watcher.php b/apps/files_sharing/tests/watcher.php
index a2e440069a4..4af5de6aaae 100644
--- a/apps/files_sharing/tests/watcher.php
+++ b/apps/files_sharing/tests/watcher.php
@@ -76,7 +76,9 @@ class Test_Files_Sharing_Watcher extends OCA\Files_sharing\Tests\TestCase {
}
protected function tearDown() {
- $this->sharedCache->clear();
+ if ($this->sharedCache) {
+ $this->sharedCache->clear();
+ }
self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
diff --git a/apps/files_trashbin/tests/trashbin.php b/apps/files_trashbin/tests/trashbin.php
index bf6446389f1..a2e1a9addf6 100644
--- a/apps/files_trashbin/tests/trashbin.php
+++ b/apps/files_trashbin/tests/trashbin.php
@@ -54,7 +54,9 @@ class Test_Trashbin extends \Test\TestCase {
// clear share hooks
\OC_Hook::clear('OCP\\Share');
\OC::registerShareHooks();
- \OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup');
+ $application = new \OCA\Files_Sharing\AppInfo\Application();
+ $application->registerMountProviders();
+ $application->setupPropagation();
//disable encryption
\OC_App::disable('files_encryption');
diff --git a/apps/files_versions/tests/versions.php b/apps/files_versions/tests/versions.php
index f8bfe38df4d..ff088ffdad3 100644
--- a/apps/files_versions/tests/versions.php
+++ b/apps/files_versions/tests/versions.php
@@ -47,7 +47,9 @@ class Test_Files_Versioning extends \Test\TestCase {
\OC_Hook::clear('OCP\\Share');
\OC::registerShareHooks();
\OCA\Files_Versions\Hooks::connectHooks();
- \OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup');
+ $application = new \OCA\Files_Sharing\AppInfo\Application();
+ $application->registerMountProviders();
+ $application->setupPropagation();
// create test user
self::loginHelper(self::TEST_VERSIONS_USER2, true);
diff --git a/apps/user_ldap/ajax/getNewServerConfigPrefix.php b/apps/user_ldap/ajax/getNewServerConfigPrefix.php
index d0135917886..aa97b181846 100644
--- a/apps/user_ldap/ajax/getNewServerConfigPrefix.php
+++ b/apps/user_ldap/ajax/getNewServerConfigPrefix.php
@@ -35,14 +35,14 @@ $nk = 's'.str_pad($ln+1, 2, '0', STR_PAD_LEFT);
$resultData = array('configPrefix' => $nk);
+$newConfig = new \OCA\user_ldap\lib\Configuration($nk, false);
if(isset($_POST['copyConfig'])) {
$originalConfig = new \OCA\user_ldap\lib\Configuration($_POST['copyConfig']);
- $newConfig = new \OCA\user_ldap\lib\Configuration($nk, false);
$newConfig->setConfiguration($originalConfig->getConfiguration());
- $newConfig->saveConfiguration();
} else {
$configuration = new \OCA\user_ldap\lib\Configuration($nk, false);
$resultData['defaults'] = $configuration->getDefaults();
}
+$newConfig->saveConfiguration();
OCP\JSON::success($resultData);
diff --git a/apps/user_ldap/js/wizard/wizardTabElementary.js b/apps/user_ldap/js/wizard/wizardTabElementary.js
index c7767b9cf66..9619f9f4c84 100644
--- a/apps/user_ldap/js/wizard/wizardTabElementary.js
+++ b/apps/user_ldap/js/wizard/wizardTabElementary.js
@@ -14,6 +14,9 @@ OCA = OCA || {};
* in the LDAP wizard.
*/
var WizardTabElementary = OCA.LDAP.Wizard.WizardTabGeneric.subClass({
+ /** @property {number} */
+ _configChooserNextServerNumber: 1,
+
/**
* initializes the instance. Always call it after initialization.
*
@@ -24,7 +27,7 @@ OCA = OCA || {};
tabIndex = 0;
this._super(tabIndex, tabID);
this.isActive = true;
- this.configChooserID = '#ldap_serverconfig_chooser';
+ this.$configChooser = $('#ldap_serverconfig_chooser');
var items = {
ldap_host: {
@@ -88,7 +91,7 @@ OCA = OCA || {};
* @returns {string}
*/
getConfigID: function() {
- return $(this.configChooserID).val();
+ return this.$configChooser.val();
},
/**
@@ -204,9 +207,17 @@ OCA = OCA || {};
*/
onNewConfiguration: function(view, result) {
if(result.isSuccess === true) {
- $(view.configChooserID + ' option:selected').removeAttr('selected');
- var html = '<option value="'+result.configPrefix+'" selected="selected">'+t('user_ldap','{nthServer}. Server', {nthServer: $(view.configChooserID + ' option').length + 1})+'</option>';
- $(view.configChooserID + ' option:last').after(html);
+ console.log('new config');
+ var nthServer = view._configChooserNextServerNumber;
+ view.$configChooser.find('option:selected').removeAttr('selected');
+ var html = '<option value="'+result.configPrefix+'" selected="selected">'+t('user_ldap','{nthServer}. Server', {nthServer: nthServer})+'</option>';
+ if(view.$configChooser.find('option:last').length > 0) {
+ view.$configChooser.find('option:last').after(html);
+ } else {
+ view.$configChooser.html(html);
+ }
+
+ view._configChooserNextServerNumber++;
}
},
@@ -222,16 +233,16 @@ OCA = OCA || {};
if(view.getConfigID() === result.configPrefix) {
// if the deleted value is still the selected one (99% of
// the cases), remove it from the list and load the topmost
- $(view.configChooserID + ' option:selected').remove();
- $(view.configChooserID + ' option:first').select();
- if($(view.configChooserID + ' option').length < 2) {
+ view.$configChooser.find('option:selected').remove();
+ view.$configChooser.find('option:first').select();
+ if(view.$configChooser.find(' option').length < 1) {
view.configModel.newConfig(false);
} else {
view.configModel.load(view.getConfigID());
}
} else {
// otherwise just remove the entry
- $(view.configChooserID + ' option[value=' + result.configPrefix + ']').remove();
+ view.$configChooser.find('option[value=' + result.configPrefix + ']').remove();
}
} else {
OC.Notification.showTemporary(result.errorMessage);
@@ -303,9 +314,10 @@ OCA = OCA || {};
* @private
*/
_enableConfigChooser: function() {
+ this._configChooserNextServerNumber = this.$configChooser.find(' option').length + 1;
var view = this;
- $(this.configChooserID).change(function(){
- var value = $(view.configChooserID + ' option:selected:first').attr('value');
+ this.$configChooser.change(function(){
+ var value = view.$configChooser.find(' option:selected:first').attr('value');
view.configModel.load(value);
});
},
diff --git a/autotest-external.sh b/autotest-external.sh
index c4d5ffb181f..6ebe093c8a7 100755
--- a/autotest-external.sh
+++ b/autotest-external.sh
@@ -32,6 +32,11 @@ if ! [ -x "$PHPUNIT" ]; then
exit 3
fi
+if ! which replace > /dev/null 2>&1; then
+ echo "The command 'replace' is not available on this system. Please install it first." >&2
+ exit 5
+fi
+
PHPUNIT_VERSION=$("$PHPUNIT" --version | cut -d" " -f2)
PHPUNIT_MAJOR_VERSION=$(echo $PHPUNIT_VERSION | cut -d"." -f1)
PHPUNIT_MINOR_VERSION=$(echo $PHPUNIT_VERSION | cut -d"." -f2)
diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php
index 100aba13668..8ff5577629d 100644
--- a/lib/private/connector/sabre/file.php
+++ b/lib/private/connector/sabre/file.php
@@ -181,6 +181,7 @@ class File extends Node implements IFile {
$view = \OC\Files\Filesystem::getView();
if ($view) {
$hookPath = $view->getRelativePath($this->fileView->getAbsolutePath($this->path));
+ $this->fileView->getUpdater()->propagate($hookPath);
if (!$exists) {
\OC_Hook::emit(\OC\Files\Filesystem::CLASSNAME, \OC\Files\Filesystem::signal_post_create, array(
\OC\Files\Filesystem::signal_param_path => $hookPath
diff --git a/lib/private/files/cache/changepropagator.php b/lib/private/files/cache/changepropagator.php
index 4a860631ae0..9696a82257e 100644
--- a/lib/private/files/cache/changepropagator.php
+++ b/lib/private/files/cache/changepropagator.php
@@ -22,12 +22,14 @@
namespace OC\Files\Cache;
+use OC\Hooks\BasicEmitter;
+
/**
* Propagates changes in etag and mtime up the filesystem tree
*
* @package OC\Files\Cache
*/
-class ChangePropagator {
+class ChangePropagator extends BasicEmitter {
/**
* @var string[]
*/
@@ -75,6 +77,7 @@ class ChangePropagator {
$cache = $storage->getCache();
$entry = $cache->get($internalPath);
$cache->update($entry['fileid'], array('mtime' => max($time, $entry['mtime']), 'etag' => $storage->getETag($internalPath)));
+ $this->emit('\OC\Files', 'propagate', [$parent, $entry]);
}
}
}
diff --git a/lib/private/files/cache/updater.php b/lib/private/files/cache/updater.php
index 14aecf01220..66345350168 100644
--- a/lib/private/files/cache/updater.php
+++ b/lib/private/files/cache/updater.php
@@ -60,6 +60,10 @@ class Updater {
$this->enabled = true;
}
+ public function getPropagator() {
+ return $this->propagator;
+ }
+
public function propagate($path, $time = null) {
if (Scanner::isPartialFile($path)) {
return;
diff --git a/lib/private/files/view.php b/lib/private/files/view.php
index 162bf568de7..63af2b616cf 100644
--- a/lib/private/files/view.php
+++ b/lib/private/files/view.php
@@ -658,6 +658,10 @@ class View {
} elseif ($result) {
if ($internalPath1 !== '') { // dont do a cache update for moved mounts
$this->updater->rename($path1, $path2);
+ } else { // only do etag propagation
+ $this->getUpdater()->getPropagator()->addChange($path1);
+ $this->getUpdater()->getPropagator()->addChange($path2);
+ $this->getUpdater()->getPropagator()->propagateChanges();
}
if ($this->shouldEmitHooks($path1) and $this->shouldEmitHooks($path2)) {
\OC_Hook::emit(
diff --git a/lib/private/helper.php b/lib/private/helper.php
index 35c5147e2fa..144ccbfe228 100644
--- a/lib/private/helper.php
+++ b/lib/private/helper.php
@@ -129,9 +129,7 @@ class OC_Helper {
/**
* Creates an url using a defined route
* @param string $route
- * @param array $parameters
- * @return
- * @internal param array $args with param=>value, will be appended to the returned url
+ * @param array $parameters with param=>value, will be appended to the returned url
* @return string the url
* @deprecated Use \OC::$server->getURLGenerator()->linkToRoute($route, $parameters)
*
@@ -694,6 +692,7 @@ class OC_Helper {
$match_length = strlen($matches[0][$last_match][0]);
} else {
$counter = 2;
+ $match_length = 0;
$offset = false;
}
do {
@@ -876,7 +875,7 @@ class OC_Helper {
/**
* Calculate PHP upload limit
*
- * @return PHP upload file size limit
+ * @return int PHP upload file size limit
*/
public static function uploadLimit() {
$upload_max_filesize = OCP\Util::computerFileSize(ini_get('upload_max_filesize'));
@@ -954,6 +953,7 @@ class OC_Helper {
* @param string $path
* @param \OCP\Files\FileInfo $rootInfo (optional)
* @return array
+ * @throws \OCP\Files\NotFoundException
*/
public static function getStorageInfo($path, $rootInfo = null) {
// return storage info without adding mount points
@@ -984,6 +984,7 @@ class OC_Helper {
// TODO: need a better way to get total space from storage
if ($storage->instanceOfStorage('\OC\Files\Storage\Wrapper\Quota')) {
+ /** @var \OC\Files\Storage\Wrapper\Quota $storage */
$quota = $storage->getQuota();
}
$free = $storage->free_space('');
diff --git a/lib/private/server.php b/lib/private/server.php
index 8fdeec5281c..7fa668b222e 100644
--- a/lib/private/server.php
+++ b/lib/private/server.php
@@ -492,7 +492,7 @@ class Server extends SimpleContainer implements IServerContainer {
/**
* Returns the root folder of ownCloud's data directory
*
- * @return \OCP\Files\Folder
+ * @return \OCP\Files\IRootFolder
*/
public function getRootFolder() {
return $this->query('RootFolder');
diff --git a/lib/private/share/share.php b/lib/private/share/share.php
index 227a3d5a411..617eeeb9d90 100644
--- a/lib/private/share/share.php
+++ b/lib/private/share/share.php
@@ -48,7 +48,7 @@ use OCP\IConfig;
* It provides the following hooks:
* - post_shared
*/
-class Share extends \OC\Share\Constants {
+class Share extends Constants {
/** CRUDS permissions (Create, Read, Update, Delete, Share) using a bitmask
* Construct permissions for share() and setPermissions with Or (|) e.g.
@@ -441,6 +441,7 @@ class Share extends \OC\Share\Constants {
/**
* Based on the given token the share information will be returned - password protected shares will be verified
* @param string $token
+ * @param bool $checkPasswordProtection
* @return array|boolean false will be returned in case the token is unknown or unauthorized
*/
public static function getShareByToken($token, $checkPasswordProtection = true) {
@@ -981,6 +982,7 @@ class Share extends \OC\Share\Constants {
* @param string $shareWith User or group the item is being shared with
* @param int $permissions CRUDS permissions
* @return boolean true on success or false on failure
+ * @throws \Exception when trying to grant more permissions then the user has himself
*/
public static function setPermissions($itemType, $itemSource, $shareType, $shareWith, $permissions) {
$l = \OC::$server->getL10N('lib');
@@ -1069,8 +1071,8 @@ class Share extends \OC\Share\Constants {
* @param string $shareTime timestamp when the file was shared
* @param string $itemType
* @param string $itemSource
- * @return DateTime validated date
- * @throws \Exception
+ * @return \DateTime validated date
+ * @throws \Exception when the expire date is in the past or further in the future then the enforced date
*/
private static function validateExpireDate($expireDate, $shareTime, $itemType, $itemSource) {
$l = \OC::$server->getL10N('lib');
@@ -1116,8 +1118,8 @@ class Share extends \OC\Share\Constants {
* @param string $itemSource
* @param string $date expiration date
* @param int $shareTime timestamp from when the file was shared
- * @throws \Exception
* @return boolean
+ * @throws \Exception when the expire date is not set, in the past or further in the future then the enforced date
*/
public static function setExpirationDate($itemType, $itemSource, $date, $shareTime = null) {
$user = \OC_User::getUser();
@@ -1266,7 +1268,7 @@ class Share extends \OC\Share\Constants {
/**
* Unshares a share given a share data array
* @param array $item Share data (usually database row)
- * @param int new parent ID
+ * @param int $newParent parent ID
* @return null
*/
protected static function unshareItem(array $item, $newParent = null) {
@@ -2176,8 +2178,8 @@ class Share extends \OC\Share\Constants {
* @param array $shareData
* @return mixed false in case of a failure or the id of the new share
*/
- private static function insertShare(array $shareData)
- {
+ private static function insertShare(array $shareData) {
+
$query = \OC_DB::prepare('INSERT INTO `*PREFIX*share` ('
.' `item_type`, `item_source`, `item_target`, `share_type`,'
.' `share_with`, `uid_owner`, `permissions`, `stime`, `file_source`,'
@@ -2220,6 +2222,7 @@ class Share extends \OC\Share\Constants {
return $id;
}
+
/**
* Delete all shares with type SHARE_TYPE_LINK
*/
@@ -2450,7 +2453,7 @@ class Share extends \OC\Share\Constants {
/**
* send server-to-server unshare to remote server
*
- * @param string remote url
+ * @param string $remote url
* @param int $id share id
* @param string $token
* @return bool
@@ -2473,16 +2476,25 @@ class Share extends \OC\Share\Constants {
return ($value === 'yes') ? true : false;
}
+ /**
+ * @return bool
+ */
public static function isDefaultExpireDateEnabled() {
$defaultExpireDateEnabled = \OCP\Config::getAppValue('core', 'shareapi_default_expire_date', 'no');
return ($defaultExpireDateEnabled === "yes") ? true : false;
}
+ /**
+ * @return bool
+ */
public static function enforceDefaultExpireDate() {
$enforceDefaultExpireDate = \OCP\Config::getAppValue('core', 'shareapi_enforce_expire_date', 'no');
return ($enforceDefaultExpireDate === "yes") ? true : false;
}
+ /**
+ * @return int
+ */
public static function getExpireInterval() {
return (int)\OCP\Config::getAppValue('core', 'shareapi_expire_after_n_days', '7');
}
@@ -2518,4 +2530,28 @@ class Share extends \OC\Share\Constants {
$enforcePassword = $config->getAppValue('core', 'shareapi_enforce_links_password', 'no');
return ($enforcePassword === "yes") ? true : false;
}
+
+ /**
+ * Get all share entries, including non-unique group items
+ *
+ * @param string $owner
+ * @return array
+ */
+ public static function getAllSharesForOwner($owner) {
+ $query = 'SELECT * FROM `*PREFIX*share` WHERE `uid_owner` = ?';
+ $result = \OC::$server->getDatabaseConnection()->executeQuery($query, [$owner]);
+ return $result->fetchAll();
+ }
+
+ /**
+ * Get all share entries, including non-unique group items for a file
+ *
+ * @param int $id
+ * @return array
+ */
+ public static function getAllSharesForFileId($id) {
+ $query = 'SELECT * FROM `*PREFIX*share` WHERE `file_source` = ?';
+ $result = \OC::$server->getDatabaseConnection()->executeQuery($query, [$id]);
+ return $result->fetchAll();
+ }
}
diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php
index 428c91429ef..5dd545aed37 100644
--- a/lib/public/iservercontainer.php
+++ b/lib/public/iservercontainer.php
@@ -87,7 +87,7 @@ interface IServerContainer {
/**
* Returns the root folder of ownCloud's data directory
*
- * @return \OCP\Files\Folder
+ * @return \OCP\Files\IRootFolder
* @since 6.0.0
*/
public function getRootFolder();
diff --git a/lib/public/share.php b/lib/public/share.php
index a96239a5c31..6c8b82f4293 100644
--- a/lib/public/share.php
+++ b/lib/public/share.php
@@ -170,7 +170,7 @@ class Share extends \OC\Share\Constants {
* @param string $itemType
* @param string $itemSource
* @param string $uidOwner Owner of link
- * @return Item
+ * @return array
* @since 5.0.0
*/
public static function getItemSharedWithByLink($itemType, $itemSource, $uidOwner) {
@@ -180,6 +180,7 @@ class Share extends \OC\Share\Constants {
/**
* Based on the given token the share information will be returned - password protected shares will be verified
* @param string $token
+ * @param bool $checkPasswordProtection
* @return array|bool false will be returned in case the token is unknown or unauthorized
* @since 5.0.0 - parameter $checkPasswordProtection was added in 7.0.0
*/
@@ -289,7 +290,8 @@ class Share extends \OC\Share\Constants {
/**
* Unshare an item shared with the current user
* @param string $itemType
- * @param string $itemTarget
+ * @param string $itemOrigin Item target or source
+ * @param boolean $originIsSource true if $itemOrigin is the source, false if $itemOrigin is the target (optional)
* @return boolean true on success or false on failure
*
* Unsharing from self is not allowed for items inside collections
diff --git a/settings/l10n/fr.js b/settings/l10n/fr.js
index 2fc62f9a1aa..be037890bfd 100644
--- a/settings/l10n/fr.js
+++ b/settings/l10n/fr.js
@@ -107,6 +107,8 @@ OC.L10N.register(
"NT LAN Manager" : "Gestionnaire du réseau NT",
"SSL" : "SSL",
"TLS" : "TLS",
+ "php does not seem to be setup properly to query system environment variables. The test with getenv(\"PATH\") only returns an empty response." : "php ne semble pas être configuré de manière à récupérer les valeurs des variables d’environnement. Le test de la commande getenv(\"PATH\") retourne seulement une réponse vide. ",
+ "Please check the installation documentation for php configuration notes and the php configuration of your server, especially when using php-fpm." : "Veuillez verifier la documentation d'installation concernant les instructions de configuration de php ainsi que la configuration de votre serveur, en particulier dans le cas où vous utilisez php-fpm.",
"The Read-Only config has been enabled. This prevents setting some configurations via the web-interface. Furthermore, the file needs to be made writable manually for every update." : "La configuration est en mode lecture seule. Ceci empêche la modification de certaines configurations via l'interface web. De plus, le fichier doit être passé manuellement en lecture-écriture pour chaque mise à jour.",
"PHP is apparently setup to strip inline doc blocks. This will make several core apps inaccessible." : "PHP est apparemment configuré pour supprimer les blocs de documentation internes. Cela rendra plusieurs applications de base inaccessibles.",
"This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "La raison est probablement l'utilisation d'un cache / accélérateur tel que Zend OPcache ou eAccelerator.",
diff --git a/settings/l10n/fr.json b/settings/l10n/fr.json
index 35b946756cc..c0c2a1ba6b3 100644
--- a/settings/l10n/fr.json
+++ b/settings/l10n/fr.json
@@ -105,6 +105,8 @@
"NT LAN Manager" : "Gestionnaire du réseau NT",
"SSL" : "SSL",
"TLS" : "TLS",
+ "php does not seem to be setup properly to query system environment variables. The test with getenv(\"PATH\") only returns an empty response." : "php ne semble pas être configuré de manière à récupérer les valeurs des variables d’environnement. Le test de la commande getenv(\"PATH\") retourne seulement une réponse vide. ",
+ "Please check the installation documentation for php configuration notes and the php configuration of your server, especially when using php-fpm." : "Veuillez verifier la documentation d'installation concernant les instructions de configuration de php ainsi que la configuration de votre serveur, en particulier dans le cas où vous utilisez php-fpm.",
"The Read-Only config has been enabled. This prevents setting some configurations via the web-interface. Furthermore, the file needs to be made writable manually for every update." : "La configuration est en mode lecture seule. Ceci empêche la modification de certaines configurations via l'interface web. De plus, le fichier doit être passé manuellement en lecture-écriture pour chaque mise à jour.",
"PHP is apparently setup to strip inline doc blocks. This will make several core apps inaccessible." : "PHP est apparemment configuré pour supprimer les blocs de documentation internes. Cela rendra plusieurs applications de base inaccessibles.",
"This is probably caused by a cache/accelerator such as Zend OPcache or eAccelerator." : "La raison est probablement l'utilisation d'un cache / accélérateur tel que Zend OPcache ou eAccelerator.",
diff --git a/settings/l10n/gl.js b/settings/l10n/gl.js
index 6387f387e2b..be7d809e120 100644
--- a/settings/l10n/gl.js
+++ b/settings/l10n/gl.js
@@ -107,7 +107,7 @@ OC.L10N.register(
"NT LAN Manager" : "Xestor NT LAN",
"SSL" : "SSL",
"TLS" : "TLS",
- "php does not seem to be setup properly to query system environment variables. The test with getenv(\"PATH\") only returns an empty response." : "Semella que PHP non está correctamente para consultar as variábeis de entorno do sistema. A proba con getenv(\"PATH\") só devolve unha resposta baleira.",
+ "php does not seem to be setup properly to query system environment variables. The test with getenv(\"PATH\") only returns an empty response." : "Semella que PHP non está configurado correctamente para consultar as variábeis de entorno do sistema. A proba con getenv(\"PATH\") só devolve unha resposta baleira.",
"Please check the installation documentation for php configuration notes and the php configuration of your server, especially when using php-fpm." : "Consulte a documentación de instalación para ver as notas de configuración de PHP e a configuración PHP do servidor, especialmente se emprega php-fpm.",
"The Read-Only config has been enabled. This prevents setting some configurations via the web-interface. Furthermore, the file needs to be made writable manually for every update." : "Foi activada a restrición da configuración a só lectura. Isto impide o estabelecemento dalgunhas configuracións a través da interface web. Ademais, ten que facer escribíbel manualmente o ficheiro para cada actualización.",
"PHP is apparently setup to strip inline doc blocks. This will make several core apps inaccessible." : "Parece que PHP foi configuración para substituír bloques de documentos en liña. Isto fará que varias aplicacións sexan inaccesíbeis.",
diff --git a/settings/l10n/gl.json b/settings/l10n/gl.json
index f44f40f8a49..bea734309f9 100644
--- a/settings/l10n/gl.json
+++ b/settings/l10n/gl.json
@@ -105,7 +105,7 @@
"NT LAN Manager" : "Xestor NT LAN",
"SSL" : "SSL",
"TLS" : "TLS",
- "php does not seem to be setup properly to query system environment variables. The test with getenv(\"PATH\") only returns an empty response." : "Semella que PHP non está correctamente para consultar as variábeis de entorno do sistema. A proba con getenv(\"PATH\") só devolve unha resposta baleira.",
+ "php does not seem to be setup properly to query system environment variables. The test with getenv(\"PATH\") only returns an empty response." : "Semella que PHP non está configurado correctamente para consultar as variábeis de entorno do sistema. A proba con getenv(\"PATH\") só devolve unha resposta baleira.",
"Please check the installation documentation for php configuration notes and the php configuration of your server, especially when using php-fpm." : "Consulte a documentación de instalación para ver as notas de configuración de PHP e a configuración PHP do servidor, especialmente se emprega php-fpm.",
"The Read-Only config has been enabled. This prevents setting some configurations via the web-interface. Furthermore, the file needs to be made writable manually for every update." : "Foi activada a restrición da configuración a só lectura. Isto impide o estabelecemento dalgunhas configuracións a través da interface web. Ademais, ten que facer escribíbel manualmente o ficheiro para cada actualización.",
"PHP is apparently setup to strip inline doc blocks. This will make several core apps inaccessible." : "Parece que PHP foi configuración para substituír bloques de documentos en liña. Isto fará que varias aplicacións sexan inaccesíbeis.",
diff --git a/tests/lib/connector/sabre/file.php b/tests/lib/connector/sabre/file.php
index 3fe5c2751f1..ee9c20fd9cb 100644
--- a/tests/lib/connector/sabre/file.php
+++ b/tests/lib/connector/sabre/file.php
@@ -52,7 +52,6 @@ class File extends \Test\TestCase {
$view = $this->getMock('\OC\Files\View', array('file_put_contents', 'getRelativePath', 'resolvePath'), array());
$view->expects($this->any())
->method('resolvePath')
- ->with('')
->will($this->returnValue(array($storage, '')));
$view->expects($this->any())
->method('getRelativePath')
diff --git a/tests/lib/files/etagtest.php b/tests/lib/files/etagtest.php
index 055927652bc..c3d364d6800 100644
--- a/tests/lib/files/etagtest.php
+++ b/tests/lib/files/etagtest.php
@@ -25,7 +25,9 @@ class EtagTest extends \Test\TestCase {
parent::setUp();
\OC_Hook::clear('OC_Filesystem', 'setup');
- \OCP\Util::connectHook('OC_Filesystem', 'setup', '\OC\Files\Storage\Shared', 'setup');
+ $application = new \OCA\Files_Sharing\AppInfo\Application();
+ $application->registerMountProviders();
+ $application->setupPropagation();
\OCP\Share::registerBackend('file', 'OC_Share_Backend_File');
\OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file');