Esempio n. 1
0
 /**
  * @brief Get the source file path for a shared file
  * @param string Shared target file path
  * @return string source file path or false if not found
  */
 private function getSourcePath($target)
 {
     $source = $this->getFile($target);
     if ($source) {
         if (!isset($source['fullPath'])) {
             \OC\Files\Filesystem::initMountPoints($source['fileOwner']);
             $mount = \OC\Files\Mount::findByNumericId($source['storage']);
             if ($mount) {
                 $this->files[$target]['fullPath'] = $mount->getMountPoint() . $source['path'];
             } else {
                 $this->files[$target]['fullPath'] = false;
             }
         }
         return $this->files[$target]['fullPath'];
     }
     return false;
 }
Esempio n. 2
0
 /**
  * @brief Get the source cache of a shared file or folder
  * @param string $target Shared target file path
  * @return \OC\Files\Cache\Cache
  */
 private function getSourceCache($target)
 {
     $source = \OC_Share_Backend_File::getSource($target);
     if (isset($source['path']) && isset($source['fileOwner'])) {
         \OC\Files\Filesystem::initMountPoints($source['fileOwner']);
         $mount = \OC\Files\Mount::findByNumericId($source['storage']);
         if ($mount) {
             $fullPath = $mount->getMountPoint() . $source['path'];
             list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath($fullPath);
             if ($storage) {
                 $this->files[$target] = $internalPath;
                 $cache = $storage->getCache();
                 $this->storageId = $storage->getId();
                 $this->numericId = $cache->getNumericStorageId();
                 return $cache;
             }
         }
     }
     return false;
 }
