Beispiel #1
0
 /**
  * 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);
 }
Beispiel #2
0
 /**
  * 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;
     }
     $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'];
         if ('text/html' === $mimetype) {
             $doc = \Zend_Search_Lucene_Document_Html::loadHTML($view->file_get_contents($path));
         } else {
             if ('application/msword' === $mimetype) {
                 // FIXME uses ZipArchive ... make compatible with OC\Files\Filesystem
                 //$doc = Zend_Search_Lucene_Document_Docx::loadDocxFile(OC\Files\Filesystem::file_get_contents($path));
                 //no special treatment yet
                 $doc = new \Zend_Search_Lucene_Document();
             } else {
                 $doc = new \Zend_Search_Lucene_Document();
             }
         }
         // store fscacheid as unique id to lookup by when deleting
         $doc->addField(\Zend_Search_Lucene_Field::Keyword('pk', $pk));
         // Store document URL to identify it in the search results
         $doc->addField(\Zend_Search_Lucene_Field::Text('path', $path));
         $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;
     }
 }
 public static function postAvatar($args)
 {
     \OC_JSON::checkLoggedIn();
     \OC_JSON::callCheck();
     $user = \OC_User::getUser();
     if (isset($_POST['path'])) {
         $path = stripslashes($_POST['path']);
         $view = new \OC\Files\View('/' . $user . '/files');
         $newAvatar = $view->file_get_contents($path);
     } elseif (!empty($_FILES)) {
         $files = $_FILES['files'];
         if ($files['error'][0] === 0 && is_uploaded_file($files['tmp_name'][0]) && !\OC\Files\Filesystem::isFileBlacklisted($files['tmp_name'][0])) {
             $newAvatar = file_get_contents($files['tmp_name'][0]);
             unlink($files['tmp_name'][0]);
         }
     } else {
         $l = new \OC_L10n('core');
         \OC_JSON::error(array("data" => array("message" => $l->t("No image or file provided"))));
         return;
     }
     try {
         $avatar = new \OC_Avatar($user);
         $avatar->set($newAvatar);
         \OC_JSON::success();
     } catch (\OC\NotSquareException $e) {
         $image = new \OC_Image($newAvatar);
         if ($image->valid()) {
             \OC_Cache::set('tmpavatar', $image->data(), 7200);
             \OC_JSON::error(array("data" => "notsquare"));
         } else {
             $l = new \OC_L10n('core');
             $mimeType = $image->mimeType();
             if ($mimeType !== 'image/jpeg' && $mimeType !== 'image/png') {
                 \OC_JSON::error(array("data" => array("message" => $l->t("Unknown filetype"))));
             }
             if (!$image->valid()) {
                 \OC_JSON::error(array("data" => array("message" => $l->t("Invalid image"))));
             }
         }
     } catch (\Exception $e) {
         \OC_JSON::error(array("data" => array("message" => $e->getMessage())));
     }
 }
Beispiel #4
0
 /**
 <	 * Test that data that is read by the crypto stream wrapper
 */
 function testGetFileSize()
 {
     \Test_Encryption_Util::loginHelper(\Test_Encryption_Util::TEST_ENCRYPTION_UTIL_USER1);
     $filename = 'tmp-' . uniqid();
     $externalFilename = '/' . $this->userId . '/files/' . $filename;
     // Test for 0 byte files
     $problematicFileSizeData = "";
     $cryptedFile = $this->view->file_put_contents($externalFilename, $problematicFileSizeData);
     $this->assertTrue(is_int($cryptedFile));
     $this->assertEquals($this->util->getFileSize($externalFilename), 0);
     $decrypt = $this->view->file_get_contents($externalFilename);
     $this->assertEquals($problematicFileSizeData, $decrypt);
     $this->view->unlink($this->userId . '/files/' . $filename);
     // Test a file with 18377 bytes as in https://github.com/owncloud/mirall/issues/1009
     $problematicFileSizeData = str_pad("", 18377, "abc");
     $cryptedFile = $this->view->file_put_contents($externalFilename, $problematicFileSizeData);
     $this->assertTrue(is_int($cryptedFile));
     $this->assertEquals($this->util->getFileSize($externalFilename), 18377);
     $decrypt = $this->view->file_get_contents($externalFilename);
     $this->assertEquals($problematicFileSizeData, $decrypt);
     $this->view->unlink($this->userId . '/files/' . $filename);
 }
