Skip to content

Commit

Permalink
Merge pull request #35961 from nextcloud/move-from-encryption-remove-…
Browse files Browse the repository at this point in the history
…flag

clear encrypted flag when moving away from encrypted storage
  • Loading branch information
szaimen authored Apr 1, 2023
2 parents 06ab4f2 + 808a80e commit 57bd5e7
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 0 deletions.
85 changes: 85 additions & 0 deletions apps/encryption/tests/EncryptedStorageTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Robin Appelman <[email protected]>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

namespace OCA\encryption\tests;

use OC\Files\Storage\Temporary;
use OC\Files\Storage\Wrapper\Encryption;
use OC\Files\View;
use OCP\Files\Mount\IMountManager;
use OCP\Files\Storage\IDisableEncryptionStorage;
use Test\TestCase;
use Test\Traits\EncryptionTrait;
use Test\Traits\MountProviderTrait;
use Test\Traits\UserTrait;

class TemporaryNoEncrypted extends Temporary implements IDisableEncryptionStorage {

}

/**
* @group DB
*/
class EncryptedStorageTest extends TestCase {
use MountProviderTrait;
use EncryptionTrait;
use UserTrait;

public function testMoveFromEncrypted() {
$this->createUser("test1", "test2");
$this->setupForUser("test1", 'test2');

$unwrapped = new Temporary();

$this->registerMount("test1", new TemporaryNoEncrypted(), "/test1/files/unenc");
$this->registerMount("test1", $unwrapped, "/test1/files/enc");

$this->loginWithEncryption("test1");

$view = new View("/test1/files");

/** @var IMountManager $mountManager */
$mountManager = \OC::$server->get(IMountManager::class);

$encryptedMount = $mountManager->find("/test1/files/enc");
$unencryptedMount = $mountManager->find("/test1/files/unenc");
$encryptedStorage = $encryptedMount->getStorage();
$unencryptedStorage = $unencryptedMount->getStorage();
$encryptedCache = $encryptedStorage->getCache();
$unencryptedCache = $unencryptedStorage->getCache();

$this->assertTrue($encryptedStorage->instanceOfStorage(Encryption::class));
$this->assertFalse($unencryptedStorage->instanceOfStorage(Encryption::class));

$encryptedStorage->file_put_contents("foo.txt", "bar");
$this->assertEquals("bar", $encryptedStorage->file_get_contents("foo.txt"));
$this->assertStringStartsWith("HBEGIN:oc_encryption_module:", $unwrapped->file_get_contents("foo.txt"));

$this->assertTrue($encryptedCache->get("foo.txt")->isEncrypted());

$view->rename("enc/foo.txt", "unenc/foo.txt");

$this->assertEquals("bar", $unencryptedStorage->file_get_contents("foo.txt"));
$this->assertFalse($unencryptedCache->get("foo.txt")->isEncrypted());
}
}
22 changes: 22 additions & 0 deletions lib/private/Files/Cache/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use OC\Files\Search\SearchComparison;
use OC\Files\Search\SearchQuery;
use OC\Files\Storage\Wrapper\Encryption;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Cache\CacheEntryInsertedEvent;
Expand Down Expand Up @@ -659,6 +660,10 @@ protected function getMoveInfo($path) {
return [$this->getNumericStorageId(), $path];
}

protected function hasEncryptionWrapper(): bool {
return $this->storage->instanceOfStorage(Encryption::class);
}

/**
* Move a file or folder in the cache
*
Expand Down Expand Up @@ -710,6 +715,11 @@ public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
->where($query->expr()->eq('storage', $query->createNamedParameter($sourceStorageId, IQueryBuilder::PARAM_INT)))
->andWhere($query->expr()->like('path', $query->createNamedParameter($this->connection->escapeLikeParameter($sourcePath) . '/%')));

// when moving from an encrypted storage to a non-encrypted storage remove the `encrypted` mark
if ($sourceCache->hasEncryptionWrapper() && !$this->hasEncryptionWrapper()) {
$query->set('encrypted', $query->createNamedParameter(0, IQueryBuilder::PARAM_INT));
}

try {
$query->execute();
} catch (\OC\DatabaseException $e) {
Expand All @@ -726,6 +736,12 @@ public function moveFromCache(ICache $sourceCache, $sourcePath, $targetPath) {
->set('name', $query->createNamedParameter(basename($targetPath)))
->set('parent', $query->createNamedParameter($newParentId, IQueryBuilder::PARAM_INT))
->whereFileId($sourceId);

// when moving from an encrypted storage to a non-encrypted storage remove the `encrypted` mark
if ($sourceCache->hasEncryptionWrapper() && !$this->hasEncryptionWrapper()) {
$query->set('encrypted', $query->createNamedParameter(0, IQueryBuilder::PARAM_INT));
}

$query->execute();

$this->connection->commit();
Expand Down Expand Up @@ -1085,6 +1101,12 @@ public function copyFromCache(ICache $sourceCache, ICacheEntry $sourceEntry, str
throw new \RuntimeException("Invalid source cache entry on copyFromCache");
}
$data = $this->cacheEntryToArray($sourceEntry);

// when moving from an encrypted storage to a non-encrypted storage remove the `encrypted` mark
if ($sourceCache instanceof Cache && $sourceCache->hasEncryptionWrapper() && !$this->hasEncryptionWrapper()) {
$data['encrypted'] = 0;
}

$fileId = $this->put($targetPath, $data);
if ($fileId <= 0) {
throw new \RuntimeException("Failed to copy to " . $targetPath . " from cache with source data " . json_encode($data) . " ");
Expand Down
9 changes: 9 additions & 0 deletions lib/private/Files/Cache/Wrapper/CacheWrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@ protected function getCache() {
return $this->cache;
}

protected function hasEncryptionWrapper(): bool {
$cache = $this->getCache();
if ($cache instanceof Cache) {
return $cache->hasEncryptionWrapper();
} else {
return false;
}
}

/**
* Make it easy for wrappers to modify every returned cache entry
*
Expand Down

0 comments on commit 57bd5e7

Please sign in to comment.