Example #1
0
 /**
  * Correct the parent folders' ETags for all users shared the file at $target
  *
  * @param string $target
  */
 public static function correctFolders($target)
 {
     $uid = \OCP\User::getUser();
     $uidOwner = \OC\Files\Filesystem::getOwner($target);
     $info = \OC\Files\Filesystem::getFileInfo($target);
     // Correct Shared folders of other users shared with
     $users = \OCP\Share::getUsersItemShared('file', $info['fileid'], $uidOwner, true);
     if (!empty($users)) {
         while (!empty($users)) {
             $reshareUsers = array();
             foreach ($users as $user) {
                 if ($user !== $uidOwner) {
                     $etag = \OC\Files\Filesystem::getETag('');
                     \OCP\Config::setUserValue($user, 'files_sharing', 'etag', $etag);
                     // Look for reshares
                     $reshareUsers = array_merge($reshareUsers, \OCP\Share::getUsersItemShared('file', $info['fileid'], $user, true));
                 }
             }
             $users = $reshareUsers;
         }
         // Correct folders of shared file owner
         $target = substr($target, 8);
         if ($uidOwner !== $uid && ($source = \OC_Share_Backend_File::getSource($target))) {
             \OC\Files\Filesystem::initMountPoints($uidOwner);
             $source = '/' . $uidOwner . '/' . $source['path'];
             \OC\Files\Cache\Updater::correctFolder($source, $info['mtime']);
         }
     }
 }
Example #2
0
	public function testMoveCrossStorage() {
		$storage2 = new Temporary(array());
		$cache2 = $storage2->getCache();
		Filesystem::mount($storage2, array(), '/bar');
		$this->storage->file_put_contents('foo.txt', 'qwerty');

		$this->updater->update('foo.txt');

		$this->assertTrue($this->cache->inCache('foo.txt'));
		$this->assertFalse($cache2->inCache('bar.txt'));
		$cached = $this->cache->get('foo.txt');

		// "rename"
		$storage2->file_put_contents('bar.txt', 'qwerty');
		$this->storage->unlink('foo.txt');

		$this->assertTrue($this->cache->inCache('foo.txt'));
		$this->assertFalse($cache2->inCache('bar.txt'));

		$this->updater->rename('foo.txt', 'bar/bar.txt');

		$this->assertFalse($this->cache->inCache('foo.txt'));
		$this->assertTrue($cache2->inCache('bar.txt'));

		$cachedTarget = $cache2->get('bar.txt');
		$this->assertEquals($cached['mtime'], $cachedTarget['mtime']);
		$this->assertEquals($cached['size'], $cachedTarget['size']);
		$this->assertEquals($cached['etag'], $cachedTarget['etag']);
		$this->assertEquals($cached['fileid'], $cachedTarget['fileid']);
	}
Example #3
0
 public function testMoveDisabled()
 {
     $this->storage->file_put_contents('foo.txt', 'qwerty');
     $this->updater->update('foo.txt');
     $this->assertTrue($this->cache->inCache('foo.txt'));
     $this->assertFalse($this->cache->inCache('bar.txt'));
     $cached = $this->cache->get('foo.txt');
     $this->storage->rename('foo.txt', 'bar.txt');
     $this->assertTrue($this->cache->inCache('foo.txt'));
     $this->assertFalse($this->cache->inCache('bar.txt'));
     $this->updater->disable();
     $this->updater->rename('foo.txt', 'bar.txt');
     $this->assertTrue($this->cache->inCache('foo.txt'));
     $this->assertFalse($this->cache->inCache('bar.txt'));
 }
