Skip to content
Snippets Groups Projects
Unverified Commit e0ae3774 authored by Julius Härtl's avatar Julius Härtl
Browse files

Do not expose direct editing if no master key is available


Signed-off-by: default avatarJulius Härtl <jus@bitgrid.net>
parent 823f94bb
No related branches found
No related tags found
No related merge requests found
...@@ -76,6 +76,9 @@ class DirectEditingController extends OCSController { ...@@ -76,6 +76,9 @@ class DirectEditingController extends OCSController {
* @NoAdminRequired * @NoAdminRequired
*/ */
public function create(string $path, string $editorId, string $creatorId, string $templateId = null): DataResponse { public function create(string $path, string $editorId, string $creatorId, string $templateId = null): DataResponse {
if (!$this->directEditingManager->isEnabled()) {
return new DataResponse(['message' => 'Direct editing is not enabled'], Http::STATUS_INTERNAL_SERVER_ERROR);
}
$this->eventDispatcher->dispatchTyped(new RegisterDirectEditorEvent($this->directEditingManager)); $this->eventDispatcher->dispatchTyped(new RegisterDirectEditorEvent($this->directEditingManager));
try { try {
...@@ -85,7 +88,7 @@ class DirectEditingController extends OCSController { ...@@ -85,7 +88,7 @@ class DirectEditingController extends OCSController {
]); ]);
} catch (Exception $e) { } catch (Exception $e) {
$this->logger->logException($e, ['message' => 'Exception when creating a new file through direct editing']); $this->logger->logException($e, ['message' => 'Exception when creating a new file through direct editing']);
return new DataResponse('Failed to create file: ' . $e->getMessage(), Http::STATUS_FORBIDDEN); return new DataResponse(['message' => 'Failed to create file: ' . $e->getMessage()], Http::STATUS_FORBIDDEN);
} }
} }
...@@ -93,6 +96,9 @@ class DirectEditingController extends OCSController { ...@@ -93,6 +96,9 @@ class DirectEditingController extends OCSController {
* @NoAdminRequired * @NoAdminRequired
*/ */
public function open(string $path, string $editorId = null): DataResponse { public function open(string $path, string $editorId = null): DataResponse {
if (!$this->directEditingManager->isEnabled()) {
return new DataResponse(['message' => 'Direct editing is not enabled'], Http::STATUS_INTERNAL_SERVER_ERROR);
}
$this->eventDispatcher->dispatchTyped(new RegisterDirectEditorEvent($this->directEditingManager)); $this->eventDispatcher->dispatchTyped(new RegisterDirectEditorEvent($this->directEditingManager));
try { try {
...@@ -102,7 +108,7 @@ class DirectEditingController extends OCSController { ...@@ -102,7 +108,7 @@ class DirectEditingController extends OCSController {
]); ]);
} catch (Exception $e) { } catch (Exception $e) {
$this->logger->logException($e, ['message' => 'Exception when opening a file through direct editing']); $this->logger->logException($e, ['message' => 'Exception when opening a file through direct editing']);
return new DataResponse('Failed to open file: ' . $e->getMessage(), Http::STATUS_FORBIDDEN); return new DataResponse(['message' => 'Failed to open file: ' . $e->getMessage()], Http::STATUS_FORBIDDEN);
} }
} }
...@@ -112,13 +118,16 @@ class DirectEditingController extends OCSController { ...@@ -112,13 +118,16 @@ class DirectEditingController extends OCSController {
* @NoAdminRequired * @NoAdminRequired
*/ */
public function templates(string $editorId, string $creatorId): DataResponse { public function templates(string $editorId, string $creatorId): DataResponse {
if (!$this->directEditingManager->isEnabled()) {
return new DataResponse(['message' => 'Direct editing is not enabled'], Http::STATUS_INTERNAL_SERVER_ERROR);
}
$this->eventDispatcher->dispatchTyped(new RegisterDirectEditorEvent($this->directEditingManager)); $this->eventDispatcher->dispatchTyped(new RegisterDirectEditorEvent($this->directEditingManager));
try { try {
return new DataResponse($this->directEditingManager->getTemplates($editorId, $creatorId)); return new DataResponse($this->directEditingManager->getTemplates($editorId, $creatorId));
} catch (Exception $e) { } catch (Exception $e) {
$this->logger->logException($e); $this->logger->logException($e);
return new DataResponse('Failed to obtain template list: ' . $e->getMessage(), Http::STATUS_INTERNAL_SERVER_ERROR); return new DataResponse(['message' => 'Failed to obtain template list: ' . $e->getMessage()], Http::STATUS_INTERNAL_SERVER_ERROR);
} }
} }
} }
...@@ -55,6 +55,10 @@ class DirectEditingService { ...@@ -55,6 +55,10 @@ class DirectEditingService {
'creators' => [] 'creators' => []
]; ];
if (!$this->directEditingManager->isEnabled()) {
return $capabilities;
}
/** /**
* @var string $id * @var string $id
* @var IEditor $editor * @var IEditor $editor
......
...@@ -35,6 +35,7 @@ use OCP\DirectEditing\ACreateFromTemplate; ...@@ -35,6 +35,7 @@ use OCP\DirectEditing\ACreateFromTemplate;
use OCP\DirectEditing\IEditor; use OCP\DirectEditing\IEditor;
use \OCP\DirectEditing\IManager; use \OCP\DirectEditing\IManager;
use OCP\DirectEditing\IToken; use OCP\DirectEditing\IToken;
use OCP\Encryption\IManager as EncryptionManager;
use OCP\Files\File; use OCP\Files\File;
use OCP\Files\IRootFolder; use OCP\Files\IRootFolder;
use OCP\Files\Node; use OCP\Files\Node;
...@@ -45,6 +46,7 @@ use OCP\IUserSession; ...@@ -45,6 +46,7 @@ use OCP\IUserSession;
use OCP\L10N\IFactory; use OCP\L10N\IFactory;
use OCP\Security\ISecureRandom; use OCP\Security\ISecureRandom;
use OCP\Share\IShare; use OCP\Share\IShare;
use Throwable;
use function array_key_exists; use function array_key_exists;
use function in_array; use function in_array;
...@@ -55,30 +57,33 @@ class Manager implements IManager { ...@@ -55,30 +57,33 @@ class Manager implements IManager {
/** @var IEditor[] */ /** @var IEditor[] */
private $editors = []; private $editors = [];
/** @var IDBConnection */ /** @var IDBConnection */
private $connection; private $connection;
/** /** @var ISecureRandom */
* @var ISecureRandom
*/
private $random; private $random;
/** @var string|null */
private $userId; private $userId;
/** @var IRootFolder */
private $rootFolder; private $rootFolder;
/** @var IL10N */ /** @var IL10N */
private $l10n; private $l10n;
/** @var EncryptionManager */
private $encryptionManager;
public function __construct( public function __construct(
ISecureRandom $random, ISecureRandom $random,
IDBConnection $connection, IDBConnection $connection,
IUserSession $userSession, IUserSession $userSession,
IRootFolder $rootFolder, IRootFolder $rootFolder,
IFactory $l10nFactory IFactory $l10nFactory,
EncryptionManager $encryptionManager
) { ) {
$this->random = $random; $this->random = $random;
$this->connection = $connection; $this->connection = $connection;
$this->userId = $userSession->getUser() ? $userSession->getUser()->getUID() : null; $this->userId = $userSession->getUser() ? $userSession->getUser()->getUID() : null;
$this->rootFolder = $rootFolder; $this->rootFolder = $rootFolder;
$this->l10n = $l10nFactory->get('core'); $this->l10n = $l10nFactory->get('core');
$this->encryptionManager = $encryptionManager;
} }
public function registerDirectEditor(IEditor $directEditor): void { public function registerDirectEditor(IEditor $directEditor): void {
...@@ -171,7 +176,7 @@ class Manager implements IManager { ...@@ -171,7 +176,7 @@ class Manager implements IManager {
} }
$editor = $this->getEditor($tokenObject->getEditor()); $editor = $this->getEditor($tokenObject->getEditor());
$this->accessToken($token); $this->accessToken($token);
} catch (\Throwable $throwable) { } catch (Throwable $throwable) {
$this->invalidateToken($token); $this->invalidateToken($token);
return new NotFoundResponse(); return new NotFoundResponse();
} }
...@@ -275,4 +280,22 @@ class Manager implements IManager { ...@@ -275,4 +280,22 @@ class Manager implements IManager {
} }
return $files[0]; return $files[0];
} }
public function isEnabled(): bool {
if (!$this->encryptionManager->isEnabled()) {
return true;
}
try {
$moduleId = $this->encryptionManager->getDefaultEncryptionModuleId();
$module = $this->encryptionManager->getEncryptionModule($moduleId);
/** @var \OCA\Encryption\Util $util */
$util = \OC::$server->get(\OCA\Encryption\Util::class);
if ($module->isReadyForUser($this->userId) && $util->isMasterKeyEnabled()) {
return true;
}
} catch (Throwable $e) {
}
return false;
}
} }
...@@ -84,4 +84,12 @@ interface IManager { ...@@ -84,4 +84,12 @@ interface IManager {
* @return int number of deleted tokens * @return int number of deleted tokens
*/ */
public function cleanup(): int; public function cleanup(): int;
/**
* Check if direct editing is enabled
*
* @since 20.0.0
* @return bool
*/
public function isEnabled(): bool;
} }
...@@ -10,6 +10,7 @@ use OCP\AppFramework\Http\Response; ...@@ -10,6 +10,7 @@ use OCP\AppFramework\Http\Response;
use OCP\DirectEditing\ACreateEmpty; use OCP\DirectEditing\ACreateEmpty;
use OCP\DirectEditing\IEditor; use OCP\DirectEditing\IEditor;
use OCP\DirectEditing\IToken; use OCP\DirectEditing\IToken;
use OCP\Encryption\IManager;
use OCP\Files\Folder; use OCP\Files\Folder;
use OCP\Files\IRootFolder; use OCP\Files\IRootFolder;
use OCP\IDBConnection; use OCP\IDBConnection;
...@@ -104,6 +105,10 @@ class ManagerTest extends TestCase { ...@@ -104,6 +105,10 @@ class ManagerTest extends TestCase {
* @var MockObject|Folder * @var MockObject|Folder
*/ */
private $userFolder; private $userFolder;
/**
* @var MockObject|IManager
*/
private $encryptionManager;
protected function setUp(): void { protected function setUp(): void {
parent::setUp(); parent::setUp();
...@@ -116,6 +121,7 @@ class ManagerTest extends TestCase { ...@@ -116,6 +121,7 @@ class ManagerTest extends TestCase {
$this->rootFolder = $this->createMock(IRootFolder::class); $this->rootFolder = $this->createMock(IRootFolder::class);
$this->userFolder = $this->createMock(Folder::class); $this->userFolder = $this->createMock(Folder::class);
$this->l10n = $this->createMock(IL10N::class); $this->l10n = $this->createMock(IL10N::class);
$this->encryptionManager = $this->createMock(IManager::class);
$l10nFactory = $this->createMock(IFactory::class); $l10nFactory = $this->createMock(IFactory::class);
$l10nFactory->expects($this->once()) $l10nFactory->expects($this->once())
...@@ -128,7 +134,7 @@ class ManagerTest extends TestCase { ...@@ -128,7 +134,7 @@ class ManagerTest extends TestCase {
->willReturn($this->userFolder); ->willReturn($this->userFolder);
$this->manager = new Manager( $this->manager = new Manager(
$this->random, $this->connection, $this->userSession, $this->rootFolder, $l10nFactory $this->random, $this->connection, $this->userSession, $this->rootFolder, $l10nFactory, $this->encryptionManager
); );
$this->manager->registerDirectEditor($this->editor); $this->manager->registerDirectEditor($this->editor);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment