private function create($imagePath, $square) { $galleryDir = \OC_User::getHome($this->user) . '/gallery/' . $this->user . '/'; $dir = dirname($imagePath); $fileInfo = $this->view->getFileInfo($imagePath); if (!$fileInfo) { return false; } if (!is_dir($galleryDir . $dir)) { mkdir($galleryDir . $dir, 0755, true); } $this->image = new \OCP\Image(); // check if file is encrypted if ($fileInfo['encrypted'] === true) { $fileName = $this->view->toTmpFile($imagePath); } else { $fileName = $this->view->getLocalFile($imagePath); } $this->image->loadFromFile($fileName); if ($this->image->valid()) { $this->image->fixOrientation(); if ($square) { $this->image->centerCrop(200); } else { $this->image->fitIn($this->image->width(), 200); if ($this->image->width() > 600) { // max aspect ratio of 3 $this->image->crop(($this->image->width() - 600) / 2, 0, 600, 200); } } $this->image->save($this->path); } }
/** * Returns the matching file info * * @return \OCP\Files\FileInfo */ public function getFileInfo() { if (!$this->fileInfo) { $this->fileInfo = $this->view->getFileInfo($this->path); } return $this->fileInfo; }
/** * rename a file * * @param string $dir * @param string $oldname * @param string $newname * @return array */ public function rename($dir, $oldname, $newname) { $result = array('success' => false, 'data' => NULL); $normalizedOldPath = \OC\Files\Filesystem::normalizePath($dir . '/' . $oldname); $normalizedNewPath = \OC\Files\Filesystem::normalizePath($dir . '/' . $newname); // rename to non-existing folder is denied if (!$this->view->file_exists($normalizedOldPath)) { $result['data'] = array('message' => $this->l10n->t('%s could not be renamed as it has been deleted', array($oldname)), 'code' => 'sourcenotfound', 'oldname' => $oldname, 'newname' => $newname); } else { if (!$this->view->file_exists($dir)) { $result['data'] = array('message' => (string) $this->l10n->t('The target folder has been moved or deleted.', array($dir)), 'code' => 'targetnotfound'); // rename to existing file is denied } else { if ($this->view->file_exists($normalizedNewPath)) { $result['data'] = array('message' => $this->l10n->t("The name %s is already used in the folder %s. Please choose a different name.", array($newname, $dir))); } else { if ($newname !== '.' and $this->view->rename($normalizedOldPath, $normalizedNewPath)) { // successful rename $meta = $this->view->getFileInfo($normalizedNewPath); $meta = \OCA\Files\Helper::populateTags(array($meta)); $fileInfo = \OCA\Files\Helper::formatFileInfo(current($meta)); $fileInfo['path'] = dirname($normalizedNewPath); $result['success'] = true; $result['data'] = $fileInfo; } else { // rename failed $result['data'] = array('message' => $this->l10n->t('%s could not be renamed', array($oldname))); } } } } return $result; }
public function testSizePropagationWhenRecipientChangesFile() { $this->loginHelper(self::TEST_FILES_SHARING_API_USER1); $recipientView = new View('/' . self::TEST_FILES_SHARING_API_USER1 . '/files'); $this->loginHelper(self::TEST_FILES_SHARING_API_USER2); $ownerView = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files'); $ownerView->mkdir('/sharedfolder/subfolder'); $ownerView->file_put_contents('/sharedfolder/subfolder/foo.txt', 'bar'); $sharedFolderInfo = $ownerView->getFileInfo('/sharedfolder', false); $this->assertInstanceOf('\\OC\\Files\\FileInfo', $sharedFolderInfo); \OCP\Share::shareItem('folder', $sharedFolderInfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER1, 31); $ownerRootInfo = $ownerView->getFileInfo('', false); $this->loginHelper(self::TEST_FILES_SHARING_API_USER1); $this->assertTrue($recipientView->file_exists('/sharedfolder/subfolder/foo.txt')); $recipientRootInfo = $recipientView->getFileInfo('', false); // when file changed as recipient $recipientView->file_put_contents('/sharedfolder/subfolder/foo.txt', 'foobar'); // size of recipient's root stays the same $newRecipientRootInfo = $recipientView->getFileInfo('', false); $this->assertEquals($recipientRootInfo->getSize(), $newRecipientRootInfo->getSize()); // size of owner's root increases $this->loginHelper(self::TEST_FILES_SHARING_API_USER2); $newOwnerRootInfo = $ownerView->getFileInfo('', false); $this->assertEquals($ownerRootInfo->getSize() + 3, $newOwnerRootInfo->getSize()); }
/** * rename a file * * @param string $dir * @param string $oldname * @param string $newname * @return array */ public function rename($dir, $oldname, $newname) { $result = array('success' => false, 'data' => NULL); // rename to "/Shared" is denied if ($dir === '/' and $newname === 'Shared') { $result['data'] = array('message' => $this->l10n->t("Invalid folder name. Usage of 'Shared' is reserved.")); // rename to existing file is denied } else { if ($this->view->file_exists($dir . '/' . $newname)) { $result['data'] = array('message' => $this->l10n->t("The name %s is already used in the folder %s. Please choose a different name.", array($newname, $dir))); } else { if ($newname !== '.' and !($dir === '/' and $oldname === 'Shared') and $this->view->rename($dir . '/' . $oldname, $dir . '/' . $newname)) { // successful rename $meta = $this->view->getFileInfo($dir . '/' . $newname); if ($meta['mimetype'] === 'httpd/unix-directory') { $meta['type'] = 'dir'; } else { $meta['type'] = 'file'; } $fileinfo = array('id' => $meta['fileid'], 'mime' => $meta['mimetype'], 'size' => $meta['size'], 'etag' => $meta['etag'], 'directory' => $dir, 'name' => $newname, 'isPreviewAvailable' => \OC::$server->getPreviewManager()->isMimeSupported($meta['mimetype']), 'icon' => \OCA\Files\Helper::determineIcon($meta)); $result['success'] = true; $result['data'] = $fileinfo; } else { // rename failed $result['data'] = array('message' => $this->l10n->t('%s could not be renamed', array($oldname))); } } } return $result; }
/** * @param string[] $users * @param string $subPath */ protected function assertEtagsNotChanged($users, $subPath = '') { $oldUser = \OC::$server->getUserSession()->getUser(); foreach ($users as $user) { $this->loginAsUser($user); $id = $this->fileIds[$user][$subPath]; $path = $this->rootView->getPath($id); $etag = $this->rootView->getFileInfo($path)->getEtag(); $this->assertEquals($this->fileEtags[$id], $etag, 'Failed asserting that the etag for "' . $subPath . '" of user ' . $user . ' has not changed'); $this->fileEtags[$id] = $etag; } $this->loginAsUser($oldUser->getUID()); }
/** * Returns the INode object for the requested path * * @param string $path * @throws \Sabre\DAV\Exception\ServiceUnavailable * @throws \Sabre\DAV\Exception\NotFound * @return \Sabre\DAV\INode */ public function getNodeForPath($path) { if (!$this->fileView) { throw new \Sabre\DAV\Exception\ServiceUnavailable('filesystem not setup'); } $path = trim($path, '/'); if (isset($this->cache[$path])) { return $this->cache[$path]; } // Is it the root node? if (!strlen($path)) { return $this->rootNode; } if (pathinfo($path, PATHINFO_EXTENSION) === 'part') { // read from storage $absPath = $this->fileView->getAbsolutePath($path); $mount = $this->fileView->getMount($path); $storage = $mount->getStorage(); $internalPath = $mount->getInternalPath($absPath); if ($storage) { /** * @var \OC\Files\Storage\Storage $storage */ $scanner = $storage->getScanner($internalPath); // get data directly $data = $scanner->getData($internalPath); $info = new FileInfo($absPath, $storage, $internalPath, $data, $mount); } else { $info = null; } } else { // read from cache try { $info = $this->fileView->getFileInfo($path); } catch (StorageNotAvailableException $e) { throw new \Sabre\DAV\Exception\ServiceUnavailable('Storage not available'); } catch (StorageInvalidException $e) { throw new \Sabre\DAV\Exception\NotFound('Storage ' . $path . ' is invalid'); } } if (!$info) { throw new \Sabre\DAV\Exception\NotFound('File with name ' . $path . ' could not be located'); } if ($info->getType() === 'dir') { $node = new \OC_Connector_Sabre_Directory($this->fileView, $info); } else { $node = new \OC_Connector_Sabre_File($this->fileView, $info); } $this->cache[$path] = $node; return $node; }
public function writeHook($params) { $path = $params['path']; $fullPath = $this->baseView->getAbsolutePath($path); $mount = $this->baseView->getMount($path); if ($mount instanceof SharedMount) { $this->propagateForOwner($mount->getShare(), $mount->getInternalPath($fullPath), $mount->getOwnerPropagator()); } $info = $this->baseView->getFileInfo($path); if ($info) { // trigger propagation if the subject of the write hook is shared. // if a parent folder of $path is shared the propagation will be triggered from the change propagator hooks $this->recipientPropagator->propagateById($info->getId()); } }
/** * Returns the matching file info * * @return FileInfo * @throws InvalidPathException * @throws NotFoundException */ public function getFileInfo() { if (!Filesystem::isValidPath($this->path)) { throw new InvalidPathException(); } if (!$this->fileInfo) { $fileInfo = $this->view->getFileInfo($this->path); if ($fileInfo instanceof FileInfo) { $this->fileInfo = $fileInfo; } else { throw new NotFoundException(); } } return $this->fileInfo; }
/** * @param string $userName * @return integer */ public function getMaximumStorageUsage($userName) { $view = new FilesView('/' . $userName . '/files'); $freeSpace = (int) $view->free_space(); $usedSpace = $view->getFileInfo('/')->getSize(); return $freeSpace + $usedSpace; }
function testDeleteSharedFile() { // generate filename $filename = 'tmp-' . $this->getUniqueID() . '.txt'; // save file with content $cryptedFile = file_put_contents('crypt:///' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename, $this->dataShort); // test that data was successfully written $this->assertTrue(is_int($cryptedFile)); // get the file info from previous created file $fileInfo = $this->view->getFileInfo('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename); // check if we have a valid file info $this->assertTrue($fileInfo instanceof \OC\Files\FileInfo); // share the file $this->assertTrue(\OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_ENCRYPTION_TRASHBIN_USER2, OCP\PERMISSION_ALL)); self::loginHelper(self::TEST_ENCRYPTION_TRASHBIN_USER2); $this->assertTrue(\OC\Files\Filesystem::file_exists($filename)); \OCA\Files_Trashbin\Trashbin::move2trash($filename); $query = \OC_DB::prepare('SELECT `timestamp` FROM `*PREFIX*files_trash`' . ' WHERE `id`=?'); $result = $query->execute(array($filename))->fetchRow(); $this->assertNotEmpty($result); $timestamp = $result['timestamp']; // check if key for both users exists $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/keyfiles/' . $filename . '.key.d' . $timestamp)); // check if key for admin exists $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER2 . '/files_trashbin/keyfiles/' . $filename . '.key.d' . $timestamp)); // check if share key for both users exists $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/share-keys/' . $filename . '.' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey.d' . $timestamp)); $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER2 . '/files_trashbin/share-keys/' . $filename . '.' . self::TEST_ENCRYPTION_TRASHBIN_USER2 . '.shareKey.d' . $timestamp)); }
public function testPropagateCrossStorage() { $storage = new Temporary(); $this->view->mkdir('/foo'); Filesystem::mount($storage, [], $this->view->getAbsolutePath('/foo/submount')); $this->view->mkdir('/foo/submount/bar'); $this->view->file_put_contents('/foo/submount/bar/sad.txt', 'qwerty'); $oldInfo1 = $this->view->getFileInfo('/'); $oldInfo2 = $this->view->getFileInfo('/foo'); $oldInfo3 = $this->view->getFileInfo('/foo/submount'); $oldInfo4 = $this->view->getFileInfo('/foo/submount/bar'); $time = time() + 50; $this->propagator->addChange('/foo/submount/bar/sad.txt'); $this->propagator->propagateChanges($time); $newInfo1 = $this->view->getFileInfo('/'); $newInfo2 = $this->view->getFileInfo('/foo'); $newInfo3 = $this->view->getFileInfo('/foo/submount'); $newInfo4 = $this->view->getFileInfo('/foo/submount/bar'); $this->assertEquals($newInfo1->getMTime(), $time); $this->assertEquals($newInfo2->getMTime(), $time); $this->assertEquals($newInfo3->getMTime(), $time); $this->assertEquals($newInfo4->getMTime(), $time); $this->assertNotSame($oldInfo1->getEtag(), $newInfo1->getEtag()); $this->assertNotSame($oldInfo2->getEtag(), $newInfo2->getEtag()); $this->assertNotSame($oldInfo3->getEtag(), $newInfo3->getEtag()); $this->assertNotSame($oldInfo4->getEtag(), $newInfo3->getEtag()); }
private function doTestRestore() { $filePath = self::TEST_VERSIONS_USER . '/files/sub/test.txt'; $this->rootView->file_put_contents($filePath, 'test file'); $t0 = $this->rootView->filemtime($filePath); // not exactly the same timestamp as the file $t1 = time() - 60; // second version is two weeks older $t2 = $t1 - 60 * 60 * 24 * 14; // create some versions $v1 = self::USERS_VERSIONS_ROOT . '/sub/test.txt.v' . $t1; $v2 = self::USERS_VERSIONS_ROOT . '/sub/test.txt.v' . $t2; $this->rootView->mkdir(self::USERS_VERSIONS_ROOT . '/sub'); $this->rootView->file_put_contents($v1, 'version1'); $this->rootView->file_put_contents($v2, 'version2'); $oldVersions = \OCA\Files_Versions\Storage::getVersions(self::TEST_VERSIONS_USER, '/sub/test.txt'); $this->assertCount(2, $oldVersions); $this->assertEquals('test file', $this->rootView->file_get_contents($filePath)); $info1 = $this->rootView->getFileInfo($filePath); \OCA\Files_Versions\Storage::rollback('sub/test.txt', $t2); $this->assertEquals('version2', $this->rootView->file_get_contents($filePath)); $info2 = $this->rootView->getFileInfo($filePath); $this->assertNotEquals($info2['etag'], $info1['etag'], 'Etag must change after rolling back version'); $this->assertEquals($info2['fileid'], $info1['fileid'], 'File id must not change after rolling back version'); $this->assertEquals($info2['mtime'], $t2, 'Restored file has mtime from version'); $newVersions = \OCA\Files_Versions\Storage::getVersions(self::TEST_VERSIONS_USER, '/sub/test.txt'); $this->assertTrue($this->rootView->file_exists(self::USERS_VERSIONS_ROOT . '/sub/test.txt.v' . $t0), 'A version file was created for the file before restoration'); $this->assertTrue($this->rootView->file_exists($v1), 'Untouched version file is still there'); $this->assertFalse($this->rootView->file_exists($v2), 'Restored version file gone from files_version folder'); $this->assertCount(2, $newVersions, 'Additional version created'); $this->assertTrue(isset($newVersions[$t0 . '#' . 'test.txt']), 'A version was created for the file before restoration'); $this->assertTrue(isset($newVersions[$t1 . '#' . 'test.txt']), 'Untouched version is still there'); $this->assertFalse(isset($newVersions[$t2 . '#' . 'test.txt']), 'Restored version is not in the list any more'); }
/** * @param string $owner * @param int $fileId * @param string $filePath * @return array */ protected function getPreview($owner, $fileId, $filePath) { $info = $this->infoCache->getInfoById($owner, $fileId, $filePath); if (!$info['exists'] || $info['view'] !== '') { return $this->getPreviewFromPath($filePath, $info); } $preview = ['link' => $this->getPreviewLink($info['path'], $info['is_dir'], $info['view']), 'source' => '', 'isMimeTypeIcon' => true]; // show a preview image if the file still exists if ($info['is_dir']) { $preview['source'] = $this->getPreviewPathFromMimeType('dir'); } else { $this->view->chroot('/' . $owner . '/files'); $fileInfo = $this->view->getFileInfo($info['path']); if (!$fileInfo instanceof FileInfo) { $pathPreview = $this->getPreviewFromPath($filePath, $info); $preview['source'] = $pathPreview['source']; } else { if ($this->preview->isAvailable($fileInfo)) { $preview['isMimeTypeIcon'] = false; $preview['source'] = $this->urlGenerator->linkToRoute('core_ajax_preview', ['file' => $info['path'], 'c' => $this->view->getETag($info['path']), 'x' => 150, 'y' => 150]); } else { $preview['source'] = $this->getPreviewPathFromMimeType($fileInfo->getMimetype()); } } } return $preview; }
/** * @return bool */ public function stream_close() { $this->flush(); // if there is no valid private key return false if ($this->privateKey === false) { // cleanup if ($this->meta['mode'] !== 'r' && $this->meta['mode'] !== 'rb' && !$this->isLocalTmpFile) { // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; if ($this->rootView->file_exists($this->rawPath) && $this->size === 0) { $this->rootView->unlink($this->rawPath); } // Re-enable proxy - our work is done \OC_FileProxy::$enabled = $proxyStatus; } // if private key is not valid redirect user to a error page \OCA\Encryption\Helper::redirectToErrorPage($this->session); } if ($this->meta['mode'] !== 'r' && $this->meta['mode'] !== 'rb' && $this->isLocalTmpFile === false && $this->size > 0 && $this->unencryptedSize > 0) { // only write keyfiles if it was a new file if ($this->newFile === true) { // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; // Fetch user's public key $this->publicKey = Keymanager::getPublicKey($this->rootView, $this->keyId); // Check if OC sharing api is enabled $sharingEnabled = \OCP\Share::isEnabled(); $util = new Util($this->rootView, $this->userId); // Get all users sharing the file includes current user $uniqueUserIds = $util->getSharingUsersArray($sharingEnabled, $this->relPath); $checkedUserIds = $util->filterShareReadyUsers($uniqueUserIds); // Fetch public keys for all sharing users $publicKeys = Keymanager::getPublicKeys($this->rootView, $checkedUserIds['ready']); // Encrypt enc key for all sharing users $this->encKeyfiles = Crypt::multiKeyEncrypt($this->plainKey, $publicKeys); // Save the new encrypted file key Keymanager::setFileKey($this->rootView, $util, $this->relPath, $this->encKeyfiles['data']); // Save the sharekeys Keymanager::setShareKeys($this->rootView, $util, $this->relPath, $this->encKeyfiles['keys']); // Re-enable proxy - our work is done \OC_FileProxy::$enabled = $proxyStatus; } // we need to update the file info for the real file, not for the // part file. $path = Helper::stripPartialFileExtension($this->rawPath); // get file info $fileInfo = $this->rootView->getFileInfo($path); if (is_array($fileInfo)) { // set encryption data $fileInfo['encrypted'] = true; $fileInfo['size'] = $this->size; $fileInfo['unencrypted_size'] = $this->unencryptedSize; // set fileinfo $this->rootView->putFileInfo($path, $fileInfo); } } return fclose($this->handle); }
public function testSinglePropagate() { $this->view->mkdir('/foo'); $this->view->mkdir('/foo/bar'); $this->view->file_put_contents('/foo/bar/sad.txt', 'qwerty'); $oldInfo1 = $this->view->getFileInfo('/'); $oldInfo2 = $this->view->getFileInfo('/foo'); $oldInfo3 = $this->view->getFileInfo('/foo/bar'); $time = time() + 50; $this->propagator->addChange('/foo/bar/sad.txt'); $this->propagator->propagateChanges($time); $newInfo1 = $this->view->getFileInfo('/'); $newInfo2 = $this->view->getFileInfo('/foo'); $newInfo3 = $this->view->getFileInfo('/foo/bar'); $this->assertEquals($newInfo1->getMTime(), $time); $this->assertEquals($newInfo2->getMTime(), $time); $this->assertEquals($newInfo3->getMTime(), $time); $this->assertNotSame($oldInfo1->getEtag(), $newInfo1->getEtag()); $this->assertNotSame($oldInfo2->getEtag(), $newInfo2->getEtag()); $this->assertNotSame($oldInfo3->getEtag(), $newInfo3->getEtag()); }
/** * @param string $userName * @return integer */ public function byUsername($userName) { $view = new FilesView('/' . $userName . '/files'); $freeSpace = (int) $view->free_space(); $fileInfo = $view->getFileInfo('/'); Assertion::notEmpty($fileInfo); $usedSpace = $fileInfo->getSize(); return KiloBytes::allocateUnits($freeSpace + $usedSpace)->units(); }
/** * Stores the sample in the filesystem and stores it in the $samples array * * @param string $fileName * @param int $sampleWidth * @param int $sampleHeight */ private function prepareSample($fileName, $sampleWidth, $sampleHeight) { $imgData = file_get_contents(\OC::$SERVERROOT . '/tests/data/' . $fileName); $imgPath = '/' . self::TEST_PREVIEW_USER1 . '/files/' . $fileName; $this->rootView->file_put_contents($imgPath, $imgData); $fileInfo = $this->rootView->getFileInfo($imgPath); list($maxPreviewWidth, $maxPreviewHeight) = $this->setMaxPreview($sampleWidth, $sampleHeight); $this->samples[] = ['sampleFileId' => $fileInfo['fileid'], 'sampleFileName' => $fileName, 'sampleWidth' => $sampleWidth, 'sampleHeight' => $sampleHeight, 'maxPreviewWidth' => $maxPreviewWidth, 'maxPreviewHeight' => $maxPreviewHeight]; }
public function testOwnerUnshares() { $this->loginAsUser(self::TEST_FILES_SHARING_API_USER1); $folderInfo = $this->rootView->getFileInfo('/' . self::TEST_FILES_SHARING_API_USER1 . '/files/sub1/sub2/folder'); $folderId = $folderInfo->getId(); $this->assertTrue(\OCP\Share::unshare('folder', $folderId, \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2)); $this->assertEtagsForFoldersChanged([self::TEST_FILES_SHARING_API_USER2, self::TEST_FILES_SHARING_API_USER4]); $this->assertAllUnchaged(); }
/** * Plugin that checks if a move can actually be performed. * @param string $source source path * @param string $destination destination path * @throws \Sabre\DAV\Exception\Forbidden */ function checkMove($source, $destination) { list($sourceDir, ) = \Sabre\HTTP\URLUtil::splitPath($source); list($destinationDir, ) = \Sabre\HTTP\URLUtil::splitPath($destination); if ($sourceDir !== $destinationDir) { $sourceFileInfo = $this->fileView->getFileInfo($source); if (!$sourceFileInfo->isDeletable()) { throw new \Sabre\DAV\Exception\Forbidden($source . " cannot be deleted"); } } }
/** * "user1" creates /test, /test/sub and shares with group1 * "user2" (in group1) reshares /test with group2 and reshared /test/sub with group3 * "user3" (in group 2) * "user4" (in group 3) */ protected function setUpShares() { $this->fileIds[self::TEST_FILES_SHARING_API_USER1] = []; $this->fileIds[self::TEST_FILES_SHARING_API_USER2] = []; $this->fileIds[self::TEST_FILES_SHARING_API_USER3] = []; $this->fileIds[self::TEST_FILES_SHARING_API_USER4] = []; $this->rootView = new View(''); $this->loginAsUser(self::TEST_FILES_SHARING_API_USER1); $view1 = new View('/' . self::TEST_FILES_SHARING_API_USER1 . '/files'); $view1->mkdir('/test/sub'); $folderInfo = $view1->getFileInfo('/test'); \OCP\Share::shareItem('folder', $folderInfo->getId(), \OCP\Share::SHARE_TYPE_GROUP, 'group1', 31); $this->fileIds[self::TEST_FILES_SHARING_API_USER1][''] = $view1->getFileInfo('')->getId(); $this->fileIds[self::TEST_FILES_SHARING_API_USER1]['test'] = $view1->getFileInfo('test')->getId(); $this->fileIds[self::TEST_FILES_SHARING_API_USER1]['test/sub'] = $view1->getFileInfo('test/sub')->getId(); $this->loginAsUser(self::TEST_FILES_SHARING_API_USER2); $view2 = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files'); $folderInfo = $view2->getFileInfo('/test'); $subFolderInfo = $view2->getFileInfo('/test/sub'); \OCP\Share::shareItem('folder', $folderInfo->getId(), \OCP\Share::SHARE_TYPE_GROUP, 'group2', 31); \OCP\Share::shareItem('folder', $subFolderInfo->getId(), \OCP\Share::SHARE_TYPE_GROUP, 'group3', 31); $this->fileIds[self::TEST_FILES_SHARING_API_USER2][''] = $view2->getFileInfo('')->getId(); $this->fileIds[self::TEST_FILES_SHARING_API_USER2]['test'] = $view2->getFileInfo('test')->getId(); $this->fileIds[self::TEST_FILES_SHARING_API_USER2]['test/sub'] = $view2->getFileInfo('test/sub')->getId(); $this->loginAsUser(self::TEST_FILES_SHARING_API_USER3); $view3 = new View('/' . self::TEST_FILES_SHARING_API_USER3 . '/files'); $this->fileIds[self::TEST_FILES_SHARING_API_USER3][''] = $view3->getFileInfo('')->getId(); $this->fileIds[self::TEST_FILES_SHARING_API_USER3]['test'] = $view3->getFileInfo('test')->getId(); $this->fileIds[self::TEST_FILES_SHARING_API_USER3]['test/sub'] = $view3->getFileInfo('test/sub')->getId(); $this->loginAsUser(self::TEST_FILES_SHARING_API_USER4); $view4 = new View('/' . self::TEST_FILES_SHARING_API_USER4 . '/files'); $this->fileIds[self::TEST_FILES_SHARING_API_USER4][''] = $view4->getFileInfo('')->getId(); $this->fileIds[self::TEST_FILES_SHARING_API_USER4]['sub'] = $view4->getFileInfo('sub')->getId(); foreach ($this->fileIds as $user => $ids) { $this->loginAsUser($user); foreach ($ids as $id) { $path = $this->rootView->getPath($id); $this->fileEtags[$id] = $this->rootView->getFileInfo($path)->getEtag(); } } }
function testDescryptAllWithBrokenFiles() { $file1 = "/decryptAll1" . $this->getUniqueID() . ".txt"; $file2 = "/decryptAll2" . $this->getUniqueID() . ".txt"; $util = new \OCA\Files_Encryption\Util($this->view, $this->userId); $this->view->file_put_contents($this->userId . '/files/' . $file1, $this->dataShort); $this->view->file_put_contents($this->userId . '/files/' . $file2, $this->dataShort); $fileInfoEncrypted1 = $this->view->getFileInfo($this->userId . '/files/' . $file1); $fileInfoEncrypted2 = $this->view->getFileInfo($this->userId . '/files/' . $file2); $this->assertTrue($fileInfoEncrypted1 instanceof \OC\Files\FileInfo); $this->assertTrue($fileInfoEncrypted2 instanceof \OC\Files\FileInfo); $this->assertEquals($fileInfoEncrypted1['encrypted'], 1); $this->assertEquals($fileInfoEncrypted2['encrypted'], 1); // rename keyfile for file1 so that the decryption for file1 fails // Expected behaviour: decryptAll() returns false, file2 gets decrypted anyway $this->view->rename($this->userId . '/files_encryption/keys/' . $file1 . '/fileKey', $this->userId . '/files_encryption/keys/' . $file1 . '/fileKey.moved'); // need to reset key cache that we don't use the cached key $this->resetKeyCache(); // decrypt all encrypted files $result = $util->decryptAll(); $this->assertFalse($result); $fileInfoUnencrypted1 = $this->view->getFileInfo($this->userId . '/files/' . $file1); $fileInfoUnencrypted2 = $this->view->getFileInfo($this->userId . '/files/' . $file2); $this->assertTrue($fileInfoUnencrypted1 instanceof \OC\Files\FileInfo); $this->assertTrue($fileInfoUnencrypted2 instanceof \OC\Files\FileInfo); // file1 should be still encrypted; file2 should be decrypted $this->assertEquals(1, $fileInfoUnencrypted1['encrypted']); $this->assertEquals(0, $fileInfoUnencrypted2['encrypted']); // keyfiles and share keys should still exist $this->assertTrue($this->view->is_dir($this->userId . '/files_encryption/keys/')); $this->assertTrue($this->view->file_exists($this->userId . '/files_encryption/keys/' . $file1 . '/fileKey.moved')); $this->assertTrue($this->view->file_exists($this->userId . '/files_encryption/keys/' . $file1 . '/' . $this->userId . '.shareKey')); // rename the keyfile for file1 back $this->view->rename($this->userId . '/files_encryption/keys/' . $file1 . '/fileKey.moved', $this->userId . '/files_encryption/keys/' . $file1 . '/fileKey'); // try again to decrypt all encrypted files $result = $util->decryptAll(); $this->assertTrue($result); $fileInfoUnencrypted1 = $this->view->getFileInfo($this->userId . '/files/' . $file1); $fileInfoUnencrypted2 = $this->view->getFileInfo($this->userId . '/files/' . $file2); $this->assertTrue($fileInfoUnencrypted1 instanceof \OC\Files\FileInfo); $this->assertTrue($fileInfoUnencrypted2 instanceof \OC\Files\FileInfo); // now both files should be decrypted $this->assertEquals(0, $fileInfoUnencrypted1['encrypted']); $this->assertEquals(0, $fileInfoUnencrypted2['encrypted']); // keyfiles and share keys should be deleted $this->assertFalse($this->view->is_dir($this->userId . '/files_encryption/keys/')); //cleanup $backupPath = $this->getBackupPath('decryptAll'); $this->view->unlink($this->userId . '/files/' . $file1); $this->view->unlink($this->userId . '/files/' . $file2); $this->view->deleteAll($backupPath); }
/** * @return Directory */ private function impl() { $rootView = new View(); $user = \OC::$server->getUserSession()->getUser(); Filesystem::initMountPoints($user->getUID()); if (!$rootView->file_exists('/' . $user->getUID() . '/uploads')) { $rootView->mkdir('/' . $user->getUID() . '/uploads'); } $view = new View('/' . $user->getUID() . '/uploads'); $rootInfo = $view->getFileInfo(''); $impl = new Directory($view, $rootInfo); return $impl; }
function testDeleteHooksForSharedFiles() { self::logoutHelper(); self::loginHelper(self::TEST_ENCRYPTION_HOOKS_USER1); \OC_User::setUserId(self::TEST_ENCRYPTION_HOOKS_USER1); // remember files_trashbin state $stateFilesTrashbin = \OC_App::isEnabled('files_trashbin'); // we want to tests with app files_trashbin disabled \OC_App::disable('files_trashbin'); // make sure that the trash bin is disabled $this->assertFalse(\OC_APP::isEnabled('files_trashbin')); $this->user1View->file_put_contents($this->filename, $this->data); // check if all keys are generated $this->assertTrue($this->rootView->file_exists(self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keys/' . $this->filename . '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '.shareKey')); $this->assertTrue($this->rootView->file_exists(self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keys/' . $this->filename . '/fileKey')); // get the file info from previous created file $fileInfo = $this->user1View->getFileInfo($this->filename); // check if we have a valid file info $this->assertTrue($fileInfo instanceof \OC\Files\FileInfo); // share the file with user2 \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_ENCRYPTION_HOOKS_USER2, \OCP\Constants::PERMISSION_ALL); // check if new share key exists $this->assertTrue($this->rootView->file_exists(self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keys/' . $this->filename . '/' . self::TEST_ENCRYPTION_HOOKS_USER2 . '.shareKey')); self::logoutHelper(); self::loginHelper(self::TEST_ENCRYPTION_HOOKS_USER2); \OC_User::setUserId(self::TEST_ENCRYPTION_HOOKS_USER2); // user2 update the shared file $this->user2View->file_put_contents($this->filename, $this->data); // keys should be stored at user1s dir, not in user2s $this->assertFalse($this->rootView->file_exists(self::TEST_ENCRYPTION_HOOKS_USER2 . '/files_encryption/keys/' . $this->filename . '/' . self::TEST_ENCRYPTION_HOOKS_USER2 . '.shareKey')); $this->assertFalse($this->rootView->file_exists(self::TEST_ENCRYPTION_HOOKS_USER2 . '/files_encryption/keys/' . $this->filename . '/fileKey')); // delete the Shared file from user1 in data/user2/files/Shared $result = $this->user2View->unlink($this->filename); $this->assertTrue($result); // share key for user2 from user1s home should be gone, all other keys should still exists $this->assertTrue($this->rootView->file_exists(self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keys/' . $this->filename . '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '.shareKey')); $this->assertFalse($this->rootView->file_exists(self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keys/' . $this->filename . '/' . self::TEST_ENCRYPTION_HOOKS_USER2 . '.shareKey')); $this->assertTrue($this->rootView->file_exists(self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keys/' . $this->filename . '/fileKey')); // cleanup self::logoutHelper(); self::loginHelper(self::TEST_ENCRYPTION_HOOKS_USER1); \OC_User::setUserId(self::TEST_ENCRYPTION_HOOKS_USER1); if ($stateFilesTrashbin) { \OC_App::enable('files_trashbin'); } else { \OC_App::disable('files_trashbin'); } }
/** * Test that deleting a file from another mounted storage properly * lands in the trashbin. This is a cross-storage situation because * the trashbin folder is in the root storage while the mounted one * isn't. */ public function testCrossStorageDelete() { $storage2 = new Temporary(array()); \OC\Files\Filesystem::mount($storage2, array(), $this->user . '/files/substorage'); $this->userView->file_put_contents('substorage/subfile.txt', 'foo'); $storage2->getScanner()->scan(''); $this->assertTrue($storage2->file_exists('subfile.txt')); $this->userView->unlink('substorage/subfile.txt'); $storage2->getScanner()->scan(''); $this->assertFalse($this->userView->getFileInfo('substorage/subfile.txt')); $this->assertFalse($storage2->file_exists('subfile.txt')); // check if file is in trashbin $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/files'); $this->assertEquals(1, count($results)); $name = $results[0]->getName(); $this->assertEquals('subfile.txt', substr($name, 0, strrpos($name, '.'))); }
/** * Test that deleted versions properly land in the trashbin when deleting as share recipient. */ public function testDeleteVersionsOfFolderAsRecipient() { \OCA\Files_Versions\Hooks::connectHooks(); $this->userView->mkdir('share'); $this->userView->mkdir('share/folder'); // trigger a version (multiple would not work because of the expire logic) $this->userView->file_put_contents('share/folder/test.txt', 'v1'); $this->userView->file_put_contents('share/folder/test.txt', 'v2'); $results = $this->rootView->getDirectoryContent($this->user . '/files_versions/share/folder/'); $this->assertEquals(1, count($results)); $recipientUser = $this->getUniqueId('recipient_'); \OC::$server->getUserManager()->createUser($recipientUser, $recipientUser); $fileinfo = $this->userView->getFileInfo('share'); $this->assertTrue(\OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, $recipientUser, 31)); $this->loginAsUser($recipientUser); // delete as recipient $recipientView = new \OC\Files\View('/' . $recipientUser . '/files'); $recipientView->rmdir('share/folder'); // rescan trash storage list($rootStorage, ) = $this->rootView->resolvePath($this->user . '/files_trashbin'); $rootStorage->getScanner()->scan(''); // check if versions are in trashbin for owner $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/versions'); $this->assertEquals(1, count($results)); $name = $results[0]->getName(); $this->assertEquals('folder.d', substr($name, 0, strlen('folder.d'))); // check if file versions are in trashbin for owner $results = $this->rootView->getDirectoryContent($this->user . '/files_trashbin/versions/' . $name . '/'); $this->assertEquals(1, count($results)); $name = $results[0]->getName(); $this->assertEquals('test.txt.v', substr($name, 0, strlen('test.txt.v'))); // check if versions are in trashbin for recipient $results = $this->rootView->getDirectoryContent($recipientUser . '/files_trashbin/versions'); $this->assertEquals(1, count($results)); $name = $results[0]->getName(); $this->assertEquals('folder.d', substr($name, 0, strlen('folder.d'))); // check if file versions are in trashbin for recipient $results = $this->rootView->getDirectoryContent($recipientUser . '/files_trashbin/versions/' . $name . '/'); $this->assertEquals(1, count($results)); $name = $results[0]->getName(); $this->assertEquals('test.txt.v', substr($name, 0, strlen('test.txt.v'))); // versions deleted $results = $this->rootView->getDirectoryContent($recipientUser . '/files_versions/share/folder/'); $this->assertEquals(0, count($results)); }
public function testCreationFromCached() { $sampleFile = '/' . $this->user . '/files/test.txt'; $this->rootView->file_put_contents($sampleFile, 'dummy file data'); // create base preview $x = 150; $y = 150; $preview = new \OC\Preview($this->user, 'files/', 'test.txt', $x, $y); $preview->getPreview(); $fileInfo = $this->rootView->getFileInfo($sampleFile); $fileId = $fileInfo['fileid']; $thumbCacheFile = '/' . $this->user . '/' . \OC\Preview::THUMBNAILS_FOLDER . '/' . $fileId . '/' . $x . '-' . $y . '.png'; $this->assertEquals($this->rootView->file_exists($thumbCacheFile), true); // create smaller previews $preview = new \OC\Preview($this->user, 'files/', 'test.txt', 50, 50); $isCached = $preview->isCached($fileId); $this->assertEquals($this->user . '/' . \OC\Preview::THUMBNAILS_FOLDER . '/' . $fileId . '/150-150.png', $isCached); }
/** * Plugin that checks if a move can actually be performed. * * @param string $source source path * @param string $destination destination path * @throws Forbidden * @throws NotFound */ function checkMove($source, $destination) { $sourceNode = $this->tree->getNodeForPath($source); if ($sourceNode instanceof FutureFile) { return; } list($sourceDir, ) = \Sabre\HTTP\URLUtil::splitPath($source); list($destinationDir, ) = \Sabre\HTTP\URLUtil::splitPath($destination); if ($sourceDir !== $destinationDir) { $sourceFileInfo = $this->fileView->getFileInfo($source); if ($sourceFileInfo === false) { throw new NotFound($source . ' does not exist'); } if (!$sourceFileInfo->isDeletable()) { throw new Forbidden($source . " cannot be deleted"); } } }
/** * fix the file size of the encrypted file * @param string $path absolute path * @return boolean true / false if file is encrypted */ public function fixFileSize($path) { $result = false; // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; $realSize = $this->getFileSize($path); if ($realSize > 0) { $cached = $this->view->getFileInfo($path); $cached['encrypted'] = true; // set the size $cached['unencrypted_size'] = $realSize; // put file info $this->view->putFileInfo($path, $cached); $result = true; } \OC_FileProxy::$enabled = $proxyStatus; return $result; }
protected function setUp() { parent::setUp(); $user = $this->getMockBuilder('\\OCP\\IUser')->disableOriginalConstructor()->getMock(); $user->method('getUID')->willReturn(self::TEST_FILES_SHARING_API_USER1); $userSession = $this->getMockBuilder('\\OCP\\IUserSession')->disableOriginalConstructor()->getMock(); $userSession->method('getUser')->willReturn(selF::TEST_FILES_SHARING_API_USER1); $this->propagationManager = $this->getMockBuilder('OCA\\Files_Sharing\\Propagation\\PropagationManager')->disableOriginalConstructor()->getMock(); $this->groupManager = \OC::$server->getGroupManager(); $this->groupPropagationManager = new GroupPropagationManager($userSession, $this->groupManager, $this->propagationManager); $this->groupPropagationManager->globalSetup(); // since the sharing code is not mockable, we have to create a real folder $this->loginAsUser(self::TEST_FILES_SHARING_API_USER1); $view1 = new View('/' . self::TEST_FILES_SHARING_API_USER1 . '/files'); $view1->mkdir('/folder'); $this->fileInfo = $view1->getFileInfo('/folder'); $this->recipientGroup = $this->groupManager->get(self::TEST_FILES_SHARING_API_GROUP1); $this->recipientUser = \OC::$server->getUserManager()->get(self::TEST_FILES_SHARING_API_USER3); Share::shareItem('folder', $this->fileInfo['fileid'], Share::SHARE_TYPE_GROUP, $this->recipientGroup->getGID(), \OCP\Constants::PERMISSION_READ); $this->loginAsUser($this->recipientUser->getUID()); }