chore(tests): UT for UuidCookie

Signed-off-by: Rubén D <nuxsmin@syspass.org>
This commit is contained in:
Rubén D
2023-11-18 10:29:18 +01:00
parent 9502b4c59d
commit a1cf1dfa0b
10 changed files with 278 additions and 22 deletions

View File

@@ -36,7 +36,7 @@ use SP\Core\Crypt\CryptSessionHandler;
use SP\Core\Crypt\Csrf;
use SP\Core\Crypt\CsrfInterface;
use SP\Core\Crypt\Session as CryptSession;
use SP\Core\Crypt\UUIDCookie;
use SP\Core\Crypt\UuidCookie;
use SP\Core\Exceptions\ConstraintException;
use SP\Core\Exceptions\InitializationException;
use SP\Core\Exceptions\InvalidArgumentException;

View File

@@ -26,6 +26,7 @@ namespace SP\Core\Crypt;
use SP\Core\Bootstrap\BootstrapBase;
use SP\Http\RequestInterface;
use function SP\logger;
/**
@@ -38,10 +39,12 @@ abstract class Cookie
/**
* Cookie constructor.
*
* @param string $cookieName
* @param RequestInterface $request
* @param string $cookieName
* @param RequestInterface $request
*/
protected function __construct(private readonly string $cookieName, protected readonly RequestInterface $request) {}
protected function __construct(private readonly string $cookieName, protected readonly RequestInterface $request)
{
}
/**
* Firmar la cookie para autentificación
@@ -50,14 +53,14 @@ abstract class Cookie
{
$data = base64_encode($data);
return Hash::signMessage($data, $cypher).';'.$data;
return Hash::signMessage($data, $cypher) . ';' . $data;
}
/**
* Comprobar la firma de la cookie y devolver los datos
*
* @param string $data
* @param string $cypher
* @param string $data
* @param string $cypher
*
* @return bool|string
*/

View File

