Merge pull request #16591 from owncloud/enc_improved_error_message

improved error message for various states
This commit is contained in:
Björn Schießle 2015-05-28 10:55:53 +02:00
commit e1483f65c3
12 changed files with 136 additions and 35 deletions

View file

@ -25,8 +25,10 @@ namespace OCA\Encryption\AppInfo;
\OCP\Util::addscript('encryption', 'encryption'); \OCP\Util::addscript('encryption', 'encryption');
$app = new Application(); $encryptionSystemReady = \OC::$server->getEncryptionManager()->isReady();
if (\OC::$server->getEncryptionManager()->isReady()) {
$app = new Application([], $encryptionSystemReady);
if ($encryptionSystemReady) {
$app->registerEncryptionModule(); $app->registerEncryptionModule();
$app->registerHooks(); $app->registerHooks();
$app->registerSettings(); $app->registerSettings();

View file

@ -52,12 +52,18 @@ class Application extends \OCP\AppFramework\App {
/** /**
* @param array $urlParams * @param array $urlParams
* @param bool $encryptionSystemReady
*/ */
public function __construct($urlParams = array()) { public function __construct($urlParams = array(), $encryptionSystemReady = true) {
parent::__construct('encryption', $urlParams); parent::__construct('encryption', $urlParams);
$this->encryptionManager = \OC::$server->getEncryptionManager(); $this->encryptionManager = \OC::$server->getEncryptionManager();
$this->config = \OC::$server->getConfig(); $this->config = \OC::$server->getConfig();
$this->registerServices(); $this->registerServices();
if($encryptionSystemReady === false) {
/** @var Session $session */
$session = $this->getContainer()->query('Session');
$session->setStatus(Session::RUN_MIGRATION);
}
} }
/** /**

View file

@ -60,20 +60,29 @@ class StatusController extends Controller {
public function getStatus() { public function getStatus() {
$status = 'error'; $status = 'error';
$message = ''; $message = 'no valid init status';
switch( $this->session->getStatus()) { switch( $this->session->getStatus()) {
case Session::RUN_MIGRATION:
$status = 'interactionNeeded';
$message = (string)$this->l->t(
'You need to migrate your encryption keys from the old encryption (ownCloud <= 8.0) to the new one. Please run \'occ encryption:migrate\' or contact your administrator'
);
break;
case Session::INIT_EXECUTED: case Session::INIT_EXECUTED:
$status = 'success'; $status = 'interactionNeeded';
$message = (string)$this->l->t( $message = (string)$this->l->t(
'Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files.' 'Invalid private key for Encryption App. Please update your private key password in your personal settings to recover access to your encrypted files.'
); );
break; break;
case Session::NOT_INITIALIZED: case Session::NOT_INITIALIZED:
$status = 'success'; $status = 'interactionNeeded';
$message = (string)$this->l->t( $message = (string)$this->l->t(
'Encryption App is enabled but your keys are not initialized, please log-out and log-in again' 'Encryption App is enabled but your keys are not initialized, please log-out and log-in again'
); );
break; break;
case Session::INIT_SUCCESSFUL:
$status = 'success';
$message = (string)$this->l->t('Encryption App is enabled and ready');
} }
return new DataResponse( return new DataResponse(

View file

@ -22,7 +22,7 @@ OC.Encryption = {
$.get( $.get(
OC.generateUrl('/apps/encryption/ajax/getStatus'), OC.generateUrl('/apps/encryption/ajax/getStatus'),
function (result) { function (result) {
if (result.status === "success") { if (result.status === "interactionNeeded") {
OC.Notification.show(result.data.message); OC.Notification.show(result.data.message);
} }
} }

View file

@ -387,7 +387,7 @@ class Encryption implements IEncryptionModule {
'" is not able to read ' . $path; '" is not able to read ' . $path;
$hint = $this->l->t('Can not read this file, probably this is a shared file. Please ask the file owner to reshare the file with you.'); $hint = $this->l->t('Can not read this file, probably this is a shared file. Please ask the file owner to reshare the file with you.');
$this->logger->warning($msg); $this->logger->warning($msg);
throw new DecryptionFailedException($msg, 0, null, $hint); throw new DecryptionFailedException($msg, $hint);
} }
return false; return false;
} }

View file

@ -33,6 +33,7 @@ class Session {
const NOT_INITIALIZED = '0'; const NOT_INITIALIZED = '0';
const INIT_EXECUTED = '1'; const INIT_EXECUTED = '1';
const INIT_SUCCESSFUL = '2'; const INIT_SUCCESSFUL = '2';
const RUN_MIGRATION = '3';
/** /**
* @param ISession $session * @param ISession $session

View file

@ -0,0 +1,90 @@
<?php
/**
* @author Björn Schießle <schiessle@owncloud.com>
*
* @copyright Copyright (c) 2015, ownCloud, Inc.
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* 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, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OCA\Encryption\Tests\Controller;
use OCA\Encryption\Controller\StatusController;
use OCA\Encryption\Session;
use Test\TestCase;
class StatusControllerTest extends TestCase {
/** @var \PHPUnit_Framework_MockObject_MockObject */
protected $requestMock;
/** @var \PHPUnit_Framework_MockObject_MockObject */
protected $l10nMock;
/** @var \OCA\Encryption\Session | \PHPUnit_Framework_MockObject_MockObject */
protected $sessionMock;
/** @var StatusController */
protected $controller;
protected function setUp() {
parent::setUp();
$this->sessionMock = $this->getMockBuilder('OCA\Encryption\Session')
->disableOriginalConstructor()->getMock();
$this->requestMock = $this->getMock('OCP\IRequest');
$this->l10nMock = $this->getMockBuilder('OCP\IL10N')
->disableOriginalConstructor()->getMock();
$this->l10nMock->expects($this->any())
->method('t')
->will($this->returnCallback(function($message) {
return $message;
}));
$this->controller = new StatusController('encryptionTest',
$this->requestMock,
$this->l10nMock,
$this->sessionMock);
}
/**
* @dataProvider dataTestGetStatus
*
* @param string $status
* @param string $expectedStatus
*/
public function testGetStatus($status, $expectedStatus) {
$this->sessionMock->expects($this->once())
->method('getStatus')->willReturn($status);
$result = $this->controller->getStatus();
$data = $result->getData();
$this->assertSame($expectedStatus, $data['status']);
}
public function dataTestGetStatus() {
return array(
array(Session::RUN_MIGRATION, 'interactionNeeded'),
array(Session::INIT_EXECUTED, 'interactionNeeded'),
array(Session::INIT_SUCCESSFUL, 'success'),
array(Session::NOT_INITIALIZED, 'interactionNeeded'),
array('unknown', 'error'),
);
}
}

View file

@ -27,15 +27,4 @@ use OCP\Encryption\Exceptions\GenericEncryptionException;
class DecryptionFailedException extends GenericEncryptionException { class DecryptionFailedException extends GenericEncryptionException {
/**
* @param string $message
* @param int $code
* @param \Exception $previous
* @param string $hint
*/
public function __construct($message = '', $code = 0, \Exception $previous = null, $hint = '') {
parent::__construct($message, $code, $previous, $hint);
}
} }

View file

@ -30,6 +30,7 @@ use OCP\Encryption\IEncryptionModule;
use OCP\Encryption\IManager; use OCP\Encryption\IManager;
use OCP\Files\Mount\IMountPoint; use OCP\Files\Mount\IMountPoint;
use OCP\IConfig; use OCP\IConfig;
use OCP\IL10N;
use OCP\ILogger; use OCP\ILogger;
class Manager implements IManager { class Manager implements IManager {
@ -43,14 +44,19 @@ class Manager implements IManager {
/** @var ILogger */ /** @var ILogger */
protected $logger; protected $logger;
/** @var Il10n */
protected $l;
/** /**
* @param IConfig $config * @param IConfig $config
* @param ILogger $logger * @param ILogger $logger
* @param IL10N $l10n
*/ */
public function __construct(IConfig $config, ILogger $logger) { public function __construct(IConfig $config, ILogger $logger, IL10N $l10n) {
$this->encryptionModules = array(); $this->encryptionModules = array();
$this->config = $config; $this->config = $config;
$this->logger = $logger; $this->logger = $logger;
$this->l = $l10n;
} }
/** /**
@ -145,7 +151,8 @@ class Manager implements IManager {
return call_user_func($this->encryptionModules[$moduleId]['callback']); return call_user_func($this->encryptionModules[$moduleId]['callback']);
} else { } else {
$message = "Module with id: $moduleId does not exists."; $message = "Module with id: $moduleId does not exists.";
throw new Exceptions\ModuleDoesNotExistsException($message); $hint = $this->l->t('Module with id: %s does not exists. Please enable it in your apps settings or contact your administrator.', [$moduleId]);
throw new Exceptions\ModuleDoesNotExistsException($message, $hint);
} }
} else { } else {
return $this->getDefaultEncryptionModule(); return $this->getDefaultEncryptionModule();

View file

@ -84,7 +84,7 @@ class Server extends SimpleContainer implements IServerContainer {
}); });
$this->registerService('EncryptionManager', function (Server $c) { $this->registerService('EncryptionManager', function (Server $c) {
return new Encryption\Manager($c->getConfig(), $c->getLogger()); return new Encryption\Manager($c->getConfig(), $c->getLogger(), $c->getL10N('core'));
}); });
$this->registerService('EncryptionFileHelper', function (Server $c) { $this->registerService('EncryptionFileHelper', function (Server $c) {

View file

@ -21,6 +21,7 @@
*/ */
namespace OCP\Encryption\Exceptions; namespace OCP\Encryption\Exceptions;
use OC\HintException;
/** /**
* Class GenericEncryptionException * Class GenericEncryptionException
@ -28,28 +29,20 @@ namespace OCP\Encryption\Exceptions;
* @package OCP\Encryption\Exceptions * @package OCP\Encryption\Exceptions
* @since 8.1.0 * @since 8.1.0
*/ */
class GenericEncryptionException extends \Exception { class GenericEncryptionException extends HintException {
/** @var string */
protected $hint;
/** /**
* @param string $message * @param string $message
* @param string $hint
* @param int $code * @param int $code
* @param \Exception $previous * @param \Exception $previous
* @since 8.1.0 * @since 8.1.0
*/ */
public function __construct($message = '', $code = 0, \Exception $previous = null, $hint = '') { public function __construct($message = '', $hint = '', $code = 0, \Exception $previous = null) {
if (empty($message)) { if (empty($message)) {
$message = 'Unspecified encryption exception'; $message = 'Unspecified encryption exception';
} }
parent::__construct($message, $code, $previous); parent::__construct($message, $hint, $code, $previous);
$this->hint = $hint;
}
public function getHint() {
return $this->hint;
} }
} }

View file

@ -16,11 +16,15 @@ class ManagerTest extends TestCase {
/** @var \PHPUnit_Framework_MockObject_MockObject */ /** @var \PHPUnit_Framework_MockObject_MockObject */
private $logger; private $logger;
/** @var \PHPUnit_Framework_MockObject_MockObject */
private $l10n;
public function setUp() { public function setUp() {
parent::setUp(); parent::setUp();
$this->config = $this->getMock('\OCP\IConfig'); $this->config = $this->getMock('\OCP\IConfig');
$this->logger = $this->getMock('\OCP\ILogger'); $this->logger = $this->getMock('\OCP\ILogger');
$this->manager = new Manager($this->config, $this->logger); $this->l10n = $this->getMock('\OCP\Il10n');
$this->manager = new Manager($this->config, $this->logger, $this->l10n);
} }
public function testManagerIsDisabled() { public function testManagerIsDisabled() {