summaryrefslogtreecommitdiffstats
path: root/apps/files_sharing
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files_sharing')
-rw-r--r--apps/files_sharing/api/local.php43
-rw-r--r--apps/files_sharing/appinfo/app.php4
-rw-r--r--apps/files_sharing/js/settings-admin.js1
-rw-r--r--apps/files_sharing/lib/deleteorphanedsharesjob.php59
-rw-r--r--apps/files_sharing/lib/helper.php1
-rw-r--r--apps/files_sharing/lib/updater.php35
-rw-r--r--apps/files_sharing/templates/settings-admin.php3
-rw-r--r--apps/files_sharing/tests/deleteorphanedsharesjobtest.php162
8 files changed, 238 insertions, 70 deletions
diff --git a/apps/files_sharing/api/local.php b/apps/files_sharing/api/local.php
index 571982d153b..1a5edbfd070 100644
--- a/apps/files_sharing/api/local.php
+++ b/apps/files_sharing/api/local.php
@@ -343,7 +343,7 @@ class Local {
if(isset($params['_put']['permissions'])) {
return self::updatePermissions($share, $params);
} elseif (isset($params['_put']['password'])) {
- return self::updatePassword($share, $params);
+ return self::updatePassword($params['id'], (int)$share['share_type'], $params['_put']['password']);
} elseif (isset($params['_put']['publicUpload'])) {
return self::updatePublicUpload($share, $params);
} elseif (isset($params['_put']['expireDate'])) {
@@ -457,47 +457,22 @@ class Local {
/**
* update password for public link share
- * @param array $share information about the share
- * @param array $params 'password'
+ * @param int $shareId
+ * @param int $shareType
+ * @param string $password
* @return \OC_OCS_Result
*/
- private static function updatePassword($share, $params) {
-
- $itemSource = $share['item_source'];
- $itemType = $share['item_type'];
-
- if( (int)$share['share_type'] !== \OCP\Share::SHARE_TYPE_LINK) {
+ private static function updatePassword($shareId, $shareType, $password) {
+ if($shareType !== \OCP\Share::SHARE_TYPE_LINK) {
return new \OC_OCS_Result(null, 400, "password protection is only supported for public shares");
}
- $shareWith = isset($params['_put']['password']) ? $params['_put']['password'] : null;
-
- if($shareWith === '') {
- $shareWith = null;
- }
-
- $items = \OCP\Share::getItemShared($itemType, $itemSource);
-
- $checkExists = false;
- foreach ($items as $item) {
- if($item['share_type'] === \OCP\Share::SHARE_TYPE_LINK) {
- $checkExists = true;
- $permissions = $item['permissions'];
- }
- }
-
- if (!$checkExists) {
- return new \OC_OCS_Result(null, 404, "share doesn't exists, can't change password");
+ if($password === '') {
+ $password = null;
}
try {
- $result = \OCP\Share::shareItem(
- $itemType,
- $itemSource,
- \OCP\Share::SHARE_TYPE_LINK,
- $shareWith,
- $permissions
- );
+ $result = \OCP\Share::setPassword($shareId, $password);
} catch (\Exception $e) {
return new \OC_OCS_Result(null, 403, $e->getMessage());
}
diff --git a/apps/files_sharing/appinfo/app.php b/apps/files_sharing/appinfo/app.php
index a222973fc34..d009fbca3b9 100644
--- a/apps/files_sharing/appinfo/app.php
+++ b/apps/files_sharing/appinfo/app.php
@@ -51,6 +51,10 @@ OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file');
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
+\OC::$server->getJobList()->add('OCA\Files_sharing\Lib\DeleteOrphanedSharesJob');
+
\OC::$server->getActivityManager()->registerExtension(function() {
return new \OCA\Files_Sharing\Activity(
\OC::$server->query('L10NFactory'),
diff --git a/apps/files_sharing/js/settings-admin.js b/apps/files_sharing/js/settings-admin.js
index 257c864b04f..95578bff548 100644
--- a/apps/files_sharing/js/settings-admin.js
+++ b/apps/files_sharing/js/settings-admin.js
@@ -8,4 +8,5 @@ $(document).ready(function() {
OC.AppConfig.setValue('files_sharing', $(this).attr('name'), value);
});
+ $('.section .icon-info').tipsy({gravity: 'w'});
});
diff --git a/apps/files_sharing/lib/deleteorphanedsharesjob.php b/apps/files_sharing/lib/deleteorphanedsharesjob.php
new file mode 100644
index 00000000000..f39078b778f
--- /dev/null
+++ b/apps/files_sharing/lib/deleteorphanedsharesjob.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @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\Lib;
+
+use Doctrine\DBAL\Platforms\SqlitePlatform;
+use OCP\IDBConnection;
+use OC\BackgroundJob\TimedJob;
+
+/**
+ * Delete all share entries that have no matching entries in the file cache table.
+ */
+class DeleteOrphanedSharesJob extends TimedJob {
+
+ /**
+ * Default interval in minutes
+ *
+ * @var int $defaultIntervalMin
+ **/
+ protected $defaultIntervalMin = 15;
+
+ /**
+ * Makes the background job do its work
+ *
+ * @param array $argument unused argument
+ */
+ public function run($argument) {
+ $connection = \OC::$server->getDatabaseConnection();
+ $logger = \OC::$server->getLogger();
+
+ $sql =
+ 'DELETE FROM `*PREFIX*share` ' .
+ 'WHERE `item_type` in (\'file\', \'folder\') ' .
+ 'AND NOT EXISTS (SELECT `fileid` FROM `*PREFIX*filecache` WHERE `file_source` = `fileid`)';
+
+ $deletedEntries = $connection->executeUpdate($sql);
+ $logger->info("$deletedEntries orphaned share(s) deleted", ['app' => 'DeleteOrphanedSharesJob']);
+ }
+
+}
diff --git a/apps/files_sharing/lib/helper.php b/apps/files_sharing/lib/helper.php
index 3f1de7233ae..5b5525e244f 100644
--- a/apps/files_sharing/lib/helper.php
+++ b/apps/files_sharing/lib/helper.php
@@ -33,7 +33,6 @@ class Helper {
\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', 'post_delete', '\OC\Files\Cache\Shared_Updater', 'postDeleteHook');
\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/updater.php b/apps/files_sharing/lib/updater.php
index d748d5555f6..322c031f2f1 100644
--- a/apps/files_sharing/lib/updater.php
+++ b/apps/files_sharing/lib/updater.php
@@ -27,9 +27,6 @@ namespace OC\Files\Cache;
class Shared_Updater {
- // shares which can be removed from oc_share after the delete operation was successful
- static private $toRemove = array();
-
/**
* walk up the users file tree and update the etags
* @param string $user
@@ -82,25 +79,6 @@ class Shared_Updater {
}
/**
- * remove all shares for a given file if the file was deleted
- *
- * @param string $path
- */
- private static function removeShare($path) {
- $fileSource = self::$toRemove[$path];
-
- if (!\OC\Files\Filesystem::file_exists($path)) {
- $query = \OC_DB::prepare('DELETE FROM `*PREFIX*share` WHERE `file_source`=?');
- try {
- \OC_DB::executeAudited($query, array($fileSource));
- } catch (\Exception $e) {
- \OCP\Util::writeLog('files_sharing', "can't remove share: " . $e->getMessage(), \OCP\Util::WARN);
- }
- }
- unset(self::$toRemove[$path]);
- }
-
- /**
* @param array $params
*/
static public function writeHook($params) {
@@ -122,19 +100,6 @@ class Shared_Updater {
static public function deleteHook($params) {
$path = $params['path'];
self::correctFolders($path);
-
- $fileInfo = \OC\Files\Filesystem::getFileInfo($path);
-
- // mark file as deleted so that we can clean up the share table if
- // the file was deleted successfully
- self::$toRemove[$path] = $fileInfo['fileid'];
- }
-
- /**
- * @param array $params
- */
- static public function postDeleteHook($params) {
- self::removeShare($params['path']);
}
/**
diff --git a/apps/files_sharing/templates/settings-admin.php b/apps/files_sharing/templates/settings-admin.php
index bd803517597..376f2b71aee 100644
--- a/apps/files_sharing/templates/settings-admin.php
+++ b/apps/files_sharing/templates/settings-admin.php
@@ -4,6 +4,9 @@
?>
<div id="fileSharingSettings">
<h3><?php p($l->t('Federated Cloud Sharing'));?></h3>
+ <a target="_blank" class="icon-info svg"
+ title="<?php p($l->t('Open documentation'));?>"
+ href="<?php p(link_to_docs('admin-sharing-federated')); ?>"></a>
<p>
<input type="checkbox" name="outgoing_server2server_share_enabled" id="outgoingServer2serverShareEnabled"
diff --git a/apps/files_sharing/tests/deleteorphanedsharesjobtest.php b/apps/files_sharing/tests/deleteorphanedsharesjobtest.php
new file mode 100644
index 00000000000..20f3bcd5ebd
--- /dev/null
+++ b/apps/files_sharing/tests/deleteorphanedsharesjobtest.php
@@ -0,0 +1,162 @@
+<?php
+/**
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @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 Test\BackgroundJob;
+
+use OCA\Files_sharing\Lib\DeleteOrphanedSharesJob;
+
+class DeleteOrphanedSharesJobTest extends \Test\TestCase {
+
+ /**
+ * @var bool
+ */
+ private static $trashBinStatus;
+
+ /**
+ * @var DeleteOrphanedSharesJob
+ */
+ private $job;
+
+ /**
+ * @var \OCP\IDBConnection
+ */
+ private $connection;
+
+ /**
+ * @var string
+ */
+ private $user1;
+
+ /**
+ * @var string
+ */
+ private $user2;
+
+ public static function setUpBeforeClass() {
+ $appManager = \OC::$server->getAppManager();
+ self::$trashBinStatus = $appManager->isEnabledForUser('files_trashbin');
+ $appManager->disableApp('files_trashbin');
+
+ // just in case...
+ \OC\Files\Filesystem::getLoader()->removeStorageWrapper('oc_trashbin');
+ }
+
+ public static function tearDownAfterClass() {
+ if (self::$trashBinStatus) {
+ \OC::$server->getAppManager()->enableApp('files_trashbin');
+ }
+ }
+
+ protected function setup() {
+ parent::setUp();
+
+ $this->connection = \OC::$server->getDatabaseConnection();
+
+ $this->user1 = $this->getUniqueID('user1_');
+ $this->user2 = $this->getUniqueID('user2_');
+
+ $userManager = \OC::$server->getUserManager();
+ $userManager->createUser($this->user1, 'pass');
+ $userManager->createUser($this->user2, 'pass');
+
+ \OC::registerShareHooks();
+
+ $this->job = new DeleteOrphanedSharesJob();
+ }
+
+ protected function tearDown() {
+ $this->connection->executeUpdate('DELETE FROM `*PREFIX*share` WHERE `item_type` in (\'file\', \'folder\')');
+
+ $userManager = \OC::$server->getUserManager();
+ $user1 = $userManager->get($this->user1);
+ if($user1) {
+ $user1->delete();
+ }
+ $user2 = $userManager->get($this->user2);
+ if($user2) {
+ $user2->delete();
+ }
+
+ $this->logout();
+
+ parent::tearDown();
+ }
+
+ private function getShares() {
+ $shares = [];
+ $result = $this->connection->executeQuery('SELECT * FROM `*PREFIX*share`');
+ while ($row = $result->fetch()) {
+ $shares[] = $row;
+ }
+ $result->closeCursor();
+ return $shares;
+ }
+
+ /**
+ * Test clearing orphaned shares
+ */
+ public function testClearShares() {
+ $this->loginAsUser($this->user1);
+
+ $view = new \OC\Files\View('/' . $this->user1 . '/');
+ $view->mkdir('files/test');
+ $view->mkdir('files/test/sub');
+
+ $fileInfo = $view->getFileInfo('files/test/sub');
+ $fileId = $fileInfo->getId();
+
+ $this->assertTrue(
+ \OCP\Share::shareItem('folder', $fileId, \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_READ),
+ 'Failed asserting that user 1 successfully shared "test/sub" with user 2.'
+ );
+
+ $this->assertCount(1, $this->getShares());
+
+ $this->job->run([]);
+
+ $this->assertCount(1, $this->getShares(), 'Linked shares not deleted');
+
+ $view->unlink('files/test');
+
+ $this->job->run([]);
+
+ $this->assertCount(0, $this->getShares(), 'Orphaned shares deleted');
+ }
+
+ public function testKeepNonFileShares() {
+ $this->loginAsUser($this->user1);
+
+ \OCP\Share::registerBackend('test', 'Test_Share_Backend');
+
+ $this->assertTrue(
+ \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_READ),
+ 'Failed asserting that user 1 successfully shared something with user 2.'
+ );
+
+ $this->assertCount(1, $this->getShares());
+
+ $this->job->run([]);
+
+ $this->assertCount(1, $this->getShares(), 'Non-file shares kept');
+ }
+}
+