Esempio n. 3
0
    /**
     * @brief Get shared items from the database
     * @param string Item type
     * @param string Item source or target (optional)
     * @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, SHARE_TYPE_LINK, $shareTypeUserAndGroups, or $shareTypeGroupUserUnique
     * @param string User or group the item is being shared with
     * @param string User that is the owner of shared items (optional)
     * @param int Format to convert items to with formatItems()
     * @param mixed Parameters to pass to formatItems()
     * @param int Number of items to return, -1 to return all matches (optional)
     * @param bool Include collection item types (optional)
     * @return mixed
     *
     * See public functions getItem(s)... for parameter usage
     *
     */
    private static function getItems($itemType, $item = null, $shareType = null, $shareWith = null, $uidOwner = null, $format = self::FORMAT_NONE, $parameters = null, $limit = -1, $includeCollections = false, $itemShareWithBySource = false)
    {
        if (!self::isEnabled()) {
            if ($limit == 1 || isset($uidOwner) && isset($item)) {
                return false;
            } else {
                return array();
            }
        }
        $backend = self::getBackend($itemType);
        $collectionTypes = false;
        // Get filesystem root to add it to the file target and remove from the
        // file source, match file_source with the file cache
        if ($itemType == 'file' || $itemType == 'folder') {
            $root = \OC\Files\Filesystem::getRoot();
            $where = 'INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid`';
            if (!isset($item)) {
                $where .= ' WHERE `file_target` IS NOT NULL';
            }
            $fileDependent = true;
            $queryArgs = array();
        } else {
            $fileDependent = false;
            $root = '';
            if ($includeCollections && !isset($item) && ($collectionTypes = self::getCollectionItemTypes($itemType))) {
                // If includeCollections is true, find collections of this item type, e.g. a music album contains songs
                if (!in_array($itemType, $collectionTypes)) {
                    $itemTypes = array_merge(array($itemType), $collectionTypes);
                } else {
                    $itemTypes = $collectionTypes;
                }
                $placeholders = join(',', array_fill(0, count($itemTypes), '?'));
                $where = ' WHERE `item_type` IN (' . $placeholders . '))';
                $queryArgs = $itemTypes;
            } else {
                $where = ' WHERE `item_type` = ?';
                $queryArgs = array($itemType);
            }
        }
        if (isset($shareType)) {
            // Include all user and group items
            if ($shareType == self::$shareTypeUserAndGroups && isset($shareWith)) {
                $where .= ' AND `share_type` IN (?,?,?)';
                $queryArgs[] = self::SHARE_TYPE_USER;
                $queryArgs[] = self::SHARE_TYPE_GROUP;
                $queryArgs[] = self::$shareTypeGroupUserUnique;
                $userAndGroups = array_merge(array($shareWith), \OC_Group::getUserGroups($shareWith));
                $placeholders = join(',', array_fill(0, count($userAndGroups), '?'));
                $where .= ' AND `share_with` IN (' . $placeholders . ')';
                $queryArgs = array_merge($queryArgs, $userAndGroups);
                // Don't include own group shares
                $where .= ' AND `uid_owner` != ?';
                $queryArgs[] = $shareWith;
            } else {
                $where .= ' AND `share_type` = ?';
                $queryArgs[] = $shareType;
                if (isset($shareWith)) {
                    $where .= ' AND `share_with` = ?';
                    $queryArgs[] = $shareWith;
                }
            }
        }
        if (isset($uidOwner)) {
            $where .= ' AND `uid_owner` = ?';
            $queryArgs[] = $uidOwner;
            if (!isset($shareType)) {
                // Prevent unique user targets for group shares from being selected
                $where .= ' AND `share_type` != ?';
                $queryArgs[] = self::$shareTypeGroupUserUnique;
            }
            if ($itemType == 'file' || $itemType == 'folder') {
                $column = 'file_source';
            } else {
                $column = 'item_source';
            }
        } else {
            if ($itemType == 'file' || $itemType == 'folder') {
                $column = 'file_target';
            } else {
                $column = 'item_target';
            }
        }
        if (isset($item)) {
            if ($includeCollections && ($collectionTypes = self::getCollectionItemTypes($itemType))) {
                $where .= ' AND (';
            } else {
                $where .= ' AND';
            }
            // If looking for own shared items, check item_source else check item_target
            if (isset($uidOwner) || $itemShareWithBySource) {
                // If item type is a file, file source needs to be checked in case the item was converted
                if ($itemType == 'file' || $itemType == 'folder') {
                    $where .= ' `file_source` = ?';
                    $column = 'file_source';
                } else {
                    $where .= ' `item_source` = ?';
                    $column = 'item_source';
                }
            } else {
                if ($itemType == 'file' || $itemType == 'folder') {
                    $where .= ' `file_target` = ?';
                    $item = \OC\Files\Filesystem::normalizePath($item);
                } else {
                    $where .= ' `item_target` = ?';
                }
            }
            $queryArgs[] = $item;
            if ($includeCollections && $collectionTypes) {
                $placeholders = join(',', array_fill(0, count($collectionTypes), '?'));
                $where .= ' OR `item_type` IN (' . $placeholders . '))';
                $queryArgs = array_merge($queryArgs, $collectionTypes);
            }
        }
        if ($limit != -1 && !$includeCollections) {
            if ($shareType == self::$shareTypeUserAndGroups) {
                // Make sure the unique user target is returned if it exists,
                // unique targets should follow the group share in the database
                // If the limit is not 1, the filtering can be done later
                $where .= ' ORDER BY `*PREFIX*share`.`id` DESC';
            }
            // The limit must be at least 3, because filtering needs to be done
            if ($limit < 3) {
                $queryLimit = 3;
            } else {
                $queryLimit = $limit;
            }
        } else {
            $queryLimit = null;
        }
        // TODO Optimize selects
        if ($format == self::FORMAT_STATUSES) {
            if ($itemType == 'file' || $itemType == 'folder') {
                $select = '`*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`,' . ' `share_type`, `file_source`, `path`, `expiration`, `storage`';
            } else {
                $select = '`id`, `item_type`, `item_source`, `parent`, `share_type`, `expiration`';
            }
        } else {
            if (isset($uidOwner)) {
                if ($itemType == 'file' || $itemType == 'folder') {
                    $select = '`*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`,' . ' `share_type`, `share_with`, `file_source`, `path`, `permissions`, `stime`,' . ' `expiration`, `token`, `storage`';
                } else {
                    $select = '`id`, `item_type`, `item_source`, `parent`, `share_type`, `share_with`, `permissions`,' . ' `stime`, `file_source`, `expiration`, `token`';
                }
            } else {
                if ($fileDependent) {
                    if (($itemType == 'file' || $itemType == 'folder') && $format == \OC_Share_Backend_File::FORMAT_GET_FOLDER_CONTENTS || $format == \OC_Share_Backend_File::FORMAT_FILE_APP_ROOT) {
                        $select = '`*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`, `uid_owner`, ' . '`share_type`, `share_with`, `file_source`, `path`, `file_target`, ' . '`permissions`, `expiration`, `storage`, `*PREFIX*filecache`.`parent` as `file_parent`, ' . '`name`, `mtime`, `mimetype`, `mimepart`, `size`, `encrypted`, `etag`';
                    } 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`, `permissions`, `stime`, `expiration`, `token`, `storage`';
                    }
                } else {
                    $select = '*';
                }
            }
        }
        $root = strlen($root);
        $query = \OC_DB::prepare('SELECT ' . $select . ' FROM `*PREFIX*share` ' . $where, $queryLimit);
        $result = $query->execute($queryArgs);
        if (\OC_DB::isError($result)) {
            \OC_Log::write('OCP\\Share', \OC_DB::getErrorMessage($result) . ', select=' . $select . ' where=' . $where, \OC_Log::ERROR);
        }
        $items = array();
        $targets = array();
        $switchedItems = array();
        $mounts = array();
        while ($row = $result->fetchRow()) {
            if (isset($row['id'])) {
                $row['id'] = (int) $row['id'];
            }
            if (isset($row['share_type'])) {
                $row['share_type'] = (int) $row['share_type'];
            }
            if (isset($row['parent'])) {
                $row['parent'] = (int) $row['parent'];
            }
            if (isset($row['file_parent'])) {
                $row['file_parent'] = (int) $row['file_parent'];
            }
            if (isset($row['file_source'])) {
                $row['file_source'] = (int) $row['file_source'];
            }
            if (isset($row['permissions'])) {
                $row['permissions'] = (int) $row['permissions'];
            }
            if (isset($row['storage'])) {
                $row['storage'] = (int) $row['storage'];
            }
            if (isset($row['stime'])) {
                $row['stime'] = (int) $row['stime'];
            }
            // Filter out duplicate group shares for users with unique targets
            if ($row['share_type'] == self::$shareTypeGroupUserUnique && isset($items[$row['parent']])) {
                $row['share_type'] = self::SHARE_TYPE_GROUP;
                $row['share_with'] = $items[$row['parent']]['share_with'];
                // Remove the parent group share
                unset($items[$row['parent']]);
                if ($row['permissions'] == 0) {
                    continue;
                }
            } else {
                if (!isset($uidOwner)) {
                    // Check if the same target already exists
                    if (isset($targets[$row[$column]])) {
                        // Check if the same owner shared with the user twice
                        // through a group and user share - this is allowed
                        $id = $targets[$row[$column]];
                        if (isset($items[$id]) && $items[$id]['uid_owner'] == $row['uid_owner']) {
                            // Switch to group share type to ensure resharing conditions aren't bypassed
                            if ($items[$id]['share_type'] != self::SHARE_TYPE_GROUP) {
                                $items[$id]['share_type'] = self::SHARE_TYPE_GROUP;
                                $items[$id]['share_with'] = $row['share_with'];
                            }
                            // Switch ids if sharing permission is granted on only
                            // one share to ensure correct parent is used if resharing
                            if (~(int) $items[$id]['permissions'] & PERMISSION_SHARE && (int) $row['permissions'] & PERMISSION_SHARE) {
                                $items[$row['id']] = $items[$id];
                                $switchedItems[$id] = $row['id'];
                                unset($items[$id]);
                                $id = $row['id'];
                            }
                            // Combine the permissions for the item
                            $items[$id]['permissions'] |= (int) $row['permissions'];
                            continue;
                        }
                    } else {
                        $targets[$row[$column]] = $row['id'];
                    }
                }
            }
            // Remove root from file source paths if retrieving own shared items
            if (isset($uidOwner) && isset($row['path'])) {
                if (isset($row['parent'])) {
                    $row['path'] = '/Shared/' . basename($row['path']);
                } else {
                    if (!isset($mounts[$row['storage']])) {
                        $mounts[$row['storage']] = \OC\Files\Mount::findByNumericId($row['storage']);
                    }
                    if ($mounts[$row['storage']]) {
                        $path = $mounts[$row['storage']]->getMountPoint() . $row['path'];
                        $row['path'] = substr($path, $root);
                    }
                }
            }
            if (isset($row['expiration'])) {
                $time = new \DateTime();
                if ($row['expiration'] < date('Y-m-d H:i', $time->format('U') - $time->getOffset())) {
                    self::delete($row['id']);
                    continue;
                }
            }
            // Check if resharing is allowed, if not remove share permission
            if (isset($row['permissions']) && !self::isResharingAllowed()) {
                $row['permissions'] &= ~PERMISSION_SHARE;
            }
            // Add display names to result
            if (isset($row['share_with']) && $row['share_with'] != '') {
                $row['share_with_displayname'] = \OCP\User::getDisplayName($row['share_with']);
            }
            if (isset($row['uid_owner']) && $row['uid_owner'] != '') {
                $row['displayname_owner'] = \OCP\User::getDisplayName($row['uid_owner']);
            }
            $items[$row['id']] = $row;
        }
        if (!empty($items)) {
            $collectionItems = array();
            foreach ($items as &$row) {
                // Return only the item instead of a 2-dimensional array
                if ($limit == 1 && $row[$column] == $item && ($row['item_type'] == $itemType || $itemType == 'file')) {
                    if ($format == self::FORMAT_NONE) {
                        return $row;
                    } else {
                        break;
                    }
                }
                // Check if this is a collection of the requested item type
                if ($includeCollections && $collectionTypes && in_array($row['item_type'], $collectionTypes)) {
                    if (($collectionBackend = self::getBackend($row['item_type'])) && $collectionBackend instanceof Share_Backend_Collection) {
                        // Collections can be inside collections, check if the item is a collection
                        if (isset($item) && $row['item_type'] == $itemType && $row[$column] == $item) {
                            $collectionItems[] = $row;
                        } else {
                            $collection = array();
                            $collection['item_type'] = $row['item_type'];
                            if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') {
                                $collection['path'] = basename($row['path']);
                            }
                            $row['collection'] = $collection;
                            // Fetch all of the children sources
                            $children = $collectionBackend->getChildren($row[$column]);
                            foreach ($children as $child) {
                                $childItem = $row;
                                $childItem['item_type'] = $itemType;
                                if ($row['item_type'] != 'file' && $row['item_type'] != 'folder') {
                                    $childItem['item_source'] = $child['source'];
                                    $childItem['item_target'] = $child['target'];
                                }
                                if ($backend instanceof Share_Backend_File_Dependent) {
                                    if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') {
                                        $childItem['file_source'] = $child['source'];
                                    } else {
                                        $meta = \OC\Files\Filesystem::getFileInfo($child['file_path']);
                                        $childItem['file_source'] = $meta['fileid'];
                                    }
                                    $childItem['file_target'] = \OC\Files\Filesystem::normalizePath($child['file_path']);
                                }
                                if (isset($item)) {
                                    if ($childItem[$column] == $item) {
                                        // Return only the item instead of a 2-dimensional array
                                        if ($limit == 1) {
                                            if ($format == self::FORMAT_NONE) {
                                                return $childItem;
                                            } else {
                                                // Unset the items array and break out of both loops
                                                $items = array();
                                                $items[] = $childItem;
                                                break 2;
                                            }
                                        } else {
                                            $collectionItems[] = $childItem;
                                        }
                                    }
                                } else {
                                    $collectionItems[] = $childItem;
                                }
                            }
                        }
                    }
                    // Remove collection item
                    $toRemove = $row['id'];
                    if (array_key_exists($toRemove, $switchedItems)) {
                        $toRemove = $switchedItems[$toRemove];
                    }
                    unset($items[$toRemove]);
                }
            }
            if (!empty($collectionItems)) {
                $items = array_merge($items, $collectionItems);
            }
            if (empty($items) && $limit == 1) {
                return false;
            }
            if ($format == self::FORMAT_NONE) {
                return $items;
            } else {
                if ($format == self::FORMAT_STATUSES) {
                    $statuses = array();
                    foreach ($items as $item) {
                        if ($item['share_type'] == self::SHARE_TYPE_LINK) {
                            $statuses[$item[$column]]['link'] = true;
                        } else {
                            if (!isset($statuses[$item[$column]])) {
                                $statuses[$item[$column]]['link'] = false;
                            }
                        }
                        if ($itemType == 'file' || $itemType == 'folder') {
                            $statuses[$item[$column]]['path'] = $item['path'];
                        }
                    }
                    return $statuses;
                } else {
                    return $backend->formatItems($items, $format, $parameters);
                }
            }
        } else {
            if ($limit == 1 || isset($uidOwner) && isset($item)) {
                return false;
            }
        }
        return array();
    }