/** * Get the template for a specific activity-event in the activities * * @param array $activity An array with all the activity data in it * @return string */ public function show($activity) { $tmpl = new Template('activity', 'stream.item'); $tmpl->assign('formattedDate', $this->dateTimeFormatter->formatDateTime($activity['timestamp'])); $tmpl->assign('formattedTimestamp', Template::relative_modified_date($activity['timestamp'])); if (strpos($activity['subjectformatted']['markup']['trimmed'], '<a ') !== false) { // We do not link the subject as we create links for the parameters instead $activity['link'] = ''; } $tmpl->assign('event', $activity); if ($activity['file']) { $this->view->chroot('/' . $activity['affecteduser'] . '/files'); $exist = $this->view->file_exists($activity['file']); $is_dir = $this->view->is_dir($activity['file']); $tmpl->assign('previewLink', $this->getPreviewLink($activity['file'], $is_dir)); // show a preview image if the file still exists $mimeType = Files::getMimeType($activity['file']); if ($mimeType && !$is_dir && $this->preview->isMimeSupported($mimeType) && $exist) { $tmpl->assign('previewImageLink', $this->urlGenerator->linkToRoute('core_ajax_preview', array('file' => $activity['file'], 'x' => 150, 'y' => 150))); } else { $mimeTypeIcon = Template::mimetype_icon($is_dir ? 'dir' : $mimeType); $mimeTypeIcon = substr($mimeTypeIcon, -4) === '.png' ? substr($mimeTypeIcon, 0, -4) . '.svg' : $mimeTypeIcon; $tmpl->assign('previewImageLink', $mimeTypeIcon); $tmpl->assign('previewLinkIsDir', true); } } return $tmpl->fetchPage(); }
/** * Returns all certificates trusted by the user * * @return \OCP\ICertificate[] */ public function listCertificates() { if (!$this->config->getSystemValue('installed', false)) { return array(); } $path = $this->getPathToCertificates() . 'uploads/'; if (!$this->view->is_dir($path)) { return array(); } $result = array(); $handle = $this->view->opendir($path); if (!is_resource($handle)) { return array(); } while (false !== ($file = readdir($handle))) { if ($file != '.' && $file != '..') { try { $result[] = new Certificate($this->view->file_get_contents($path . $file), $file); } catch (\Exception $e) { } } } closedir($handle); return $result; }
public function run() { $view = new View('/'); $children = $view->getDirectoryContent('/'); foreach ($children as $child) { if ($view->is_dir($child->getPath())) { $thumbnailsFolder = $child->getPath() . '/thumbnails'; if ($view->is_dir($thumbnailsFolder)) { $view->rmdir($thumbnailsFolder); } } } }
/** * check if the parent folder exists otherwise move the mount point up * * @param \OCP\Share\IShare $share * @param SharedMount[] $mountpoints * @return string */ private function verifyMountPoint(\OCP\Share\IShare $share, array $mountpoints) { $mountPoint = basename($share->getTarget()); $parent = dirname($share->getTarget()); if (!$this->recipientView->is_dir($parent)) { $parent = Helper::getShareFolder(); } $newMountPoint = $this->generateUniqueTarget(\OC\Files\Filesystem::normalizePath($parent . '/' . $mountPoint), $this->recipientView, $mountpoints); if ($newMountPoint !== $share->getTarget()) { $this->updateFileTarget($newMountPoint, $share); } return $newMountPoint; }
public function testAreAllPreviewsDeleted() { $sampleFile = '/' . $this->user . '/files/test.txt'; $this->rootView->file_put_contents($sampleFile, 'dummy file data'); $x = 50; $y = 50; $preview = new \OC\Preview($this->user, 'files/', 'test.txt', $x, $y); $preview->getPreview(); $fileInfo = $this->rootView->getFileInfo($sampleFile); $fileId = $fileInfo['fileid']; $thumbCacheFolder = '/' . $this->user . '/' . \OC\Preview::THUMBNAILS_FOLDER . '/' . $fileId . '/'; $this->assertEquals($this->rootView->is_dir($thumbCacheFolder), true); $preview->deleteAllPreviews(); $this->assertEquals($this->rootView->is_dir($thumbCacheFolder), false); }
/** * check if the parent folder exists otherwise move the mount point up * * @param array $share * @return string */ private function verifyMountPoint(&$share) { $mountPoint = basename($share['file_target']); $parent = dirname($share['file_target']); if (!$this->recipientView->is_dir($parent)) { $parent = Helper::getShareFolder(); } $newMountPoint = \OCA\Files_Sharing\Helper::generateUniqueTarget(\OC\Files\Filesystem::normalizePath($parent . '/' . $mountPoint), [], $this->recipientView); if ($newMountPoint !== $share['file_target']) { $this->updateFileTarget($newMountPoint, $share); $share['file_target'] = $newMountPoint; $share['unique_name'] = true; } return $newMountPoint; }
/** * Prepares a file parameter for usage * * Removes the path from filenames and adds highlights * * @param string $param * @param bool $stripPath Shall we remove the path from the filename * @param bool $highlightParams * @return string */ protected function prepareFileParam($param, $stripPath, $highlightParams) { $param = $this->fixLegacyFilename($param); $is_dir = $this->rootView->is_dir('/' . User::getUser() . '/files' . $param); if ($is_dir) { $parent_dir = $param; } else { $parent_dir = substr_count($param, '/') == 1 ? '/' : dirname($param); } $fileLink = Util::linkTo('files', 'index.php', array('dir' => $parent_dir)); $param = trim($param, '/'); if (!$stripPath) { if (!$highlightParams) { return $param; } return '<a class="filename" href="' . $fileLink . '">' . Util::sanitizeHTML($param) . '</a>'; } if (!$highlightParams) { return $this->stripPathFromFilename($param); } $title = $param; $title = ' title="' . Util::sanitizeHTML($title) . '"'; $newParam = $this->stripPathFromFilename($param); return '<a class="filename tooltip" href="' . $fileLink . '"' . $title . '>' . Util::sanitizeHTML($newParam) . '</a>'; }
/** * Get the template for a specific activity-event in the activities * * @param array $activity An array with all the activity data in it * @return string */ public static function show($activity) { $tmpl = new Template('activity', 'activity.box'); $tmpl->assign('formattedDate', Util::formatDate($activity['timestamp'])); $tmpl->assign('formattedTimestamp', \OCP\relative_modified_date($activity['timestamp'])); $tmpl->assign('user', $activity['user']); $tmpl->assign('displayName', User::getDisplayName($activity['user'])); if ($activity['app'] === 'files') { // We do not link the subject as we create links for the parameters instead $activity['link'] = ''; } $tmpl->assign('event', $activity); if ($activity['file']) { $rootView = new View('/' . $activity['affecteduser'] . '/files'); $exist = $rootView->file_exists($activity['file']); $is_dir = $rootView->is_dir($activity['file']); unset($rootView); // show a preview image if the file still exists $mimetype = \OC_Helper::getFileNameMimeType($activity['file']); if (!$is_dir && \OC::$server->getPreviewManager()->isMimeSupported($mimetype) && $exist) { $tmpl->assign('previewLink', Util::linkTo('files', 'index.php', array('dir' => dirname($activity['file'])))); $tmpl->assign('previewImageLink', Util::linkToRoute('core_ajax_preview', array('file' => $activity['file'], 'x' => 150, 'y' => 150))); } else { $tmpl->assign('previewLink', Util::linkTo('files', 'index.php', array('dir' => $activity['file']))); $tmpl->assign('previewImageLink', \OC_Helper::mimetypeIcon($is_dir ? 'dir' : $mimetype)); $tmpl->assign('previewLinkIsDir', true); } } return $tmpl->fetchPage(); }
/** * @param string $user * @param int $fileId * @param string $filePath * @return array */ protected function findInfoById($user, $fileId, $filePath) { $this->view->chroot('/' . $user . '/files'); $cache = ['path' => $filePath, 'exists' => false, 'is_dir' => false, 'view' => '']; $notFound = false; try { $path = $this->view->getPath($fileId); $cache['path'] = $path; $cache['is_dir'] = $this->view->is_dir($path); $cache['exists'] = true; } catch (NotFoundException $e) { // The file was not found in the normal view, maybe it is in // the trashbin? $this->view->chroot('/' . $user . '/files_trashbin'); try { $path = $this->view->getPath($fileId); $cache = ['path' => substr($path, strlen('/files')), 'exists' => true, 'is_dir' => $this->view->is_dir($path), 'view' => 'trashbin']; } catch (NotFoundException $e) { $notFound = true; } } $this->cacheId[$user][$fileId] = $cache; if ($notFound) { $this->cacheId[$user][$fileId]['path'] = null; } return $cache; }
/** * Prepares a file parameter for usage * * Removes the path from filenames and adds highlights * * @param string $param * @param bool $stripPath Shall we remove the path from the filename * @param bool $highlightParams * @return string */ protected function prepareFileParam($param, $stripPath, $highlightParams) { $param = $this->fixLegacyFilename($param); $is_dir = $this->rootView->is_dir('/' . User::getUser() . '/files' . $param); if ($is_dir) { $fileLink = Util::linkTo('files', 'index.php', array('dir' => $param)); } else { $parentDir = substr_count($param, '/') == 1 ? '/' : dirname($param); $fileName = basename($param); $fileLink = Util::linkTo('files', 'index.php', array('dir' => $parentDir, 'scrollto' => $fileName)); } $param = trim($param, '/'); list($path, $name) = $this->splitPathFromFilename($param); if (!$stripPath || $path === '') { if (!$highlightParams) { return $param; } return '<a class="filename" href="' . $fileLink . '">' . Util::sanitizeHTML($param) . '</a>'; } if (!$highlightParams) { return $name; } $title = ' title="' . $this->l->t('in %s', array(Util::sanitizeHTML($path))) . '"'; return '<a class="filename tooltip" href="' . $fileLink . '"' . $title . '>' . Util::sanitizeHTML($name) . '</a>'; }
/** * encrypt files from the given user * * @param string $uid * @param ProgressBar $progress * @param string $userCount */ protected function decryptUsersFiles($uid, ProgressBar $progress, $userCount) { $this->setupUserFS($uid); $directories = array(); $directories[] = '/' . $uid . '/files'; while ($root = array_pop($directories)) { $content = $this->rootView->getDirectoryContent($root); foreach ($content as $file) { $path = $root . '/' . $file['name']; if ($this->rootView->is_dir($path)) { $directories[] = $path; continue; } else { try { $progress->setMessage("decrypt files for user {$userCount}: {$path}"); $progress->advance(); if ($this->decryptFile($path) === false) { $progress->setMessage("decrypt files for user {$userCount}: {$path} (already decrypted)"); $progress->advance(); } } catch (\Exception $e) { if (isset($this->failed[$uid])) { $this->failed[$uid][] = $path; } else { $this->failed[$uid] = [$path]; } } } } } }
/** * Tests if a preview of max dimensions gets created * * @dataProvider dimensionsDataProvider * * @param int $sampleId * @param int $widthAdjustment * @param int $heightAdjustment * @param bool $keepAspect * @param bool $scalingUp */ public function testCreateMaxAndNormalPreviewsAtFirstRequest( $sampleId, $widthAdjustment, $heightAdjustment, $keepAspect = false, $scalingUp = false ) { //$this->markTestSkipped('Not testing this at this time'); // Get the right sample for the experiment $this->getSample($sampleId); $sampleWidth = $this->sampleWidth; $sampleHeight = $this->sampleHeight; $sampleFileId = $this->sampleFileId; // Adjust the requested size so that we trigger various test cases $previewWidth = $sampleWidth + $widthAdjustment; $previewHeight = $sampleHeight + $heightAdjustment; $this->keepAspect = $keepAspect; $this->scalingUp = $scalingUp; // Generates the max preview $preview = $this->createPreview($previewWidth, $previewHeight); // There should be no cached thumbnails $thumbnailFolder = '/' . self::TEST_PREVIEW_USER1 . '/' . \OC\Preview::THUMBNAILS_FOLDER . '/' . $sampleFileId; $this->assertSame(false, $this->rootView->is_dir($thumbnailFolder)); $image = $preview->getPreview(); $this->assertNotSame(false, $image); $maxThumbCacheFile = $this->buildCachePath( $sampleFileId, $this->maxPreviewWidth, $this->maxPreviewHeight, true, '-max' ); $this->assertSame( true, $this->rootView->file_exists($maxThumbCacheFile), "$maxThumbCacheFile \n" ); // We check the dimensions of the file we've just stored $maxPreview = imagecreatefromstring($this->rootView->file_get_contents($maxThumbCacheFile)); $this->assertEquals($this->maxPreviewWidth, imagesx($maxPreview)); $this->assertEquals($this->maxPreviewHeight, imagesy($maxPreview)); // A thumbnail of the asked dimensions should also have been created (within the constraints of the max preview) list($limitedPreviewWidth, $limitedPreviewHeight) = $this->simulatePreviewDimensions($previewWidth, $previewHeight); $actualWidth = $image->width(); $actualHeight = $image->height(); $this->assertEquals( (int)$limitedPreviewWidth, $image->width(), "$actualWidth x $actualHeight \n" ); $this->assertEquals((int)$limitedPreviewHeight, $image->height()); // And it should be cached $this->checkCache($sampleFileId, $limitedPreviewWidth, $limitedPreviewHeight); $preview->deleteAllPreviews(); }
/** * move user encryption folder to new root folder * * @param string $user * @param string $oldRoot * @param string $newRoot * @throws \Exception */ protected function moveUserEncryptionFolder($user, $oldRoot, $newRoot) { if ($this->userManager->userExists($user)) { $source = $oldRoot . '/' . $user . '/files_encryption'; $target = $newRoot . '/' . $user . '/files_encryption'; if ($this->rootView->is_dir($source) && $this->targetExists($target) === false) { $this->prepareParentFolder($newRoot . '/' . $user); $this->rootView->rename($source, $target); } } }
function testKeySetPreperation() { $basePath = '/' . self::TEST_USER . '/files'; $path = '/folder1/subfolder/subsubfolder/file.txt'; $this->assertFalse($this->view->is_dir($basePath . '/testKeySetPreperation')); TestProtectedKeymanagerMethods::testKeySetPreperation($this->view, $basePath . $path); // check if directory structure was created $this->assertTrue($this->view->is_dir($basePath . $path)); // cleanup $this->view->deleteAll($basePath . '/folder1'); }
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); }
/** * create directories for the keys recursively * * @param string $path */ private function createPathForKeys($path) { if (!$this->view->file_exists($path)) { $sub_dirs = explode('/', $path); $dir = ''; foreach ($sub_dirs as $sub_dir) { $dir .= '/' . $sub_dir; if (!$this->view->is_dir($dir)) { $this->view->mkdir($dir); } } } }
/** * collect all files and recover them one by one * @param string $path to look for files keys * @param string $privateKey private recovery key which is used to decrypt the files */ private function recoverAllFiles($path, $privateKey) { $dirContent = $this->view->getDirectoryContent($this->keysPath . '/' . $path); foreach ($dirContent as $item) { // get relative path from files_encryption/keyfiles $filePath = substr($item['path'], strlen('files_encryption/keys')); if ($this->view->is_dir($this->userFilesDir . '/' . $filePath)) { $this->recoverAllFiles($filePath . '/', $privateKey); } else { $this->recoverFile($filePath, $privateKey); } } }
/** * recover users files * * @param string $path * @param string $privateKey * @param string $uid */ private function recoverAllFiles($path, $privateKey, $uid) { $dirContent = $this->view->getDirectoryContent($path); foreach ($dirContent as $item) { // Get relative path from encryption/keyfiles $filePath = $item->getPath(); if ($this->view->is_dir($filePath)) { $this->recoverAllFiles($filePath . '/', $privateKey, $uid); } else { $this->recoverFile($filePath, $privateKey, $uid); } } }
/** * notify encryption module about added/removed users from a file/folder * * @param string $path relative to data/ * @throws Exceptions\ModuleDoesNotExistsException */ public function update($path) { // if a folder was shared, get a list of all (sub-)folders if ($this->view->is_dir($path)) { $allFiles = $this->util->getAllFiles($path); } else { $allFiles = array($path); } $encryptionModule = $this->encryptionManager->getEncryptionModule(); foreach ($allFiles as $file) { $usersSharing = $this->file->getAccessList($file); $encryptionModule->update($file, $this->uid, $usersSharing); } }
/** * @medium * test delete file */ function testDeleteFile() { // generate filename $filename = 'tmp-' . $this->getUniqueID() . '.txt'; $filename2 = $filename . '.backup'; // a second file with similar name // save file with content $cryptedFile = file_put_contents('crypt:///' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename, $this->dataShort); $cryptedFile2 = file_put_contents('crypt:///' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename2, $this->dataShort); // test that data was successfully written $this->assertTrue(is_int($cryptedFile)); $this->assertTrue(is_int($cryptedFile2)); // check if key for admin exists $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keys/' . $filename . '/fileKey')); $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keys/' . $filename2 . '/fileKey')); // check if share key for admin exists $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keys/' . $filename . '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keys/' . $filename2 . '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); // delete first file \OC\Files\Filesystem::unlink($filename); // check if file not exists $this->assertFalse($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename)); // check if key for admin not exists $this->assertFalse($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keys/' . $filename . '/fileKey')); // check if share key for admin not exists $this->assertFalse($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keys/' . $filename . '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); // check that second file still exists $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename2)); // check that key for second file still exists $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keys/' . $filename2 . '/fileKey')); // check that share key for second file still exists $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keys/' . $filename2 . '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); // get files $trashFiles = $this->view->getDirectoryContent('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/files/'); $trashFileSuffix = null; // find created file with timestamp foreach ($trashFiles as $file) { if (strpos($file['path'], $filename . '.d') !== false) { $path_parts = pathinfo($file['name']); $trashFileSuffix = $path_parts['extension']; } } // check if we found the file we created $this->assertNotNull($trashFileSuffix); $this->assertTrue($this->view->is_dir('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/keys/' . $filename . '.' . $trashFileSuffix)); // check if key for admin not exists $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/keys/' . $filename . '.' . $trashFileSuffix . '/fileKey')); // check if share key for admin not exists $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/keys/' . $filename . '.' . $trashFileSuffix . '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); }
/** * @medium * test delete file */ function testDeleteFile() { // generate filename $filename = 'tmp-' . $this->getUniqueID() . '.txt'; $filename2 = $filename . '.backup'; // a second file with similar name // save file with content $cryptedFile = file_put_contents('crypt:///' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename, $this->dataShort); $cryptedFile2 = file_put_contents('crypt:///' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename2, $this->dataShort); // test that data was successfully written $this->assertTrue(is_int($cryptedFile)); $this->assertTrue(is_int($cryptedFile2)); // check if key for admin exists $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keys/' . $filename . '/fileKey')); $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keys/' . $filename2 . '/fileKey')); // check if share key for admin exists $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keys/' . $filename . '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keys/' . $filename2 . '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); // delete first file \OC\Files\Filesystem::unlink($filename); // check if file not exists $this->assertFalse($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename)); // check if key for admin not exists $this->assertFalse($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keys/' . $filename . '/fileKey')); // check if share key for admin not exists $this->assertFalse($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keys/' . $filename . '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); // check that second file still exists $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files/' . $filename2)); // check that key for second file still exists $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keys/' . $filename2 . '/fileKey')); // check that share key for second file still exists $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_encryption/keys/' . $filename2 . '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); // get files $trashFiles = \OCA\Files_Trashbin\Helper::getTrashFiles('/', self::TEST_ENCRYPTION_TRASHBIN_USER1); // find created file with timestamp $timestamp = null; foreach ($trashFiles as $file) { if ($file['name'] === $filename) { $timestamp = $file['mtime']; break; } } // check if we found the file we created $this->assertNotNull($timestamp); $this->assertTrue($this->view->is_dir('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/keys/' . $filename . '.d' . $timestamp)); // check if key for admin not exists $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/keys/' . $filename . '.d' . $timestamp . '/fileKey')); // check if share key for admin not exists $this->assertTrue($this->view->file_exists('/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '/files_trashbin/keys/' . $filename . '.d' . $timestamp . '/' . self::TEST_ENCRYPTION_TRASHBIN_USER1 . '.shareKey')); }
/** * Make preparations to filesystem for saving a key file * * @param string $path relative to the views root */ protected function keySetPreparation($path) { // If the file resides within a subdirectory, create it if (!$this->view->file_exists($path)) { $sub_dirs = explode('/', ltrim($path, '/')); $dir = ''; foreach ($sub_dirs as $sub_dir) { $dir .= '/' . $sub_dir; if (!$this->view->is_dir($dir)) { $this->view->mkdir($dir); } } } }
/** * check if the parent folder exists otherwise move the mount point up */ private function verifyMountPoint(&$share, $user) { $mountPoint = basename($share['file_target']); $parent = dirname($share['file_target']); $view = new View('/' . $user . '/files'); if (!$view->is_dir($parent)) { $parent = Helper::getShareFolder(); } $newMountPoint = \OCA\Files_Sharing\Helper::generateUniqueTarget(\OC\Files\Filesystem::normalizePath($parent . '/' . $mountPoint), array(), new \OC\Files\View('/' . $user . '/files')); if ($newMountPoint !== $share['file_target']) { self::updateFileTarget($newMountPoint, $share); $share['file_target'] = $newMountPoint; $share['unique_name'] = true; } return $newMountPoint; }
public function testBasicUpload() { $user = $this->getUniqueID(); $userView = $this->setupUser($user, 'pass'); $userView->mkdir('/a/b/share'); $subView = new View('/' . $user . '/files/a/b/share'); $this->assertTrue($subView->is_dir('')); $oldInfos = [$userView->getFileInfo(''), $userView->getFileInfo('a'), $userView->getFileInfo('a/b'), $userView->getFileInfo('a/b/share')]; $this->assertFalse($subView->file_exists('foo.txt')); $response = $this->request($subView, $user, 'pass', 'PUT', '/foo.txt', 'asd'); $this->assertEquals(Http::STATUS_CREATED, $response->getStatus()); $this->assertTrue($subView->file_exists('foo.txt')); $this->assertEquals('asd', $subView->file_get_contents('foo.txt')); $newInfos = [$userView->getFileInfo(''), $userView->getFileInfo('a'), $userView->getFileInfo('a/b'), $userView->getFileInfo('a/b/share')]; foreach ($oldInfos as $i => $oldInfo) { $this->assertNotEquals($oldInfo->getEtag(), $newInfos[$i]->getEtag(), 'Etag for ' . $oldInfo->getPath()); } }
/** * if session is started, check if ownCloud key pair is set up, if not create it * @param \OC\Files\View $view * * @note The ownCloud key pair is used to allow public link sharing even if encryption is enabled */ public function __construct($view) { $this->view = $view; if (!$this->view->is_dir('owncloud_private_key')) { $this->view->mkdir('owncloud_private_key'); } $appConfig = \OC::$server->getAppConfig(); $publicShareKeyId = $appConfig->getValue('files_encryption', 'publicShareKeyId'); if ($publicShareKeyId === null) { $publicShareKeyId = 'pubShare_' . substr(md5(time()), 0, 8); $appConfig->setValue('files_encryption', 'publicShareKeyId', $publicShareKeyId); } if (!$this->view->file_exists("/public-keys/" . $publicShareKeyId . ".public.key") || !$this->view->file_exists("/owncloud_private_key/" . $publicShareKeyId . ".private.key")) { $keypair = Crypt::createKeypair(); // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; // Save public key if (!$view->is_dir('/public-keys')) { $view->mkdir('/public-keys'); } $this->view->file_put_contents('/public-keys/' . $publicShareKeyId . '.public.key', $keypair['publicKey']); // Encrypt private key empty passphrase $cipher = \OCA\Encryption\Helper::getCipher(); $encryptedKey = \OCA\Encryption\Crypt::symmetricEncryptFileContent($keypair['privateKey'], '', $cipher); if ($encryptedKey) { Keymanager::setPrivateSystemKey($encryptedKey, $publicShareKeyId . '.private.key'); } else { \OCP\Util::writeLog('files_encryption', 'Could not create public share keys', \OCP\Util::ERROR); } \OC_FileProxy::$enabled = $proxyStatus; } if (\OCA\Encryption\Helper::isPublicAccess()) { // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; $encryptedKey = $this->view->file_get_contents('/owncloud_private_key/' . $publicShareKeyId . '.private.key'); $privateKey = Crypt::decryptPrivateKey($encryptedKey, ''); $this->setPublicSharePrivateKey($privateKey); $this->setInitialized(\OCA\Encryption\Session::INIT_SUCCESSFUL); \OC_FileProxy::$enabled = $proxyStatus; } }
/** * test rename operation */ function doTestCopyHook($filename) { // check if keys exists $this->assertTrue($this->rootView->file_exists( '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/' . $filename . '.' . self::TEST_ENCRYPTION_HOOKS_USER1 . '.shareKey')); $this->assertTrue($this->rootView->file_exists( '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keyfiles/' . $filename . '.key')); // make subfolder and sub-subfolder $this->rootView->mkdir('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->folder); $this->rootView->mkdir('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->folder . '/' . $this->folder); $this->assertTrue($this->rootView->is_dir('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->folder . '/' . $this->folder)); // copy the file to the sub-subfolder \OC\Files\Filesystem::copy($filename, '/' . $this->folder . '/' . $this->folder . '/' . $filename); $this->assertTrue($this->rootView->file_exists('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $filename)); $this->assertTrue($this->rootView->file_exists('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->folder . '/' . $this->folder . '/' . $filename)); // keys should be copied too $this->assertTrue($this->rootView->file_exists( '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/' . $filename . '.' . self::TEST_ENCRYPTION_HOOKS_USER1 . '.shareKey')); $this->assertTrue($this->rootView->file_exists( '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keyfiles/' . $filename . '.key')); $this->assertTrue($this->rootView->file_exists( '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/' . $this->folder . '/' . $this->folder . '/' . $filename . '.' . self::TEST_ENCRYPTION_HOOKS_USER1 . '.shareKey')); $this->assertTrue($this->rootView->file_exists( '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/keyfiles/' . $this->folder . '/' . $this->folder . '/' . $filename . '.key')); // cleanup $this->rootView->unlink('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $this->folder); $this->rootView->unlink('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/' . $filename); }
/** * update keyfiles and share keys recursively * * @param int $fileSource file source id */ private function update($fileSource) { $path = \OC\Files\Filesystem::getPath($fileSource); $info = \OC\Files\Filesystem::getFileInfo($path); $owner = \OC\Files\Filesystem::getOwner($path); $view = new \OC\Files\View('/' . $owner . '/files'); $ownerPath = $view->getPath($info->getId()); $absPath = '/' . $owner . '/files' . $ownerPath; $mount = $this->mountManager->find($path); $mountPoint = $mount->getMountPoint(); // if a folder was shared, get a list of all (sub-)folders if ($this->view->is_dir($absPath)) { $allFiles = $this->util->getAllFiles($absPath, $mountPoint); } else { $allFiles = array($absPath); } $encryptionModule = $this->encryptionManager->getDefaultEncryptionModule(); foreach ($allFiles as $path) { $usersSharing = $this->file->getAccessList($path); $encryptionModule->update($path, $this->uid, $usersSharing); } }
/** * @NoAdminRequired */ public function create() { $mimetype = $this->request->post['mimetype']; $view = new View('/' . $this->uid . '/files'); $dir = $this->settings->getUserValue($this->uid, $this->appName, 'save_path', '/'); if (!$view->is_dir($dir)) { $dir = '/'; } $basename = $this->l10n->t('New Document.odt'); switch ($mimetype) { case 'application/vnd.oasis.opendocument.spreadsheet': $basename = $this->l10n->t('New Spreadsheet.ods'); break; case 'application/vnd.oasis.opendocument.presentation': $basename = $this->l10n->t('New Presentation.odp'); break; default: // to be safe $mimetype = 'application/vnd.oasis.opendocument.text'; break; } $path = Helper::getNewFileName($view, $dir . '/' . $basename); $content = ''; if (class_exists('\\OC\\Files\\Type\\TemplateManager')) { $manager = \OC_Helper::getFileTemplateManager(); $content = $manager->getTemplate($mimetype); } if (!$content) { $content = file_get_contents(dirname(__DIR__) . self::ODT_TEMPLATE_PATH); } if ($content && $view->file_put_contents($path, $content)) { $info = $view->getFileInfo($path); $response = array('status' => 'success', 'fileid' => $info['fileid']); } else { $response = array('status' => 'error', 'message' => (string) $this->l10n->t('Can\'t create document')); } return $response; }
/** * @param string $owner * @param int $fileId * @param string $filePath * @return array */ protected function getPreview($owner, $fileId, $filePath) { $this->view->chroot('/' . $owner . '/files'); $path = $this->view->getPath($fileId); if ($path === null || $path === '' || !$this->view->file_exists($path)) { return $this->getPreviewFromPath($filePath); } $is_dir = $this->view->is_dir($path); $preview = ['link' => $this->getPreviewLink($path, $is_dir), 'source' => '', 'isMimeTypeIcon' => true]; // show a preview image if the file still exists if ($is_dir) { $preview['source'] = $this->getPreviewPathFromMimeType('dir'); } else { $fileInfo = $this->view->getFileInfo($path); if ($this->preview->isAvailable($fileInfo)) { $preview['isMimeTypeIcon'] = false; $preview['source'] = $this->urlGenerator->linkToRoute('core_ajax_preview', ['file' => $path, 'c' => $this->view->getETag($path), 'x' => 150, 'y' => 150]); } else { $preview['source'] = $this->getPreviewPathFromMimeType($fileInfo->getMimetype()); } } return $preview; }
/** * @NoAdminRequired */ public function create() { $view = new View('/' . $this->uid . '/files'); $dir = $this->settings->getUserValue($this->uid, $this->appName, 'save_path', '/'); if (!$view->is_dir($dir)) { $dir = '/'; } $path = Helper::getNewFileName($view, $dir . '/New Document.odt'); $content = ''; if (class_exists('\\OC\\Files\\Type\\TemplateManager')) { $manager = \OC_Helper::getFileTemplateManager(); $content = $manager->getTemplate(Storage::MIMETYPE_LIBREOFFICE_WORDPROCESSOR); } if (!$content) { $content = file_get_contents(dirname(__DIR__) . self::ODT_TEMPLATE_PATH); } if ($content && $view->file_put_contents($path, $content)) { $info = $view->getFileInfo($path); $response = array('status' => 'success', 'fileid' => $info['fileid']); } else { $response = array('status' => 'error', 'message' => (string) $this->l10n->t('Can\'t create document')); } return $response; }