/** * @medium */ public function testDeleteParentOfMountPoint() { // share to user $share = $this->share(\OCP\Share::SHARE_TYPE_USER, $this->folder, self::TEST_FILES_SHARING_API_USER1, self::TEST_FILES_SHARING_API_USER2, \OCP\Constants::PERMISSION_ALL); self::loginHelper(self::TEST_FILES_SHARING_API_USER2); $user2View = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files'); $this->assertTrue($user2View->file_exists($this->folder)); // create a local folder $result = $user2View->mkdir('localfolder'); $this->assertTrue($result); // move mount point to local folder $result = $user2View->rename($this->folder, '/localfolder/' . $this->folder); $this->assertTrue($result); // mount point in the root folder should no longer exist $this->assertFalse($user2View->is_dir($this->folder)); // delete the local folder $result = $user2View->unlink('/localfolder'); $this->assertTrue($result); //enforce reload of the mount points self::loginHelper(self::TEST_FILES_SHARING_API_USER2); //mount point should be back at the root $this->assertTrue($user2View->is_dir($this->folder)); //cleanup self::loginHelper(self::TEST_FILES_SHARING_API_USER1); $this->view->unlink($this->folder); }
/** * check if path is excluded from encryption * * @param string $path relative to data/ * @return boolean */ protected function isExcludedPath($path) { $view = new \OC\Files\View(); $normalizedPath = \OC\Files\Filesystem::normalizePath($path); $parts = explode('/', $normalizedPath); // we only encrypt/decrypt files in the files and files_versions folder if (sizeof($parts) < 3) { /** * Less then 3 parts means, we can't match: * - /{$uid}/files/* nor * - /{$uid}/files_versions/* * So this is not a path we are looking for. */ return true; } if (!($parts[2] === 'files' && \OCP\User::userExists($parts[1])) && !($parts[2] === 'files_versions' && \OCP\User::userExists($parts[1]))) { return true; } if (!$view->file_exists($normalizedPath)) { $normalizedPath = dirname($normalizedPath); } // we don't encrypt server-to-server shares list($storage, ) = \OC\Files\Filesystem::resolvePath($normalizedPath); /** * @var \OCP\Files\Storage $storage */ if ($storage->instanceOfStorage('OCA\\Files_Sharing\\External\\Storage')) { return true; } return false; }
function testDelAllShareKeysFile() { $this->view->mkdir('/' . Test_Encryption_Keymanager::TEST_USER . '/files/folder1'); $this->view->file_put_contents('/' . Test_Encryption_Keymanager::TEST_USER . '/files/folder1/existingFile.txt', 'data'); // create folder structure for some dummy share key files $this->view->mkdir('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1'); // create some dummy share keys for the existing file $this->view->file_put_contents('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.user1.shareKey', 'data'); $this->view->file_put_contents('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.user2.shareKey', 'data'); $this->view->file_put_contents('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.user3.shareKey', 'data'); $this->view->file_put_contents('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.' . Test_Encryption_Keymanager::TEST_USER . '.shareKey', 'data'); // create some dummy share keys for a non-existing file $this->view->file_put_contents('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/nonexistingFile.txt.user1.shareKey', 'data'); $this->view->file_put_contents('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/nonexistingFile.txt.user2.shareKey', 'data'); $this->view->file_put_contents('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/nonexistingFile.txt.user3.shareKey', 'data'); $this->view->file_put_contents('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/nonexistingFile.txt.' . Test_Encryption_Keymanager::TEST_USER . '.shareKey', 'data'); // try to del all share keys from a existing file, should fail because the file still exists $result = Encryption\Keymanager::delAllShareKeys($this->view, Test_Encryption_Keymanager::TEST_USER, 'folder1/existingFile.txt'); $this->assertFalse($result); // check if share keys still exists $this->assertTrue($this->view->file_exists('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.' . Test_Encryption_Keymanager::TEST_USER . '.shareKey')); $this->assertTrue($this->view->file_exists('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.user1.shareKey')); $this->assertTrue($this->view->file_exists('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.user2.shareKey')); $this->assertTrue($this->view->file_exists('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/existingFile.txt.user3.shareKey')); // try to del all share keys froma file, should fail because the file still exists $result2 = Encryption\Keymanager::delAllShareKeys($this->view, Test_Encryption_Keymanager::TEST_USER, 'folder1/nonexistingFile.txt'); $this->assertTrue($result2); // check if share keys are really gone $this->assertFalse($this->view->file_exists('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/nonexistingFile.txt.' . Test_Encryption_Keymanager::TEST_USER . '.shareKey')); $this->assertFalse($this->view->file_exists('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/nonexistingFile.txt.user1.shareKey')); $this->assertFalse($this->view->file_exists('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/nonexistingFile.txt.user2.shareKey')); $this->assertFalse($this->view->file_exists('/' . Test_Encryption_Keymanager::TEST_USER . '/files_encryption/share-keys/folder1/nonexistingFile.txt.user3.shareKey')); // cleanup $this->view->deleteAll('/' . Test_Encryption_Keymanager::TEST_USER . '/files/folder1'); }
/** * test if all keys get moved to the backup folder correctly */ function testBackupAllKeys() { self::loginHelper(self::TEST_ENCRYPTION_UTIL_USER1); // create some dummy key files $encPath = '/' . self::TEST_ENCRYPTION_UTIL_USER1 . '/files_encryption'; $this->view->file_put_contents($encPath . '/keyfiles/foo.key', 'key'); $this->view->file_put_contents($encPath . '/share-keys/foo.user1.shareKey', 'share key'); $util = new \OCA\Encryption\Util($this->view, self::TEST_ENCRYPTION_UTIL_USER1); $util->backupAllKeys('testing'); $encFolderContent = $this->view->getDirectoryContent($encPath); $backupPath = ''; foreach ($encFolderContent as $c) { $name = $c['name']; if (substr($name, 0, strlen('backup')) === 'backup') { $backupPath = $encPath . '/' . $c['name']; break; } } $this->assertTrue($backupPath !== ''); // check backupDir Content $this->assertTrue($this->view->is_dir($backupPath . '/keyfiles')); $this->assertTrue($this->view->is_dir($backupPath . '/share-keys')); $this->assertTrue($this->view->file_exists($backupPath . '/keyfiles/foo.key')); $this->assertTrue($this->view->file_exists($backupPath . '/share-keys/foo.user1.shareKey')); $this->assertTrue($this->view->file_exists($backupPath . '/' . self::TEST_ENCRYPTION_UTIL_USER1 . '.private.key')); $this->assertTrue($this->view->file_exists($backupPath . '/' . self::TEST_ENCRYPTION_UTIL_USER1 . '.public.key')); //cleanup $this->view->deleteAll($backupPath); $this->view->unlink($encPath . '/keyfiles/foo.key', 'key'); $this->view->unlink($encPath . '/share-keys/foo.user1.shareKey', 'share key'); }
/** * test moving a shared file out of the Shared folder */ function testRename() { // login as admin \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); // save file with content $cryptedFile = file_put_contents('crypt:///' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->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('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename); // check if we have a valid file info $this->assertTrue($fileInfo instanceof \OC\Files\FileInfo); // share the file \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2, OCP\PERMISSION_ALL); // check if share key for user2 exists $this->assertTrue($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/' . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '.shareKey')); // login as user2 \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2); $this->assertTrue($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->filename)); // get file contents $retrievedCryptedFile = $this->view->file_get_contents('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->filename); // check if data is the same as we previously written $this->assertEquals($this->dataShort, $retrievedCryptedFile); // move the file to a subfolder $this->view->rename('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->filename, '/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->folder1 . $this->filename); // check if we can read the moved file $retrievedRenamedFile = $this->view->file_get_contents('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2 . '/files/' . $this->folder1 . $this->filename); // check if data is the same as we previously written $this->assertEquals($this->dataShort, $retrievedRenamedFile); // cleanup \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1); $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename); }
/** * Get the template for a specific activity-event in the activities * * @param array $activity An array with all the activity data in it * @param return string */ public static function show($activity) { $tmpl = new \OCP\Template('activity', 'activity.box'); $tmpl->assign('formattedDate', \OCP\Util::formatDate($activity['timestamp'])); $tmpl->assign('formattedTimestamp', \OCP\relative_modified_date($activity['timestamp'])); $tmpl->assign('user', $activity['user']); $tmpl->assign('displayName', \OCP\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 \OC\Files\View(''); $exist = $rootView->file_exists('/' . $activity['user'] . '/files' . $activity['file']); $is_dir = $rootView->is_dir('/' . $activity['user'] . '/files' . $activity['file']); unset($rootView); // show a preview image if the file still exists if (!$is_dir && $exist) { $tmpl->assign('previewLink', \OCP\Util::linkTo('files', 'index.php', array('dir' => dirname($activity['file'])))); $tmpl->assign('previewImageLink', \OCP\Util::linkToRoute('core_ajax_preview', array('file' => $activity['file'], 'x' => 150, 'y' => 150))); } else { if ($exist) { $tmpl->assign('previewLink', \OCP\Util::linkTo('files', 'index.php', array('dir' => $activity['file']))); $tmpl->assign('previewImageLink', \OC_Helper::mimetypeIcon('dir')); $tmpl->assign('previewLinkIsDir', true); } } } return $tmpl->fetchPage(); }
/** * @medium */ function testDeleteParentOfMountPoint() { // share to user $fileinfo = $this->view->getFileInfo($this->folder); $result = \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 31); $this->assertTrue($result); self::loginHelper(self::TEST_FILES_SHARING_API_USER2); $user2View = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files'); $this->assertTrue($user2View->file_exists($this->folder)); // create a local folder $result = $user2View->mkdir('localfolder'); $this->assertTrue($result); // move mount point to local folder $result = $user2View->rename($this->folder, '/localfolder/' . $this->folder); $this->assertTrue($result); // mount point in the root folder should no longer exist $this->assertFalse($user2View->is_dir($this->folder)); // delete the local folder $result = $user2View->unlink('/localfolder'); $this->assertTrue($result); //enforce reload of the mount points self::loginHelper(self::TEST_FILES_SHARING_API_USER2); //mount point should be back at the root $this->assertTrue($user2View->is_dir($this->folder)); //cleanup self::loginHelper(self::TEST_FILES_SHARING_API_USER1); $this->view->unlink($this->folder); }
/** * update script for the removal of the logical "Shared" folder, we create physical "Shared" folder and * update the users file_target so that it doesn't make any difference for the user * @note parameters are just for testing, please ignore them */ function removeSharedFolder($mkdirs = true, $chunkSize = 99) { $query = OCP\DB::prepare('SELECT * FROM `*PREFIX*share`'); $result = $query->execute(); $view = new \OC\Files\View('/'); $users = array(); $shares = array(); //we need to set up user backends OC_User::useBackend(new OC_User_Database()); OC_Group::useBackend(new OC_Group_Database()); OC_App::loadApps(array('authentication')); //we need to set up user backends, otherwise creating the shares will fail with "because user does not exist" while ($row = $result->fetchRow()) { //collect all user shares if ((int) $row['share_type'] === 0 && ($row['item_type'] === 'file' || $row['item_type'] === 'folder')) { $users[] = $row['share_with']; $shares[$row['id']] = $row['file_target']; } else { if ((int) $row['share_type'] === 1 && ($row['item_type'] === 'file' || $row['item_type'] === 'folder')) { //collect all group shares $users = array_merge($users, \OC_group::usersInGroup($row['share_with'])); $shares[$row['id']] = $row['file_target']; } else { if ((int) $row['share_type'] === 2) { $shares[$row['id']] = $row['file_target']; } } } } $unique_users = array_unique($users); if (!empty($unique_users) && !empty($shares)) { // create folder Shared for each user if ($mkdirs) { foreach ($unique_users as $user) { \OC\Files\Filesystem::initMountPoints($user); if (!$view->file_exists('/' . $user . '/files/Shared')) { $view->mkdir('/' . $user . '/files/Shared'); } } } $chunkedShareList = array_chunk($shares, $chunkSize, true); $connection = \OC_DB::getConnection(); foreach ($chunkedShareList as $subList) { $statement = "UPDATE `*PREFIX*share` SET `file_target` = CASE `id` "; //update share table $ids = implode(',', array_keys($subList)); foreach ($subList as $id => $target) { $statement .= "WHEN " . $connection->quote($id, \PDO::PARAM_INT) . " THEN " . $connection->quote('/Shared' . $target, \PDO::PARAM_STR); } $statement .= ' END WHERE `id` IN (' . $ids . ')'; $query = OCP\DB::prepare($statement); $query->execute(array()); } // set config to keep the Shared folder as the default location for new shares \OCA\Files_Sharing\Helper::setShareFolder('/Shared'); } }
/** * test deletion of a folder which contains share mount points. Share mount * points should be unshared before the folder gets deleted so * that the mount point doesn't end up at the trash bin */ function testDeleteParentFolder() { $status = \OC_App::isEnabled('files_trashbin'); \OC_App::enable('files_trashbin'); \OCA\Files_Trashbin\Trashbin::registerHooks(); $fileinfo = \OC\Files\Filesystem::getFileInfo($this->folder); $this->assertTrue($fileinfo instanceof \OC\Files\FileInfo); \OCP\Share::shareItem('folder', $fileinfo->getId(), \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 31); $this->loginHelper(self::TEST_FILES_SHARING_API_USER2); $view = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files'); // check if user2 can see the shared folder $this->assertTrue($view->file_exists($this->folder)); $foldersShared = \OCP\Share::getItemsSharedWith('folder'); $this->assertSame(1, count($foldersShared)); $view->mkdir("localFolder"); $view->file_put_contents("localFolder/localFile.txt", "local file"); $view->rename($this->folder, 'localFolder/' . $this->folder); // share mount point should now be moved to the subfolder $this->assertFalse($view->file_exists($this->folder)); $this->assertTrue($view->file_exists('localFolder/' . $this->folder)); $view->unlink('localFolder'); $this->loginHelper(self::TEST_FILES_SHARING_API_USER2); // shared folder should be unshared $foldersShared = \OCP\Share::getItemsSharedWith('folder'); $this->assertTrue(empty($foldersShared)); // trashbin should contain the local file but not the mount point $rootView = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2); $trashContent = \OCA\Files_Trashbin\Helper::getTrashFiles('/', self::TEST_FILES_SHARING_API_USER2); $this->assertSame(1, count($trashContent)); $firstElement = reset($trashContent); $timestamp = $firstElement['mtime']; $this->assertTrue($rootView->file_exists('files_trashbin/files/localFolder.d' . $timestamp . '/localFile.txt')); $this->assertFalse($rootView->file_exists('files_trashbin/files/localFolder.d' . $timestamp . '/' . $this->folder)); //cleanup $rootView->deleteAll('files_trashin'); if ($status === false) { \OC_App::disable('files_trashbin'); } \OC\Files\Filesystem::getLoader()->removeStorageWrapper('oc_trashbin'); }
function testDecryptAll() { $filename = "/decryptAll" . uniqid() . ".txt"; $datadir = \OC_Config::getValue('datadirectory', \OC::$SERVERROOT . '/data/'); $userdir = $datadir . '/' . $this->userId . '/files/'; $this->view->file_put_contents($this->userId . '/files/' . $filename, $this->dataShort); $fileInfoEncrypted = $this->view->getFileInfo($this->userId . '/files/' . $filename); $this->assertTrue($fileInfoEncrypted instanceof \OC\Files\FileInfo); $this->assertEquals($fileInfoEncrypted['encrypted'], 1); $encContent = file_get_contents($userdir . $filename); \OC_App::disable('files_encryption'); $user = \OCP\User::getUser(); $this->logoutHelper(); $this->loginHelper($user, false, false, false); $content = file_get_contents($userdir . $filename); //content should be encrypted $this->assertSame($encContent, $content); // now we load the encryption app again OC_App::loadApp('files_encryption'); // init encryption app $params = array('uid' => \OCP\User::getUser(), 'password' => \OCP\User::getUser()); $view = new OC\Files\View('/'); $util = new \OCA\Encryption\Util($view, \OCP\User::getUser()); $result = $util->initEncryption($params); $this->assertTrue($result instanceof \OCA\Encryption\Session); $successful = $util->decryptAll(); $this->assertTrue($successful); $this->logoutHelper(); $this->loginHelper($user, false, false, false); // file should be unencrypted and fileInfo should contain the correct values $content = file_get_contents($userdir . $filename); // now we should get the plain data $this->assertSame($this->dataShort, $content); $fileInfoUnencrypted = $this->view->getFileInfo($this->userId . '/files/' . $filename); $this->assertTrue($fileInfoUnencrypted instanceof \OC\Files\FileInfo); // check if mtime and etags unchanged $this->assertEquals($fileInfoEncrypted['mtime'], $fileInfoUnencrypted['mtime']); $this->assertSame($fileInfoEncrypted['etag'], $fileInfoUnencrypted['etag']); // file should no longer be encrypted $this->assertEquals(0, $fileInfoUnencrypted['encrypted']); // check if the keys where moved to the backup location $this->assertTrue($this->view->is_dir($this->userId . '/files_encryption/keyfiles.backup')); $this->assertTrue($this->view->file_exists($this->userId . '/files_encryption/keyfiles.backup/' . $filename . '.key')); $this->assertTrue($this->view->is_dir($this->userId . '/files_encryption/share-keys.backup')); $this->assertTrue($this->view->file_exists($this->userId . '/files_encryption/share-keys.backup/' . $filename . '.' . $user . '.shareKey')); // cleanup $this->view->unlink($this->userId . '/files/' . $filename); $this->view->deleteAll($this->userId . '/files_encryption/keyfiles.backup'); $this->view->deleteAll($this->userId . '/files_encryption/share-keys.backup'); OC_App::enable('files_encryption'); }
/** * walk up the users file tree and update the etags * @param string $user * @param string $path */ private static function correctUsersFolder($user, $path) { // $path points to the mount point which is a virtual folder, so we start with // the parent $path = '/files' . dirname($path); \OC\Files\Filesystem::initMountPoints($user); $view = new \OC\Files\View('/' . $user); if ($view->file_exists($path)) { while ($path !== dirname($path)) { $etag = $view->getETag($path); $view->putFileInfo($path, array('etag' => $etag)); $path = dirname($path); } } else { \OCP\Util::writeLog('files_sharing', 'can not update etags on ' . $path . ' for user ' . $user . '. Path does not exists', \OCP\Util::DEBUG); } }
protected function getStorage() { if (isset($this->storage)) { return $this->storage; } if (\OC_User::isLoggedIn()) { \OC\Files\Filesystem::initMountPoints(\OC_User::getUser()); $subdir = 'cache'; $view = new \OC\Files\View('/' . \OC_User::getUser()); if (!$view->file_exists($subdir)) { $view->mkdir($subdir); } $this->storage = new \OC\Files\View('/' . \OC_User::getUser() . '/' . $subdir); return $this->storage; } else { \OC_Log::write('core', 'Can\'t get cache storage, user not logged in', \OC_Log::ERROR); return false; } }
/** * check if path is excluded from encryption * * @param string $path relative to data/ * @param string $uid user * @return boolean */ private function isExcludedPath($path, $uid) { $view = new \OC\Files\View(); // files outside of the files-folder are excluded if (strpos($path, '/' . $uid . '/files') !== 0) { return true; } if (!$view->file_exists($path)) { $path = dirname($path); } // we don't encrypt server-to-server shares list($storage, ) = \OC\Files\Filesystem::resolvePath($path); /** * @var \OCP\Files\Storage $storage */ if ($storage->instanceOfStorage('OCA\\Files_Sharing\\External\\Storage')) { return true; } return false; }
/** * check if path is excluded from encryption * * @param string $path relative to data/ * @param string $uid user * @return boolean */ protected function isExcludedPath($path, $uid) { $view = new \OC\Files\View(); $path = \OC\Files\Filesystem::normalizePath($path); // we only encrypt/decrypt files in the files and files_versions folder if (strpos($path, '/' . $uid . '/files/') !== 0 && strpos($path, '/' . $uid . '/files_versions/') !== 0) { return true; } if (!$view->file_exists($path)) { $path = dirname($path); } // we don't encrypt server-to-server shares list($storage, ) = \OC\Files\Filesystem::resolvePath($path); /** * @var \OCP\Files\Storage $storage */ if ($storage->instanceOfStorage('OCA\\Files_Sharing\\External\\Storage')) { return true; } return false; }
/** * @medium */ function testRenamePartFile() { // share to user $fileinfo = $this->view->getFileInfo($this->folder); $result = \OCP\Share::shareItem('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2, 31); $this->assertTrue($result); self::loginHelper(self::TEST_FILES_SHARING_API_USER2); $user2View = new \OC\Files\View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files'); $this->assertTrue($user2View->file_exists($this->folder)); // create part file $result = $user2View->file_put_contents($this->folder . '/foo.txt.part', 'some test data'); $this->assertTrue(is_int($result)); // rename part file to real file $result = $user2View->rename($this->folder . '/foo.txt.part', $this->folder . '/foo.txt'); $this->assertTrue($result); // check if the new file really exists $this->assertTrue($user2View->file_exists($this->folder . '/foo.txt')); // check if the rename also affected the owner self::loginHelper(self::TEST_FILES_SHARING_API_USER1); $this->assertTrue($this->view->file_exists($this->folder . '/foo.txt')); //cleanup \OCP\Share::unshare('folder', $fileinfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_FILES_SHARING_API_USER2); }
/** * rollback to an old version of a file. */ public static function rollback($file, $revision) { if (\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED) == 'true') { list($uid, $filename) = self::getUidAndFilename($file); $users_view = new \OC\Files\View('/' . $uid); $files_view = new \OC\Files\View('/' . \OCP\User::getUser() . '/files'); $versionCreated = false; //first create a new version $version = 'files_versions' . $filename . '.v' . $users_view->filemtime('files' . $filename); if (!$users_view->file_exists($version)) { // disable proxy to prevent multiple fopen calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; $users_view->copy('files' . $filename, 'files_versions' . $filename . '.v' . $users_view->filemtime('files' . $filename)); // reset proxy state \OC_FileProxy::$enabled = $proxyStatus; $versionCreated = true; } // rollback if (@$users_view->rename('files_versions' . $filename . '.v' . $revision, 'files' . $filename)) { $files_view->touch($file, $revision); Storage::expire($file); return true; } else { if ($versionCreated) { $users_view->unlink($version); } } } return false; }
/** * @brief if the file was really deleted we remove the encryption keys * @param array $params * @return boolean */ public static function postDelete($params) { if (!isset(self::$deleteFiles[$params[\OC\Files\Filesystem::signal_param_path]])) { return true; } $deletedFile = self::$deleteFiles[$params[\OC\Files\Filesystem::signal_param_path]]; $path = $deletedFile['path']; $user = $deletedFile['uid']; // we don't need to remember the file any longer unset(self::$deleteFiles[$params[\OC\Files\Filesystem::signal_param_path]]); $view = new \OC\Files\View('/'); // return if the file still exists and wasn't deleted correctly if ($view->file_exists('/' . $user . '/files/' . $path)) { return true; } // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; // Delete keyfile & shareKey so it isn't orphaned if (!Keymanager::deleteFileKey($view, $path, $user)) { \OCP\Util::writeLog('Encryption library', 'Keyfile or shareKey could not be deleted for file "' . $user . '/files/' . $path . '"', \OCP\Util::ERROR); } Keymanager::delAllShareKeys($view, $user, $path); \OC_FileProxy::$enabled = $proxyStatus; }
/** * Find which users can access a shared item * @param string $path to the file * @param string $ownerUser owner of the file * @param boolean $includeOwner include owner to the list of users with access to the file * @param boolean $returnUserPaths Return an array with the user => path map * @return array * @note $path needs to be relative to user data dir, e.g. 'file.txt' * not '/admin/data/file.txt' */ public static function getUsersSharingFile($path, $ownerUser, $includeOwner = false, $returnUserPaths = false) { $shares = $sharePaths = $fileTargets = array(); $publicShare = false; $source = -1; $cache = false; $view = new \OC\Files\View('/' . $ownerUser . '/files'); if ($view->file_exists($path)) { $meta = $view->getFileInfo($path); $path = substr($meta->getPath(), strlen('/' . $ownerUser . '/files')); } else { // if the file doesn't exists yet we start with the parent folder $meta = $view->getFileInfo(dirname($path)); } if ($meta !== false) { $source = $meta['fileid']; $cache = new \OC\Files\Cache\Cache($meta['storage']); } while ($source !== -1) { // Fetch all shares with another user $query = \OC_DB::prepare('SELECT `share_with`, `file_source`, `file_target` FROM `*PREFIX*share` WHERE `item_source` = ? AND `share_type` = ? AND `item_type` IN (\'file\', \'folder\')'); $result = $query->execute(array($source, self::SHARE_TYPE_USER)); if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('OCP\\Share', \OC_DB::getErrorMessage($result), \OC_Log::ERROR); } else { while ($row = $result->fetchRow()) { $shares[] = $row['share_with']; if ($returnUserPaths) { $fileTargets[(int) $row['file_source']][$row['share_with']] = $row; } } } // We also need to take group shares into account $query = \OC_DB::prepare('SELECT `share_with`, `file_source`, `file_target` FROM `*PREFIX*share` WHERE `item_source` = ? AND `share_type` = ? AND `item_type` IN (\'file\', \'folder\')'); $result = $query->execute(array($source, self::SHARE_TYPE_GROUP)); if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('OCP\\Share', \OC_DB::getErrorMessage($result), \OC_Log::ERROR); } else { while ($row = $result->fetchRow()) { $usersInGroup = \OC_Group::usersInGroup($row['share_with']); $shares = array_merge($shares, $usersInGroup); if ($returnUserPaths) { foreach ($usersInGroup as $user) { $fileTargets[(int) $row['file_source']][$user] = $row; } } } } //check for public link shares if (!$publicShare) { $query = \OC_DB::prepare('SELECT `share_with` FROM `*PREFIX*share` WHERE `item_source` = ? AND `share_type` = ? AND `item_type` IN (\'file\', \'folder\')'); $result = $query->execute(array($source, self::SHARE_TYPE_LINK)); if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('OCP\\Share', \OC_DB::getErrorMessage($result), \OC_Log::ERROR); } else { if ($result->fetchRow()) { $publicShare = true; } } } // let's get the parent for the next round $meta = $cache->get((int) $source); if ($meta !== false) { $source = (int) $meta['parent']; } else { $source = -1; } } // Include owner in list of users, if requested if ($includeOwner) { $shares[] = $ownerUser; if ($returnUserPaths) { $sharePaths[$ownerUser] = $path; } } if ($returnUserPaths) { $fileTargetIDs = array_keys($fileTargets); $fileTargetIDs = array_unique($fileTargetIDs); if (!empty($fileTargetIDs)) { $query = \OC_DB::prepare('SELECT `fileid`, `path` FROM `*PREFIX*filecache` WHERE `fileid` IN (' . implode(',', $fileTargetIDs) . ')'); $result = $query->execute(); if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('OCP\\Share', \OC_DB::getErrorMessage($result), \OC_Log::ERROR); } else { while ($row = $result->fetchRow()) { foreach ($fileTargets[$row['fileid']] as $uid => $shareData) { $sharedPath = $shareData['file_target']; $sharedPath .= substr($path, strlen($row['path']) - 5); $sharePaths[$uid] = $sharedPath; } } } } return $sharePaths; } return array("users" => array_unique($shares), "public" => $publicShare); }
/** * check to see whether a file exists in trashbin * * @param string $filename path to the file * @param int $timestamp of deletion time * @return bool true if file exists, otherwise false */ public static function file_exists($filename, $timestamp = null) { $user = \OCP\User::getUser(); $view = new \OC\Files\View('/' . $user); if ($timestamp) { $filename = $filename . '.d' . $timestamp; } else { $filename = $filename; } $target = \OC\Files\Filesystem::normalizePath('files_trashbin/files/' . $filename); return $view->file_exists($target); }
/** * index a file * * @author Jörn Dreyer <*****@*****.**> * * @param string $path the path of the file * * @return bool */ public static function indexFile($path = '', $user = null) { if (!Filesystem::isValidPath($path)) { return; } if ($path === '') { //ignore the empty path element return false; } if (is_null($user)) { $view = Filesystem::getView(); $user = \OCP\User::getUser(); } else { $view = new \OC\Files\View('/' . $user . '/files'); } if (!$view) { Util::writeLog('search_lucene', 'could not resolve filesystem view', Util::WARN); return false; } if (!$view->file_exists($path)) { Util::writeLog('search_lucene', 'file vanished, ignoring', Util::DEBUG); return true; } $root = $view->getRoot(); $pk = md5($root . $path); // the cache already knows mime and other basic stuff $data = $view->getFileInfo($path); if (isset($data['mimetype'])) { $mimeType = $data['mimetype']; // initialize plain lucene document $doc = new \Zend_Search_Lucene_Document(); // index content for local files only $localFile = $view->getLocalFile($path); if ($localFile) { //try to use special lucene document types if ('text/plain' === $mimeType) { $body = $view->file_get_contents($path); if ($body != '') { $doc->addField(\Zend_Search_Lucene_Field::UnStored('body', $body)); } } else { if ('text/html' === $mimeType) { //TODO could be indexed, even if not local $doc = \Zend_Search_Lucene_Document_Html::loadHTML($view->file_get_contents($path)); } else { if ('application/pdf' === $mimeType) { $doc = Pdf::loadPdf($view->file_get_contents($path)); // commented the mimetype checks, as the zend classes only understand docx and not doc files. // FIXME distinguish doc and docx, xls and xlsx, ppt and pptx, in oc core mimetype helper ... //} else if ('application/msword' === $mimeType) { } else { if (strtolower(substr($data['name'], -5)) === '.docx') { $doc = \Zend_Search_Lucene_Document_Docx::loadDocxFile($localFile); //} else if ('application/msexcel' === $mimeType) { } else { if (strtolower(substr($data['name'], -5)) === '.xlsx') { $doc = \Zend_Search_Lucene_Document_Xlsx::loadXlsxFile($localFile); //} else if ('application/mspowerpoint' === $mimeType) { } else { if (strtolower(substr($data['name'], -5)) === '.pptx') { $doc = \Zend_Search_Lucene_Document_Pptx::loadPptxFile($localFile); } else { if (strtolower(substr($data['name'], -4)) === '.odt') { $doc = Odt::loadOdtFile($localFile); } else { if (strtolower(substr($data['name'], -4)) === '.ods') { $doc = Ods::loadOdsFile($localFile); } } } } } } } } } // Store filecache id as unique id to lookup by when deleting $doc->addField(\Zend_Search_Lucene_Field::Keyword('pk', $pk)); // Store filename $doc->addField(\Zend_Search_Lucene_Field::Text('filename', $data['name'], 'UTF-8')); // Store document path to identify it in the search results $doc->addField(\Zend_Search_Lucene_Field::Text('path', $path, 'UTF-8')); $doc->addField(\Zend_Search_Lucene_Field::unIndexed('size', $data['size'])); $doc->addField(\Zend_Search_Lucene_Field::unIndexed('mimetype', $mimeType)); //self::extractMetadata($doc, $path, $view, $mimeType); Lucene::updateFile($doc, $path, $user); return true; } else { Util::writeLog('search_lucene', 'need mimetype for content extraction', Util::ERROR); return false; } }
/** * store private key from the user * @param string $key * @return bool * @note Encryption of the private key must be performed by client code * as no encryption takes place here */ public static function setPrivateKey($key) { $user = \OCP\User::getUser(); $view = new \OC\Files\View('/' . $user . '/files_encryption'); $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; if (!$view->file_exists('')) { $view->mkdir(''); } $result = $view->file_put_contents($user . '.private.key', $key); \OC_FileProxy::$enabled = $proxyStatus; return $result; }
/** * @brief Show a specific event in the activities * @param array $event An array with all the event data in it */ public static function show($event) { $l = \OC_L10N::get('lib'); $user = $event['user']; if (!isset($event['isGrouped'])) { $event['isGrouped'] = false; } $formattedDate = \OCP\Util::formatDate($event['timestamp']); $formattedTimestamp = \OCP\relative_modified_date($event['timestamp']); $displayName = \OCP\User::getDisplayName($user); // TODO: move into template? echo '<div class="box">'; echo '<div class="header">'; echo '<span class="avatar" data-user="******"></span>'; echo '<span>'; echo '<span class="user">' . \OC_Util::sanitizeHTML($displayName) . '</span>'; echo '<span class="activitytime tooltip" title="' . \OC_Util::sanitizeHTML($formattedDate) . '">' . \OC_Util::sanitizeHTML($formattedTimestamp) . '</span>'; echo '<span class="appname">' . \OC_Util::sanitizeHTML($event['app']) . '</span>'; echo '</span>'; echo '</div>'; echo '<div class="messagecontainer">'; if ($event['isGrouped']) { $count = 0; echo '<ul class="activitysubject grouped">'; foreach ($event['events'] as $subEvent) { echo '<li>'; if ($subEvent['link'] != '') { echo '<a href="' . $subEvent['link'] . '">'; } echo \OC_Util::sanitizeHTML($subEvent['subject']); if ($subEvent['link'] != '') { echo '</a>'; } echo '</li>'; $count++; if ($count > 5) { echo '<li class="more">' . $l->n('%n more...', '%n more...', count($event['events']) - $count) . '</li>'; break; } } echo '</ul>'; } else { if ($event['link'] != '') { echo '<a href="' . $event['link'] . '">'; } echo '<div class="activitysubject">' . \OC_Util::sanitizeHTML($event['subject']) . '</div>'; echo '<div class="activitymessage">' . \OC_Util::sanitizeHTML($event['message']) . '</div>'; } $rootView = new \OC\Files\View(''); if ($event['file'] !== null) { $exist = $rootView->file_exists('/' . $user . '/files' . $event['file']); unset($rootView); // show a preview image if the file still exists if ($exist) { echo '<img class="preview" src="' . \OCP\Util::linkToRoute('core_ajax_preview', array('file' => $event['file'], 'x' => 150, 'y' => 150)) . '" />'; } } if (!$event['isGrouped'] && $event['link'] != '') { echo '</a>'; } echo '</div>'; // end messagecontainer echo '</div>'; // end box }
/** * @param string $appId * @return \OC\Files\View */ public static function getStorage($appId) { if (OC_App::isEnabled($appId)) { //sanity check if (OC_User::isLoggedIn()) { $view = new \OC\Files\View('/' . OC_User::getUser()); if (!$view->file_exists($appId)) { $view->mkdir($appId); } return new \OC\Files\View('/' . OC_User::getUser() . '/' . $appId); } else { OC_Log::write('core', 'Can\'t get app storage, app ' . $appId . ', user not logged in', OC_Log::ERROR); return false; } } else { OC_Log::write('core', 'Can\'t get app storage, app ' . $appId . ' not enabled', OC_Log::ERROR); return false; } }
/** * Tests mounting a folder that is an external storage mount point. */ public function testShareStorageMountPoint() { self::$tempStorage = new \OC\Files\Storage\Temporary(array()); self::$tempStorage->file_put_contents('test.txt', 'abcdef'); self::$tempStorage->getScanner()->scan(''); // needed because the sharing code sometimes switches the user internally and mounts the user's // storages. In our case the temp storage isn't mounted automatically, so doing it in the post hook // (similar to how ext storage works) OCP\Util::connectHook('OC_Filesystem', 'post_initMountPoints', '\\Test_Files_Sharing_Api', 'initTestMountPointsHook'); // logging in will auto-mount the temp storage for user1 as well \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1); $fileInfo = $this->view->getFileInfo($this->folder); // user 1 shares the mount point folder with user2 $result = \OCP\Share::shareItem('folder', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2, 31); $this->assertTrue($result); // user2: check that mount point name appears correctly \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2); $view = new \OC\Files\View('/' . \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2 . '/files'); $this->assertTrue($view->file_exists($this->folder)); $this->assertTrue($view->file_exists($this->folder . '/test.txt')); \Test_Files_Sharing_Api::loginHelper(\Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER1); \OCP\Share::unshare('folder', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, \Test_Files_Sharing_Api::TEST_FILES_SHARING_API_USER2); \OC_Hook::clear('OC_Filesystem', 'post_initMountPoints', '\\Test_Files_Sharing_Api', 'initTestMountPointsHook'); }
/** * Remember owner and the owner path of the source file. * If the file already exists, then it was a upload of a existing file * over the web interface and we call Storage::store() directly * * @param array $params array with oldpath and newpath * */ public static function pre_renameOrCopy_hook($params) { if (\OCP\App::isEnabled('files_versions')) { // if we rename a movable mount point, then the versions don't have // to be renamed $absOldPath = \OC\Files\Filesystem::normalizePath('/' . \OCP\User::getUser() . '/files' . $params['oldpath']); $manager = \OC\Files\Filesystem::getMountManager(); $mount = $manager->find($absOldPath); $internalPath = $mount->getInternalPath($absOldPath); if ($internalPath === '' and $mount instanceof \OC\Files\Mount\MoveableMount) { return; } $view = new \OC\Files\View(\OCP\User::getUser() . '/files'); if ($view->file_exists($params['newpath'])) { Storage::store($params['newpath']); } else { Storage::setSourcePathAndUser($params['oldpath']); } } }
public function testLongPath() { $storage = new \OC\Files\Storage\Temporary(array()); \OC\Files\Filesystem::mount($storage, array(), '/'); $rootView = new \OC\Files\View(''); $longPath = ''; // 4000 is the maximum path length in file_cache.path $folderName = 'abcdefghijklmnopqrstuvwxyz012345678901234567890123456789'; $depth = 4000 / 57; foreach (range(0, $depth - 1) as $i) { $longPath .= '/' . $folderName; $result = $rootView->mkdir($longPath); $this->assertTrue($result, "mkdir failed on {$i} - path length: " . strlen($longPath)); $result = $rootView->file_put_contents($longPath . '/test.txt', 'lorem'); $this->assertEquals(5, $result, "file_put_contents failed on {$i}"); $this->assertTrue($rootView->file_exists($longPath)); $this->assertTrue($rootView->file_exists($longPath . '/test.txt')); } $cache = $storage->getCache(); $scanner = $storage->getScanner(); $scanner->scan(''); $longPath = $folderName; foreach (range(0, $depth - 1) as $i) { $cachedFolder = $cache->get($longPath); $this->assertTrue(is_array($cachedFolder), "No cache entry for folder at {$i}"); $this->assertEquals($folderName, $cachedFolder['name'], "Wrong cache entry for folder at {$i}"); $cachedFile = $cache->get($longPath . '/test.txt'); $this->assertTrue(is_array($cachedFile), "No cache entry for file at {$i}"); $this->assertEquals('test.txt', $cachedFile['name'], "Wrong cache entry for file at {$i}"); $longPath .= '/' . $folderName; } }
/** * @brief replacing encryption keys during password change should be allowed * until the user logged in for the first time */ public function testSetPassphrase() { $view = new \OC\Files\View(); // set user password for the first time \OC_User::createUser(self::TEST_ENCRYPTION_HOOKS_USER3, 'newUserPassword'); \OCA\Files_Encryption\Hooks::postCreateUser(array('uid' => self::TEST_ENCRYPTION_HOOKS_USER3, 'password' => 'newUserPassword')); $this->assertTrue($view->file_exists(\OCA\Files_Encryption\Keymanager::getPublicKeyPath() . '/' . self::TEST_ENCRYPTION_HOOKS_USER3 . '.publicKey')); $this->assertTrue($view->file_exists(self::TEST_ENCRYPTION_HOOKS_USER3 . '/files_encryption/' . self::TEST_ENCRYPTION_HOOKS_USER3 . '.privateKey')); // check if we are able to decrypt the private key $encryptedKey = \OCA\Files_Encryption\Keymanager::getPrivateKey($view, self::TEST_ENCRYPTION_HOOKS_USER3); $privateKey = \OCA\Files_Encryption\Crypt::decryptPrivateKey($encryptedKey, 'newUserPassword'); $this->assertTrue(is_string($privateKey)); // change the password before the user logged-in for the first time, // we can replace the encryption keys \OCA\Files_Encryption\Hooks::setPassphrase(array('uid' => self::TEST_ENCRYPTION_HOOKS_USER3, 'password' => 'passwordChanged')); $encryptedKey = \OCA\Files_Encryption\Keymanager::getPrivateKey($view, self::TEST_ENCRYPTION_HOOKS_USER3); $privateKey = \OCA\Files_Encryption\Crypt::decryptPrivateKey($encryptedKey, 'passwordChanged'); $this->assertTrue(is_string($privateKey)); // now create a files folder to simulate a already used account $view->mkdir('/' . self::TEST_ENCRYPTION_HOOKS_USER3 . '/files'); // change the password after the user logged in, now the password should not change \OCA\Files_Encryption\Hooks::setPassphrase(array('uid' => self::TEST_ENCRYPTION_HOOKS_USER3, 'password' => 'passwordChanged2')); $encryptedKey = \OCA\Files_Encryption\Keymanager::getPrivateKey($view, self::TEST_ENCRYPTION_HOOKS_USER3); $privateKey = \OCA\Files_Encryption\Crypt::decryptPrivateKey($encryptedKey, 'passwordChanged2'); $this->assertFalse($privateKey); $privateKey = \OCA\Files_Encryption\Crypt::decryptPrivateKey($encryptedKey, 'passwordChanged'); $this->assertTrue(is_string($privateKey)); }
/** * Mounts the cache directory * @param string $user user name */ private static function mountCacheDir($user) { $cacheBaseDir = \OC_Config::getValue('cache_path', ''); if ($cacheBaseDir === '') { // use local cache dir relative to the user's home $subdir = 'cache'; $view = new \OC\Files\View('/' . $user); if (!$view->file_exists($subdir)) { $view->mkdir($subdir); } } else { $cacheDir = rtrim($cacheBaseDir, '/') . '/' . $user; if (!file_exists($cacheDir)) { mkdir($cacheDir, 0770, true); } // mount external cache dir to "/$user/cache" mount point self::mount('\\OC\\Files\\Storage\\Local', array('datadir' => $cacheDir), '/' . $user . '/cache'); } }
public function xtestLongPath() { $storage = new \OC\Files\Storage\Temporary(array()); \OC\Files\Filesystem::mount($storage, array(), '/'); $rootView = new \OC\Files\View(''); $longPath = ''; $ds = DIRECTORY_SEPARATOR; /* * 4096 is the maximum path length in file_cache.path in *nix * 1024 is the max path length in mac * 228 is the max path length in windows */ $folderName = 'abcdefghijklmnopqrstuvwxyz012345678901234567890123456789'; $tmpdirLength = strlen(\OC_Helper::tmpFolder()); if (\OC_Util::runningOnWindows()) { $this->markTestSkipped('[Windows] '); $depth = (260 - $tmpdirLength) / 57; } elseif (\OC_Util::runningOnMac()) { $depth = (1024 - $tmpdirLength) / 57; } else { $depth = (4000 - $tmpdirLength) / 57; } foreach (range(0, $depth - 1) as $i) { $longPath .= $ds . $folderName; $result = $rootView->mkdir($longPath); $this->assertTrue($result, "mkdir failed on {$i} - path length: " . strlen($longPath)); $result = $rootView->file_put_contents($longPath . "{$ds}test.txt", 'lorem'); $this->assertEquals(5, $result, "file_put_contents failed on {$i}"); $this->assertTrue($rootView->file_exists($longPath)); $this->assertTrue($rootView->file_exists($longPath . "{$ds}test.txt")); } $cache = $storage->getCache(); $scanner = $storage->getScanner(); $scanner->scan(''); $longPath = $folderName; foreach (range(0, $depth - 1) as $i) { $cachedFolder = $cache->get($longPath); $this->assertTrue(is_array($cachedFolder), "No cache entry for folder at {$i}"); $this->assertEquals($folderName, $cachedFolder['name'], "Wrong cache entry for folder at {$i}"); $cachedFile = $cache->get($longPath . '/test.txt'); $this->assertTrue(is_array($cachedFile), "No cache entry for file at {$i}"); $this->assertEquals('test.txt', $cachedFile['name'], "Wrong cache entry for file at {$i}"); $longPath .= $ds . $folderName; } }
/** * @brief enable recovery * * @param $recoveryKeyId * @param $recoveryPassword * @internal param \OCA\Encryption\Util $util * @internal param string $password * @return bool */ public static function adminEnableRecovery($recoveryKeyId, $recoveryPassword) { $view = new \OC\Files\View('/'); if ($recoveryKeyId === null) { $recoveryKeyId = 'recovery_' . substr(md5(time()), 0, 8); \OC_Appconfig::setValue('files_encryption', 'recoveryKeyId', $recoveryKeyId); } if (!$view->is_dir('/owncloud_private_key')) { $view->mkdir('/owncloud_private_key'); } if (!$view->file_exists("/public-keys/" . $recoveryKeyId . ".public.key") || !$view->file_exists("/owncloud_private_key/" . $recoveryKeyId . ".private.key")) { $keypair = \OCA\Encryption\Crypt::createKeypair(); \OC_FileProxy::$enabled = false; // Save public key if (!$view->is_dir('/public-keys')) { $view->mkdir('/public-keys'); } $view->file_put_contents('/public-keys/' . $recoveryKeyId . '.public.key', $keypair['publicKey']); // Encrypt private key empty passphrase $encryptedPrivateKey = \OCA\Encryption\Crypt::symmetricEncryptFileContent($keypair['privateKey'], $recoveryPassword); // Save private key $view->file_put_contents('/owncloud_private_key/' . $recoveryKeyId . '.private.key', $encryptedPrivateKey); \OC_FileProxy::$enabled = true; // Set recoveryAdmin as enabled \OC_Appconfig::setValue('files_encryption', 'recoveryAdminEnabled', 1); $return = true; } else { // get recovery key and check the password $util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), \OCP\User::getUser()); $return = $util->checkRecoveryPassword($recoveryPassword); if ($return) { \OC_Appconfig::setValue('files_encryption', 'recoveryAdminEnabled', 1); } } return $return; }