[Pkg-owncloud-commits] [owncloud] 10/103: Do not return shares for files outside "files"

David Prévot taffit at moszumanska.debian.org
Sun May 31 12:32:33 UTC 2015


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to annotated tag v8.0.4RC1
in repository owncloud.

commit 80461daa2832eacf2451604362284b8933c75d22
Author: Vincent Petry <pvince81 at owncloud.com>
Date:   Tue Mar 24 11:08:19 2015 +0100

    Do not return shares for files outside "files"
---
 lib/private/share/share.php | 59 ++++++++++++++++++++++++++++++++++++---------
 tests/lib/share/share.php   | 39 ++++++++++++++++++++++++++++++
 2 files changed, 87 insertions(+), 11 deletions(-)

diff --git a/lib/private/share/share.php b/lib/private/share/share.php
index 0069d70..a548698 100644
--- a/lib/private/share/share.php
+++ b/lib/private/share/share.php
@@ -312,18 +312,20 @@ class Share extends \OC\Share\Constants {
 	 */
 	public static function getItemSharedWithUser($itemType, $itemSource, $user, $owner = null, $shareType = null) {
 		$shares = array();
-		$fileDependend = false;
+		$fileDependent = false;
 
 		if ($itemType === 'file' || $itemType === 'folder') {
-			$fileDependend = true;
+			$fileDependent = true;
 			$column = 'file_source';
-			$where = 'INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid` WHERE';
+			$where = 'INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid` ';
+			$where .= 'INNER JOIN `*PREFIX*storages` ON `numeric_id` = `*PREFIX*filecache`.`storage` ';
+			$where .= ' WHERE';
 		} else {
 			$column = 'item_source';
 			$where = 'WHERE';
 		}
 
-		$select = self::createSelectStatement(self::FORMAT_NONE, $fileDependend);
+		$select = self::createSelectStatement(self::FORMAT_NONE, $fileDependent);
 
 		$where .= ' `' . $column . '` = ? AND `item_type` = ? ';
 		$arguments = array($itemSource, $itemType);
@@ -348,6 +350,9 @@ class Share extends \OC\Share\Constants {
 		$result = \OC_DB::executeAudited($query, $arguments);
 
 		while ($row = $result->fetchRow()) {
+			if ($fileDependent && !self::isFileReachable($row['path'], $row['storage_id'])) {
+				continue;
+			}
 			$shares[] = $row;
 		}
 
@@ -1360,10 +1365,11 @@ class Share extends \OC\Share\Constants {
 			} else {
 				$root = '';
 			}
-			$where = 'INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid`';
+			$where = 'INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid` ';
 			if (!isset($item)) {
-				$where .= ' WHERE `file_target` IS NOT NULL';
+				$where .= ' AND `file_target` IS NOT NULL ';
 			}
+			$where .= 'INNER JOIN `*PREFIX*storages` ON `numeric_id` = `*PREFIX*filecache`.`storage` ';
 			$fileDependent = true;
 			$queryArgs = array();
 		} else {
@@ -1504,6 +1510,9 @@ class Share extends \OC\Share\Constants {
 		while ($row = $result->fetchRow()) {
 			self::transformDBResults($row);
 			// Filter out duplicate group shares for users with unique targets
+			if ($fileDependent && !self::isFileReachable($row['path'], $row['storage_id'])) {
+				continue;
+			}
 			if ($row['share_type'] == self::$shareTypeGroupUserUnique && isset($items[$row['parent']])) {
 				$row['share_type'] = self::SHARE_TYPE_GROUP;
 				$row['unique_name'] = true; // remember that we use a unique name for this user
@@ -2160,7 +2169,9 @@ class Share extends \OC\Share\Constants {
 		$select = '*';
 		if ($format == self::FORMAT_STATUSES) {
 			if ($fileDependent) {
-				$select = '`*PREFIX*share`.`id`, `*PREFIX*share`.`parent`, `share_type`, `path`, `storage`, `share_with`, `uid_owner` , `file_source`, `stime`, `*PREFIX*share`.`permissions`';
+				$select = '`*PREFIX*share`.`id`, `*PREFIX*share`.`parent`, `share_type`, `path`, `storage`, '
+					. '`share_with`, `uid_owner` , `file_source`, `stime`, `*PREFIX*share`.`permissions`, '
+					. '`*PREFIX*storages`.`id` AS `storage_id`';
 			} else {
 				$select = '`id`, `parent`, `share_type`, `share_with`, `uid_owner`, `item_source`, `stime`, `*PREFIX*share`.`permissions`';
 			}
@@ -2169,7 +2180,8 @@ class Share extends \OC\Share\Constants {
 				if ($fileDependent) {
 					$select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `*PREFIX*share`.`parent`,'
 						. ' `share_type`, `share_with`, `file_source`, `file_target`, `path`, `*PREFIX*share`.`permissions`, `stime`,'
-						. ' `expiration`, `token`, `storage`, `mail_send`, `uid_owner`';
+						. ' `expiration`, `token`, `storage`, `mail_send`, `uid_owner`, '
+						. '`*PREFIX*storages`.`id` AS `storage_id`';
 				} else {
 					$select = '`id`, `item_type`, `item_source`, `parent`, `share_type`, `share_with`, `*PREFIX*share`.`permissions`,'
 						. ' `stime`, `file_source`, `expiration`, `token`, `mail_send`, `uid_owner`';
@@ -2182,9 +2194,11 @@ class Share extends \OC\Share\Constants {
 							. '`*PREFIX*share`.`permissions`, `expiration`, `storage`, `*PREFIX*filecache`.`parent` as `file_parent`, '
 							. '`name`, `mtime`, `mimetype`, `mimepart`, `size`, `unencrypted_size`, `encrypted`, `etag`, `mail_send`';
 					} else {
-						$select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `item_target`,
-							`*PREFIX*share`.`parent`, `share_type`, `share_with`, `uid_owner`,
-							`file_source`, `path`, `file_target`, `*PREFIX*share`.`permissions`, `stime`, `expiration`, `token`, `storage`, `mail_send`';
+						$select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `item_target`,'
+							. '`*PREFIX*share`.`parent`, `share_type`, `share_with`, `uid_owner`,'
+							. '`file_source`, `path`, `file_target`, `*PREFIX*share`.`permissions`,'
+						    . '`stime`, `expiration`, `token`, `storage`, `mail_send`,'
+							. '`*PREFIX*storages`.`id` AS `storage_id`';
 					}
 				}
 			}
@@ -2370,4 +2384,27 @@ class Share extends \OC\Share\Constants {
 		return (int)\OCP\Config::getAppValue('core', 'shareapi_expire_after_n_days', '7');
 	}
 
+	/**
+	 * Checks whether the given path is reachable for the given owner
+	 *
+	 * @param string $path path relative to files
+	 * @param string $ownerStorageId storage id of the owner
+	 *
+	 * @return boolean true if file is reachable, false otherwise
+	 */
+	private static function isFileReachable($path, $ownerStorageId) {
+		// if outside the home storage, file is always considered reachable
+		if (!(substr($ownerStorageId, 0, 6) === 'home::')) {
+			return true;
+		}
+
+		// if inside the home storage, the file has to be under "/files/"
+		$path = ltrim($path, '/');
+		if (substr($path, 0, 6) === 'files/') {
+			return true;
+		}
+
+		return false;
+	}
+
 }
diff --git a/tests/lib/share/share.php b/tests/lib/share/share.php
index 42bb829..2bc1e32 100644
--- a/tests/lib/share/share.php
+++ b/tests/lib/share/share.php
@@ -388,6 +388,45 @@ class Test_Share extends \Test\TestCase {
 		$this->assertSame(\OCP\Share::SHARE_TYPE_USER, $share['share_type']);
 	}
 
+	public function testGetShareFromOutsideFilesFolder() {
+		OC_User::setUserId($this->user1);
+		$view = new \OC\Files\View('/' . $this->user1 . '/');
+		$view->mkdir('files/test');
+		$view->mkdir('files/test/sub');
+
+		$view->mkdir('files_trashbin');
+		$view->mkdir('files_trashbin/files');
+
+		$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.'
+		);
+
+		$result = OCP\Share::getItemShared('folder', $fileId, Test_Share_Backend::FORMAT_SOURCE);
+		$this->assertNotEmpty($result);
+
+		$result = OCP\Share::getItemSharedWithUser('folder', $fileId, $this->user2);
+		$this->assertNotEmpty($result);
+
+		$result = OCP\Share::getItemsSharedWithUser('folder', $this->user2);
+		$this->assertNotEmpty($result);
+
+		// move to trash (keeps file id)
+		$view->rename('files/test', 'files_trashbin/files/test');
+
+		$result = OCP\Share::getItemShared('folder', $fileId, Test_Share_Backend::FORMAT_SOURCE);
+		$this->assertEmpty($result, 'Share must not be returned for files outside of "files"');
+
+		$result = OCP\Share::getItemSharedWithUser('folder', $fileId, $this->user2);
+		$this->assertEmpty($result, 'Share must not be returned for files outside of "files"');
+
+		$result = OCP\Share::getItemsSharedWithUser('folder', $this->user2);
+		$this->assertEmpty($result, 'Share must not be returned for files outside of "files"');
+	}
+
 	public function testSetExpireDateInPast() {
 		OC_User::setUserId($this->user1);
 		$this->shareUserOneTestFileWithUserTwo();

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/owncloud.git



More information about the Pkg-owncloud-commits mailing list