diff options
-rw-r--r-- | apps/files_sharing/sharedstorage.php | 90 | ||||
-rw-r--r-- | lib/files.php | 5 | ||||
-rw-r--r-- | lib/public/share.php | 115 |
3 files changed, 108 insertions, 102 deletions
diff --git a/apps/files_sharing/sharedstorage.php b/apps/files_sharing/sharedstorage.php index fed1b834fa3..21aa2f23b94 100644 --- a/apps/files_sharing/sharedstorage.php +++ b/apps/files_sharing/sharedstorage.php @@ -3,7 +3,7 @@ * ownCloud * * @author Michael Gapczynski - * @copyright 2011 Michael Gapczynski GapczynskiM@gmail.com + * @copyright 2011 Michael Gapczynski mtgap@owncloud.com * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -20,43 +20,50 @@ * */ -require_once( 'lib_share.php' ); - /** * Convert target path to source path and pass the function call to the correct storage provider */ class OC_Filestorage_Shared extends OC_Filestorage_Common { - private $datadir; + private $sharedFolder; private $sourcePaths = array(); public function __construct($arguments) { - $this->datadir = $arguments['datadir']; - $this->datadir .= "/"; + $this->sharedFolder = $arguments['sharedFolder']; } - - public function getInternalPath($path) { - $mountPoint = OC_Filesystem::getMountPoint($path); - $internalPath = substr($path, strlen($mountPoint)); - return $internalPath; - } - - public function getSource($target) { - $target = $this->datadir.$target; - if (array_key_exists($target, $this->sourcePaths)) { + + public function getSourcePath($target) { + $target = $this->sharedFolder.$target; + if (isset($this->sourcePaths[$target])) { return $this->sourcePaths[$target]; } else { - $source = OC_Share::getSource($target); - $this->sourcePaths[$target] = $source; - return $source; + if (dirname($target) != $this->sharedFolder) { + $pos = strlen($this->sharedFolder); + // Get shared folder name + $itemTarget = substr($target, $pos, strpos($target, '/', $pos)); + } else { + $itemTarget = $target; + } + $sourcePath = OCP\Share::getItemSharedWith('file', $itemTarget, OC_Share_Backend_File::FORMAT_SOURCE_PATH); + if ($sourcePath) { + $this->sourcePaths[$target] = $sourcePath; + return $sourcePath; + } + return false; } } + + private function getInternalPath($path) { + $mountPoint = OC_Filesystem::getMountPoint($path); + $internalPath = substr($path, strlen($mountPoint)); + return $internalPath; + } public function mkdir($path) { if ($path == "" || $path == "/" || !$this->is_writable($path)) { return false; } else { - $source = $this->getSource($path); + $source = $this->getSourcePath($path); if ($source) { $storage = OC_Filesystem::getStorage($source); return $storage->mkdir($this->getInternalPath($source)); @@ -73,6 +80,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { public function opendir($path) { if ($path == "" || $path == "/") { $path = $this->datadir.$path; + // TODO $sharedItems = OC_Share::getItemsInFolder($path); $files = array(); foreach ($sharedItems as $item) { @@ -84,7 +92,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { OC_FakeDirStream::$dirs['shared']=$files; return opendir('fakedir://shared'); } else { - $source = $this->getSource($path); + $source = $this->getSourcePath($path); if ($source) { $storage = OC_Filesystem::getStorage($source); $dh = $storage->opendir($this->getInternalPath($source)); @@ -143,7 +151,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { if ($path == "" || $path == "/") { return true; } else { - $source = $this->getSource($path); + $source = $this->getSourcePath($path); if ($source) { $storage = OC_Filesystem::getStorage($source); return $storage->is_dir($this->getInternalPath($source)); @@ -152,7 +160,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { } public function is_file($path) { - $source = $this->getSource($path); + $source = $this->getSourcePath($path); if ($source) { $storage = OC_Filesystem::getStorage($source); return $storage->is_file($this->getInternalPath($source)); @@ -167,7 +175,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { $stat["ctime"] = $this->filectime($path); return $stat; } else { - $source = $this->getSource($path); + $source = $this->getSourcePath($path); if ($source) { $storage = OC_Filesystem::getStorage($source); return $storage->stat($this->getInternalPath($source)); @@ -179,7 +187,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { if ($path == "" || $path == "/") { return "dir"; } else { - $source = $this->getSource($path); + $source = $this->getSourcePath($path); if ($source) { $storage = OC_Filesystem::getStorage($source); return $storage->filetype($this->getInternalPath($source)); @@ -192,7 +200,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { if ($path == "" || $path == "/" || $this->is_dir($path)) { return $this->getFolderSize($path); } else { - $source = $this->getSource($path); + $source = $this->getSourcePath($path); if ($source) { $storage = OC_Filesystem::getStorage($source); return $storage->filesize($this->getInternalPath($source)); @@ -267,7 +275,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { if ($path == "" || $path == "/") { return true; } else { - $source = $this->getSource($path); + $source = $this->getSourcePath($path); if ($source) { $storage = OC_Filesystem::getStorage($source); return $storage->file_exists($this->getInternalPath($source)); @@ -288,7 +296,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { } return $ctime; } else { - $source = $this->getSource($path); + $source = $this->getSourcePath($path); if ($source) { $storage = OC_Filesystem::getStorage($source); return $storage->filectime($this->getInternalPath($source)); @@ -309,7 +317,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { } return $mtime; } else { - $source = $this->getSource($path); + $source = $this->getSourcePath($path); if ($source) { $storage = OC_Filesystem::getStorage($source); return $storage->filemtime($this->getInternalPath($source)); @@ -318,7 +326,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { } public function file_get_contents($path) { - $source = $this->getSource($path); + $source = $this->getSourcePath($path); if ($source) { $info = array( 'target' => $this->datadir.$path, @@ -332,7 +340,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { public function file_put_contents($path, $data) { if ($this->is_writable($path)) { - $source = $this->getSource($path); + $source = $this->getSourcePath($path); if ($source) { $info = array( 'target' => $this->datadir.$path, @@ -381,7 +389,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { return false; // Check if both paths have write permission } else if ($this->is_writable($path1) && $this->is_writable($path2)) { - $oldSource = $this->getSource($path1); + $oldSource = $this->getSourcePath($path1); $newSource = $folders['source'].substr($newTarget, strlen($folders['target'])); if ($oldSource) { $storage = OC_Filesystem::getStorage($oldSource); @@ -424,7 +432,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { } public function fopen($path, $mode) { - $source = $this->getSource($path); + $source = $this->getSourcePath($path); if ($source) { $info = array( 'target' => $this->datadir.$path, @@ -438,7 +446,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { } public function toTmpFile($path) { - $source = $this->getSource($path); + $source = $this->getSourcePath($path); if ($source) { $storage = OC_Filesystem::getStorage($source); return $storage->toTmpFile($this->getInternalPath($source)); @@ -447,7 +455,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { public function fromTmpFile($tmpFile, $path) { if ($this->is_writable($path)) { - $source = $this->getSource($path); + $source = $this->getSourcePath($path); if ($source) { $storage = OC_Filesystem::getStorage($source); $result = $storage->fromTmpFile($tmpFile, $this->getInternalPath($source)); @@ -465,7 +473,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { if ($path == "" || $path == "/") { return 'httpd/unix-directory'; } - $source = $this->getSource($path); + $source = $this->getSourcePath($path); if ($source) { $storage = OC_Filesystem::getStorage($source); return $storage->getMimeType($this->getInternalPath($source)); @@ -473,7 +481,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { } public function hash($type, $path, $raw) { - $source = $this->getSource($path); + $source = $this->getSourcePath($path); if ($source) { $storage = OC_Filesystem::getStorage($source); return $storage->hash($type, $this->getInternalPath($source), $raw); @@ -481,7 +489,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { } public function free_space($path) { - $source = $this->getSource($path); + $source = $this->getSourcePath($path); if ($source) { $storage = OC_Filesystem::getStorage($source); return $storage->free_space($this->getInternalPath($source)); @@ -510,14 +518,14 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { } public function getLocalFile($path) { - $source = $this->getSource($path); + $source = $this->getSourcePath($path); if ($source) { $storage = OC_Filesystem::getStorage($source); return $storage->getLocalFile($this->getInternalPath($source)); } } public function touch($path, $mtime=null){ - $source = $this->getSource($path); + $source = $this->getSourcePath($path); if ($source) { $storage = OC_Filesystem::getStorage($source); return $storage->touch($this->getInternalPath($source),$time); @@ -526,7 +534,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common { public static function setup($options) { $user_dir = $options['user_dir']; - OC_Filesystem::mount('OC_Filestorage_Shared', array('datadir' => $user_dir.'/Shared'), $user_dir.'/Shared/'); + OC_Filesystem::mount('OC_Filestorage_Shared', array('sharedFolder' => $user_dir.'/Shared'), $user_dir.'/Shared/'); } /** diff --git a/lib/files.php b/lib/files.php index 469c3a15b8e..2feae20afe6 100644 --- a/lib/files.php +++ b/lib/files.php @@ -34,6 +34,11 @@ class OC_Files { */ public static function getDirectoryContent($directory, $mimetype_filter = ''){ $files=OC_FileCache::getFolderContent($directory, false, $mimetype_filter); + if ($directory == '') { + $files = array_merge($files, array()); + } else if (substr($directory, 7) == '/Shared') { + $files = array_merge($files, OCP\Share::getItemsSharedWith('file', $directory, OC_Share_Backend_File::FORMAT_FILE_APP)); + } foreach($files as &$file){ $file['directory']=$directory; $file['type']=($file['mimetype']=='httpd/unix-directory')?'dir':'file'; diff --git a/lib/public/share.php b/lib/public/share.php index 18388fec983..2ba3187dffc 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -31,13 +31,15 @@ class Share { const SHARE_TYPE_USER = 0; const SHARE_TYPE_GROUP = 1; const SHARETYPE_CONTACT = 2; - const SHARETYPE_PRIVATE_LINK = 4; + const SHARETYPE_PRIVATE_LINK = 4; const PERMISSION_READ = 0; const PERMISSION_UPDATE = 1; const PERMISSION_DELETE = 2; const PERMISSION_SHARE = 3; + const FORMAT_NONE = -1; + private static $shareTypeUserAndGroups = -1; private static $shareTypeGroupUserUnique = 3; private static $backends = array(); @@ -67,37 +69,45 @@ class Share { /** * @brief Get the items of item type shared with the current user * @param string Item type - * @return + * @param int Format (optional) Format type must be defined by the backend + * @param int Number of items to return (optional) Returns all by default + * @return Return depends on format */ - public static function getItemsSharedWith($itemType) { - return self::getItems($itemType, null, \OC_User::getUser(), true, null, true); + public static function getItemsSharedWith($itemType, $format = self::FORMAT_NONE, $limit = -1) { + return self::getItems($itemType, null, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format, $limit); } /** * @brief Get the item of item type shared with the current user * @param string Item type - * @return + * @param string Item target + * @param int Format (optional) Format type must be defined by the backend + * @return Return depends on format */ - public static function getItemSharedWith($itemType, $item) { - return self::getItems($itemType, $item, \OC_User::getUser(), true, null, true, 1); + public static function getItemSharedWith($itemType, $itemTarget, $format = self::FORMAT_NONE) { + return self::getItems($itemType, $itemTarget, self::$shareTypeUserAndGroups, \OC_User::getUser(), null, $format, 1); } /** * @brief Get the shared items of item type owned by the current user * @param string Item type - * @return The + * @param int Format (optional) Format type must be defined by the backend + * @param int Number of items to return (optional) Returns all by default + * @return Return depends on format */ - public static function getItemsOwned($itemType) { - return self::getItems($itemType, null, null, null, \OC_User::getUser(), true); + public static function getItemsOwned($itemType, $format = self::FORMAT_NONE, $limit = -1) { + return self::getItems($itemType, null, null, null, \OC_User::getUser(), $format, $limit); } /** * @brief Get the shared item of item type owned by the current user * @param string Item type - * @return The + * @param string Item + * @param int Format (optional) Format type must be defined by the backend + * @return Return depends on format */ - public static function getItemOwned($itemType, $item) { - return self::getItems($itemType, $item, null, null, \OC_User::getUser(), true, 1); + public static function getItemOwned($itemType, $item, $format = self::FORMAT_NONE) { + return self::getItems($itemType, $item, null, null, \OC_User::getUser(), $format, 1); } /** @@ -130,7 +140,7 @@ class Share { return false; } } - if (self::getItems($itemType, $item, $shareWith, true, $uidOwner, false, 1)) { + if (self::getItems($itemType, $item, self::SHARE_TYPE_USER, $shareWith, $uidOwner, self::FORMAT_NONE, 1)) { \OC_Log::write('OCP\Share', 'Sharing '.$item.' failed, because this item is already shared with the user '.$shareWith, \OC_Log::ERROR); return false; } @@ -143,7 +153,7 @@ class Share { \OC_Log::write('OCP\Share', 'Sharing '.$item.' failed, because '.$uidOwner.' is not a member of the group '.$shareWith, \OC_Log::ERROR); return false; } - if (self::getItems($itemType, $item, null, $shareWith, $uidOwner, false, 1)) { + if (self::getItems($itemType, $item, self::SHARE_TYPE_GROUP, $shareWith, $uidOwner, self::FORMAT_NONE, 1)) { \OC_Log::write('OCP\Share', 'Sharing '.$item.' failed, because this item is already shared with the group '.$shareWith, \OC_Log::ERROR); return false; } @@ -375,7 +385,7 @@ class Share { /** * @brief Get shared items from the database * @param string Item type - * @param string Item (optional) + * @param string Item or item target (optional) * @param string User the item(s) is(are) shared with * @param string|bool Group the item(s) is(are) shared with * @param string User that is the owner of shared items (optional) @@ -385,7 +395,7 @@ class Share { * See public functions getItem(s)... for parameter usage * */ - private static function getItems($itemType, $item = null, $shareType = null, $shareWith = null, $uidOwner = null, $format = true, $checkOnly = false, $limit = -1) { + private static function getItems($itemType, $item = null, $shareType = null, $shareWith = null, $uidOwner = null, $format = self::FORMAT_NONE, $limit = -1) { if ($backend = self::getBackend($itemType)) { // Check if there are any parent types that include this type of items, e.g. a music album contains songs if (isset($itemType)) { @@ -410,7 +420,6 @@ class Share { $groups = \OC_Group::getUserGroups($shareWith); $userAndGroups = array_merge(array($shareWith), $groups); $where .= " AND share_with IN ('".implode("','", $userAndGroups)."')"; - } else { $where .= " AND share_type = '".$shareType."' AND share_with = '".$shareWith."'"; } @@ -443,32 +452,24 @@ class Share { } $query = \OC_DB::prepare('SELECT * FROM *PREFIX*sharing '.$where); $result = $query->execute(); - if (!$checkOnly) { - $items = array(); - while ($item = $result->fetchRow()) { - // Filter out duplicate group shares for users with unique targets - if ($item['share_type'] == self::$shareTypeGroupUserUnique) { - - } - $sources[] = $item['item_source']; - if ($format) { - $shareInfo[$item['item_source']] = array('item_target' => $item['item_target'], 'permissions' => $item['permissions'], 'stime' => $item['stime']); - } else { - $shareInfo[$item['item_source']][$item['id']] = array('item_target' => $item['item_target'], 'permissions' => $item['permissions'], 'stime' => $item['stime']); - } - } - if ($format) { - return $backend->formatItems($sources, $shareInfo); - } else { - // TODO wrap items back into share type, share with, permissions - $items = $backend->getItems($sources); + $items = array(); + while ($item = $result->fetchRow()) { + // TODO Filter out duplicate group shares for users with unique targets + if ($item['share_type'] == self::$shareTypeGroupUserUnique) { + // Group shares should already be in items array } - if (!empty($items)) { - return $items; + // TODO Add in parent item types children? + if ($parents && in_array($item['item_type'], $parents)) { + $children[] = $item; } +// $items[] = array($item['item_source'] => $item['id']; + $items[$item['item']][$item['id']] = array('item_target' => $item['item_target'], 'permissions' => $item['permissions'], 'stime' => $item['stime']); + } + if ($format == self::FORMAT_NONE) { + return $items; } else { - return $result->fetchAll(); + return $backend->formatItems($items, $format); } } return false; @@ -523,7 +524,7 @@ class Share { $fileSource = null; } } - $query = \OC_DB::prepare('INSERT INTO *PREFIX*sharing (item_type, item_source, item_target, parent, uid_shared_with, gid_shared_with, uid_owner, permissions, stime, file_source, file_target) VALUES (?,?,?,?,?,?,?,?,?,?,?)'); + $query = \OC_DB::prepare('INSERT INTO *PREFIX*sharing (item_type, item, item_source, item_target, parent, uid_shared_with, gid_shared_with, uid_owner, permissions, stime, file_source, file_target) VALUES (?,?,?,?,?,?,?,?,?,?,?)'); // Share with a group if ($shareType == self::SHARE_TYPE_GROUP) { if (isset($fileSource)) { @@ -547,7 +548,7 @@ class Share { $groupFileTarget = null; } $groupItemTarget = $backend->generateTarget($item, false); - $query->execute(array($itemType, $itemSource, $groupItemTarget, $parent, $shareType, $shareWith['group'], $uidOwner, $permissions, time(), $fileSource, $groupFileTarget)); + $query->execute(array($itemType, $item, $itemSource, $groupItemTarget, $parent, $shareType, $shareWith['group'], $uidOwner, $permissions, time(), $fileSource, $groupFileTarget)); // Save this id, any extra rows for this group share will need to reference it $parent = \OC_DB::insertid('*PREFIX*sharing'); // Loop through all users of this group in case we need to add an extra row @@ -572,7 +573,7 @@ class Share { } // Insert an extra row for the group share if the item or file target is unique for this user if ($itemTarget != $groupItemTarget || (isset($fileSource) && $fileTarget != $groupFileTarget)) { - $query->execute(array($itemType, $itemSource, $itemTarget, $parent, self::$shareTypeGroupUserUnique, $uid, $uidOwner, $permissions, time(), $fileSource, $fileTarget)); + $query->execute(array($itemType, $item, $itemSource, $itemTarget, $parent, self::$shareTypeGroupUserUnique, $uid, $uidOwner, $permissions, time(), $fileSource, $fileTarget)); $id = \OC_DB::insertid('*PREFIX*sharing'); } if ($parentFolder === true) { @@ -600,7 +601,7 @@ class Share { } else { $fileTarget = null; } - $query->execute(array($itemType, $itemSource, $itemTarget, $parent, $shareType, $shareWith, $uidOwner, $permissions, time(), $fileSource, $fileTarget)); + $query->execute(array($itemType, $item, $itemSource, $itemTarget, $parent, $shareType, $shareWith, $uidOwner, $permissions, time(), $fileSource, $fileTarget)); $id = \OC_DB::insertid('*PREFIX*sharing'); if ($parentFolder === true) { $parentFolders['id'] = $id; @@ -638,10 +639,6 @@ class Share { * Hook Listeners */ - public static function post_writeFile($arguments) { - // TODO - } - public static function post_deleteUser($arguments) { // Delete any items shared with the deleted user $query = \OC_DB::prepare('DELETE FROM *PREFIX*sharing WHERE uid_shared_with = ?'); @@ -705,22 +702,18 @@ abstract class Share_Backend { /** - * @brief - * @param array - * @return + * @brief Converts the shared item sources back into the item in the specified format + * @param array Sources of shared items + * @param int Format + * @return ? + * + * The items array is formatted with the sources as the keys to an array with the following keys: item_target, permissions, stime + * This function allows the backend to control the output of shared items with custom formats. + * It is only called through calls to the public getItem(s)SharedWith functions. */ - public abstract function getItems($sources); + public abstract function formatItems($items, $format); - - /** - * @brief - * @param array - * @param array - * @return - */ - public abstract function formatItems($sources, $shareInfo); - } abstract class Share_Backend_Parent extends Share_Backend { |