improved rename and file size support

fix missing user_id on write
This commit is contained in:
Florin Peter 2013-04-22 04:40:49 +02:00
parent 9a0b73070c
commit 6b47da10be
2 changed files with 115 additions and 90 deletions

View File

@ -288,30 +288,46 @@ class Proxy extends \OC_FileProxy {
* @return bool Result of rename() * @return bool Result of rename()
* @note This is pre rather than post because using post didn't work * @note This is pre rather than post because using post didn't work
*/ */
public function preRename( $oldPath, $newPath ) { public function preRename( $oldPath, $newPath )
{
// Disable encryption proxy to prevent recursive calls // Disable encryption proxy to prevent recursive calls
\OC_FileProxy::$enabled = false; \OC_FileProxy::$enabled = false;
$view = new \OC_FilesystemView( '/' ); $view = new \OC_FilesystemView('/');
$userId = \OCP\USER::getUser(); $userId = \OCP\USER::getUser();
// Format paths to be relative to user files dir // Format paths to be relative to user files dir
$oldTrimmed = ltrim( $oldPath, '/' ); $oldTrimmed = ltrim($oldPath, '/');
$oldSplit = explode( '/', $oldTrimmed ); $oldSplit = explode('/', $oldTrimmed);
$oldSliced = array_slice( $oldSplit, 2 ); $oldSliced = array_slice($oldSplit, 2);
$oldRelPath = implode( '/', $oldSliced ); $oldRelPath = implode('/', $oldSliced);
$oldKeyfilePath = $userId . '/' . 'files_encryption' . '/' . 'keyfiles' . '/' . $oldRelPath . '.key'; $oldKeyfilePath = $userId . '/' . 'files_encryption' . '/' . 'keyfiles' . '/' . $oldRelPath;
$newTrimmed = ltrim( $newPath, '/' );
$newSplit = explode( '/', $newTrimmed ); $newTrimmed = ltrim($newPath, '/');
$newSliced = array_slice( $newSplit, 2 ); $newSplit = explode('/', $newTrimmed);
$newRelPath = implode( '/', $newSliced ); $newSliced = array_slice($newSplit, 2);
$newKeyfilePath = $userId . '/' . 'files_encryption' . '/' . 'keyfiles' . '/' . $newRelPath . '.key'; $newRelPath = implode('/', $newSliced);
$newKeyfilePath = $userId . '/' . 'files_encryption' . '/' . 'keyfiles' . '/' . $newRelPath;
// add key ext if this is not an folder
if (!$view->is_dir($oldKeyfilePath)) {
$oldKeyfilePath .= '.key';
$newKeyfilePath .= '.key';
} else {
// handle share-keys folders
$oldShareKeyfilePath = $userId . '/' . 'files_encryption' . '/' . 'share-keys' . '/' . $oldRelPath;
$newShareKeyfilePath = $userId . '/' . 'files_encryption' . '/' . 'share-keys' . '/' . $newRelPath;
$view->rename($oldShareKeyfilePath, $newShareKeyfilePath);
}
//TODO add support for share-keys files
//...
// Rename keyfile so it isn't orphaned // Rename keyfile so it isn't orphaned
$result = $view->rename( $oldKeyfilePath, $newKeyfilePath ); $result = $view->rename($oldKeyfilePath, $newKeyfilePath);
\OC_FileProxy::$enabled = true; \OC_FileProxy::$enabled = true;
@ -423,40 +439,46 @@ class Proxy extends \OC_FileProxy {
public function postFileSize( $path, $size ) { public function postFileSize( $path, $size ) {
// Reformat path for use with OC_FSV // Reformat path for use with OC_FSV
$path_split = explode( '/', $path ); $path_split = explode('/', $path);
$path_f = implode( '/', array_slice( $path_split, 3 ) ); $path_f = implode('/', array_slice($path_split, 3));
if ( Crypt::isEncryptedMeta( $path_f ) ) { $view = new \OC_FilesystemView( '/' );
$userId = \OCP\User::getUser();
$util = new Util( $view, $userId );
if ($util->isEncryptedPath($path)) {
// Disable encryption proxy to prevent recursive calls // Disable encryption proxy to prevent recursive calls
\OC_FileProxy::$enabled = false; \OC_FileProxy::$enabled = false;
// get file info // get file info
$cached = \OC\Files\Filesystem::getFileInfo( $path_f, '' ); $cached = \OC\Files\Filesystem::getFileInfo($path_f, '');
// calculate last chunk nr // calculate last chunk nr
$lastChunckNr = floor( $size / 8192); $lastChunckNr = floor($size / 8192);
// open stream // open stream
$result = fopen( 'crypt://'.$path_f, "r" ); $result = fopen('crypt://' . $path_f, "r");
if(is_resource($result)) {
// calculate last chunk position // calculate last chunk position
$lastChunckPos = ( $lastChunckNr * 8192 ); $lastChunckPos = ($lastChunckNr * 8192);
// seek to end // seek to end
fseek( $result, $lastChunckPos ); fseek($result, $lastChunckPos);
// get the content of the last chunck // get the content of the last chunck
$lastChunkContent = fgets( $result ); $lastChunkContent = fgets($result);
// calc the real filesize with the size of the last chunk // calc the real file size with the size of the last chunk
$realSize = ( ( $lastChunckNr * 6126 ) + strlen( $lastChunkContent ) ); $realSize = (($lastChunckNr * 6126) + strlen($lastChunkContent));
// enable proxy
\OC_FileProxy::$enabled = true;
// set the size // set the size
$cached['size'] = $realSize; $cached['size'] = $realSize;
}
// enable proxy
\OC_FileProxy::$enabled = true;
return $cached['size']; return $cached['size'];

View File

@ -101,6 +101,9 @@ class Stream {
} else { } else {
// Disable fileproxies so we can get the file size and open the source file without recursive encryption
\OC_FileProxy::$enabled = false;
if ( if (
$mode == 'w' $mode == 'w'
or $mode == 'w+' or $mode == 'w+'
@ -119,9 +122,6 @@ class Stream {
} }
// Disable fileproxies so we can open the source file without recursive encryption
\OC_FileProxy::$enabled = false;
//$this->handle = fopen( $this->rawPath, $mode ); //$this->handle = fopen( $this->rawPath, $mode );
$this->handle = $this->rootView->fopen( $this->rawPath, $mode ); $this->handle = $this->rootView->fopen( $this->rawPath, $mode );
@ -241,13 +241,12 @@ class Stream {
// Avoid problems with .part file extensions // Avoid problems with .part file extensions
$this->relPath = Keymanager::fixPartialFilePath( $this->relPath ); $this->relPath = Keymanager::fixPartialFilePath( $this->relPath );
// If a keyfile already exists
if ( $this->rootView->file_exists( $this->userId . '/'. 'files_encryption' . '/' . 'keyfiles' . '/' . $this->relPath . '.key' ) ) {
// Fetch and decrypt keyfile // Fetch and decrypt keyfile
// Fetch existing keyfile // Fetch existing keyfile
$this->encKeyfile = Keymanager::getFileKey( $this->rootView, $this->userId, $this->relPath ); $this->encKeyfile = Keymanager::getFileKey( $this->rootView, $this->userId, $this->relPath );
// If a keyfile already exists
if ( $this->encKeyfile ) {
$this->setUserProperty(); $this->setUserProperty();
$session = new Session( $this->rootView ); $session = new Session( $this->rootView );
@ -339,6 +338,10 @@ class Stream {
// Get all users sharing the file // Get all users sharing the file
$uniqueUserIds = $util->getSharingUsersArray( $sharingEnabled, $this->relPath ); $uniqueUserIds = $util->getSharingUsersArray( $sharingEnabled, $this->relPath );
// allways add current user
$uniqueUserIds[] = $this->userId;
array_unique( $uniqueUserIds );
// Fetch public keys for all sharing users // Fetch public keys for all sharing users
$publicKeys = Keymanager::getPublicKeys( $this->rootView, $uniqueUserIds ); $publicKeys = Keymanager::getPublicKeys( $this->rootView, $uniqueUserIds );
@ -429,7 +432,7 @@ class Stream {
$encrypted = $this->preWriteEncrypt( $chunk, $this->plainKey ); $encrypted = $this->preWriteEncrypt( $chunk, $this->plainKey );
trigger_error("\$encrypted = $encrypted"); //trigger_error("\$encrypted = $encrypted");
// Write the data chunk to disk. This will be // Write the data chunk to disk. This will be
// attended to the last data chunk if the file // attended to the last data chunk if the file