@@ -27,18 +27,18 @@ namespace SP\Core\Crypt;
use SP\Http\RequestInterface;
/**
* Class SecureCookie
* Class UuidCookie
*
* @package SP\Core\Crypt
*/
class UUIDCookie extends Cookie
class UuidCookie extends Cookie implements UuidCookieInterface
{
/**
* Nombre de la cookie
*/
public const COOKIE_NAME = 'SYSPASS_UUID';
public static function factory(RequestInterface $request): UUIDCookie
public static function factory(RequestInterface $request): UuidCookie
{
return new self(self::COOKIE_NAME, $request);
}

View File

@@ -0,0 +1,62 @@
<?php
/*
* sysPass
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2023, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Core\Crypt;
/**
* Class UuidCookie
*
* @package SP\Core\Crypt
*/
interface UuidCookieInterface
{
/**
* Firmar la cookie para autentificación
*/
public function sign(string $data, string $cypher): string;
/**
* Comprobar la firma de la cookie y devolver los datos
*
* @param string $data
* @param string $cypher
*
* @return bool|string
*/
public function getCookieData(string $data, string $cypher): bool|string;
/**
* Creates a cookie and sets its data
*
* @return string|false
*/
public function create(string $signKey): bool|string;
/**
* Loads cookie data
*
* @return false|string
*/
public function load(string $signKey): bool|string;
}

View File

@@ -41,7 +41,7 @@ use SP\Core\Crypt\CryptPKIInterface;
use SP\Core\Crypt\Csrf;
use SP\Core\Crypt\RequestBasedPassword;
use SP\Core\Crypt\RequestBasedPasswordInterface;
use SP\Core\Crypt\UUIDCookie;
use SP\Core\Crypt\UuidCookie;
use SP\Core\Exceptions\SPException;
use SP\Core\Language;
use SP\Core\LanguageInterface;
@@ -223,7 +223,7 @@ final class CoreDefinitions
->constructorParameter('privateKeyFile', new FileHandler(CryptPKI::PRIVATE_KEY_FILE)),
FileCacheInterface::class => create(FileCache::class),
Application::class => autowire(Application::class),
UUIDCookie::class => factory([UUIDCookie::class, 'factory'])
UuidCookie::class => factory([UuidCookie::class, 'factory'])
->parameter(
'request',
get(RequestInterface::class)

View File

@@ -28,7 +28,7 @@ use Psr\Container\ContainerInterface;
use SP\Core\Application;
use SP\Core\Crypt\CryptInterface;
use SP\Core\Crypt\RequestBasedPassword;
use SP\Core\Crypt\UUIDCookie;
use SP\Core\Crypt\UuidCookie;
use SP\Domain\Account\Ports\AccountSearchDataBuilderInterface;
use SP\Domain\Account\Search\AccountSearchDataBuilder;
use SP\Domain\Config\Ports\ConfigDataInterface;
@@ -106,7 +106,7 @@ final class DomainDefinitions
static function (ContainerInterface $c) {
$fileCache = new FileCache(
SecureSessionService::getFileNameFrom(
$c->get(UUIDCookie::class),
$c->get(UuidCookie::class),
$c->get(ConfigDataInterface::class)->getPasswordSalt()
)
);

View File

@@ -25,7 +25,8 @@
namespace SP\Domain\Crypt\Ports;
use Defuse\Crypto\Key;
use SP\Core\Crypt\UUIDCookie;
use SP\Core\Crypt\UuidCookie;
use SP\Core\Crypt\UuidCookieInterface;
use SP\Domain\Common\Services\ServiceException;
/**
@@ -40,7 +41,7 @@ interface SecureSessionServiceInterface
*
* @throws ServiceException
*/
public static function getFileNameFrom(UUIDCookie $cookie, string $seed): string;
public static function getFileNameFrom(UuidCookieInterface $cookie, string $seed): string;
/**
* Returns the encryption key

View File

@@ -30,7 +30,8 @@ use SP\Core\Application;
use SP\Core\Crypt\CryptInterface;
use SP\Core\Crypt\RequestBasedPassword;
use SP\Core\Crypt\RequestBasedPasswordInterface;
use SP\Core\Crypt\UUIDCookie;
use SP\Core\Crypt\UuidCookie;
use SP\Core\Crypt\UuidCookieInterface;
use SP\Core\Crypt\Vault;
use SP\Domain\Common\Services\Service;
use SP\Domain\Common\Services\ServiceException;
@@ -64,7 +65,7 @@ final class SecureSessionService extends Service implements SecureSessionService
*
* @throws ServiceException
*/
public static function getFileNameFrom(UUIDCookie $cookie, string $seed): string
public static function getFileNameFrom(UuidCookieInterface $cookie, string $seed): string
{
if (($uuid = $cookie->load($seed)) === false
&& ($uuid = $cookie->create($seed)) === false

View File

@@ -0,0 +1,189 @@
<?php
/*
* sysPass
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2023, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Tests\Core\Crypt;
use Klein\DataCollection\DataCollection;
use Klein\Request;
use PHPUnit\Framework\MockObject\Exception;
use PHPUnit\Framework\MockObject\MockObject;
use SP\Core\Crypt\Hash;
use SP\Core\Crypt\UuidCookie;
use SP\Http\RequestInterface;
use SP\Tests\UnitaryTestCase;
/**
* Class UuidCookieTest
*
* @group unitary
*/
class UuidCookieTest extends UnitaryTestCase
{
private RequestInterface|MockObject $requestInterface;
/**
* @throws Exception
*/
public function testLoad()
{
$key = self::$faker->sha1;
$message = base64_encode('test');
$data = sprintf('%s;%s', Hash::signMessage($message, $key), $message);
$cookies = $this->createMock(DataCollection::class);
$cookies->expects(self::once())
->method('get')
->with('SYSPASS_UUID', false)
->willReturn($data);
$request = $this->createMock(Request::class);
$request->expects(self::once())
->method('cookies')
->willReturn($cookies);
$this->requestInterface
->expects(self::once())
->method('getRequest')
->willReturn($request);
$cookie = UuidCookie::factory($this->requestInterface);
self::assertEquals('test', $cookie->load($key));
}
/**
* @throws Exception
*/
public function testLoadWithNoData()
{
$key = self::$faker->sha1;
$cookies = $this->createMock(DataCollection::class);
$cookies->expects(self::once())
->method('get')
->with('SYSPASS_UUID', false)
->willReturn(false);
$request = $this->createMock(Request::class);
$request->expects(self::once())
->method('cookies')
->willReturn($cookies);
$this->requestInterface
->expects(self::once())
->method('getRequest')
->willReturn($request);
$cookie = UuidCookie::factory($this->requestInterface);
self::assertFalse($cookie->load($key));
}
/**
* @throws Exception
*/
public function testLoadWithInvalidData()
{
$key = self::$faker->sha1;
$data = self::$faker->text;
$cookies = $this->createMock(DataCollection::class);
$cookies->expects(self::once())
->method('get')
->with('SYSPASS_UUID', false)
->willReturn($data);
$request = $this->createMock(Request::class);
$request->expects(self::once())
->method('cookies')
->willReturn($cookies);
$this->requestInterface
->expects(self::once())
->method('getRequest')
->willReturn($request);
$cookie = UuidCookie::factory($this->requestInterface);
self::assertFalse($cookie->load($key));
}
/**
* @throws Exception
*/
public function testLoadWithInvalidSignature()
{
$key = self::$faker->sha1;
$data = sprintf('%s;%s', Hash::signMessage(base64_encode('invalid'), $key), base64_encode('test'));
$cookies = $this->createMock(DataCollection::class);
$cookies->expects(self::once())
->method('get')
->with('SYSPASS_UUID', false)
->willReturn($data);
$request = $this->createMock(Request::class);
$request->expects(self::once())
->method('cookies')
->willReturn($cookies);
$this->requestInterface
->expects(self::once())
->method('getRequest')
->willReturn($request);
$cookie = UuidCookie::factory($this->requestInterface);
self::assertFalse($cookie->load($key));
}
public function testCreate()
{
$uuidCookie = UuidCookie::factory($this->requestInterface);
$key = self::$faker->sha1;
$cookie = $uuidCookie->create($key);
self::assertNotEmpty($cookie);
}
public function testSign()
{
$key = self::$faker->sha1;
$uuidCookie = UuidCookie::factory($this->requestInterface);
$cookieData = $uuidCookie->sign('test', $key);
$out = $uuidCookie->getCookieData($cookieData, $key);
self::assertEquals('test', $out);
}
protected function setUp(): void
{
parent::setUp();
$this->requestInterface = $this->createMock(RequestInterface::class);
}
}

View File

@@ -30,7 +30,7 @@ use PHPUnit\Framework\MockObject\MockObject;
use SP\Core\Crypt\Crypt;
use SP\Core\Crypt\CryptInterface;
use SP\Core\Crypt\RequestBasedPasswordInterface;
use SP\Core\Crypt\UUIDCookie;
use SP\Core\Crypt\UuidCookie;
use SP\Core\Crypt\Vault;
use SP\Domain\Common\Services\ServiceException;
use SP\Domain\Crypt\Services\SecureSessionService;
@@ -140,7 +140,7 @@ class SecureSessionServiceTest extends UnitaryTestCase
*/
public function testGetFileNameFrom()
{
$uuidCookie = $this->createMock(UUIDCookie::class);
$uuidCookie = $this->createMock(UuidCookie::class);
$uuidCookie->method('load')
->willReturn(uniqid('', true));
@@ -156,7 +156,7 @@ class SecureSessionServiceTest extends UnitaryTestCase
*/
public function testGetFileNameFromErrorLoadingCookie()
{
$uuidCookie = $this->createMock(UUIDCookie::class);
$uuidCookie = $this->createMock(UuidCookie::class);
$uuidCookie->method('load')->willReturn(false);
@@ -172,7 +172,7 @@ class SecureSessionServiceTest extends UnitaryTestCase
*/
public function testGetFileNameFromErrorCreatingCookie()
{
$uuidCookie = $this->createMock(UUIDCookie::class);
$uuidCookie = $this->createMock(UuidCookie::class);
$uuidCookie->method('create')->willReturn(false);