/** * get the relative path of the root data directory for the current user * * @return string * * Returns path like /admin/files */ public static function getRoot() { if (!self::$defaultInstance) { return null; } return self::$defaultInstance->getRoot(); }
/** * @param \OC\Files\View $view the view the updater works on, usually the view of the logged in user * @param View | null $userView */ public function __construct(View $view, $userView = null) { $this->view = $view; // use the userview if the view is a subfolder if ($userView && $userView->getRelativePath($view->getRoot())) { $this->propagatorView = $userView; $this->propagator = new ChangePropagator($userView); } else { $this->propagatorView = $view; $this->propagator = new ChangePropagator($view); } }
/** * Encrypt all files in a directory * @param string $dirPath the directory whose files will be encrypted * @return bool * @note Encryption is recursive */ public function encryptAll($dirPath) { $result = true; $found = $this->findEncFiles($dirPath); // Disable proxy to prevent file being encrypted twice \OC_FileProxy::$enabled = false; $versionStatus = \OCP\App::isEnabled('files_versions'); \OC_App::disable('files_versions'); $encryptedFiles = array(); // Encrypt unencrypted files foreach ($found['plain'] as $plainFile) { //get file info $fileInfo = \OC\Files\Filesystem::getFileInfo($plainFile['path']); //relative to data/<user>/file $relPath = $plainFile['path']; //relative to /data $rawPath = '/' . $this->userId . '/files/' . $plainFile['path']; // keep timestamp $timestamp = $fileInfo['mtime']; // Open plain file handle for binary reading $plainHandle = $this->view->fopen($rawPath, 'rb'); // Open enc file handle for binary writing, with same filename as original plain file $encHandle = fopen('crypt://' . $rawPath . '.part', 'wb'); if (is_resource($encHandle) && is_resource($plainHandle)) { // Move plain file to a temporary location $size = stream_copy_to_stream($plainHandle, $encHandle); fclose($encHandle); fclose($plainHandle); $fakeRoot = $this->view->getRoot(); $this->view->chroot('/' . $this->userId . '/files'); $this->view->rename($relPath . '.part', $relPath); // set timestamp $this->view->touch($relPath, $timestamp); $encSize = $this->view->filesize($relPath); $this->view->chroot($fakeRoot); // Add the file to the cache \OC\Files\Filesystem::putFileInfo($relPath, array('encrypted' => true, 'size' => $encSize, 'unencrypted_size' => $size, 'etag' => $fileInfo['etag'])); $encryptedFiles[] = $relPath; } else { \OCP\Util::writeLog('files_encryption', 'initial encryption: could not encrypt ' . $rawPath, \OCP\Util::FATAL); $result = false; } } \OC_FileProxy::$enabled = true; if ($versionStatus) { \OC_App::enable('files_versions'); } $result = $result && $this->encryptVersions($encryptedFiles); return $result; }
/** * test rename operation */ function doTestRenameHook($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)); // move the file to the sub-subfolder $root = $this->rootView->getRoot(); $this->rootView->chroot('/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files/'); $this->rootView->rename($filename, '/' . $this->folder . '/' . $this->folder . '/' . $filename); $this->rootView->chroot($root); $this->assertFalse($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 renamed too $this->assertFalse($this->rootView->file_exists( '/' . self::TEST_ENCRYPTION_HOOKS_USER1 . '/files_encryption/share-keys/' . $filename . '.' . self::TEST_ENCRYPTION_HOOKS_USER1 . '.shareKey')); $this->assertFalse($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); }
/** * @param \OC\Files\View $view * @param string $path * * @return array */ private static function getAllChildren($view, $path) { $children = $view->getDirectoryContent($path); $childrensFiles = array(); $fakeRootLength = strlen($view->getRoot()); for ($i = 0; $i < count($children); $i++) { $child = $children[$i]; $childsPath = substr($child->getPath(), $fakeRootLength); if ($view->is_dir($childsPath)) { $children = array_merge($children, $view->getDirectoryContent($childsPath)); } else { $childrensFiles[] = $child; } } return $childrensFiles; }
/** * @brief get the relative path of the root data directory for the current user * @return string * * Returns path like /admin/files */ public static function getRoot() { return self::$defaultInstance->getRoot(); }