Example #4
0
 public function testMove()
 {
     $this->storage->file_put_contents('foo.txt', 'qwerty');
     $this->updater->update('foo.txt');
     $this->assertTrue($this->cache->inCache('foo.txt'));
     $this->assertFalse($this->cache->inCache('bar.txt'));
     $cached = $this->cache->get('foo.txt');
     $this->storage->rename('foo.txt', 'bar.txt');
     $this->assertTrue($this->cache->inCache('foo.txt'));
     $this->assertFalse($this->cache->inCache('bar.txt'));
     $this->updater->rename('foo.txt', 'bar.txt');
     $this->assertFalse($this->cache->inCache('foo.txt'));
     $this->assertTrue($this->cache->inCache('bar.txt'));
     $cachedTarget = $this->cache->get('bar.txt');
     $this->assertEquals($cached['etag'], $cachedTarget['etag']);
     $this->assertEquals($cached['mtime'], $cachedTarget['mtime']);
     $this->assertEquals($cached['size'], $cachedTarget['size']);
     $this->assertEquals($cached['fileid'], $cachedTarget['fileid']);
 }
Example #5
0
 /**
  * abstraction layer for basic filesystem functions: wrapper for \OC\Files\Storage\Storage
  *
  * @param string $operation
  * @param string $path
  * @param array $hooks (optional)
  * @param mixed $extraParam (optional)
  * @return mixed
  *
  * This method takes requests for basic filesystem functions (e.g. reading & writing
  * files), processes hooks and proxies, sanitises paths, and finally passes them on to
  * \OC\Files\Storage\Storage for delegation to a storage backend for execution
  */
 private function basicOperation($operation, $path, $hooks = array(), $extraParam = null)
 {
     $postFix = substr($path, -1, 1) === '/' ? '/' : '';
     $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path));
     if (\OC_FileProxy::runPreProxies($operation, $absolutePath, $extraParam) and Filesystem::isValidPath($path) and !Filesystem::isFileBlacklisted($path)) {
         $path = $this->getRelativePath($absolutePath);
         if ($path == null) {
             return false;
         }
         $run = $this->runHooks($hooks, $path);
         list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix);
         if ($run and $storage) {
             if (!is_null($extraParam)) {
                 $result = $storage->{$operation}($internalPath, $extraParam);
             } else {
                 $result = $storage->{$operation}($internalPath);
             }
             $result = \OC_FileProxy::runPostProxies($operation, $this->getAbsolutePath($path), $result);
             if (in_array('delete', $hooks)) {
                 $this->updater->remove($path);
             }
             if (in_array('write', $hooks)) {
                 $this->updater->update($path);
             }
             if (in_array('touch', $hooks)) {
                 $this->updater->update($path, $extraParam);
             }
             if ($this->shouldEmitHooks($path) && $result !== false) {
                 if ($operation != 'fopen') {
                     //no post hooks for fopen, the file stream is still open
                     $this->runHooks($hooks, $path, true);
                 }
             }
             return $result;
         }
     }
     return null;
 }
Example #6
0
 /**
  * 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;
 }
Example #7
0
 /**
  * @param string[] $hooks
  * @param string $path
  * @param bool $post
  * @return bool
  */
 private function runHooks($hooks, $path, $post = false)
 {
     $path = $this->getHookPath($path);
     $prefix = $post ? 'post_' : '';
     $run = true;
     if ($this->shouldEmitHooks($path)) {
         foreach ($hooks as $hook) {
             // manually triger updater hooks to ensure they are called first
             if ($post) {
                 if ($hook == 'write') {
                     Updater::writeHook(array('path' => $path));
                 } elseif ($hook == 'touch') {
                     Updater::touchHook(array('path' => $path));
                 } else {
                     if ($hook == 'delete') {
                         Updater::deleteHook(array('path' => $path));
                     }
                 }
             }
             if ($hook != 'read') {
                 \OC_Hook::emit(Filesystem::CLASSNAME, $prefix . $hook, array(Filesystem::signal_param_run => &$run, Filesystem::signal_param_path => $path));
             } elseif (!$post) {
                 \OC_Hook::emit(Filesystem::CLASSNAME, $prefix . $hook, array(Filesystem::signal_param_path => $path));
             }
         }
     }
     return $run;
 }