Browse Source

fix: encrypt and store password, decrypt and retrieve the same

Signed-off-by: yemkareems <yemkareems@gmail.com>
pull/48915/head
yemkareems 1 year ago
parent
commit
505dfd65fd
No known key found for this signature in database GPG Key ID: 4293DA00B9478934
  1. 10
      lib/private/Authentication/LoginCredentials/Store.php
  2. 3
      lib/private/Server.php
  3. 23
      tests/lib/Authentication/LoginCredentials/StoreTest.php

10
lib/private/Authentication/LoginCredentials/Store.php

@ -10,6 +10,7 @@ namespace OC\Authentication\LoginCredentials;
use OC\Authentication\Exceptions\PasswordlessTokenException;
use OC\Authentication\Token\IProvider;
use OC\Security\Crypto;
use OCP\Authentication\Exceptions\CredentialsUnavailableException;
use OCP\Authentication\Exceptions\InvalidTokenException;
use OCP\Authentication\LoginCredentials\ICredentials;
@ -29,12 +30,17 @@ class Store implements IStore {
/** @var IProvider|null */
private $tokenProvider;
/** @var Crypto|null */
private $crypto;
public function __construct(ISession $session,
LoggerInterface $logger,
?IProvider $tokenProvider = null) {
?IProvider $tokenProvider = null,
?Crypto $crypto = null) {
$this->session = $session;
$this->logger = $logger;
$this->tokenProvider = $tokenProvider;
$this->crypto = $crypto;
Util::connectHook('OC_User', 'post_login', $this, 'authenticate');
}
@ -45,6 +51,7 @@ class Store implements IStore {
* @param array $params
*/
public function authenticate(array $params) {
$params['password'] = $this->crypto->encrypt((string)$params['password']);
$this->session->set('login_credentials', json_encode($params));
}
@ -91,6 +98,7 @@ class Store implements IStore {
if ($trySession && $this->session->exists('login_credentials')) {
/** @var array $creds */
$creds = json_decode($this->session->get('login_credentials'), true);
$creds['password'] = $this->crypto->decrypt($creds['password']);
return new Credentials(
$creds['uid'],
$creds['loginName'] ?? $this->session->get('loginname') ?? $creds['uid'], // Pre 20 didn't have a loginName property, hence fall back to the session value and then to the UID

3
lib/private/Server.php

@ -451,7 +451,8 @@ class Server extends ServerContainer implements IServerContainer {
$tokenProvider = null;
}
$logger = $c->get(LoggerInterface::class);
return new Store($session, $logger, $tokenProvider);
$crypto = $c->get(Crypto::class);
return new Store($session, $logger, $tokenProvider, $crypto);
});
$this->registerAlias(IStore::class, Store::class);
$this->registerAlias(IProvider::class, Authentication\Token\Manager::class);

23
tests/lib/Authentication/LoginCredentials/StoreTest.php

@ -13,8 +13,10 @@ use OC\Authentication\LoginCredentials\Credentials;
use OC\Authentication\LoginCredentials\Store;
use OC\Authentication\Token\IProvider;
use OC\Authentication\Token\IToken;
use OC\Security\Crypto;
use OCP\Authentication\Exceptions\CredentialsUnavailableException;
use OCP\ISession;
use OCP\Security\ICrypto;
use OCP\Session\Exceptions\SessionNotAvailableException;
use Psr\Log\LoggerInterface;
use Test\TestCase;
@ -29,6 +31,8 @@ class StoreTest extends TestCase {
/** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */
private $logger;
/** @var ICrypto|\PHPUnit\Framework\MockObject\MockObject */
private $crypto;
/** @var Store */
private $store;
@ -39,20 +43,24 @@ class StoreTest extends TestCase {
$this->session = $this->createMock(ISession::class);
$this->tokenProvider = $this->createMock(IProvider::class);
$this->logger = $this->createMock(LoggerInterface::class);
$this->crypto = $this->createMock(Crypto::class);
$this->store = new Store($this->session, $this->logger, $this->tokenProvider);
$this->store = new Store($this->session, $this->logger, $this->tokenProvider, $this->crypto);
}
public function testAuthenticate(): void {
$params = [
'run' => true,
'uid' => 'user123',
'password' => 123456,
'password' => '123456',
];
$this->session->expects($this->once())
->method('set')
->with($this->equalTo('login_credentials'), $this->equalTo(json_encode($params)));
$this->crypto->expects($this->once())
->method('encrypt')
->willReturn($params['password']);
$this->store->authenticate($params);
}
@ -65,7 +73,7 @@ class StoreTest extends TestCase {
}
public function testGetLoginCredentialsNoTokenProvider(): void {
$this->store = new Store($this->session, $this->logger, null);
$this->store = new Store($this->session, $this->logger, null, $this->crypto);
$this->expectException(CredentialsUnavailableException::class);
@ -139,6 +147,9 @@ class StoreTest extends TestCase {
->method('exists')
->with($this->equalTo('login_credentials'))
->willReturn(true);
$this->crypto->expects($this->once())
->method('decrypt')
->willReturn($password);
$this->session->expects($this->exactly(2))
->method('get')
->willReturnMap([
@ -176,6 +187,9 @@ class StoreTest extends TestCase {
->method('exists')
->with($this->equalTo('login_credentials'))
->willReturn(true);
$this->crypto->expects($this->once())
->method('decrypt')
->willReturn($password);
$this->session->expects($this->exactly(2))
->method('get')
->willReturnMap([
@ -214,6 +228,9 @@ class StoreTest extends TestCase {
->method('exists')
->with($this->equalTo('login_credentials'))
->willReturn(true);
$this->crypto->expects($this->once())
->method('decrypt')
->willReturn($password);
$this->session->expects($this->once())
->method('get')
->with($this->equalTo('login_credentials'))

Loading…
Cancel
Save