public function isSharable($path) { if (\OCP\Util::isSharingDisabledForUser() || !\OC\Share\Share::isResharingAllowed()) { return false; } return $this->getPermissions($path) & \OCP\Constants::PERMISSION_SHARE; }
/** * Get shared items from the database * @param string $itemType * @param string $item Item source or target (optional) * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, SHARE_TYPE_LINK, $shareTypeUserAndGroups, or $shareTypeGroupUserUnique * @param string $shareWith User or group the item is being shared with * @param string $uidOwner User that is the owner of shared items (optional) * @param int $format Format to convert items to with formatItems() (optional) * @param mixed $parameters to pass to formatItems() (optional) * @param int $limit Number of items to return, -1 to return all matches (optional) * @param boolean $includeCollections Include collection item types (optional) * @param boolean $itemShareWithBySource (optional) * @param boolean $checkExpireDate * @return array * * See public functions getItem(s)... for parameter usage * */ public static function getItems($itemType, $item = null, $shareType = null, $shareWith = null, $uidOwner = null, $format = self::FORMAT_NONE, $parameters = null, $limit = -1, $includeCollections = false, $itemShareWithBySource = false, $checkExpireDate = true) { if (!self::isEnabled()) { 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') { if (!is_null($uidOwner)) { $root = \OC\Files\Filesystem::getRoot(); } else { $root = ''; } $where = 'INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid` '; if (!isset($item)) { $where .= ' AND `file_target` IS NOT NULL '; } $where .= 'INNER JOIN `*PREFIX*storages` ON `numeric_id` = `*PREFIX*filecache`.`storage` '; $fileDependent = true; $queryArgs = array(); } else { $fileDependent = false; $root = ''; $collectionTypes = self::getCollectionItemTypes($itemType); if ($includeCollections && !isset($item) && $collectionTypes) { // 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 (\OC::$server->getAppConfig()->getValue('core', 'shareapi_allow_links', 'yes') !== 'yes') { $where .= ' AND `share_type` != ?'; $queryArgs[] = self::SHARE_TYPE_LINK; } if (isset($shareType)) { // Include all user and group items if ($shareType == self::$shareTypeUserAndGroups && isset($shareWith)) { $where .= ' AND ((`share_type` in (?, ?) AND `share_with` = ?) '; $queryArgs[] = self::SHARE_TYPE_USER; $queryArgs[] = self::$shareTypeGroupUserUnique; $queryArgs[] = $shareWith; $groups = \OC_Group::getUserGroups($shareWith); if (!empty($groups)) { $placeholders = join(',', array_fill(0, count($groups), '?')); $where .= ' OR (`share_type` = ? AND `share_with` IN (' . $placeholders . ')) '; $queryArgs[] = self::SHARE_TYPE_GROUP; $queryArgs = array_merge($queryArgs, $groups); } $where .= ')'; // 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 ($fileDependent) { $column = 'file_source'; } else { $column = 'item_source'; } } else { if ($fileDependent) { $column = 'file_target'; } else { $column = 'item_target'; } } if (isset($item)) { $collectionTypes = self::getCollectionItemTypes($itemType); if ($includeCollections && $collectionTypes && !in_array('folder', $collectionTypes)) { $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 ($fileDependent) { $where .= ' `file_source` = ?'; $column = 'file_source'; } else { $where .= ' `item_source` = ?'; $column = 'item_source'; } } else { if ($fileDependent) { $where .= ' `file_target` = ?'; $item = \OC\Files\Filesystem::normalizePath($item); } else { $where .= ' `item_target` = ?'; } } $queryArgs[] = $item; if ($includeCollections && $collectionTypes && !in_array('folder', $collectionTypes)) { $placeholders = join(',', array_fill(0, count($collectionTypes), '?')); $where .= ' OR `item_type` IN (' . $placeholders . '))'; $queryArgs = array_merge($queryArgs, $collectionTypes); } } if ($shareType == self::$shareTypeUserAndGroups && $limit === 1) { // 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'; } else { $where .= ' ORDER BY `*PREFIX*share`.`id` ASC'; } if ($limit != -1 && !$includeCollections) { // The limit must be at least 3, because filtering needs to be done if ($limit < 3) { $queryLimit = 3; } else { $queryLimit = $limit; } } else { $queryLimit = null; } $select = self::createSelectStatement($format, $fileDependent, $uidOwner); $root = strlen($root); $query = \OC_DB::prepare('SELECT ' . $select . ' FROM `*PREFIX*share` ' . $where, $queryLimit); $result = $query->execute($queryArgs); if (\OC_DB::isError($result)) { \OCP\Util::writeLog('OCP\\Share', \OC_DB::getErrorMessage() . ', select=' . $select . ' where=', \OCP\Util::ERROR); } $items = array(); $targets = array(); $switchedItems = array(); $mounts = array(); 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 $row['share_with'] = $items[$row['parent']]['share_with']; // if the group share was unshared from the user we keep the permission, otherwise // we take the permission from the parent because this is always the up-to-date // permission for the group share if ($row['permissions'] > 0) { $row['permissions'] = $items[$row['parent']]['permissions']; } // 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['id']])) { // Check if the same owner shared with the user twice // through a group and user share - this is allowed $id = $targets[$row['id']]; 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'] & \OCP\Constants::PERMISSION_SHARE && (int) $row['permissions'] & \OCP\Constants::PERMISSION_SHARE) { $items[$row['id']] = $items[$id]; $switchedItems[$id] = $row['id']; unset($items[$id]); $id = $row['id']; } $items[$id]['permissions'] |= (int) $row['permissions']; } continue; } elseif (!empty($row['parent'])) { $targets[$row['parent']] = $row['id']; } } } // Remove root from file source paths if retrieving own shared items if (isset($uidOwner) && isset($row['path'])) { if (isset($row['parent'])) { $query = \OC_DB::prepare('SELECT `file_target` FROM `*PREFIX*share` WHERE `id` = ?'); $parentResult = $query->execute(array($row['parent'])); if (\OC_DB::isError($result)) { \OCP\Util::writeLog('OCP\\Share', 'Can\'t select parent: ' . \OC_DB::getErrorMessage() . ', select=' . $select . ' where=' . $where, \OCP\Util::ERROR); } else { $parentRow = $parentResult->fetchRow(); $tmpPath = $parentRow['file_target']; // find the right position where the row path continues from the target path $pos = strrpos($row['path'], $parentRow['file_target']); $subPath = substr($row['path'], $pos); $splitPath = explode('/', $subPath); foreach (array_slice($splitPath, 2) as $pathPart) { $tmpPath = $tmpPath . '/' . $pathPart; } $row['path'] = $tmpPath; } } else { if (!isset($mounts[$row['storage']])) { $mountPoints = \OC\Files\Filesystem::getMountByNumericId($row['storage']); if (is_array($mountPoints) && !empty($mountPoints)) { $mounts[$row['storage']] = current($mountPoints); } } if (!empty($mounts[$row['storage']])) { $path = $mounts[$row['storage']]->getMountPoint() . $row['path']; $relPath = substr($path, $root); // path relative to data/user $row['path'] = rtrim($relPath, '/'); } } } if ($checkExpireDate) { if (self::expireItem($row)) { continue; } } // Check if resharing is allowed, if not remove share permission if (isset($row['permissions']) && !self::isResharingAllowed() | \OCP\Util::isSharingDisabledForUser()) { $row['permissions'] &= ~\OCP\Constants::PERMISSION_SHARE; } // Add display names to result $row['share_with_displayname'] = $row['share_with']; if (isset($row['share_with']) && $row['share_with'] != '' && $row['share_type'] === self::SHARE_TYPE_USER) { $row['share_with_displayname'] = \OCP\User::getDisplayName($row['share_with']); } else { if (isset($row['share_with']) && $row['share_with'] != '' && $row['share_type'] === self::SHARE_TYPE_REMOTE) { $addressBookEntries = \OC::$server->getContactsManager()->search($row['share_with'], ['CLOUD']); foreach ($addressBookEntries as $entry) { foreach ($entry['CLOUD'] as $cloudID) { if ($cloudID === $row['share_with']) { $row['share_with_displayname'] = $entry['FN']; } } } } } if (isset($row['uid_owner']) && $row['uid_owner'] != '') { $row['displayname_owner'] = \OCP\User::getDisplayName($row['uid_owner']); } if ($row['permissions'] > 0) { $items[$row['id']] = $row; } } // group items if we are looking for items shared with the current user if (isset($shareWith) && $shareWith === \OCP\User::getUser()) { $items = self::groupItems($items, $itemType); } 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 && $row['item_type'] !== 'folder' && in_array($row['item_type'], $collectionTypes)) { if (($collectionBackend = self::getBackend($row['item_type'])) && $collectionBackend instanceof \OCP\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 \OCP\Share_Backend_File_Dependent) { if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') { $childItem['file_source'] = $child['source']; } else { // TODO is this really needed if we already know that we use the file backend? $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]); } elseif ($includeCollections && $collectionTypes && in_array($row['item_type'], $collectionTypes)) { // FIXME: Thats a dirty hack to improve file sharing performance, // see github issue #10588 for more details // Need to find a solution which works for all back-ends $collectionBackend = self::getBackend($row['item_type']); $sharedParents = $collectionBackend->getParents($row['item_source']); foreach ($sharedParents as $parent) { $collectionItems[] = $parent; } } } if (!empty($collectionItems)) { $collectionItems = array_unique($collectionItems, SORT_REGULAR); $items = array_merge($items, $collectionItems); } // filter out invalid items, these can appear when subshare entries exist // for a group in which the requested user isn't a member any more $items = array_filter($items, function ($item) { return $item['share_type'] !== self::$shareTypeGroupUserUnique; }); return self::formatResult($items, $column, $backend, $format, $parameters); } elseif ($includeCollections && $collectionTypes && in_array('folder', $collectionTypes)) { // FIXME: Thats a dirty hack to improve file sharing performance, // see github issue #10588 for more details // Need to find a solution which works for all back-ends $collectionItems = array(); $collectionBackend = self::getBackend('folder'); $sharedParents = $collectionBackend->getParents($item, $shareWith, $uidOwner); foreach ($sharedParents as $parent) { $collectionItems[] = $parent; } if ($limit === 1) { return reset($collectionItems); } return self::formatResult($collectionItems, $column, $backend, $format, $parameters); } return array(); }
/** * get the content of a directory * * @param string $directory path under datadirectory * @param string $mimetype_filter limit returned content to this mimetype or mimepart * @return FileInfo[] */ public function getDirectoryContent($directory, $mimetype_filter = '') { $this->assertPathLength($directory); $result = array(); if (!Filesystem::isValidPath($directory)) { return $result; } $path = $this->getAbsolutePath($directory); $path = Filesystem::normalizePath($path); $mount = $this->getMount($directory); $storage = $mount->getStorage(); $internalPath = $mount->getInternalPath($path); if ($storage) { $cache = $storage->getCache($internalPath); $user = \OC_User::getUser(); $data = $cache->get($internalPath); $watcher = $storage->getWatcher($internalPath); if (!$data or $data['size'] === -1) { if (!$storage->file_exists($internalPath)) { return array(); } $scanner = $storage->getScanner($internalPath); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); $data = $cache->get($internalPath); } else { if ($watcher->checkUpdate($internalPath, $data)) { $this->updater->propagate($path); $data = $cache->get($internalPath); } } $folderId = $data['fileid']; /** * @var \OC\Files\FileInfo[] $files */ $files = array(); $contents = $cache->getFolderContentsById($folderId); //TODO: mimetype_filter foreach ($contents as $content) { if ($content['permissions'] === 0) { $content['permissions'] = $storage->getPermissions($content['path']); $cache->update($content['fileid'], array('permissions' => $content['permissions'])); } // if sharing was disabled for the user we remove the share permissions if (\OCP\Util::isSharingDisabledForUser()) { $content['permissions'] = $content['permissions'] & ~\OCP\Constants::PERMISSION_SHARE; } $files[] = new FileInfo($path . '/' . $content['name'], $storage, $content['path'], $content, $mount); } //add a folder for any mountpoint in this directory and add the sizes of other mountpoints to the folders $mounts = Filesystem::getMountManager()->findIn($path); $dirLength = strlen($path); foreach ($mounts as $mount) { $mountPoint = $mount->getMountPoint(); $subStorage = $mount->getStorage(); if ($subStorage) { $subCache = $subStorage->getCache(''); if ($subCache->getStatus('') === Cache\Cache::NOT_FOUND) { $subScanner = $subStorage->getScanner(''); try { $subScanner->scanFile(''); } catch (\OCP\Files\StorageNotAvailableException $e) { continue; } catch (\OCP\Files\StorageInvalidException $e) { continue; } catch (\Exception $e) { // sometimes when the storage is not available it can be any exception \OCP\Util::writeLog('core', 'Exception while scanning storage "' . $subStorage->getId() . '": ' . get_class($e) . ': ' . $e->getMessage(), \OCP\Util::ERROR); continue; } } $rootEntry = $subCache->get(''); if ($rootEntry) { $relativePath = trim(substr($mountPoint, $dirLength), '/'); if ($pos = strpos($relativePath, '/')) { //mountpoint inside subfolder add size to the correct folder $entryName = substr($relativePath, 0, $pos); foreach ($files as &$entry) { if ($entry['name'] === $entryName) { $entry['size'] += $rootEntry['size']; } } } else { //mountpoint in this folder, add an entry for it $rootEntry['name'] = $relativePath; $rootEntry['type'] = $rootEntry['mimetype'] === 'httpd/unix-directory' ? 'dir' : 'file'; $permissions = $rootEntry['permissions']; // do not allow renaming/deleting the mount point if they are not shared files/folders // for shared files/folders we use the permissions given by the owner if ($mount instanceof MoveableMount) { $rootEntry['permissions'] = $permissions | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE; } else { $rootEntry['permissions'] = $permissions & \OCP\Constants::PERMISSION_ALL - (\OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE); } //remove any existing entry with the same name foreach ($files as $i => $file) { if ($file['name'] === $rootEntry['name']) { unset($files[$i]); break; } } $rootEntry['path'] = substr(Filesystem::normalizePath($path . '/' . $rootEntry['name']), strlen($user) + 2); // full path without /$user/ // if sharing was disabled for the user we remove the share permissions if (\OCP\Util::isSharingDisabledForUser()) { $content['permissions'] = $content['permissions'] & ~\OCP\Constants::PERMISSION_SHARE; } $files[] = new FileInfo($path . '/' . $rootEntry['name'], $subStorage, '', $rootEntry, $mount); } } } } if ($mimetype_filter) { foreach ($files as $file) { if (strpos($mimetype_filter, '/')) { if ($file['mimetype'] === $mimetype_filter) { $result[] = $file; } } else { if ($file['mimepart'] === $mimetype_filter) { $result[] = $file; } } } } else { $result = $files; } } return $result; }
public function isSharable($path) { if (\OCP\Util::isSharingDisabledForUser()) { return false; } return $this->getPermissions($path) & \OCP\PERMISSION_SHARE; }
// Set the content type to Javascript header("Content-type: text/javascript"); // Disallow caching header("Cache-Control: no-cache, must-revalidate"); header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Enable l10n support $l = \OC::$server->getL10N('core'); // Enable OC_Defaults support $defaults = new OC_Defaults(); // Get the config $apps_paths = array(); foreach (OC_App::getEnabledApps() as $app) { $apps_paths[$app] = OC_App::getAppWebPath($app); } $config = \OC::$server->getConfig(); $value = $config->getAppValue('core', 'shareapi_default_expire_date', 'no'); $defaultExpireDateEnabled = $value === 'yes' ? true : false; $defaultExpireDate = $enforceDefaultExpireDate = null; if ($defaultExpireDateEnabled) { $defaultExpireDate = (int) $config->getAppValue('core', 'shareapi_expire_after_n_days', '7'); $value = $config->getAppValue('core', 'shareapi_enforce_expire_date', 'no'); $enforceDefaultExpireDate = $value === 'yes' ? true : false; } $outgoingServer2serverShareEnabled = $config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'yes'; $array = array("oc_debug" => defined('DEBUG') && DEBUG ? 'true' : 'false', "oc_isadmin" => OC_User::isAdminUser(OC_User::getUser()) ? 'true' : 'false', "oc_webroot" => "\"" . OC::$WEBROOT . "\"", "oc_appswebroots" => str_replace('\\/', '/', json_encode($apps_paths)), "datepickerFormatDate" => json_encode($l->getDateFormat()), "dayNames" => json_encode(array((string) $l->t('Sunday'), (string) $l->t('Monday'), (string) $l->t('Tuesday'), (string) $l->t('Wednesday'), (string) $l->t('Thursday'), (string) $l->t('Friday'), (string) $l->t('Saturday'))), "monthNames" => json_encode(array((string) $l->t('January'), (string) $l->t('February'), (string) $l->t('March'), (string) $l->t('April'), (string) $l->t('May'), (string) $l->t('June'), (string) $l->t('July'), (string) $l->t('August'), (string) $l->t('September'), (string) $l->t('October'), (string) $l->t('November'), (string) $l->t('December'))), "firstDay" => json_encode($l->getFirstWeekDay()), "oc_config" => json_encode(array('session_lifetime' => min(\OCP\Config::getSystemValue('session_lifetime', ini_get('session.gc_maxlifetime')), ini_get('session.gc_maxlifetime')), 'session_keepalive' => \OCP\Config::getSystemValue('session_keepalive', true), 'version' => implode('.', OC_Util::getVersion()), 'versionstring' => OC_Util::getVersionString(), 'enable_avatars' => \OC::$server->getConfig()->getSystemValue('enable_avatars', true))), "oc_appconfig" => json_encode(array("core" => array('defaultExpireDateEnabled' => $defaultExpireDateEnabled, 'defaultExpireDate' => $defaultExpireDate, 'defaultExpireDateEnforced' => $enforceDefaultExpireDate, 'enforcePasswordForPublicLink' => \OCP\Util::isPublicLinkPasswordRequired(), 'sharingDisabledForUser' => \OCP\Util::isSharingDisabledForUser(), 'resharingAllowed' => \OCP\Share::isResharingAllowed(), 'remoteShareAllowed' => $outgoingServer2serverShareEnabled, 'federatedCloudShareDoc' => \OC::$server->getURLGenerator()->linkToDocs('user-sharing-federated')))), "oc_defaults" => json_encode(array('entity' => $defaults->getEntity(), 'name' => $defaults->getName(), 'title' => $defaults->getTitle(), 'baseUrl' => $defaults->getBaseUrl(), 'syncClientUrl' => $defaults->getSyncClientUrl(), 'docBaseUrl' => $defaults->getDocBaseUrl(), 'slogan' => $defaults->getSlogan(), 'logoClaim' => $defaults->getLogoClaim(), 'shortFooter' => $defaults->getShortFooter(), 'longFooter' => $defaults->getLongFooter()))); // Allow hooks to modify the output values OC_Hook::emit('\\OCP\\Config', 'js', array('array' => &$array)); // Echo it foreach ($array as $setting => $value) { echo "var " . $setting . "=" . $value . ";\n"; }
public function isSharable($path) { if (\OCP\Util::isSharingDisabledForUser()) { return false; } return $this->isReadable($path); }
/** * @dataProvider dataProviderForTestIsSharingDisabledForUser * @param array $groups existing groups * @param array $membership groups the user belong to * @param array $excludedGroups groups which should be excluded from sharing * @param bool $expected expected result */ function testIsSharingDisabledForUser($groups, $membership, $excludedGroups, $expected) { $uid = "user1"; \OC_User::setUserId($uid); \OC_User::createUser($uid, "passwd"); foreach ($groups as $group) { \OC_Group::createGroup($group); } foreach ($membership as $group) { \OC_Group::addToGroup($uid, $group); } $appConfig = \OC::$server->getAppConfig(); $appConfig->setValue('core', 'shareapi_exclude_groups_list', implode(',', $excludedGroups)); $appConfig->setValue('core', 'shareapi_exclude_groups', 'yes'); $result = \OCP\Util::isSharingDisabledForUser(); $this->assertSame($expected, $result); // cleanup \OC_User::deleteUser($uid); \OC_User::setUserId(''); foreach ($groups as $group) { \OC_Group::deleteGroup($group); } $appConfig->setValue('core', 'shareapi_exclude_groups_list', ''); $appConfig->setValue('core', 'shareapi_exclude_groups', 'no'); }
/** * @return int */ public function getPermissions() { $perms = $this->data['permissions']; if (\OCP\Util::isSharingDisabledForUser() || $this->isShared() && !\OC\Share\Share::isResharingAllowed()) { $perms = $perms & ~\OCP\Constants::PERMISSION_SHARE; } return $perms; }
\OC::$CLASSPATH['OC_Share_Backend_Folder'] = 'files_sharing/lib/share/folder.php'; \OC::$CLASSPATH['OC\\Files\\Storage\\Shared'] = 'files_sharing/lib/sharedstorage.php'; $application = new \OCA\Files_Sharing\AppInfo\Application(); $application->registerMountProviders(); \OCA\Files_Sharing\Helper::registerHooks(); \OCP\Share::registerBackend('file', 'OC_Share_Backend_File'); \OCP\Share::registerBackend('folder', 'OC_Share_Backend_Folder', 'file'); $eventDispatcher = \OC::$server->getEventDispatcher(); $eventDispatcher->addListener('OCA\\Files::loadAdditionalScripts', function () { \OCP\Util::addScript('files_sharing', 'share'); \OCP\Util::addScript('files_sharing', 'sharetabview'); if (\OC::$server->getConfig()->getAppValue('files_sharing', 'incoming_server2server_share_enabled', 'yes') === 'yes') { \OCP\Util::addScript('files_sharing', 'external'); } \OCP\Util::addStyle('files_sharing', 'sharetabview'); }); // \OCP\Util::addStyle('files_sharing', 'sharetabview'); \OC::$server->getActivityManager()->registerExtension(function () { return new \OCA\Files_Sharing\Activity(\OC::$server->query('L10NFactory'), \OC::$server->getURLGenerator(), \OC::$server->getActivityManager()); }); $config = \OC::$server->getConfig(); if ($config->getAppValue('core', 'shareapi_enabled', 'yes') === 'yes') { \OCA\Files\App::getNavigationManager()->add(array("id" => 'sharingin', "appname" => 'files_sharing', "script" => 'list.php', "order" => 10, "name" => $l->t('Shared with you'))); if (\OCP\Util::isSharingDisabledForUser() === false) { \OCA\Files\App::getNavigationManager()->add(array("id" => 'sharingout', "appname" => 'files_sharing', "script" => 'list.php', "order" => 15, "name" => $l->t('Shared with others'))); // Check if sharing by link is enabled if ($config->getAppValue('core', 'shareapi_allow_links', 'yes') === 'yes') { \OCA\Files\App::getNavigationManager()->add(array("id" => 'sharinglinks', "appname" => 'files_sharing', "script" => 'list.php', "order" => 20, "name" => $l->t('Shared by link'))); } } }
// Set the content type to Javascript header("Content-type: text/javascript"); // Disallow caching header("Cache-Control: no-cache, must-revalidate"); header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Enable l10n support $l = \OC::$server->getL10N('core'); // Enable OC_Defaults support $defaults = new OC_Defaults(); // Get the config $apps_paths = array(); foreach (OC_App::getEnabledApps() as $app) { $apps_paths[$app] = OC_App::getAppWebPath($app); } $config = \OC::$server->getConfig(); $value = $config->getAppValue('core', 'shareapi_default_expire_date', 'no'); $defaultExpireDateEnabled = $value === 'yes' ? true : false; $defaultExpireDate = $enforceDefaultExpireDate = null; if ($defaultExpireDateEnabled) { $defaultExpireDate = (int) $config->getAppValue('core', 'shareapi_expire_after_n_days', '7'); $value = $config->getAppValue('core', 'shareapi_enforce_expire_date', 'no'); $enforceDefaultExpireDate = $value === 'yes' ? true : false; } $outgoingServer2serverShareEnabled = $config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'yes'; $array = array("oc_debug" => $config->getSystemValue('debug', false) ? 'true' : 'false', "oc_isadmin" => OC_User::isAdminUser(OC_User::getUser()) ? 'true' : 'false', "oc_webroot" => "\"" . OC::$WEBROOT . "\"", "oc_appswebroots" => str_replace('\\/', '/', json_encode($apps_paths)), "datepickerFormatDate" => json_encode($l->l('jsdate', null)), "dayNames" => json_encode(array((string) $l->t('Sunday'), (string) $l->t('Monday'), (string) $l->t('Tuesday'), (string) $l->t('Wednesday'), (string) $l->t('Thursday'), (string) $l->t('Friday'), (string) $l->t('Saturday'))), "dayNamesShort" => json_encode(array((string) $l->t('Sun.'), (string) $l->t('Mon.'), (string) $l->t('Tue.'), (string) $l->t('Wed.'), (string) $l->t('Thu.'), (string) $l->t('Fri.'), (string) $l->t('Sat.'))), "dayNamesMin" => json_encode(array((string) $l->t('Su'), (string) $l->t('Mo'), (string) $l->t('Tu'), (string) $l->t('We'), (string) $l->t('Th'), (string) $l->t('Fr'), (string) $l->t('Sa'))), "monthNames" => json_encode(array((string) $l->t('January'), (string) $l->t('February'), (string) $l->t('March'), (string) $l->t('April'), (string) $l->t('May'), (string) $l->t('June'), (string) $l->t('July'), (string) $l->t('August'), (string) $l->t('September'), (string) $l->t('October'), (string) $l->t('November'), (string) $l->t('December'))), "monthNamesShort" => json_encode(array((string) $l->t('Jan.'), (string) $l->t('Feb.'), (string) $l->t('Mar.'), (string) $l->t('Apr.'), (string) $l->t('May.'), (string) $l->t('Jun.'), (string) $l->t('Jul.'), (string) $l->t('Aug.'), (string) $l->t('Sep.'), (string) $l->t('Oct.'), (string) $l->t('Nov.'), (string) $l->t('Dec.'))), "firstDay" => json_encode($l->l('firstday', null)), "oc_config" => json_encode(array('session_lifetime' => min(\OCP\Config::getSystemValue('session_lifetime', OC::$server->getIniWrapper()->getNumeric('session.gc_maxlifetime')), OC::$server->getIniWrapper()->getNumeric('session.gc_maxlifetime')), 'session_keepalive' => \OCP\Config::getSystemValue('session_keepalive', true), 'version' => implode('.', \OCP\Util::getVersion()), 'versionstring' => OC_Util::getVersionString(), 'enable_avatars' => \OC::$server->getConfig()->getSystemValue('enable_avatars', true), 'lost_password_link' => \OC::$server->getConfig()->getSystemValue('lost_password_link', null), 'modRewriteWorking' => getenv('front_controller_active') === 'true')), "oc_appconfig" => json_encode(array("core" => array('defaultExpireDateEnabled' => $defaultExpireDateEnabled, 'defaultExpireDate' => $defaultExpireDate, 'defaultExpireDateEnforced' => $enforceDefaultExpireDate, 'enforcePasswordForPublicLink' => \OCP\Util::isPublicLinkPasswordRequired(), 'sharingDisabledForUser' => \OCP\Util::isSharingDisabledForUser(), 'resharingAllowed' => \OCP\Share::isResharingAllowed(), 'remoteShareAllowed' => $outgoingServer2serverShareEnabled, 'federatedCloudShareDoc' => \OC::$server->getURLGenerator()->linkToDocs('user-sharing-federated')))), "oc_defaults" => json_encode(array('entity' => $defaults->getEntity(), 'name' => $defaults->getName(), 'title' => $defaults->getTitle(), 'baseUrl' => $defaults->getBaseUrl(), 'syncClientUrl' => $defaults->getSyncClientUrl(), 'docBaseUrl' => $defaults->getDocBaseUrl(), 'docPlaceholderUrl' => $defaults->buildDocLinkToKey('PLACEHOLDER'), 'slogan' => $defaults->getSlogan(), 'logoClaim' => $defaults->getLogoClaim(), 'shortFooter' => $defaults->getShortFooter(), 'longFooter' => $defaults->getLongFooter(), 'folder' => OC_Util::getTheme()))); // Allow hooks to modify the output values OC_Hook::emit('\\OCP\\Config', 'js', array('array' => &$array)); // Echo it foreach ($array as $setting => $value) { echo "var " . $setting . "=" . $value . ";\n"; }
/** * Share an item with a user, group, or via private link * @param string $itemType * @param string $itemSource * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, or SHARE_TYPE_LINK * @param string $shareWith User or group the item is being shared with * @param int $permissions CRUDS * @param string $itemSourceName * @param \DateTime $expirationDate * @param bool $passwordChanged * @return boolean|string Returns true on success or false on failure, Returns token on success for links * @throws \OC\HintException when the share type is remote and the shareWith is invalid * @throws \Exception */ public static function shareItem($itemType, $itemSource, $shareType, $shareWith, $permissions, $itemSourceName = null, \DateTime $expirationDate = null, $passwordChanged = null) { $backend = self::getBackend($itemType); $l = \OC::$server->getL10N('lib'); if ($backend->isShareTypeAllowed($shareType) === false) { $message = 'Sharing %s failed, because the backend does not allow shares from type %i'; $message_t = $l->t('Sharing %s failed, because the backend does not allow shares from type %i', array($itemSourceName, $shareType)); \OCP\Util::writeLog('OCP\\Share', sprintf($message, $itemSourceName, $shareType), \OCP\Util::DEBUG); throw new \Exception($message_t); } $uidOwner = \OC_User::getUser(); $shareWithinGroupOnly = self::shareWithGroupMembersOnly(); if (is_null($itemSourceName)) { $itemSourceName = $itemSource; } $itemName = $itemSourceName; // check if file can be shared if ($itemType === 'file' or $itemType === 'folder') { $path = \OC\Files\Filesystem::getPath($itemSource); $itemName = $path; // verify that the file exists before we try to share it if (!$path) { $message = 'Sharing %s failed, because the file does not exist'; $message_t = $l->t('Sharing %s failed, because the file does not exist', array($itemSourceName)); \OCP\Util::writeLog('OCP\\Share', sprintf($message, $itemSourceName), \OCP\Util::DEBUG); throw new \Exception($message_t); } // verify that the user has share permission if (!\OC\Files\Filesystem::isSharable($path) || \OCP\Util::isSharingDisabledForUser()) { $message = 'You are not allowed to share %s'; $message_t = $l->t('You are not allowed to share %s', [$path]); \OCP\Util::writeLog('OCP\\Share', sprintf($message, $path), \OCP\Util::DEBUG); throw new \Exception($message_t); } } //verify that we don't share a folder which already contains a share mount point if ($itemType === 'folder') { $path = '/' . $uidOwner . '/files' . \OC\Files\Filesystem::getPath($itemSource) . '/'; $mountManager = \OC\Files\Filesystem::getMountManager(); $mounts = $mountManager->findIn($path); foreach ($mounts as $mount) { if ($mount->getStorage()->instanceOfStorage('\\OCA\\Files_Sharing\\ISharedStorage')) { $message = 'Sharing "' . $itemSourceName . '" failed, because it contains files shared with you!'; \OCP\Util::writeLog('OCP\\Share', $message, \OCP\Util::DEBUG); throw new \Exception($message); } } } // single file shares should never have delete permissions if ($itemType === 'file') { $permissions = (int) $permissions & ~\OCP\Constants::PERMISSION_DELETE; } //Validate expirationDate if ($expirationDate !== null) { try { /* * Reuse the validateExpireDate. * We have to pass time() since the second arg is the time * the file was shared, since it is not shared yet we just use * the current time. */ $expirationDate = self::validateExpireDate($expirationDate->format('Y-m-d'), time(), $itemType, $itemSource); } catch (\Exception $e) { throw new \OC\HintException($e->getMessage(), $e->getMessage(), 404); } } // Verify share type and sharing conditions are met if ($shareType === self::SHARE_TYPE_USER) { if ($shareWith == $uidOwner) { $message = 'Sharing %s failed, because you can not share with yourself'; $message_t = $l->t('Sharing %s failed, because you can not share with yourself', [$itemName]); \OCP\Util::writeLog('OCP\\Share', sprintf($message, $itemSourceName), \OCP\Util::DEBUG); throw new \Exception($message_t); } if (!\OC_User::userExists($shareWith)) { $message = 'Sharing %s failed, because the user %s does not exist'; $message_t = $l->t('Sharing %s failed, because the user %s does not exist', array($itemSourceName, $shareWith)); \OCP\Util::writeLog('OCP\\Share', sprintf($message, $itemSourceName, $shareWith), \OCP\Util::DEBUG); throw new \Exception($message_t); } if ($shareWithinGroupOnly) { $inGroup = array_intersect(\OC_Group::getUserGroups($uidOwner), \OC_Group::getUserGroups($shareWith)); if (empty($inGroup)) { $message = 'Sharing %s failed, because the user ' . '%s is not a member of any groups that %s is a member of'; $message_t = $l->t('Sharing %s failed, because the user %s is not a member of any groups that %s is a member of', array($itemName, $shareWith, $uidOwner)); \OCP\Util::writeLog('OCP\\Share', sprintf($message, $itemName, $shareWith, $uidOwner), \OCP\Util::DEBUG); throw new \Exception($message_t); } } // Check if the item source is already shared with the user, either from the same owner or a different user if ($checkExists = self::getItems($itemType, $itemSource, self::$shareTypeUserAndGroups, $shareWith, null, self::FORMAT_NONE, null, 1, true, true)) { // Only allow the same share to occur again if it is the same // owner and is not a user share, this use case is for increasing // permissions for a specific user if ($checkExists['uid_owner'] != $uidOwner || $checkExists['share_type'] == $shareType) { $message = 'Sharing %s failed, because this item is already shared with %s'; $message_t = $l->t('Sharing %s failed, because this item is already shared with %s', array($itemSourceName, $shareWith)); \OCP\Util::writeLog('OCP\\Share', sprintf($message, $itemSourceName, $shareWith), \OCP\Util::DEBUG); throw new \Exception($message_t); } } if ($checkExists = self::getItems($itemType, $itemSource, self::SHARE_TYPE_USER, $shareWith, null, self::FORMAT_NONE, null, 1, true, true)) { // Only allow the same share to occur again if it is the same // owner and is not a user share, this use case is for increasing // permissions for a specific user if ($checkExists['uid_owner'] != $uidOwner || $checkExists['share_type'] == $shareType) { $message = 'Sharing %s failed, because this item is already shared with user %s'; $message_t = $l->t('Sharing %s failed, because this item is already shared with user %s', array($itemSourceName, $shareWith)); \OCP\Util::writeLog('OCP\\Share', sprintf($message, $itemSourceName, $shareWith), \OCP\Util::ERROR); throw new \Exception($message_t); } } } else { if ($shareType === self::SHARE_TYPE_GROUP) { if (!\OC_Group::groupExists($shareWith)) { $message = 'Sharing %s failed, because the group %s does not exist'; $message_t = $l->t('Sharing %s failed, because the group %s does not exist', array($itemSourceName, $shareWith)); \OCP\Util::writeLog('OCP\\Share', sprintf($message, $itemSourceName, $shareWith), \OCP\Util::DEBUG); throw new \Exception($message_t); } if ($shareWithinGroupOnly && !\OC_Group::inGroup($uidOwner, $shareWith)) { $message = 'Sharing %s failed, because ' . '%s is not a member of the group %s'; $message_t = $l->t('Sharing %s failed, because %s is not a member of the group %s', array($itemSourceName, $uidOwner, $shareWith)); \OCP\Util::writeLog('OCP\\Share', sprintf($message, $itemSourceName, $uidOwner, $shareWith), \OCP\Util::DEBUG); throw new \Exception($message_t); } // Check if the item source is already shared with the group, either from the same owner or a different user // The check for each user in the group is done inside the put() function if ($checkExists = self::getItems($itemType, $itemSource, self::SHARE_TYPE_GROUP, $shareWith, null, self::FORMAT_NONE, null, 1, true, true)) { if ($checkExists['share_with'] === $shareWith && $checkExists['share_type'] === \OCP\Share::SHARE_TYPE_GROUP) { $message = 'Sharing %s failed, because this item is already shared with %s'; $message_t = $l->t('Sharing %s failed, because this item is already shared with %s', array($itemSourceName, $shareWith)); \OCP\Util::writeLog('OCP\\Share', sprintf($message, $itemSourceName, $shareWith), \OCP\Util::DEBUG); throw new \Exception($message_t); } } // Convert share with into an array with the keys group and users $group = $shareWith; $shareWith = array(); $shareWith['group'] = $group; $shareWith['users'] = array_diff(\OC_Group::usersInGroup($group), array($uidOwner)); } else { if ($shareType === self::SHARE_TYPE_LINK) { $updateExistingShare = false; if (\OC::$server->getAppConfig()->getValue('core', 'shareapi_allow_links', 'yes') == 'yes') { // IF the password is changed via the old ajax endpoint verify it before deleting the old share if ($passwordChanged === true) { self::verifyPassword($shareWith); } // when updating a link share // FIXME Don't delete link if we update it if ($checkExists = self::getItems($itemType, $itemSource, self::SHARE_TYPE_LINK, null, $uidOwner, self::FORMAT_NONE, null, 1)) { // remember old token $oldToken = $checkExists['token']; $oldPermissions = $checkExists['permissions']; //delete the old share Helper::delete($checkExists['id']); $updateExistingShare = true; } if ($passwordChanged === null) { // Generate hash of password - same method as user passwords if (is_string($shareWith) && $shareWith !== '') { self::verifyPassword($shareWith); $shareWith = \OC::$server->getHasher()->hash($shareWith); } else { // reuse the already set password, but only if we change permissions // otherwise the user disabled the password protection if ($checkExists && (int) $permissions !== (int) $oldPermissions) { $shareWith = $checkExists['share_with']; } } } else { if ($passwordChanged === true) { if (is_string($shareWith) && $shareWith !== '') { self::verifyPassword($shareWith); $shareWith = \OC::$server->getHasher()->hash($shareWith); } } else { if ($updateExistingShare) { $shareWith = $checkExists['share_with']; } } } if (\OCP\Util::isPublicLinkPasswordRequired() && empty($shareWith)) { $message = 'You need to provide a password to create a public link, only protected links are allowed'; $message_t = $l->t('You need to provide a password to create a public link, only protected links are allowed'); \OCP\Util::writeLog('OCP\\Share', $message, \OCP\Util::DEBUG); throw new \Exception($message_t); } if ($updateExistingShare === false && self::isDefaultExpireDateEnabled() && empty($expirationDate)) { $expirationDate = Helper::calcExpireDate(); } // Generate token if (isset($oldToken)) { $token = $oldToken; } else { $token = \OC::$server->getSecureRandom()->getMediumStrengthGenerator()->generate(self::TOKEN_LENGTH, \OCP\Security\ISecureRandom::CHAR_LOWER . \OCP\Security\ISecureRandom::CHAR_UPPER . \OCP\Security\ISecureRandom::CHAR_DIGITS); } $result = self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, null, $token, $itemSourceName, $expirationDate); if ($result) { return $token; } else { return false; } } $message = 'Sharing %s failed, because sharing with links is not allowed'; $message_t = $l->t('Sharing %s failed, because sharing with links is not allowed', array($itemSourceName)); \OCP\Util::writeLog('OCP\\Share', sprintf($message, $itemSourceName), \OCP\Util::DEBUG); throw new \Exception($message_t); } else { if ($shareType === self::SHARE_TYPE_REMOTE) { /* * Check if file is not already shared with the remote user */ if ($checkExists = self::getItems($itemType, $itemSource, self::SHARE_TYPE_REMOTE, $shareWith, $uidOwner, self::FORMAT_NONE, null, 1, true, true)) { $message = 'Sharing %s failed, because this item is already shared with %s'; $message_t = $l->t('Sharing %s failed, because this item is already shared with %s', array($itemSourceName, $shareWith)); \OCP\Util::writeLog('OCP\\Share', sprintf($message, $itemSourceName, $shareWith), \OCP\Util::DEBUG); throw new \Exception($message_t); } // don't allow federated shares if source and target server are the same list($user, $remote) = Helper::splitUserRemote($shareWith); $currentServer = self::removeProtocolFromUrl(\OC::$server->getURLGenerator()->getAbsoluteURL('/')); $currentUser = \OC::$server->getUserSession()->getUser()->getUID(); if (Helper::isSameUserOnSameServer($user, $remote, $currentUser, $currentServer)) { $message = 'Not allowed to create a federated share with the same user.'; $message_t = $l->t('Not allowed to create a federated share with the same user'); \OCP\Util::writeLog('OCP\\Share', $message, \OCP\Util::DEBUG); throw new \Exception($message_t); } $token = \OC::$server->getSecureRandom()->getMediumStrengthGenerator()->generate(self::TOKEN_LENGTH, \OCP\Security\ISecureRandom::CHAR_LOWER . \OCP\Security\ISecureRandom::CHAR_UPPER . \OCP\Security\ISecureRandom::CHAR_DIGITS); $shareWith = $user . '@' . $remote; $shareId = self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, null, $token, $itemSourceName); $send = false; if ($shareId) { $send = self::sendRemoteShare($token, $shareWith, $itemSourceName, $shareId, $uidOwner); } if ($send === false) { $currentUser = \OC::$server->getUserSession()->getUser()->getUID(); self::unshare($itemType, $itemSource, $shareType, $shareWith, $currentUser); $message_t = $l->t('Sharing %s failed, could not find %s, maybe the server is currently unreachable.', array($itemSourceName, $shareWith)); throw new \Exception($message_t); } return $send; } else { // Future share types need to include their own conditions $message = 'Share type %s is not valid for %s'; $message_t = $l->t('Share type %s is not valid for %s', array($shareType, $itemSource)); \OCP\Util::writeLog('OCP\\Share', sprintf($message, $shareType, $itemSource), \OCP\Util::DEBUG); throw new \Exception($message_t); } } } } // Put the item into the database $result = self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, null, null, $itemSourceName, $expirationDate); return $result ? true : false; }
"oc_config" => json_encode( array( 'session_lifetime' => min(\OCP\Config::getSystemValue('session_lifetime', ini_get('session.gc_maxlifetime')), ini_get('session.gc_maxlifetime')), 'session_keepalive' => \OCP\Config::getSystemValue('session_keepalive', true), 'version' => implode('.', OC_Util::getVersion()), 'versionstring' => OC_Util::getVersionString(), 'enable_avatars' => \OC::$server->getConfig()->getSystemValue('enable_avatars', true), ) ), "oc_appconfig" => json_encode( array("core" => array( 'defaultExpireDateEnabled' => $defaultExpireDateEnabled, 'defaultExpireDate' => $defaultExpireDate, 'defaultExpireDateEnforced' => $enforceDefaultExpireDate, 'enforcePasswordForPublicLink' => \OCP\Util::isPublicLinkPasswordRequired(), 'sharingDisabledForUser' => \OCP\Util::isSharingDisabledForUser(), 'resharingAllowed' => \OCP\Share::isResharingAllowed(), 'remoteShareAllowed' => $outgoingServer2serverShareEnabled, 'federatedCloudShareDoc' => \OC::$server->getURLGenerator()->linkToDocs('user-sharing-federated') ) ) ), "oc_defaults" => json_encode( array( 'entity' => $defaults->getEntity(), 'name' => $defaults->getName(), 'title' => $defaults->getTitle(), 'baseUrl' => $defaults->getBaseUrl(), 'syncClientUrl' => $defaults->getSyncClientUrl(), 'docBaseUrl' => $defaults->getDocBaseUrl(), 'slogan' => $defaults->getSlogan(),