/** * get the filesystem info * * @param string $path * @param boolean|string $includeMountPoints true to add mountpoint sizes, * 'ext' to add only ext storage mount point sizes. Defaults to true. * defaults to true * @return \OC\Files\FileInfo|false */ public function getFileInfo($path, $includeMountPoints = true) { $this->assertPathLength($path); $data = array(); if (!Filesystem::isValidPath($path)) { return $data; } if (Cache\Scanner::isPartialFile($path)) { return $this->getPartFileInfo($path); } $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path); $mount = Filesystem::getMountManager()->find($path); $storage = $mount->getStorage(); $internalPath = $mount->getInternalPath($path); $data = null; if ($storage) { $cache = $storage->getCache($internalPath); $data = $cache->get($internalPath); $watcher = $storage->getWatcher($internalPath); // if the file is not in the cache or needs to be updated, trigger the scanner and reload the data if (!$data) { if (!$storage->file_exists($internalPath)) { return false; } $scanner = $storage->getScanner($internalPath); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); $data = $cache->get($internalPath); } else { if (!Cache\Scanner::isPartialFile($internalPath) && $watcher->checkUpdate($internalPath, $data)) { $this->updater->propagate($path); $data = $cache->get($internalPath); } } if ($data and isset($data['fileid'])) { // upgrades from oc6 or lower might not have the permissions set in the file cache if ($data['permissions'] === 0) { $data['permissions'] = $storage->getPermissions($data['path']); $cache->update($data['fileid'], array('permissions' => $data['permissions'])); } if ($includeMountPoints and $data['mimetype'] === 'httpd/unix-directory') { //add the sizes of other mount points to the folder $extOnly = $includeMountPoints === 'ext'; $mountPoints = Filesystem::getMountPoints($path); foreach ($mountPoints as $mountPoint) { $subStorage = Filesystem::getStorage($mountPoint); if ($subStorage) { // exclude shared storage ? if ($extOnly && $subStorage instanceof \OC\Files\Storage\Shared) { continue; } $subCache = $subStorage->getCache(''); $rootEntry = $subCache->get(''); $data['size'] += isset($rootEntry['size']) ? $rootEntry['size'] : 0; } } } } } if (!$data) { return false; } if ($mount instanceof MoveableMount && $internalPath === '') { $data['permissions'] |= \OCP\Constants::PERMISSION_DELETE; } return new FileInfo($path, $storage, $internalPath, $data, $mount); }
/** * Rename a file or folder in the cache and update the size, etag and mtime of the parent folders * * @param IStorage $sourceStorage * @param string $source * @param string $target */ public function renameFromStorage(IStorage $sourceStorage, $source, $target) { if (!$this->enabled or Scanner::isPartialFile($source) or Scanner::isPartialFile($target)) { return; } $time = time(); $sourceCache = $sourceStorage->getCache(); $sourceUpdater = $sourceStorage->getUpdater(); $sourcePropagator = $sourceStorage->getPropagator(); if ($sourceCache->inCache($source)) { if ($this->cache->inCache($target)) { $this->cache->remove($target); } if ($sourceStorage === $this->storage) { $this->cache->move($source, $target); } else { $this->cache->moveFromCache($sourceCache, $source, $target); } } if (pathinfo($source, PATHINFO_EXTENSION) !== pathinfo($target, PATHINFO_EXTENSION)) { // handle mime type change $mimeType = $this->storage->getMimeType($target); $fileId = $this->cache->getId($target); $this->cache->update($fileId, ['mimetype' => $mimeType]); } if ($sourceCache instanceof Cache) { $sourceCache->correctFolderSize($source); } if ($this->cache instanceof Cache) { $this->cache->correctFolderSize($target); } if ($sourceUpdater instanceof Updater) { $sourceUpdater->correctParentStorageMtime($source); } $this->correctParentStorageMtime($target); $this->updateStorageMTimeOnly($target); $sourcePropagator->propagateChange($source, $time); $this->propagator->propagateChange($target, $time); }
/** * get the filesystem info * * @param string $path * @param boolean|string $includeMountPoints true to add mountpoint sizes, * 'ext' to add only ext storage mount point sizes. Defaults to true. * defaults to true * @return \OC\Files\FileInfo|false False if file does not exist */ public function getFileInfo($path, $includeMountPoints = true) { $this->assertPathLength($path); if (!Filesystem::isValidPath($path)) { return false; } if (Cache\Scanner::isPartialFile($path)) { return $this->getPartFileInfo($path); } $relativePath = $path; $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path); $mount = Filesystem::getMountManager()->find($path); $storage = $mount->getStorage(); $internalPath = $mount->getInternalPath($path); if ($storage) { $data = $this->getCacheEntry($storage, $internalPath, $relativePath); if (!$data instanceof ICacheEntry) { return false; } if ($mount instanceof MoveableMount && $internalPath === '') { $data['permissions'] |= \OCP\Constants::PERMISSION_DELETE; } $owner = $this->getUserObjectForOwner($storage->getOwner($internalPath)); $info = new FileInfo($path, $storage, $internalPath, $data, $mount, $owner); if ($data and isset($data['fileid'])) { if ($includeMountPoints and $data['mimetype'] === 'httpd/unix-directory') { //add the sizes of other mount points to the folder $extOnly = $includeMountPoints === 'ext'; $mounts = Filesystem::getMountManager()->findIn($path); foreach ($mounts as $mount) { $subStorage = $mount->getStorage(); if ($subStorage) { // exclude shared storage ? if ($extOnly && $subStorage instanceof \OC\Files\Storage\Shared) { continue; } $subCache = $subStorage->getCache(''); $rootEntry = $subCache->get(''); $info->addSubEntry($rootEntry, $mount->getMountPoint()); } } } } return $info; } return false; }
/** * last chunk received. This is the place where you can perform some final * operation and return some remaining data if something is left in your * buffer. * * @param string $path to the file * @param int $position * @return string remained data which should be written to the file in case * of a write operation * @throws PublicKeyMissingException * @throws \Exception * @throws \OCA\Encryption\Exceptions\MultiKeyEncryptException */ public function end($path, $position = 0) { $result = ''; if ($this->isWriteOperation) { $this->keyManager->setVersion($path, $this->version + 1, new View()); // in case of a part file we remember the new signature versions // the version will be set later on update. // This way we make sure that other apps listening to the pre-hooks // still get the old version which should be the correct value for them if (Scanner::isPartialFile($path)) { self::$rememberVersion[$this->stripPartFileExtension($path)] = $this->version + 1; } if (!empty($this->writeCache)) { $result = $this->crypt->symmetricEncryptFileContent($this->writeCache, $this->fileKey, $this->version + 1, $position); $this->writeCache = ''; } $publicKeys = array(); if ($this->useMasterPassword === true) { $publicKeys[$this->keyManager->getMasterKeyId()] = $this->keyManager->getPublicMasterKey(); } else { foreach ($this->accessList['users'] as $uid) { try { $publicKeys[$uid] = $this->keyManager->getPublicKey($uid); } catch (PublicKeyMissingException $e) { $this->logger->warning('no public key found for user "{uid}", user will not be able to read the file', ['app' => 'encryption', 'uid' => $uid]); // if the public key of the owner is missing we should fail if ($uid === $this->user) { throw $e; } } } } $publicKeys = $this->keyManager->addSystemKeys($this->accessList, $publicKeys, $this->user); $encryptedKeyfiles = $this->crypt->multiKeyEncrypt($this->fileKey, $publicKeys); $this->keyManager->setAllFileKeys($this->path, $encryptedKeyfiles); } return $result; }
/** * @dataProvider dataTestIsPartialFile * * @param string $path * @param bool $expected */ public function testIsPartialFile($path, $expected) { $this->assertSame($expected, $this->scanner->isPartialFile($path)); }
private function shouldEmitHooks($path = '') { if ($path && Cache\Scanner::isPartialFile($path)) { return false; } if (!Filesystem::$loaded) { return false; } $defaultRoot = Filesystem::getRoot(); if ($this->fakeRoot === $defaultRoot) { return true; } return strlen($this->fakeRoot) > strlen($defaultRoot) && substr($this->fakeRoot, 0, strlen($defaultRoot) + 1) === $defaultRoot . '/'; }
/** * get the filesystem info * * @param string $path * @param boolean|string $includeMountPoints true to add mountpoint sizes, * 'ext' to add only ext storage mount point sizes. Defaults to true. * defaults to true * @return \OC\Files\FileInfo|false */ public function getFileInfo($path, $includeMountPoints = true) { $this->assertPathLength($path); $data = array(); if (!Filesystem::isValidPath($path)) { return $data; } if (Cache\Scanner::isPartialFile($path)) { return $this->getPartFileInfo($path); } $path = Filesystem::normalizePath($this->fakeRoot . '/' . $path); $mount = Filesystem::getMountManager()->find($path); $storage = $mount->getStorage(); $internalPath = $mount->getInternalPath($path); $data = null; if ($storage) { $cache = $storage->getCache($internalPath); if (!$cache->inCache($internalPath)) { if (!$storage->file_exists($internalPath)) { return false; } $scanner = $storage->getScanner($internalPath); $scanner->scan($internalPath, Cache\Scanner::SCAN_SHALLOW); } else { $watcher = $storage->getWatcher($internalPath); $data = $watcher->checkUpdate($internalPath); } if (!is_array($data)) { $data = $cache->get($internalPath); } if ($data and isset($data['fileid'])) { if ($data['permissions'] === 0) { $data['permissions'] = $storage->getPermissions($data['path']); $cache->update($data['fileid'], array('permissions' => $data['permissions'])); } if ($includeMountPoints and $data['mimetype'] === 'httpd/unix-directory') { //add the sizes of other mount points to the folder $extOnly = $includeMountPoints === 'ext'; $mountPoints = Filesystem::getMountPoints($path); foreach ($mountPoints as $mountPoint) { $subStorage = Filesystem::getStorage($mountPoint); if ($subStorage) { // exclude shared storage ? if ($extOnly && $subStorage instanceof \OC\Files\Storage\Shared) { continue; } $subCache = $subStorage->getCache(''); $rootEntry = $subCache->get(''); $data['size'] += isset($rootEntry['size']) ? $rootEntry['size'] : 0; } } } } } if (!$data) { return false; } if ($mount instanceof MoveableMount && $internalPath === '') { $data['permissions'] |= \OCP\PERMISSION_DELETE | \OCP\PERMISSION_UPDATE; } $data = \OC_FileProxy::runPostProxies('getFileInfo', $path, $data); return new FileInfo($path, $storage, $internalPath, $data); }
/** * Rename a file or folder in the cache and update the size, etag and mtime of the parent folders * * @param string $source * @param string $target */ public function rename($source, $target) { if (!$this->enabled or Scanner::isPartialFile($source) or Scanner::isPartialFile($target)) { return; } /** * @var \OC\Files\Storage\Storage $sourceStorage * @var \OC\Files\Storage\Storage $targetStorage * @var string $sourceInternalPath * @var string $targetInternalPath */ list($sourceStorage, $sourceInternalPath) = $this->view->resolvePath($source); // if it's a moved mountpoint we dont need to do anything if ($sourceInternalPath === '') { return; } list($targetStorage, $targetInternalPath) = $this->view->resolvePath($target); if ($sourceStorage && $targetStorage) { $targetCache = $targetStorage->getCache($sourceInternalPath); if ($sourceStorage->getCache($sourceInternalPath)->inCache($sourceInternalPath)) { if ($targetCache->inCache($targetInternalPath)) { $targetCache->remove($targetInternalPath); } if ($sourceStorage === $targetStorage) { $targetCache->move($sourceInternalPath, $targetInternalPath); } else { $targetCache->moveFromCache($sourceStorage->getCache(), $sourceInternalPath, $targetInternalPath); } } if (pathinfo($sourceInternalPath, PATHINFO_EXTENSION) !== pathinfo($targetInternalPath, PATHINFO_EXTENSION)) { // handle mime type change $mimeType = $targetStorage->getMimeType($targetInternalPath); $fileId = $targetCache->getId($targetInternalPath); $targetCache->update($fileId, array('mimetype' => $mimeType)); } $targetCache->correctFolderSize($sourceInternalPath); $targetCache->correctFolderSize($targetInternalPath); $this->correctParentStorageMtime($sourceStorage, $sourceInternalPath); $this->correctParentStorageMtime($targetStorage, $targetInternalPath); $this->propagator->addChange($this->getPropagatorPath($source)); $this->propagator->addChange($this->getPropagatorPath($target)); $this->propagator->propagateChanges(); } }