Beispiel #5
0
 public function testFilePutContentsClearsChecksum()
 {
     $storage = new Temporary(array());
     $scanner = $storage->getScanner();
     $storage->file_put_contents('foo.txt', 'bar');
     \OC\Files\Filesystem::mount($storage, array(), '/test/');
     $scanner->scan('');
     $view = new \OC\Files\View('/test/foo.txt');
     $view->putFileInfo('.', ['checksum' => '42']);
     $this->assertEquals('bar', $view->file_get_contents(''));
     $fh = tmpfile();
     fwrite($fh, 'fooo');
     rewind($fh);
     $view->file_put_contents('', $fh);
     $this->assertEquals('fooo', $view->file_get_contents(''));
     $data = $view->getFileInfo('.');
     $this->assertEquals('', $data->getChecksum());
 }
Beispiel #6
0
 /**
  * @medium
  */
 function testTouchFile()
 {
     $filename = '/tmp-' . uniqid();
     $view = new \OC\Files\View('/' . $this->userId . '/files');
     $view->touch($filename);
     // Save short data as encrypted file using stream wrapper
     $cryptedFile = $view->file_put_contents($filename, $this->dataShort);
     // Test that data was successfully written
     $this->assertTrue(is_int($cryptedFile));
     // Get file decrypted contents
     $decrypt = $view->file_get_contents($filename);
     $this->assertEquals($this->dataShort, $decrypt);
     // tear down
     $view->unlink($filename);
 }
Beispiel #7
0
 /**
  * @param string $path
  * @param string $data
  * @return bool
  */
 public function preFile_put_contents($path, &$data)
 {
     if ($this->shouldEncrypt($path)) {
         if (!is_resource($data)) {
             // get root view
             $view = new \OC\Files\View('/');
             // get relative path
             $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path);
             if (!isset($relativePath)) {
                 return true;
             }
             // create random cache folder
             $cacheFolder = rand();
             $path_slices = explode('/', \OC\Files\Filesystem::normalizePath($path));
             $path_slices[2] = "cache/" . $cacheFolder;
             $tmpPath = implode('/', $path_slices);
             $handle = fopen('crypt://' . $tmpPath, 'w');
             if (is_resource($handle)) {
                 // write data to stream
                 fwrite($handle, $data);
                 // close stream
                 fclose($handle);
                 // disable encryption proxy to prevent recursive calls
                 $proxyStatus = \OC_FileProxy::$enabled;
                 \OC_FileProxy::$enabled = false;
                 // get encrypted content
                 $data = $view->file_get_contents($tmpPath);
                 // store new unenecrypted size so that it can be updated
                 // in the post proxy
                 $tmpFileInfo = $view->getFileInfo($tmpPath);
                 if (isset($tmpFileInfo['unencrypted_size'])) {
                     self::$unencryptedSizes[\OC\Files\Filesystem::normalizePath($path)] = $tmpFileInfo['unencrypted_size'];
                 }
                 // remove our temp file
                 $view->deleteAll('/' . \OCP\User::getUser() . '/cache/' . $cacheFolder);
                 // re-enable proxy - our work is done
                 \OC_FileProxy::$enabled = $proxyStatus;
             } else {
                 return false;
             }
         }
     }
     return true;
 }
