/** * if the parent of the mount point is gone then the mount point should move up * * @medium */ public function testParentOfMountPointIsGone() { // 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 /** @var \OC\Files\Storage\Storage $storage */ list($storage, $internalPath) = \OC\Files\Filesystem::resolvePath('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/localfolder'); $storage->rmdir($internalPath); //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); }
/** * if the parent of the mount point is gone then the mount point should move up * * @medium */ function testParentOfMountPointIsGone() { // 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 $fullPath = \OC_Config::getValue('datadirectory') . '/' . self::TEST_FILES_SHARING_API_USER2 . '/files/localfolder'; rmdir($fullPath); //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); }
/** * create unique target * @param string $filePath * @param string $shareWith * @param string $exclude * @return string */ public function generateTarget($filePath, $shareWith, $exclude = null) { $shareFolder = \OCA\Files_Sharing\Helper::getShareFolder(); $target = \OC\Files\Filesystem::normalizePath($shareFolder . '/' . basename($filePath)); // for group shares we return the target right away if ($shareWith === false) { return $target; } \OC\Files\Filesystem::initMountPoints($shareWith); $view = new \OC\Files\View('/' . $shareWith . '/files'); if (!$view->is_dir($shareFolder)) { $dir = ''; $subdirs = explode('/', $shareFolder); foreach ($subdirs as $subdir) { $dir = $dir . '/' . $subdir; if (!$view->is_dir($dir)) { $view->mkdir($dir); } } } $excludeList = \OCP\Share::getItemsSharedWithUser('file', $shareWith, self::FORMAT_TARGET_NAMES); if (is_array($exclude)) { $excludeList = array_merge($excludeList, $exclude); } return \OCA\Files_Sharing\Helper::generateUniqueTarget($target, $excludeList, $view); }
/** * Retrieves the contents of a trash bin directory. * * @param string $dir path to the directory inside the trashbin * or empty to retrieve the root of the trashbin * @param string $user * @param string $sortAttribute attribute to sort on or empty to disable sorting * @param bool $sortDescending true for descending sort, false otherwise * @return \OCP\Files\FileInfo[] */ public static function getTrashFiles($dir, $user, $sortAttribute = '', $sortDescending = false) { $result = array(); $timestamp = null; $view = new \OC\Files\View('/' . $user . '/files_trashbin/files'); if (ltrim($dir, '/') !== '' && !$view->is_dir($dir)) { throw new \Exception('Directory does not exists'); } $dirContent = $view->opendir($dir); if ($dirContent === false) { return $result; } $mount = $view->getMount($dir); $storage = $mount->getStorage(); $absoluteDir = $view->getAbsolutePath($dir); $internalPath = $mount->getInternalPath($absoluteDir); if (is_resource($dirContent)) { $originalLocations = \OCA\Files_Trashbin\Trashbin::getLocations($user); while (($entryName = readdir($dirContent)) !== false) { if (!\OC\Files\Filesystem::isIgnoredDir($entryName)) { $id = $entryName; if ($dir === '' || $dir === '/') { $size = $view->filesize($id); $pathparts = pathinfo($entryName); $timestamp = substr($pathparts['extension'], 1); $id = $pathparts['filename']; } else { if ($timestamp === null) { // for subfolders we need to calculate the timestamp only once $size = $view->filesize($dir . '/' . $id); $parts = explode('/', ltrim($dir, '/')); $timestamp = substr(pathinfo($parts[0], PATHINFO_EXTENSION), 1); } } $originalPath = ''; if (isset($originalLocations[$id][$timestamp])) { $originalPath = $originalLocations[$id][$timestamp]; if (substr($originalPath, -1) === '/') { $originalPath = substr($originalPath, 0, -1); } } $i = array('name' => $id, 'mtime' => $timestamp, 'mimetype' => $view->is_dir($dir . '/' . $entryName) ? 'httpd/unix-directory' : \OC_Helper::getFileNameMimeType($id), 'type' => $view->is_dir($dir . '/' . $entryName) ? 'dir' : 'file', 'directory' => $dir === '/' ? '' : $dir, 'size' => $size); if ($originalPath) { $i['extraData'] = $originalPath . '/' . $id; } $result[] = new FileInfo($absoluteDir . '/' . $i['name'], $storage, $internalPath . '/' . $i['name'], $i, $mount); } } closedir($dirContent); } if ($sortAttribute !== '') { return \OCA\Files\Helper::sortFiles($result, $sortAttribute, $sortDescending); } return $result; }
/** * 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(); }
/** * Act on behalf on trash item owner * @param string $user * @return boolean */ protected function setupFS($user) { \OC_Util::tearDownFS(); \OC_Util::setupFS($user); // Check if this user has a versions directory $view = new \OC\Files\View('/' . $user); if (!$view->is_dir('/files_versions')) { return false; } return true; }
function testKeySetPreperation() { $basePath = '/' . Test_Encryption_Keymanager::TEST_USER . '/files'; $path = '/folder1/subfolder/subsubfolder/file.txt'; $this->assertFalse($this->view->is_dir($basePath . '/testKeySetPreperation')); $result = TestProtectedKeymanagerMethods::testKeySetPreperation($this->view, $path, $basePath); // return path without leading slash $this->assertSame('folder1/subfolder/subsubfolder/file.txt', $result); // check if directory structure was created $this->assertTrue($this->view->is_dir($basePath . '/folder1/subfolder/subsubfolder')); // cleanup $this->view->deleteAll($basePath . '/folder1'); }
function testDescryptAllWithBrokenFiles() { $file1 = "/decryptAll1" . uniqid() . ".txt"; $file2 = "/decryptAll2" . uniqid() . ".txt"; $util = new 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/keyfiles/' . $file1 . '.key', $this->userId . '/files_encryption/keyfiles/' . $file1 . '.key.moved'); // 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/keyfiles/')); $this->assertTrue($this->view->is_dir($this->userId . '/files_encryption/share-keys/')); // rename the keyfile for file1 back $this->view->rename($this->userId . '/files_encryption/keyfiles/' . $file1 . '.key.moved', $this->userId . '/files_encryption/keyfiles/' . $file1 . '.key'); // 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/keyfiles/')); $this->assertFalse($this->view->is_dir($this->userId . '/files_encryption/share-keys/')); //cleanup $this->view->unlink($this->userId . '/files/' . $file1); $this->view->unlink($this->userId . '/files/' . $file2); $this->view->deleteAll($this->userId . '/files_encryption/keyfiles.backup'); $this->view->deleteAll($this->userId . '/files_encryption/share-keys.backup'); }
/** * Retrieves the contents of a trash bin directory. * * @param string $dir path to the directory inside the trashbin * or empty to retrieve the root of the trashbin * @param string $user * @param string $sortAttribute attribute to sort on or empty to disable sorting * @param bool $sortDescending true for descending sort, false otherwise * @return \OCP\Files\FileInfo[] */ public static function getTrashFiles($dir, $user, $sortAttribute = '', $sortDescending = false) { $result = array(); $timestamp = null; $view = new \OC\Files\View('/' . $user . '/files_trashbin/files'); if (ltrim($dir, '/') !== '' && !$view->is_dir($dir)) { throw new \Exception('Directory does not exists'); } $mount = $view->getMount($dir); $storage = $mount->getStorage(); $absoluteDir = $view->getAbsolutePath($dir); $internalPath = $mount->getInternalPath($absoluteDir); $originalLocations = \OCA\Files_Trashbin\Trashbin::getLocations($user); $dirContent = $storage->getCache()->getFolderContents($mount->getInternalPath($view->getAbsolutePath($dir))); foreach ($dirContent as $entry) { $entryName = $entry->getName(); $id = $entry->getId(); $name = $entryName; if ($dir === '' || $dir === '/') { $pathparts = pathinfo($entryName); $timestamp = substr($pathparts['extension'], 1); $name = $pathparts['filename']; } else { if ($timestamp === null) { // for subfolders we need to calculate the timestamp only once $parts = explode('/', ltrim($dir, '/')); $timestamp = substr(pathinfo($parts[0], PATHINFO_EXTENSION), 1); } } $originalPath = ''; if (isset($originalLocations[$id][$timestamp])) { $originalPath = $originalLocations[$id][$timestamp]; if (substr($originalPath, -1) === '/') { $originalPath = substr($originalPath, 0, -1); } } $i = array('name' => $name, 'mtime' => $timestamp, 'mimetype' => $entry->getMimeType(), 'type' => $entry->getMimeType() === ICacheEntry::DIRECTORY_MIMETYPE ? 'dir' : 'file', 'directory' => $dir === '/' ? '' : $dir, 'size' => $entry->getSize(), 'etag' => '', 'permissions' => Constants::PERMISSION_ALL - Constants::PERMISSION_SHARE); if ($originalPath) { $i['extraData'] = $originalPath . '/' . $id; } $result[] = new FileInfo($absoluteDir . '/' . $i['name'], $storage, $internalPath . '/' . $i['name'], $i, $mount); } if ($sortAttribute !== '') { return \OCA\Files\Helper::sortFiles($result, $sortAttribute, $sortDescending); } return $result; }
public static function create($args) { $uid = self::preDispatch(); $view = new \OC\Files\View('/' . $uid . '/files'); $dir = \OCP\Config::getUserValue(\OCP\User::getUser(), 'documents', 'save_path', '/'); if (!$view->is_dir($dir)) { $dir = '/'; } $path = Helper::getNewFileName($view, $dir . '/New Document.odt'); $content = base64_decode(self::ODT_TEMPLATE); if (class_exists('\\OC\\Files\\Type\\TemplateManager')) { $manager = \OC_Helper::getFileTemplateManager(); $templateContent = $manager->getTemplate(Storage::MIMETYPE_LIBREOFFICE_WORDPROCESSOR); if ($templateContent) { $content = $templateContent; } } if ($view->file_put_contents($path, $content)) { $info = $view->getFileInfo($path); \OCP\JSON::success(array('fileid' => $info['fileid'])); } else { \OCP\JSON::error(array('message' => Config::getL10n()->t('Can\'t create document'))); } }
/** * get a list of all available versions of a file in descending chronological order * @param string $uid user id from the owner of the file * @param string $filename file to find versions of, relative to the user files dir * @param string $userFullPath * @return array versions newest version first */ public static function getVersions($uid, $filename, $userFullPath = '') { $versions = array(); if (empty($filename)) { return $versions; } // fetch for old versions $view = new \OC\Files\View('/' . $uid . '/'); $pathinfo = pathinfo($filename); $versionedFile = $pathinfo['basename']; $dir = \OC\Files\Filesystem::normalizePath(self::VERSIONS_ROOT . '/' . $pathinfo['dirname']); $dirContent = false; if ($view->is_dir($dir)) { $dirContent = $view->opendir($dir); } if ($dirContent === false) { return $versions; } if (is_resource($dirContent)) { while (($entryName = readdir($dirContent)) !== false) { if (!\OC\Files\Filesystem::isIgnoredDir($entryName)) { $pathparts = pathinfo($entryName); $filename = $pathparts['filename']; if ($filename === $versionedFile) { $pathparts = pathinfo($entryName); $timestamp = substr($pathparts['extension'], 1); $filename = $pathparts['filename']; $key = $timestamp . '#' . $filename; $versions[$key]['version'] = $timestamp; $versions[$key]['humanReadableTimestamp'] = self::getHumanReadableTimestamp($timestamp); if (empty($userFullPath)) { $versions[$key]['preview'] = ''; } else { $versions[$key]['preview'] = \OCP\Util::linkToRoute('core_ajax_versions_preview', array('file' => $userFullPath, 'version' => $timestamp)); } $versions[$key]['path'] = \OC\Files\Filesystem::normalizePath($pathinfo['dirname'] . '/' . $filename); $versions[$key]['name'] = $versionedFile; $versions[$key]['size'] = $view->filesize($dir . '/' . $entryName); } } } closedir($dirContent); } // sort with newest version first krsort($versions); return $versions; }
/** * check if trash bin is empty for a given user * @param string $user */ public static function isEmpty($user) { $view = new \OC\Files\View('/' . $user . '/files_trashbin'); if ($view->is_dir('/files') && ($dh = $view->opendir('/files'))) { while ($file = readdir($dh)) { if ($file !== '.' and $file !== '..') { return false; } } } return true; }
/** * @param string $path * @param int $size * @return int|bool */ public function postFileSize($path, $size, $fileInfo = null) { $view = new \OC\Files\View('/'); $userId = Helper::getUser($path); $util = new Util($view, $userId); // if encryption is no longer enabled or if the files aren't migrated yet // we return the default file size if (!\OCP\App::isEnabled('files_encryption') || $util->getMigrationStatus() !== Util::MIGRATION_COMPLETED) { return $size; } // if path is a folder do nothing if ($view->is_dir($path)) { $proxyState = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; $fileInfo = $view->getFileInfo($path); \OC_FileProxy::$enabled = $proxyState; if (isset($fileInfo['unencrypted_size']) && $fileInfo['unencrypted_size'] > 0) { return $fileInfo['unencrypted_size']; } return $size; } // get relative path $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path); // if path is empty we cannot resolve anything if (empty($relativePath)) { return $size; } // get file info from database/cache if not .part file if (empty($fileInfo) && !Helper::isPartialFilePath($path)) { $proxyState = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; $fileInfo = $view->getFileInfo($path); \OC_FileProxy::$enabled = $proxyState; } // if file is encrypted return real file size if (isset($fileInfo['encrypted']) && $fileInfo['encrypted'] === true) { // try to fix unencrypted file size if it doesn't look plausible if ((int) $fileInfo['size'] > 0 && (int) $fileInfo['unencrypted_size'] === 0) { $fixSize = $util->getFileSize($path); $fileInfo['unencrypted_size'] = $fixSize; // put file info if not .part file if (!Helper::isPartialFilePath($relativePath)) { $view->putFileInfo($path, array('unencrypted_size' => $fixSize)); } } $size = $fileInfo['unencrypted_size']; } else { $fileInfoUpdates = array(); $fixSize = $util->getFileSize($path); if ($fixSize > 0) { $size = $fixSize; $fileInfoUpdates['encrypted'] = true; $fileInfoUpdates['unencrypted_size'] = $size; // put file info if not .part file if (!Helper::isPartialFilePath($relativePath)) { $view->putFileInfo($path, $fileInfoUpdates); } } } return $size; }
/** * @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; }
/** * Act on behalf on trash item owner * @param string $user * @return boolean */ private function setupFS($user) { if (!$this->userManager->userExists($user)) { return false; } //Check if this user has a trashbin directory $view = new \OC\Files\View('/' . $user); if (!$view->is_dir('/files_trashbin/files')) { return false; } \OC_Util::tearDownFS(); \OC_Util::setupFS($user); return true; }
if ($file === '') { \OC_Response::setStatus(400); //400 Bad Request \OCP\Util::writeLog('core-preview', 'No file parameter was passed', \OCP\Util::DEBUG); exit; } if ($maxX === 0 || $maxY === 0) { \OC_Response::setStatus(400); //400 Bad Request \OCP\Util::writeLog('core-preview', 'x and/or y set to 0', \OCP\Util::DEBUG); exit; } try { $preview = new \OC\Preview(\OC_User::getUser(), 'files_trashbin/files', $file); $view = new \OC\Files\View('/' . \OC_User::getUser() . '/files_trashbin/files'); if ($view->is_dir($file)) { $mimetype = 'httpd/unix-directory'; } else { $pathInfo = pathinfo(ltrim($file, '/')); $fileName = $pathInfo['basename']; // if in root dir if ($pathInfo['dirname'] === '.') { // cut off the .d* suffix $i = strrpos($fileName, '.'); if ($i !== false) { $fileName = substr($fileName, 0, $i); } } $mimetype = \OC::$server->getMimeTypeDetector()->detectPath($fileName); } $preview->setMimetype($mimetype);
/** * update keyfiles and share keys recursively * * @param string $path to the file/folder */ private static function updateKeyfiles($path) { $view = new \OC\Files\View('/'); $userId = \OCP\User::getUser(); $session = new Session($view); $util = new Util($view, $userId); $sharingEnabled = \OCP\Share::isEnabled(); $mountManager = \OC\Files\Filesystem::getMountManager(); $mount = $mountManager->find('/' . $userId . '/files' . $path); $mountPoint = $mount->getMountPoint(); // if a folder was shared, get a list of all (sub-)folders if ($view->is_dir('/' . $userId . '/files' . $path)) { $allFiles = $util->getAllFiles($path, $mountPoint); } else { $allFiles = array($path); } foreach ($allFiles as $path) { $usersSharing = $util->getSharingUsersArray($sharingEnabled, $path); $util->setSharedFileKeyfiles($session, $usersSharing, $path); } }
/** * mark file as renamed so that we know the original source after the file was renamed * @param array $params with the old path and the new path */ public static function preCopy($params) { $user = \OCP\User::getUser(); $view = new \OC\Files\View('/'); $util = new Util($view, $user); list($ownerOld, $pathOld) = $util->getUidAndFilename($params['oldpath']); // we only need to rename the keys if the rename happens on the same mountpoint // otherwise we perform a stream copy, so we get a new set of keys $mp1 = $view->getMountPoint('/' . $user . '/files/' . $params['oldpath']); $mp2 = $view->getMountPoint('/' . $user . '/files/' . $params['newpath']); $type = $view->is_dir('/' . $user . '/files/' . $params['oldpath']) ? 'folder' : 'file'; if ($mp1 === $mp2) { self::$renamedFiles[$params['oldpath']] = array('uid' => $ownerOld, 'path' => $pathOld, 'type' => $type, 'operation' => 'copy'); } }
/** * get itemType * @param string $path * @return string type 'file', 'folder' or null of file/folder doesn't exists */ private static function getItemType($path) { $view = new \OC\Files\View('/' . \OCP\User::getUser() . '/files'); $itemType = null; if ($view->is_dir($path)) { $itemType = "folder"; } elseif ($view->is_file($path)) { $itemType = "file"; } return $itemType; }
/** * unmount file from yourself * remember files/folders which get unmounted */ public static function preUmount($params) { $path = $params[\OC\Files\Filesystem::signal_param_path]; $user = \OCP\USER::getUser(); $view = new \OC\Files\View(); $itemType = $view->is_dir('/' . $user . '/files' . $path) ? 'folder' : 'file'; $util = new Util($view, $user); list($owner, $ownerPath) = $util->getUidAndFilename($path); self::$umountedFiles[$params[\OC\Files\Filesystem::signal_param_path]] = array('uid' => $owner, 'path' => $ownerPath, 'itemType' => $itemType); }
/** * check if a backup from the encryption keys exists * * @return boolean */ public static function backupKeysExists() { //check if encryption was enabled in the past $backupExists = false; if (OC_App::isEnabled('files_encryption') === false) { $view = new OC\Files\View('/' . OCP\User::getUser()); $backupPath = '/files_encryption/keyfiles.backup'; if ($view->is_dir($backupPath)) { $dircontent = $view->getDirectoryContent($backupPath); if (!empty($dircontent)) { $backupExists = true; } } } return $backupExists; }
public function test() { // FIXME: Use as expression in empty once PHP 5.4 support is dropped $host = $this->getHost(); if (empty($host)) { \OC::$server->getLogger()->warning('Hostname has not been specified'); return false; } // FIXME: Use as expression in empty once PHP 5.4 support is dropped $user = $this->getUser(); if (empty($user)) { \OC::$server->getLogger()->warning('Username has not been specified'); return false; } if (!isset($this->privateKey)) { \OC::$server->getLogger()->warning('Private key was missing from the request'); return false; } // Sanity check the host $hostParts = explode(':', $this->getHost()); try { if (count($hostParts) == 1) { $hostname = $hostParts[0]; $this->assertHostAddressValid($hostname); } else { if (count($hostParts) == 2) { $hostname = $hostParts[0]; $this->assertHostAddressValid($hostname); $this->assertPortNumberValid($hostParts[1]); } else { throw new \Exception('Host connection string is invalid.'); } } } catch (\Exception $e) { \OC::$server->getLogger()->warning($e->getMessage()); return false; } // Validate the key $key = $this->getPrivateKey(); if (is_null($key)) { \OC::$server->getLogger()->warning('Secret key could not be loaded'); return false; } try { if ($this->getConnection()->nlist() === false) { return false; } } catch (\Exception $e) { // We should be throwing a more specific error, so we're not just catching // Exception here \OC::$server->getLogger()->warning($e->getMessage()); return false; } // Save the key somewhere it can easily be extracted later if (\OC::$server->getUserSession()->getUser()) { $view = new \OC\Files\View('/' . \OC::$server->getUserSession()->getUser()->getUId() . '/files_external/sftp_keys'); if (!$view->is_dir('')) { if (!$view->mkdir('')) { \OC::$server->getLogger()->warning('Could not create secret key directory.'); return false; } } $key_filename = $this->sanitizeUserName($this->getUser()) . '@' . $this->sanitizeHostName($hostname) . '.pub'; $key_file = $view->fopen($key_filename, "w"); if ($key_file) { fwrite($key_file, $this->publicKey); fclose($key_file); } else { \OC::$server->getLogger()->warning('Could not write secret key file.'); } } return true; }
/** * rename versions of a file */ public static function rename($old_path, $new_path) { list($uid, $oldpath) = self::getUidAndFilename($old_path); list($uidn, $newpath) = self::getUidAndFilename($new_path); $versions_view = new \OC\Files\View('/' . $uid . '/files_versions'); $files_view = new \OC\Files\View('/' . $uid . '/files'); // if the file already exists than it was a upload of a existing file // over the web interface -> store() is the right function we need here if ($files_view->file_exists($newpath)) { return self::store($new_path); } self::expire($newpath); $abs_newpath = $versions_view->getLocalFile($newpath); if ($files_view->is_dir($oldpath) && $versions_view->is_dir($oldpath)) { $versions_view->rename($oldpath, $newpath); } else { if ($versions = Storage::getVersions($uid, $oldpath)) { $info = pathinfo($abs_newpath); if (!file_exists($info['dirname'])) { mkdir($info['dirname'], 0750, true); } foreach ($versions as $v) { $versions_view->rename($oldpath . '.v' . $v['version'], $newpath . '.v' . $v['version']); } } } }
/** * rename versions of a file */ public static function rename($old_path, $new_path) { list($uid, $oldpath) = self::getUidAndFilename($old_path); list($uidn, $newpath) = self::getUidAndFilename($new_path); $versions_view = new \OC\Files\View('/' . $uid . '/files_versions'); $files_view = new \OC\Files\View('/' . $uid . '/files'); // if the file already exists than it was a upload of a existing file // over the web interface -> store() is the right function we need here if ($files_view->file_exists($newpath)) { return self::store($new_path); } self::expire($newpath); if ($files_view->is_dir($oldpath) && $versions_view->is_dir($oldpath)) { $versions_view->rename($oldpath, $newpath); } else { if ($versions = Storage::getVersions($uid, $oldpath)) { // create missing dirs if necessary self::createMissingDirectories($newpath, new \OC\Files\View('/' . $uidn)); foreach ($versions as $v) { $versions_view->rename($oldpath . '.v' . $v['version'], $newpath . '.v' . $v['version']); } } } }
/** * @param array $args * @param string $prefix */ public static function prepare_delete($args, $prefix = '') { $path = $args['path']; if (substr($path, 0, 1) === '/') { $path = substr($path, 1); } $view = new \OC\Files\View('/' . \OC_User::getUser() . '/' . $prefix); $absPath = Files\Filesystem::normalizePath($view->getAbsolutePath($path)); self::addPathToDeleteFileMapper($absPath, $view->getFileInfo($path)); if ($view->is_dir($path)) { $children = self::getAllChildren($view, $path); self::$deleteChildrenMapper[$absPath] = $children; } }
/** * @brief restore encryption keys from trash bin * * @param \OC\Files\View $view * @param $file complete path to file * @param $filename name of file * @param $uniqueFilename new file name to restore the file without overwriting existing files * @param $location location of file * @param $timestamp deleteion time * * @return size of restored encrypted file */ private static function restoreEncryptionKeys($view, $file, $filename, $uniqueFilename, $location, $timestamp) { // Take care of encryption keys TODO! Get '.key' in file between file name and delete date (also for permanent delete!) $size = 0; if (\OCP\App::isEnabled('files_encryption')) { $user = \OCP\User::getUser(); $rootView = new \OC\Files\View('/'); $target = \OC\Files\Filesystem::normalizePath('/' . $location . '/' . $uniqueFilename); list($owner, $ownerPath) = self::getUidAndFilename($target); $util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), $user); if ($util->isSystemWideMountPoint($ownerPath)) { $baseDir = '/files_encryption/'; } else { $baseDir = $owner . '/files_encryption/'; } $path_parts = pathinfo($file); $source_location = $path_parts['dirname']; if ($view->is_dir('/files_trashbin/keyfiles/' . $file)) { if ($source_location != '.') { $keyfile = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/keyfiles/' . $source_location . '/' . $filename); $sharekey = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/share-keys/' . $source_location . '/' . $filename); } else { $keyfile = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/keyfiles/' . $filename); $sharekey = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/share-keys/' . $filename); } } else { $keyfile = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/keyfiles/' . $source_location . '/' . $filename . '.key'); } if ($timestamp) { $keyfile .= '.d' . $timestamp; } // disable proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; if ($rootView->file_exists($keyfile)) { // handle directory if ($rootView->is_dir($keyfile)) { // handle keyfiles $size += self::calculateSize(new \OC\Files\View($keyfile)); $rootView->rename($keyfile, $baseDir . '/keyfiles/' . $ownerPath); // handle share-keys if ($timestamp) { $sharekey .= '.d' . $timestamp; } $size += self::calculateSize(new \OC\Files\View($sharekey)); $rootView->rename($sharekey, $baseDir . '/share-keys/' . $ownerPath); } else { // handle keyfiles $size += $rootView->filesize($keyfile); $rootView->rename($keyfile, $baseDir . '/keyfiles/' . $ownerPath . '.key'); // handle share-keys $ownerShareKey = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/share-keys/' . $source_location . '/' . $filename . '.' . $user . '.shareKey'); if ($timestamp) { $ownerShareKey .= '.d' . $timestamp; } $size += $rootView->filesize($ownerShareKey); // move only owners key $rootView->rename($ownerShareKey, $baseDir . '/share-keys/' . $ownerPath . '.' . $user . '.shareKey'); // try to re-share if file is shared $filesystemView = new \OC_FilesystemView('/'); $session = new \OCA\Encryption\Session($filesystemView); $util = new \OCA\Encryption\Util($filesystemView, $user); // fix the file size $absolutePath = \OC\Files\Filesystem::normalizePath('/' . $owner . '/files/' . $ownerPath); $util->fixFileSize($absolutePath); // get current sharing state $sharingEnabled = \OCP\Share::isEnabled(); // get users sharing this file $usersSharing = $util->getSharingUsersArray($sharingEnabled, $target, $user); // Attempt to set shareKey $util->setSharedFileKeyfiles($session, $usersSharing, $target); } } // enable proxy \OC_FileProxy::$enabled = $proxyStatus; } return $size; }
/** * @medium */ function testMoveBetweenStorages() { $storage1 = $this->getTestStorage(); $storage2 = $this->getTestStorage(); \OC\Files\Filesystem::mount($storage1, array(), '/'); \OC\Files\Filesystem::mount($storage2, array(), '/substorage'); $rootView = new \OC\Files\View(''); $rootView->rename('foo.txt', 'substorage/folder/foo.txt'); $this->assertFalse($rootView->file_exists('foo.txt')); $this->assertTrue($rootView->file_exists('substorage/folder/foo.txt')); $rootView->rename('substorage/folder', 'anotherfolder'); $this->assertFalse($rootView->is_dir('substorage/folder')); $this->assertTrue($rootView->file_exists('anotherfolder/foo.txt')); $this->assertTrue($rootView->file_exists('anotherfolder/bar.txt')); }
function run() { $query = \OCP\DB::prepare('SELECT * FROM `*PREFIX*fc_mail_attachments`'); $results = $query->execute()->fetchAll(); foreach ($results as $entry) { $fs = new \OC\Files\View('/' . $entry['user']); $udir = $this->sanitizeFSName($entry["dir"]); $path = array('files', $this->dir_mail, $udir); for ($i = 1; $i < sizeof($path); $i++) { $ppath = array(); for ($y = 0; $y <= $i; $y++) { $ppath[] = $path[$y]; } $ppath = implode(DIRECTORY_SEPARATOR, $ppath); if (!$fs->is_dir($ppath)) { $fs->mkdir($ppath); } } $maildir = implode(DIRECTORY_SEPARATOR, $path) . DIRECTORY_SEPARATOR; $mstats = array('folders' => array()); if (isset($entry["stats"]) && $entry["stats"] != "") { $mstats = \OCA\fc_mail_attachments\lib\Utils::array_merge_recursive_distinct($mstats, json_decode($entry["stats"], true)); } $imap = new \OCA\fc_mail_attachments\lib\imap($entry['mail_host'], $entry['mail_port'], $entry['mail_security'], $entry['mail_user'], $entry['mail_password']); try { $imap->open(); $mailboxes = $imap->listMailboxes(); foreach ($mailboxes as $mbname) { if ($this->skipMailbox($entry, $mbname)) { continue; } $imap->open($mbname); $mboxLastMsgNo = $imap->countMessages(); if (!$mboxLastMsgNo) { continue; } $mboxdir = $maildir . DIRECTORY_SEPARATOR . $this->sanitizeFSName($mbname) . DIRECTORY_SEPARATOR; if (!$fs->is_dir($mboxdir)) { $fs->mkdir($mboxdir); } $mboxLastMsgUid = $imap->getLastMessageUid(); $mboxStatus = $imap->status($mbname); $curMboxInfo = array("fcmaVersion" => 0, "lastSeenUid" => -1, "historyUid" => -1, "uidValidity" => -1); if ($fs->file_exists($mboxdir . '.info')) { $savedMboxInfo = json_decode($fs->file_get_contents($mboxdir . '.info'), true); $curMboxInfo = \OCA\fc_mail_attachments\lib\Utils::array_merge_recursive_distinct($curMboxInfo, $savedMboxInfo); } if ($mboxStatus->uidvalidity != $curMboxInfo["uidValidity"]) { $curMboxInfo["lastSeenUid"] = $curMboxInfo["historyUid"] = -1; $curMboxInfo["uidValidity"] = $mboxStatus->uidvalidity; } if ($curMboxInfo["lastSeenUid"] == -1) { $curMboxInfo["lastSeenUid"] = $mboxLastMsgUid; } if ($curMboxInfo["historyUid"] == -1) { $curMboxInfo["historyUid"] = $mboxLastMsgUid; } if ($mboxLastMsgUid != $curMboxInfo["lastSeenUid"]) { $mboxCurMsgNo = $imap->getMessageNumber($curMboxInfo["lastSeenUid"]); for ($mboxCurMsgNo, $i = 0; $mboxCurMsgNo <= $mboxLastMsgNo && $i < $this->IMAP_BATCH_LIMIT; $mboxCurMsgNo++, $i++) { $mboxCurMsgUid = $imap->getMessageUid($mboxCurMsgNo); if (!$mboxCurMsgUid) { break; } $this->saveAttachments($imap, $fs, $mboxdir, $mboxCurMsgUid); $curMboxInfo["lastSeenUid"] = $mboxCurMsgUid; } } $historyMsgNo = $imap->getMessageNumber($curMboxInfo["historyUid"]); if ($historyMsgNo > 1) { for ($i = 0; $historyMsgNo > 0 && $i < $this->IMAP_BATCH_LIMIT; $historyMsgNo--, $i++) { $historyMsgUid = $imap->getMessageUid($historyMsgNo); if (!$historyMsgUid) { break; } $this->saveAttachments($imap, $fs, $mboxdir, $historyMsgUid); $curMboxInfo["historyUid"] = $historyMsgUid; } } $fs->file_put_contents($mboxdir . '.info', json_encode($curMboxInfo)); } $imap->close(); } catch (\Exception $e) { echo "FCMA ERROR [" . $entry["user"] . "]: " . $e->getMessage(); } } }