diff options
Diffstat (limited to 'apps/files_sharing/lib')
-rw-r--r-- | apps/files_sharing/lib/activity.php | 214 | ||||
-rw-r--r-- | apps/files_sharing/lib/cache.php | 30 | ||||
-rw-r--r-- | apps/files_sharing/lib/controllers/sharecontroller.php | 60 | ||||
-rw-r--r-- | apps/files_sharing/lib/external/manager.php | 2 | ||||
-rw-r--r-- | apps/files_sharing/lib/external/scanner.php | 18 | ||||
-rw-r--r-- | apps/files_sharing/lib/external/storage.php | 2 | ||||
-rw-r--r-- | apps/files_sharing/lib/sharedstorage.php | 2 |
7 files changed, 229 insertions, 99 deletions
diff --git a/apps/files_sharing/lib/activity.php b/apps/files_sharing/lib/activity.php index bfac91fd71a..0cd874d69f0 100644 --- a/apps/files_sharing/lib/activity.php +++ b/apps/files_sharing/lib/activity.php @@ -1,37 +1,70 @@ <?php /** - * ownCloud - publish activities + * ownCloud - Sharing Activity Extension * * @copyright (c) 2014, ownCloud Inc. * * @author Bjoern Schiessle <schiessle@owncloud.com> + * @author Joas Schilling <nickvergessen@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 - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AFFERO GENERAL PUBLIC LICENSE for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. */ namespace OCA\Files_Sharing; -class Activity implements \OCP\Activity\IExtension { +use OC\L10N\Factory; +use OCP\Activity\IExtension; +use OCP\IURLGenerator; - const TYPE_REMOTE_SHARE = 'remote_share'; +class Activity implements IExtension { + /** + * Filter with all sharing related activities + */ + const FILTER_SHARES = 'shares'; + + /** + * Activity types known to this extension + */ const TYPE_PUBLIC_LINKS = 'public_links'; - const SUBJECT_REMOTE_SHARE_RECEIVED = 'remote_share_received'; + const TYPE_REMOTE_SHARE = 'remote_share'; + const TYPE_SHARED = 'shared'; + + /** + * Subject keys for translation of the subjections + */ + const SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED = 'public_shared_file_downloaded'; + const SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED = 'public_shared_folder_downloaded'; + const SUBJECT_REMOTE_SHARE_ACCEPTED = 'remote_share_accepted'; const SUBJECT_REMOTE_SHARE_DECLINED = 'remote_share_declined'; + const SUBJECT_REMOTE_SHARE_RECEIVED = 'remote_share_received'; const SUBJECT_REMOTE_SHARE_UNSHARED = 'remote_share_unshared'; - const SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED = 'public_shared_file_downloaded'; - const SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED = 'public_shared_folder_downloaded'; + + const SUBJECT_SHARED_GROUP_SELF = 'shared_group_self'; + const SUBJECT_SHARED_LINK_SELF = 'shared_link_self'; + const SUBJECT_SHARED_USER_SELF = 'shared_user_self'; + const SUBJECT_SHARED_WITH_BY = 'shared_with_by'; + + /** @var Factory */ + protected $languageFactory; + + /** @var IURLGenerator */ + protected $URLGenerator; + + /** + * @param Factory $languageFactory + * @param IURLGenerator $URLGenerator + */ + public function __construct(Factory $languageFactory, IURLGenerator $URLGenerator) { + $this->languageFactory = $languageFactory; + $this->URLGenerator = $URLGenerator; + } + + protected function getL10N($languageCode = null) { + return $this->languageFactory->get('files_sharing', $languageCode); + } /** * The extension can return an array of additional notification types. @@ -41,45 +74,52 @@ class Activity implements \OCP\Activity\IExtension { * @return array|false */ public function getNotificationTypes($languageCode) { - $l = \OC::$server->getL10N('files_sharing', $languageCode); + $l = $this->getL10N($languageCode); + return array( - self::TYPE_REMOTE_SHARE => $l->t('A file or folder was shared from <strong>another server</strong>'), - self::TYPE_PUBLIC_LINKS => $l->t('A public shared file or folder was <strong>downloaded</strong>'), + self::TYPE_SHARED => (string) $l->t('A file or folder has been <strong>shared</strong>'), + self::TYPE_REMOTE_SHARE => (string) $l->t('A file or folder was shared from <strong>another server</strong>'), + self::TYPE_PUBLIC_LINKS => (string) $l->t('A public shared file or folder was <strong>downloaded</strong>'), ); } /** - * The extension can filter the types based on the filter if required. - * In case no filter is to be applied false is to be returned unchanged. + * For a given method additional types to be displayed in the settings can be returned. + * In case no additional types are to be added false is to be returned. * - * @param array $types - * @param string $filter + * @param string $method * @return array|false */ - public function filterNotificationTypes($types, $filter) { - return $types; + public function getDefaultTypes($method) { + $defaultTypes = [ + self::TYPE_SHARED, + self::TYPE_REMOTE_SHARE, + ]; + + if ($method === 'stream') { + $defaultTypes[] = self::TYPE_PUBLIC_LINKS; + } + + return $defaultTypes; } /** - * For a given method additional types to be displayed in the settings can be returned. - * In case no additional types are to be added false is to be returned. + * A string naming the css class for the icon to be used can be returned. + * If no icon is known for the given type false is to be returned. * - * @param string $method - * @return array|false + * @param string $type + * @return string|false */ - public function getDefaultTypes($method) { - switch ($method) { - case 'email': - $result = array(self::TYPE_REMOTE_SHARE); - break; - case 'stream': - $result = array(self::TYPE_REMOTE_SHARE, self::TYPE_PUBLIC_LINKS); - break; - default: - $result = false; + public function getTypeIcon($type) { + switch ($type) { + case self::TYPE_SHARED: + case self::TYPE_REMOTE_SHARE: + return 'icon-share'; + case self::TYPE_PUBLIC_LINKS: + return 'icon-download'; } - return $result; + return false; } /** @@ -95,23 +135,33 @@ class Activity implements \OCP\Activity\IExtension { * @return string|false */ public function translate($app, $text, $params, $stripPath, $highlightParams, $languageCode) { - - $l = \OC::$server->getL10N('files_sharing', $languageCode); + $l = $this->getL10N($languageCode); if ($app === 'files_sharing') { switch ($text) { case self::SUBJECT_REMOTE_SHARE_RECEIVED: - return $l->t('You received a new remote share from %s', $params)->__toString(); + return (string) $l->t('You received a new remote share from %s', $params); case self::SUBJECT_REMOTE_SHARE_ACCEPTED: - return $l->t('%1$s accepted remote share %2$s', $params)->__toString(); + return (string) $l->t('%1$s accepted remote share %2$s', $params); case self::SUBJECT_REMOTE_SHARE_DECLINED: - return $l->t('%1$s declined remote share %2$s', $params)->__toString(); + return (string) $l->t('%1$s declined remote share %2$s', $params); case self::SUBJECT_REMOTE_SHARE_UNSHARED: - return $l->t('%1$s unshared %2$s from you', $params)->__toString(); + return (string) $l->t('%1$s unshared %2$s from you', $params); case self::SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED: - return $l->t('Public shared folder %1$s was downloaded', $params)->__toString(); + return (string) $l->t('Public shared folder %1$s was downloaded', $params); case self::SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED: - return $l->t('Public shared file %1$s was downloaded', $params)->__toString(); + return (string) $l->t('Public shared file %1$s was downloaded', $params); + } + } else if ($app === 'files') { + switch ($text) { + case self::SUBJECT_SHARED_USER_SELF: + return (string) $l->t('You shared %1$s with %2$s', $params); + case self::SUBJECT_SHARED_GROUP_SELF: + return (string) $l->t('You shared %1$s with group %2$s', $params); + case self::SUBJECT_SHARED_WITH_BY: + return (string) $l->t('%2$s shared %1$s with you', $params); + case self::SUBJECT_SHARED_LINK_SELF: + return (string) $l->t('You shared %1$s via link', $params); } } @@ -149,24 +199,19 @@ class Activity implements \OCP\Activity\IExtension { 0 => 'file', ); } - } - - return false; - } + } else if ($app === 'files') { + switch ($text) { + case self::SUBJECT_SHARED_LINK_SELF: + case self::SUBJECT_SHARED_USER_SELF: + case self::SUBJECT_SHARED_WITH_BY: + return [0 => 'file', 1 => 'username']; - /** - * A string naming the css class for the icon to be used can be returned. - * If no icon is known for the given type false is to be returned. - * - * @param string $type - * @return string|false - */ - public function getTypeIcon($type) { - switch ($type) { - case self::TYPE_REMOTE_SHARE: - return 'icon-share'; - case self::TYPE_PUBLIC_LINKS: - return 'icon-download'; + case self::SUBJECT_SHARED_GROUP_SELF: + return [ + 0 => 'file', + //1 => 'group', Group does not exist yet + ]; + } } return false; @@ -191,7 +236,17 @@ class Activity implements \OCP\Activity\IExtension { * @return array|false */ public function getNavigation() { - return false; + $l = $this->getL10N(); + return [ + 'apps' => [], + 'top' => [ + self::FILTER_SHARES => [ + 'id' => self::FILTER_SHARES, + 'name' => (string) $l->t('Shares'), + 'url' => $this->URLGenerator->linkToRoute('activity.Activities.showList', ['filter' => self::FILTER_SHARES]), + ], + ], + ]; } /** @@ -201,6 +256,22 @@ class Activity implements \OCP\Activity\IExtension { * @return boolean */ public function isFilterValid($filterValue) { + return $filterValue === self::FILTER_SHARES; + } + + /** + * The extension can filter the types based on the filter if required. + * In case no filter is to be applied false is to be returned unchanged. + * + * @param array $types + * @param string $filter + * @return array|false + */ + public function filterNotificationTypes($types, $filter) { + switch ($filter) { + case self::FILTER_SHARES: + return array_intersect([self::TYPE_SHARED, self::TYPE_REMOTE_SHARE], $types); + } return false; } @@ -214,8 +285,11 @@ class Activity implements \OCP\Activity\IExtension { * @return array|false */ public function getQueryForFilter($filter) { - if ($filter === 'shares') { - return array('`app` = ? and `type` = ?', array('files_sharing', self::TYPE_REMOTE_SHARE)); + if ($filter === self::FILTER_SHARES) { + return [ + '(`app` = ? or `app` = ?)', + ['files_sharing', 'files'], + ]; } return false; } diff --git a/apps/files_sharing/lib/cache.php b/apps/files_sharing/lib/cache.php index 21f807f3533..b71dfb44ab0 100644 --- a/apps/files_sharing/lib/cache.php +++ b/apps/files_sharing/lib/cache.php @@ -45,7 +45,7 @@ class Shared_Cache extends Cache { * Get the source cache of a shared file or folder * * @param string $target Shared target file path - * @return \OC\Files\Cache\Cache + * @return \OC\Files\Cache\Cache|false */ private function getSourceCache($target) { if ($target === false || $target === $this->storage->getMountPoint()) { @@ -82,7 +82,7 @@ class Shared_Cache extends Cache { * get the stored metadata of a file or folder * * @param string|int $file - * @return array + * @return array|false */ public function get($file) { if (is_string($file)) { @@ -148,7 +148,7 @@ class Shared_Cache extends Cache { * get the metadata of all files stored in $folder * * @param string $folderId - * @return array + * @return array|false */ public function getFolderContentsById($folderId) { $cache = $this->getSourceCache(''); @@ -178,7 +178,7 @@ class Shared_Cache extends Cache { * @param string $file * @param array $data * - * @return int file id + * @return int|false file id */ public function put($file, array $data) { $file = ($file === false) ? '' : $file; @@ -395,6 +395,28 @@ class Shared_Cache extends Cache { } /** + * update the folder size and the size of all parent folders + * + * @param string|boolean $path + * @param array $data (optional) meta data of the folder + */ + public function correctFolderSize($path, $data = null) { + $this->calculateFolderSize($path, $data); + if ($path !== '') { + $parent = dirname($path); + if ($parent === '.' or $parent === '/') { + $parent = ''; + } + $this->correctFolderSize($parent); + } else { + // bubble up to source cache + $sourceCache = $this->getSourceCache($path); + $parent = dirname($this->files[$path]); + $sourceCache->correctFolderSize($parent); + } + } + + /** * get the size of a folder and set it in the cache * * @param string $path diff --git a/apps/files_sharing/lib/controllers/sharecontroller.php b/apps/files_sharing/lib/controllers/sharecontroller.php index cd013d4ca96..b0d7781515f 100644 --- a/apps/files_sharing/lib/controllers/sharecontroller.php +++ b/apps/files_sharing/lib/controllers/sharecontroller.php @@ -131,7 +131,7 @@ class ShareController extends Controller { * * @param string $token * @param string $path - * @return TemplateResponse + * @return TemplateResponse|RedirectResponse */ public function showShare($token, $path = '') { \OC_User::setIncognitoMode(true); @@ -170,6 +170,7 @@ class ShareController extends Controller { $shareTmpl['filename'] = $file; $shareTmpl['directory_path'] = $linkItem['file_target']; $shareTmpl['mimetype'] = Filesystem::getMimeType($originalSharePath); + $shareTmpl['previewSupported'] = \OC::$server->getPreviewManager()->isMimeSupported($shareTmpl['mimetype']); $shareTmpl['dirToken'] = $linkItem['token']; $shareTmpl['sharingToken'] = $token; $shareTmpl['server2serversharing'] = Helper::isOutgoingServer2serverShareEnabled(); @@ -182,7 +183,6 @@ class ShareController extends Controller { // Show file list if (Filesystem::is_dir($originalSharePath)) { $shareTmpl['dir'] = $getPath; - $files = array(); $maxUploadFilesize = Util::maxUploadFilesize($originalSharePath); $freeSpace = Util::freeSpace($originalSharePath); $uploadLimit = Util::uploadLimit(); @@ -192,7 +192,6 @@ class ShareController extends Controller { $folder->assign('permissions', \OCP\Constants::PERMISSION_READ); $folder->assign('isPublic', true); $folder->assign('publicUploadEnabled', 'no'); - $folder->assign('files', $files); $folder->assign('uploadMaxFilesize', $maxUploadFilesize); $folder->assign('uploadMaxHumanFilesize', OCP\Util::humanFileSize($maxUploadFilesize)); $folder->assign('freeSpace', $freeSpace); @@ -205,7 +204,12 @@ class ShareController extends Controller { $shareTmpl['downloadURL'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.downloadShare', array('token' => $token)); $shareTmpl['maxSizeAnimateGif'] = $this->config->getSystemValue('max_filesize_animated_gifs_public_sharing', 10); - return new TemplateResponse($this->appName, 'public', $shareTmpl, 'base'); + $csp = new OCP\AppFramework\Http\ContentSecurityPolicy(); + $csp->addAllowedFrameDomain('\'self\''); + $response = new TemplateResponse($this->appName, 'public', $shareTmpl, 'base'); + $response->setContentSecurityPolicy($csp); + + return $response; } /** @@ -230,26 +234,48 @@ class ShareController extends Controller { } } + $files_list = null; + if (!is_null($files)) { // download selected files + $files_list = json_decode($files); + // in case we get only a single file + if ($files_list === null) { + $files_list = array($files); + } + } + $originalSharePath = self::getPath($token); + // Create the activities if (isset($originalSharePath) && Filesystem::isReadable($originalSharePath . $path)) { $originalSharePath = Filesystem::normalizePath($originalSharePath . $path); - $type = \OC\Files\Filesystem::is_dir($originalSharePath) ? 'folder' : 'file'; - $args = $type === 'folder' ? array('dir' => $originalSharePath) : array('dir' => dirname($originalSharePath), 'scrollto' => basename($originalSharePath)); - $linkToFile = \OCP\Util::linkToAbsolute('files', 'index.php', $args); - $subject = $type === 'folder' ? Activity::SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED : Activity::SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED; - $this->activityManager->publishActivity( - 'files_sharing', $subject, array($originalSharePath), '', array(), $originalSharePath, - $linkToFile, $linkItem['uid_owner'], Activity::TYPE_PUBLIC_LINKS, Activity::PRIORITY_MEDIUM); - } + $isDir = \OC\Files\Filesystem::is_dir($originalSharePath); - if (!is_null($files)) { // download selected files - $files_list = json_decode($files); - // in case we get only a single file - if ($files_list === NULL) { - $files_list = array($files); + $activities = []; + if (!$isDir) { + // Single file public share + $activities[$originalSharePath] = Activity::SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED; + } else if (!empty($files_list)) { + // Only some files are downloaded + foreach ($files_list as $file) { + $filePath = Filesystem::normalizePath($originalSharePath . '/' . $file); + $isDir = \OC\Files\Filesystem::is_dir($filePath); + $activities[$filePath] = ($isDir) ? Activity::SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED : Activity::SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED; + } + } else { + // The folder is downloaded + $activities[$originalSharePath] = Activity::SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED; + } + + foreach ($activities as $filePath => $subject) { + $this->activityManager->publishActivity( + 'files_sharing', $subject, array($filePath), '', array(), + $filePath, '', $linkItem['uid_owner'], Activity::TYPE_PUBLIC_LINKS, Activity::PRIORITY_MEDIUM + ); } + } + // download selected files + if (!is_null($files)) { // FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well // after dispatching the request which results in a "Cannot modify header information" notice. OC_Files::get($originalSharePath, $files_list, $_SERVER['REQUEST_METHOD'] == 'HEAD'); diff --git a/apps/files_sharing/lib/external/manager.php b/apps/files_sharing/lib/external/manager.php index 8985aeb3fce..490e5e5003d 100644 --- a/apps/files_sharing/lib/external/manager.php +++ b/apps/files_sharing/lib/external/manager.php @@ -321,4 +321,4 @@ class Manager { return $result ? $openShares->fetchAll() : array(); } -}
\ No newline at end of file +} diff --git a/apps/files_sharing/lib/external/scanner.php b/apps/files_sharing/lib/external/scanner.php index b45a8942e96..616d4db44e5 100644 --- a/apps/files_sharing/lib/external/scanner.php +++ b/apps/files_sharing/lib/external/scanner.php @@ -14,11 +14,10 @@ use OCP\Files\StorageInvalidException; use OCP\Files\StorageNotAvailableException; class Scanner extends \OC\Files\Cache\Scanner { - /** - * @var \OCA\Files_Sharing\External\Storage - */ + /** @var \OCA\Files_Sharing\External\Storage */ protected $storage; + /** {@inheritDoc} */ public function scan($path, $recursive = self::SCAN_RECURSIVE, $reuse = -1) { $this->scanAll(); } @@ -31,9 +30,11 @@ class Scanner extends \OC\Files\Cache\Scanner { * * @param string $file file to scan * @param int $reuseExisting + * @param int $parentId + * @param array | null $cacheData existing data in the cache for the file to be scanned * @return array an array of metadata of the scanned file */ - public function scanFile($file, $reuseExisting = 0) { + public function scanFile($file, $reuseExisting = 0, $parentId = -1, $cacheData = null) { try { return parent::scanFile($file, $reuseExisting); } catch (ForbiddenException $e) { @@ -54,6 +55,9 @@ class Scanner extends \OC\Files\Cache\Scanner { * Checks the remote share for changes. * If changes are available, scan them and update * the cache. + * @throws NotFoundException + * @throws StorageInvalidException + * @throws \Exception */ public function scanAll() { try { @@ -76,10 +80,14 @@ class Scanner extends \OC\Files\Cache\Scanner { } } + /** + * @param array $data + * @param string $path + */ private function addResult($data, $path) { $id = $this->cache->put($path, $data); if (isset($data['children'])) { - $children = array(); + $children = []; foreach ($data['children'] as $child) { $children[$child['name']] = true; $this->addResult($child, ltrim($path . '/' . $child['name'], '/')); diff --git a/apps/files_sharing/lib/external/storage.php b/apps/files_sharing/lib/external/storage.php index 648376e8cb5..51c4a36029e 100644 --- a/apps/files_sharing/lib/external/storage.php +++ b/apps/files_sharing/lib/external/storage.php @@ -70,7 +70,7 @@ class Storage extends DAV implements ISharedStorage { 'host' => $host, 'root' => $root, 'user' => $options['token'], - 'password' => $options['password'] + 'password' => (string)$options['password'] )); } diff --git a/apps/files_sharing/lib/sharedstorage.php b/apps/files_sharing/lib/sharedstorage.php index d992f8f70b4..ccfbebddb29 100644 --- a/apps/files_sharing/lib/sharedstorage.php +++ b/apps/files_sharing/lib/sharedstorage.php @@ -80,7 +80,7 @@ class Shared extends \OC\Files\Storage\Common implements ISharedStorage { /** * Get the source file path for a shared file * @param string $target Shared target file path - * @return string source file path or false if not found + * @return string|false source file path or false if not found */ public function getSourcePath($target) { $source = $this->getFile($target); |