Beispiel #8
0
 /**
  * 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;
     }
 }
Beispiel #9
0
    $root = \OC\Files\Filesystem::getPath($linkItem['file_source']) . '/';
    $images = array_map(function ($image) use($root) {
        return $root . $image;
    }, $images);
} else {
    $root = '';
    OCP\JSON::checkLoggedIn();
    $user = OCP\User::getUser();
}
session_write_close();
$eventSource = new OC_EventSource();
foreach ($images as $image) {
    $height = 200 * $scale;
    if ($square) {
        $width = 200 * $scale;
    } else {
        $width = 400 * $scale;
    }
    $userView = new \OC\Files\View('/' . $user);
    $preview = new \OC\Preview($user, 'files', '/' . $image, $width, $height);
    $preview->setKeepAspect(!$square);
    $fileInfo = $userView->getFileInfo('/files/' . $image);
    // if the thumbnails is already cached, get it directly from the filesystem to avoid decoding and re-encoding the image
    $imageName = substr($image, strlen($root));
    if ($path = $preview->isCached($fileInfo->getId())) {
        $eventSource->send('preview', array('image' => $imageName, 'preview' => base64_encode($userView->file_get_contents('/' . $path))));
    } else {
        $eventSource->send('preview', array('image' => $imageName, 'preview' => (string) $preview->getPreview()));
    }
}
$eventSource->close();
Beispiel #10
0
 public function testFileView()
 {
     $storage = new Temporary(array());
     $scanner = $storage->getScanner();
     $storage->file_put_contents('foo.txt', 'bar');
     \OC\Files\Filesystem::mount($storage, array(), '/test/');
     $scanner->scan('');
     $view = new \OC\Files\View('/test/foo.txt');
     $this->assertEquals('bar', $view->file_get_contents(''));
     $fh = tmpfile();
     fwrite($fh, 'foo');
     rewind($fh);
     $view->file_put_contents('', $fh);
     $this->assertEquals('foo', $view->file_get_contents(''));
 }
Beispiel #11
0
 function testDownloadVersions()
 {
     // login as admin
     self::loginHelper(self::TEST_ENCRYPTION_SHARE_USER1);
     $rootView = new \OC\Files\View();
     // save file twice to create a new version
     \OC\Files\Filesystem::file_put_contents($this->filename, "revision1");
     \OCA\Files_Versions\Storage::store($this->filename);
     \OC\Files\Filesystem::file_put_contents($this->filename, "revision2");
     // check if the owner can retrieve the correct version
     $versions = \OCA\Files_Versions\Storage::getVersions(self::TEST_ENCRYPTION_SHARE_USER1, $this->filename);
     $this->assertSame(1, count($versions));
     $version = reset($versions);
     $versionUser1 = $rootView->file_get_contents('/' . self::TEST_ENCRYPTION_SHARE_USER1 . '/files_versions/' . $this->filename . '.v' . $version['version']);
     $this->assertSame('revision1', $versionUser1);
     // share the file
     $fileInfo = \OC\Files\Filesystem::getFileInfo($this->filename);
     $this->assertInstanceOf('\\OC\\Files\\FileInfo', $fileInfo);
     $this->assertTrue(\OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_ENCRYPTION_SHARE_USER2, \OCP\Constants::PERMISSION_ALL));
     // try to download the version as user2
     self::loginHelper(self::TEST_ENCRYPTION_SHARE_USER2);
     $versionUser2 = $rootView->file_get_contents('/' . self::TEST_ENCRYPTION_SHARE_USER1 . '/files_versions/' . $this->filename . '.v' . $version['version']);
     $this->assertSame('revision1', $versionUser2);
     //cleanup
     self::loginHelper(self::TEST_ENCRYPTION_SHARE_USER1);
     \OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_ENCRYPTION_SHARE_USER2);
     \OC\Files\Filesystem::unlink($this->filename);
 }
 */
