/** * after a file is renamed/copied, rename/copy its keyfile and share-keys also fix the file size and fix also the sharing * * @param array $params array with oldpath and newpath */ public static function postRenameOrCopy($params) { if (\OCP\App::isEnabled('files_encryption') === false) { return true; } // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; $view = new \OC_FilesystemView('/'); $userId = \OCP\User::getUser(); $util = new Util($view, $userId); if (isset(self::$renamedFiles[$params['oldpath']]['uid']) && isset(self::$renamedFiles[$params['oldpath']]['path'])) { $ownerOld = self::$renamedFiles[$params['oldpath']]['uid']; $pathOld = self::$renamedFiles[$params['oldpath']]['path']; $type = self::$renamedFiles[$params['oldpath']]['type']; $operation = self::$renamedFiles[$params['oldpath']]['operation']; unset(self::$renamedFiles[$params['oldpath']]); } else { \OCP\Util::writeLog('Encryption library', "can't get path and owner from the file before it was renamed", \OCP\Util::DEBUG); \OC_FileProxy::$enabled = $proxyStatus; return false; } list($ownerNew, $pathNew) = $util->getUidAndFilename($params['newpath']); // Format paths to be relative to user files dir if ($util->isSystemWideMountPoint($pathOld)) { $oldKeyfilePath = 'files_encryption/keyfiles/' . $pathOld; $oldShareKeyPath = 'files_encryption/share-keys/' . $pathOld; } else { $oldKeyfilePath = $ownerOld . '/' . 'files_encryption/keyfiles/' . $pathOld; $oldShareKeyPath = $ownerOld . '/' . 'files_encryption/share-keys/' . $pathOld; } if ($util->isSystemWideMountPoint($pathNew)) { $newKeyfilePath = 'files_encryption/keyfiles/' . $pathNew; $newShareKeyPath = 'files_encryption/share-keys/' . $pathNew; } else { $newKeyfilePath = $ownerNew . '/files_encryption/keyfiles/' . $pathNew; $newShareKeyPath = $ownerNew . '/files_encryption/share-keys/' . $pathNew; } // add key ext if this is not an folder if ($type === 'file') { $oldKeyfilePath .= '.key'; $newKeyfilePath .= '.key'; // create destination folder if not exists $localKeyPath = $view->getLocalFile($oldShareKeyPath); $newLocalKeyPath = \OC\Files\Filesystem::normalizePath(str_replace($pathOld, $pathNew, $localKeyPath)); if (!file_exists(dirname($newLocalKeyPath))) { mkdir(dirname($newLocalKeyPath), 0750, true); } // handle share-keys $matches = Helper::findShareKeys($pathOld, $oldShareKeyPath, $view); if (count($matches) === 0) { \OC_Log::write('Encryption library', 'No share keys found for "' . $pathOld . '"', \OC_Log::WARN); } foreach ($matches as $src) { $dst = \OC\Files\Filesystem::normalizePath(str_replace($pathOld, $pathNew, $src)); $view->{$operation}($src, $dst); } } else { // handle share-keys folders // create destination folder if not exists if (!$view->file_exists(dirname($newShareKeyPath))) { mkdir($view->getLocalFile($newShareKeyPath), 0750, true); } $view->{$operation}($oldShareKeyPath, $newShareKeyPath); } // Rename keyfile so it isn't orphaned if ($view->file_exists($oldKeyfilePath)) { // create destination folder if not exists if (!$view->file_exists(dirname($newKeyfilePath))) { mkdir(dirname($view->getLocalFile($newKeyfilePath)), 0750, true); } $view->{$operation}($oldKeyfilePath, $newKeyfilePath); } // build the path to the file $newPath = '/' . $ownerNew . '/files' . $pathNew; // update sharing-keys self::updateKeyfiles($params['newpath'], $type); \OC_FileProxy::$enabled = $proxyStatus; }
/** * @brief get a list of all available versions of a file in descending chronological order * @param $filename file to find versions of, relative to the user files dir * @param $count number of versions to return * @returns array */ public static function getVersions($filename, $count = 0) { if (\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED) == 'true') { list($uid, $filename) = self::getUidAndFilename($filename); $versions_fileview = new \OC_FilesystemView('/' . $uid . '/files_versions'); $versionsName = \OCP\Config::getSystemValue('datadirectory') . $versions_fileview->getAbsolutePath($filename); $versions = array(); // fetch for old versions $matches = glob($versionsName . '.v*'); sort($matches); $i = 0; $files_view = new \OC_FilesystemView('/' . \OCP\User::getUser() . '/files'); $local_file = $files_view->getLocalFile($filename); foreach ($matches as $ma) { $i++; $versions[$i]['cur'] = 0; $parts = explode('.v', $ma); $versions[$i]['version'] = end($parts); \md5_file($ma) == \md5_file($local_file) ? $versions[$i]['fileMatch'] = 1 : ($versions[$i]['fileMatch'] = 0); } $versions = array_reverse($versions); foreach ($versions as $key => $value) { // flag the first matched file in array (which will have latest modification date) as current version if ($value['fileMatch']) { $value['cur'] = 1; break; } } $versions = array_reverse($versions); // only show the newest commits if ($count != 0 and count($versions) > $count) { $versions = array_slice($versions, count($versions) - $count); } return $versions; } else { // if versioning isn't enabled then return an empty array return array(); } }
/** * @brief after a file is renamed, rename its keyfile and share-keys also fix the file size and fix also the sharing * @param array with oldpath and newpath * * This function is connected to the rename signal of OC_Filesystem and adjust the name and location * of the stored versions along the actual file */ public static function postRename($params) { if (\OCP\App::isEnabled('files_encryption') === false) { return true; } // Disable encryption proxy to prevent recursive calls $proxyStatus = \OC_FileProxy::$enabled; \OC_FileProxy::$enabled = false; $view = new \OC_FilesystemView('/'); $session = new \OCA\Encryption\Session($view); $userId = \OCP\User::getUser(); $util = new Util($view, $userId); // Format paths to be relative to user files dir if ($util->isSystemWideMountPoint($params['oldpath'])) { $baseDir = 'files_encryption/'; $oldKeyfilePath = $baseDir . 'keyfiles/' . $params['oldpath']; } else { $baseDir = $userId . '/' . 'files_encryption/'; $oldKeyfilePath = $baseDir . 'keyfiles/' . $params['oldpath']; } if ($util->isSystemWideMountPoint($params['newpath'])) { $newKeyfilePath = $baseDir . 'keyfiles/' . $params['newpath']; } else { $newKeyfilePath = $baseDir . 'keyfiles/' . $params['newpath']; } // add key ext if this is not an folder if (!$view->is_dir($oldKeyfilePath)) { $oldKeyfilePath .= '.key'; $newKeyfilePath .= '.key'; // handle share-keys $localKeyPath = $view->getLocalFile($baseDir . 'share-keys/' . $params['oldpath']); $escapedPath = Helper::escapeGlobPattern($localKeyPath); $matches = glob($escapedPath . '*.shareKey'); foreach ($matches as $src) { $dst = \OC\Files\Filesystem::normalizePath(str_replace($params['oldpath'], $params['newpath'], $src)); // create destination folder if not exists if (!file_exists(dirname($dst))) { mkdir(dirname($dst), 0750, true); } rename($src, $dst); } } else { // handle share-keys folders $oldShareKeyfilePath = $baseDir . 'share-keys/' . $params['oldpath']; $newShareKeyfilePath = $baseDir . 'share-keys/' . $params['newpath']; // create destination folder if not exists if (!$view->file_exists(dirname($newShareKeyfilePath))) { $view->mkdir(dirname($newShareKeyfilePath), 0750, true); } $view->rename($oldShareKeyfilePath, $newShareKeyfilePath); } // Rename keyfile so it isn't orphaned if ($view->file_exists($oldKeyfilePath)) { // create destination folder if not exists if (!$view->file_exists(dirname($newKeyfilePath))) { $view->mkdir(dirname($newKeyfilePath), 0750, true); } $view->rename($oldKeyfilePath, $newKeyfilePath); } // build the path to the file $newPath = '/' . $userId . '/files' . $params['newpath']; $newPathRelative = $params['newpath']; if ($util->fixFileSize($newPath)) { // get sharing app state $sharingEnabled = \OCP\Share::isEnabled(); // get users $usersSharing = $util->getSharingUsersArray($sharingEnabled, $newPathRelative); // update sharing-keys $util->setSharedFileKeyfiles($session, $usersSharing, $newPathRelative); } \OC_FileProxy::$enabled = $proxyStatus; }
/** * @brief delete all share keys of a given file * @param \OC_FilesystemView $view * @param string $userId owner of the file * @param string $filePath path to the file, relative to the owners file dir */ public static function delAllShareKeys(\OC_FilesystemView $view, $userId, $filePath) { $util = new util($view, $userId); if ($util->isSystemWideMountPoint($filePath)) { $baseDir = '/files_encryption/share-keys/'; } else { $baseDir = $userId . '/files_encryption/share-keys/'; } if ($view->is_dir($userId . '/files/' . $filePath)) { $view->unlink($baseDir . $filePath); } else { $localKeyPath = $view->getLocalFile($baseDir . $filePath); $escapedPath = Helper::escapeGlobPattern($localKeyPath); $matches = glob($escapedPath . '*.shareKey'); foreach ($matches as $ma) { $result = unlink($ma); if (!$result) { \OCP\Util::writeLog('Encryption library', 'Keyfile or shareKey could not be deleted for file "' . $filePath . '"', \OCP\Util::ERROR); } } } }