Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[stable10] Backport of Fix login exception in decryptall #31986

Merged
merged 1 commit into from
Jul 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/encryption/lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ function (IAppContainer $c) {
$c->query('KeyManager'),
$c->query('Crypt'),
$c->query('Session'),
$c->getServer()->getUserManager(),
new QuestionHelper()
);
}
Expand Down
29 changes: 29 additions & 0 deletions apps/encryption/lib/Crypto/DecryptAll.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@
namespace OCA\Encryption\Crypto;


use OC\User\LoginException;
use OCA\Encryption\KeyManager;
use OCA\Encryption\Session;
use OCA\Encryption\Util;
use OCP\IUserManager;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
Expand All @@ -49,6 +51,9 @@ class DecryptAll {
/** @var Session */
protected $session;

/** @var IUserManager */
protected $userManager;

/**
* @param Util $util
* @param KeyManager $keyManager
Expand All @@ -61,22 +66,28 @@ public function __construct(
KeyManager $keyManager,
Crypt $crypt,
Session $session,
IUserManager $userManager,
QuestionHelper $questionHelper
) {
$this->util = $util;
$this->keyManager = $keyManager;
$this->crypt = $crypt;
$this->session = $session;
$this->userManager = $userManager;
$this->questionHelper = $questionHelper;
}

/**
* prepare encryption module to decrypt all files
*
* - Throws LoginException when user login fails either recovery password fails
* or if the user password fails
*
* @param InputInterface $input
* @param OutputInterface $output
* @param $user
* @return bool
* @throws LoginException
*/
public function prepare(InputInterface $input, OutputInterface $output, $user) {

Expand Down Expand Up @@ -115,6 +126,24 @@ public function prepare(InputInterface $input, OutputInterface $output, $user) {
$question->setHidden(true);
$question->setHiddenFallback(false);
$password = $this->questionHelper->ask($input, $output, $question);


$throwLoginException = false;
if ($recoveryKeyId === $user) {
try {
if ($this->keyManager->checkRecoveryPassword($password) === false) {
$throwLoginException = true;
}
} catch (\Exception $e) {
$throwLoginException = true;
}
} elseif ($this->userManager->checkPassword($user, $password) === false) {
$throwLoginException = true;
}

if ($throwLoginException === true) {
throw new LoginException('Invalid credentials provided');
}
}

$privateKey = $this->getPrivateKey($user, $password);
Expand Down
64 changes: 64 additions & 0 deletions apps/encryption/tests/Crypto/DecryptAllTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,27 @@
namespace OCA\Encryption\Tests\Crypto;


use OC\User\LoginException;
use OCA\Encryption\Crypto\Crypt;
use OCA\Encryption\Crypto\DecryptAll;
use OCA\Encryption\KeyManager;
use OCA\Encryption\Session;
use OCA\Encryption\Util;
use OCP\IUserManager;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Test\TestCase;
use Test\Traits\UserTrait;

/**
* Class DecryptAllTest
*
* @group DB
* @package OCA\Encryption\Tests\Crypto
*/
class DecryptAllTest extends TestCase {
use UserTrait;

/** @var DecryptAll */
protected $instance;
Expand All @@ -49,6 +61,8 @@ class DecryptAllTest extends TestCase {
/** @var Session | \PHPUnit_Framework_MockObject_MockObject */
protected $session;

protected $userManager;

/** @var QuestionHelper | \PHPUnit_Framework_MockObject_MockObject */
protected $questionHelper;

Expand All @@ -63,6 +77,7 @@ public function setUp() {
->disableOriginalConstructor()->getMock();
$this->session = $this->getMockBuilder('OCA\Encryption\Session')
->disableOriginalConstructor()->getMock();
$this->userManager = $this->createMock(IUserManager::class);
$this->questionHelper = $this->getMockBuilder('Symfony\Component\Console\Helper\QuestionHelper')
->disableOriginalConstructor()->getMock();

Expand All @@ -71,6 +86,7 @@ public function setUp() {
$this->keyManager,
$this->crypt,
$this->session,
$this->userManager,
$this->questionHelper
);
}
Expand Down Expand Up @@ -131,4 +147,52 @@ public function dataTestGetPrivateKey() {
];
}

public function providerPrepareLoginException() {
return [
['user1'],
['recoverykey'],
['throwExceptionInCheckRecovery']
];
}
/**
* @dataProvider providerPrepareLoginException
* @expectedException \OC\User\LoginException
* @expectedExceptionMessage Invalid credentials provided
*/
public function testPrepareLoginException($loginType) {
$this->createUser('user1', 'pass');
$input = $this->createMock(InputInterface::class);
$output = $this->createMock(OutputInterface::class);

$this->util->expects($this->once())
->method('isMasterKeyEnabled')
->willReturn(false);

$this->keyManager->expects($this->any())
->method('getRecoveryKeyId')
->willReturn('xyz');

$this->questionHelper->expects($this->any())
->method('ask')
->willReturn('foo');

if ($loginType === 'user1') {
$this->userManager->expects($this->any())
->method('checkPassword')
->willReturn(false);
$this->instance->prepare($input, $output, 'user1');
} elseif ($loginType === 'recoverykey') {
$this->keyManager->expects($this->once())
->method('checkRecoveryPassword')
->willReturn(false);
$this->instance->prepare($input, $output, 'xyz');
} else {
$this->keyManager->expects($this->once())
->method('checkRecoveryPassword')
->willThrowException(new \Exception());
$this->instance->prepare($input, $output, 'xyz');
}


}
}