use OCA\Encryption;
\OCP\JSON::checkLoggedIn();
\OCP\JSON::checkAppEnabled('files_encryption');
\OCP\JSON::callCheck();
$l = \OC::$server->getL10N('core');
$return = false;
$oldPassword = $_POST['oldPassword'];
$newPassword = $_POST['newPassword'];
$view = new \OC\Files\View('/');
$session = new \OCA\Encryption\Session($view);
$user = \OCP\User::getUser();
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
$keyPath = '/' . $user . '/files_encryption/' . $user . '.private.key';
$encryptedKey = $view->file_get_contents($keyPath);
$decryptedKey = \OCA\Encryption\Crypt::decryptPrivateKey($encryptedKey, $oldPassword);
if ($decryptedKey) {
    $cipher = \OCA\Encryption\Helper::getCipher();
    $encryptedKey = \OCA\Encryption\Crypt::symmetricEncryptFileContent($decryptedKey, $newPassword, $cipher);
    if ($encryptedKey) {
        \OCA\Encryption\Keymanager::setPrivateKey($encryptedKey, $user);
        $session->setPrivateKey($decryptedKey);
        $return = true;
    }
}
\OC_FileProxy::$enabled = $proxyStatus;
// success or failure
if ($return) {
    $session->setInitialized(\OCA\Encryption\Session::INIT_SUCCESSFUL);
    \OCP\JSON::success(array('data' => array('message' => $l->t('Private key password successfully updated.'))));
    $errorMessage = $l->t('Please repeat the new recovery password');
    \OCP\JSON::error(array('data' => array('message' => $errorMessage)));
    exit;
}
if ($_POST['newPassword'] !== $_POST['confirmPassword']) {
    $errorMessage = $l->t('Repeated recovery key password does not match the provided recovery key password');
    \OCP\JSON::error(array('data' => array('message' => $errorMessage)));
    exit;
}
$view = new \OC\Files\View('/');
$util = new \OCA\Encryption\Util(new \OC\Files\View('/'), \OCP\User::getUser());
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
$keyId = $util->getRecoveryKeyId();
$keyPath = '/owncloud_private_key/' . $keyId . '.private.key';
$encryptedRecoveryKey = $view->file_get_contents($keyPath);
$decryptedRecoveryKey = \OCA\Encryption\Crypt::decryptPrivateKey($encryptedRecoveryKey, $oldPassword);
if ($decryptedRecoveryKey) {
    $cipher = \OCA\Encryption\Helper::getCipher();
    $encryptedKey = \OCA\Encryption\Crypt::symmetricEncryptFileContent($decryptedRecoveryKey, $newPassword, $cipher);
    if ($encryptedKey) {
        \OCA\Encryption\Keymanager::setPrivateSystemKey($encryptedKey, $keyId . '.private.key');
        $return = true;
    }
}
\OC_FileProxy::$enabled = $proxyStatus;
// success or failure
if ($return) {
    \OCP\JSON::success(array('data' => array('message' => $l->t('Password successfully changed.'))));
} else {
    \OCP\JSON::error(array('data' => array('message' => $l->t('Could not change the password. Maybe the old password was not correct.'))));
Beispiel #14
0
 /**
  * Startup encryption backend upon user login
  * @note This method should never be called for users using client side encryption
  */
 public static function login($params)
 {
     if (\OCP\App::isEnabled('files_encryption') === false) {
         return true;
     }
     $l = new \OC_L10N('files_encryption');
     $view = new \OC\Files\View('/');
     // ensure filesystem is loaded
     if (!\OC\Files\Filesystem::$loaded) {
         \OC_Util::setupFS($params['uid']);
     }
     $privateKey = \OCA\Encryption\Keymanager::getPrivateKey($view, $params['uid']);
     // if no private key exists, check server configuration
     if (!$privateKey) {
         //check if all requirements are met
         if (!Helper::checkRequirements() || !Helper::checkConfiguration()) {
             $error_msg = $l->t("Missing requirements.");
             $hint = $l->t('Please make sure that PHP 5.3.3 or newer is installed and that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled.');
             \OC_App::disable('files_encryption');
             \OCP\Util::writeLog('Encryption library', $error_msg . ' ' . $hint, \OCP\Util::ERROR);
             \OCP\Template::printErrorPage($error_msg, $hint);
         }
     }
     $util = new Util($view, $params['uid']);
     // setup user, if user not ready force relogin
     if (Helper::setupUser($util, $params['password']) === false) {
         return false;
     }
     $session = $util->initEncryption($params);
     // Check if first-run file migration has already been performed
     $ready = false;
     $migrationStatus = $util->getMigrationStatus();
     if ($migrationStatus === Util::MIGRATION_OPEN && $session !== false) {
         $ready = $util->beginMigration();
     } elseif ($migrationStatus === Util::MIGRATION_IN_PROGRESS) {
         // refuse login as long as the initial encryption is running
         sleep(5);
         \OCP\User::logout();
         return false;
     }
     $result = true;
     // If migration not yet done
     if ($ready) {
         $userView = new \OC\Files\View('/' . $params['uid']);
         // Set legacy encryption key if it exists, to support
         // depreciated encryption system
         if ($userView->file_exists('encryption.key')) {
             $encLegacyKey = $userView->file_get_contents('encryption.key');
             if ($encLegacyKey) {
                 $plainLegacyKey = Crypt::legacyDecrypt($encLegacyKey, $params['password']);
                 $session->setLegacyKey($plainLegacyKey);
             }
         }
         // Encrypt existing user files
         try {
             $result = $util->encryptAll('/' . $params['uid'] . '/' . 'files', $session->getLegacyKey(), $params['password']);
         } catch (\Exception $ex) {
             \OCP\Util::writeLog('Encryption library', 'Initial encryption failed! Error: ' . $ex->getMessage(), \OCP\Util::FATAL);
             $result = false;
         }
         if ($result) {
             \OC_Log::write('Encryption library', 'Encryption of existing files belonging to "' . $params['uid'] . '" completed', \OC_Log::INFO);
             // Register successful migration in DB
             $util->finishMigration();
         } else {
             \OCP\Util::writeLog('Encryption library', 'Initial encryption failed!', \OCP\Util::FATAL);
             $util->resetMigrationStatus();
             \OCP\User::logout();
         }
     }
     return $result;
 }
 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();
         }
     }
 }