chore: Create AccountCryptService tests

Signed-off-by: Rubén D <nuxsmin@syspass.org>
This commit is contained in:
Rubén D
2022-11-27 16:01:51 +01:00
parent 41b171e89d
commit 930b1f7139
51 changed files with 989 additions and 367 deletions

View File

@@ -29,7 +29,7 @@ use Exception;
use SP\Core\Acl\ActionsInterface;
use SP\Core\Events\Event;
use SP\Core\Events\EventMessage;
use SP\Domain\Account\Services\AccountRequest;
use SP\Domain\Account\Dtos\AccountRequest;
use SP\Domain\Api\Services\ApiResponse;
/**
@@ -74,7 +74,7 @@ final class CreateController extends AccountBase
}
/**
* @return \SP\Domain\Account\Services\AccountRequest
* @return \SP\Domain\Account\Dtos\AccountRequest
* @throws \SP\Domain\Common\Services\ServiceException
*/
private function buildAccountRequest(): AccountRequest
@@ -103,4 +103,4 @@ final class CreateController extends AccountBase
return $accountRequest;
}
}
}

View File

@@ -28,7 +28,7 @@ use Exception;
use SP\Core\Acl\ActionsInterface;
use SP\Core\Events\Event;
use SP\Core\Events\EventMessage;
use SP\Domain\Account\Services\AccountRequest;
use SP\Domain\Account\Dtos\AccountRequest;
use SP\Domain\Api\Services\ApiResponse;
/**
@@ -73,7 +73,7 @@ final class EditController extends AccountBase
}
/**
* @return \SP\Domain\Account\Services\AccountRequest
* @return \SP\Domain\Account\Dtos\AccountRequest
* @throws \SP\Domain\Common\Services\ServiceException
*/
private function buildAccountRequest(): AccountRequest
@@ -106,4 +106,4 @@ final class EditController extends AccountBase
return $accountRequest;
}
}
}

View File

@@ -28,7 +28,7 @@ use Exception;
use SP\Core\Acl\ActionsInterface;
use SP\Core\Events\Event;
use SP\Core\Events\EventMessage;
use SP\Domain\Account\Services\AccountRequest;
use SP\Domain\Account\Dtos\AccountRequest;
use SP\Domain\Api\Services\ApiResponse;
/**
@@ -75,7 +75,7 @@ final class EditPassController extends AccountBase
}
/**
* @return \SP\Domain\Account\Services\AccountRequest
* @return \SP\Domain\Account\Dtos\AccountRequest
* @throws \SP\Domain\Common\Services\ServiceException
*/
private function buildAccountRequest(): AccountRequest
@@ -88,4 +88,4 @@ final class EditPassController extends AccountBase
return $accountRequest;
}
}
}

View File

@@ -29,10 +29,10 @@ use SP\Core\Acl\ActionsInterface;
use SP\Core\Application;
use SP\Core\Events\Event;
use SP\Core\Events\EventMessage;
use SP\Domain\Account\Dtos\AccountBulkRequest;
use SP\Domain\Account\Ports\AccountHistoryServiceInterface;
use SP\Domain\Account\Ports\AccountPresetServiceInterface;
use SP\Domain\Account\Ports\AccountServiceInterface;
use SP\Domain\Account\Services\AccountBulkRequest;
use SP\Http\JsonResponse;
use SP\Modules\Web\Controllers\ControllerBase;
use SP\Modules\Web\Controllers\Traits\JsonTrait;

View File

@@ -35,6 +35,7 @@ use SP\Domain\Config\Ports\ConfigServiceInterface;
use SP\Domain\Crypt\Ports\MasterPassServiceInterface;
use SP\Domain\Crypt\Services\MasterPassService;
use SP\Domain\Crypt\Services\UpdateMasterPassRequest;
use SP\Domain\Task\Ports\TaskInterface;
use SP\Domain\Task\Services\Task;
use SP\Domain\Task\Services\TaskFactory;
use SP\Http\JsonResponse;
@@ -191,12 +192,12 @@ final class SaveController extends SimpleControllerBase
/**
* @throws \SP\Infrastructure\File\FileException
*/
private function getTask(): ?Task
private function getTask(): ?TaskInterface
{
$taskId = $this->request->analyzeString('taskId');
return $taskId !== null
? TaskFactory::create(__FUNCTION__, $taskId)
? TaskFactory::register(new Task(__FUNCTION__, $taskId))
: null;
}

View File

@@ -40,7 +40,7 @@ final class TestTaskController
*/
public function testTaskAction(string $taskId): void
{
$task = TaskFactory::create($taskId, $taskId);
$task = TaskFactory::register($taskId, $taskId);
echo $task->getTaskId();
@@ -55,4 +55,4 @@ final class TestTaskController
TaskFactory::end($task);
}
}
}

View File

@@ -30,8 +30,8 @@ use SP\Core\Exceptions\ConstraintException;
use SP\Core\Exceptions\NoSuchPropertyException;
use SP\Core\Exceptions\QueryException;
use SP\Core\Exceptions\ValidationException;
use SP\Domain\Account\Dtos\AccountRequest;
use SP\Domain\Account\Ports\AccountPresetServiceInterface;
use SP\Domain\Account\Services\AccountRequest;
use SP\Http\RequestInterface;
/**

View File

@@ -4,7 +4,7 @@
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org
* @copyright 2012-2022, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
@@ -28,91 +28,116 @@ use Defuse\Crypto\Crypto;
use Defuse\Crypto\Exception\CryptoException;
use Defuse\Crypto\Key;
use Defuse\Crypto\KeyProtectedByPassword;
use SP\Core\Exceptions\CryptException;
use SP\Core\Exceptions\SPException;
/**
* Class Crypt
*
* @package SP\Core\Crypt
*/
class Crypt
class Crypt implements CryptInterface
{
/**
* Securiza una clave de seguridad
*
* @param string $password
* @param bool $useAscii
*
* @return string|KeyProtectedByPassword
* @throws \SP\Core\Exceptions\CryptException
* @TODO: Update callers to use instance
*/
public function makeSecuredKey(
string $password,
bool $useAscii = true
): KeyProtectedByPassword|string {
try {
if ($useAscii) {
return KeyProtectedByPassword::createRandomPasswordProtectedKey($password)->saveToAsciiSafeString();
}
return KeyProtectedByPassword::createRandomPasswordProtectedKey($password);
} catch (CryptoException $e) {
throw new CryptException($e->getMessage(), SPException::ERROR, null, $e->getCode(), $e);
}
}
/**
* Encriptar datos con una clave segura
*
* @param string $data
* @param string|Key $securedKey
* @param string|null $password
* @param string $data
* @param string|Key $securedKey
* @param string|null $password
*
* @return string
* @throws \Defuse\Crypto\Exception\BadFormatException
* @throws \Defuse\Crypto\Exception\CryptoException
* @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
* @throws \SP\Core\Exceptions\CryptException
*
* @TODO: Update callers to use instance
*/
public static function encrypt(
string $data,
$securedKey,
public function encrypt(
string $data,
Key|string $securedKey,
?string $password = null
): string
{
): string {
try {
if ($securedKey instanceof Key) {
$key = $securedKey;
} elseif (null !== $password) {
$key = self::unlockSecuredKey($securedKey, $password, false);
$key = $this->unlockSecuredKey($securedKey, $password, false);
} else {
$key = Key::loadFromAsciiSafeString($securedKey);
}
return Crypto::encrypt($data, $key);
} catch (CryptoException $e) {
logger($e->getMessage());
throw $e;
throw new CryptException($e->getMessage(), SPException::ERROR, null, $e->getCode(), $e);
}
}
/**
* @param string $key
* @param string $password
* @param bool $useAscii
*
* @return string|Key
* @throws CryptoException
* @throws \SP\Core\Exceptions\CryptException
* @TODO: Update callers to use instance
*/
public static function unlockSecuredKey(
public function unlockSecuredKey(
string $key,
string $password,
bool $useAscii = true
)
{
bool $useAscii = true
): Key|string {
try {
if ($useAscii) {
return KeyProtectedByPassword::loadFromAsciiSafeString($key)->unlockKey($password)->saveToAsciiSafeString();
return KeyProtectedByPassword::loadFromAsciiSafeString($key)
->unlockKey($password)
->saveToAsciiSafeString();
}
return KeyProtectedByPassword::loadFromAsciiSafeString($key)->unlockKey($password);
} catch (CryptoException $e) {
logger($e->getMessage());
throw $e;
throw new CryptException($e->getMessage(), SPException::ERROR, null, $e->getCode(), $e);
}
}
/**
* Desencriptar datos con una clave segura
*
* @param string $data
* @param string|Key|KeyProtectedByPassword $securedKey
* @param string|null $password
* @param string $data
* @param string|Key|KeyProtectedByPassword $securedKey
* @param string|null $password
*
* @return string
* @throws \Defuse\Crypto\Exception\BadFormatException
* @throws \Defuse\Crypto\Exception\CryptoException
* @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
* @throws \Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException
* @throws \SP\Core\Exceptions\CryptException
* @TODO: Update callers to use instance
*/
public static function decrypt(
string $data,
$securedKey,
public function decrypt(
string $data,
Key|KeyProtectedByPassword|string $securedKey,
?string $password = null
): string
{
): string {
try {
if ($securedKey instanceof Key) {
return Crypto::decrypt($data, $securedKey);
@@ -123,39 +148,12 @@ class Crypt
return Crypto::decrypt($data, $securedKey->unlockKey($password));
}
return Crypto::decrypt($data, self::unlockSecuredKey($securedKey, $password, false));
return Crypto::decrypt($data, $this->unlockSecuredKey($securedKey, $password, false));
}
return Crypto::decrypt($data, Key::loadFromAsciiSafeString($securedKey));
} catch (CryptoException $e) {
logger($e->getMessage());
throw $e;
}
}
/**
* Securiza una clave de seguridad
*
* @return string|KeyProtectedByPassword
* @throws CryptoException
*/
public static function makeSecuredKey(
string $password,
bool $useAscii = true
)
{
try {
if ($useAscii) {
return KeyProtectedByPassword::createRandomPasswordProtectedKey($password)->saveToAsciiSafeString();
}
return KeyProtectedByPassword::createRandomPasswordProtectedKey($password);
} catch (CryptoException $e) {
logger($e->getMessage());
throw $e;
throw new CryptException($e->getMessage(), SPException::ERROR, null, $e->getCode(), $e);
}
}
}
}

View File

@@ -0,0 +1,85 @@
<?php
/*
* sysPass
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2022, 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;
use Defuse\Crypto\Key;
use Defuse\Crypto\KeyProtectedByPassword;
/**
* Class Crypt
*
* @package SP\Core\Crypt
*/
interface CryptInterface
{
/**
* Securiza una clave de seguridad
*
* @param string $password
* @param bool $useAscii
*
* @return string|KeyProtectedByPassword
* @throws \SP\Core\Exceptions\CryptException
*/
public function makeSecuredKey(string $password, bool $useAscii = true): KeyProtectedByPassword|string;
/**
* Encriptar datos con una clave segura
*
* @param string $data
* @param string|Key $securedKey
* @param string|null $password
*
* @return string
* @throws \SP\Core\Exceptions\CryptException
*/
public function encrypt(string $data, Key|string $securedKey, ?string $password = null): string;
/**
* @param string $key
* @param string $password
* @param bool $useAscii
*
* @return string|Key
* @throws \SP\Core\Exceptions\CryptException
*/
public function unlockSecuredKey(string $key, string $password, bool $useAscii = true): Key|string;
/**
* Desencriptar datos con una clave segura
*
* @param string $data
* @param string|Key|KeyProtectedByPassword $securedKey
* @param string|null $password
*
* @return string
* @throws \SP\Core\Exceptions\CryptException
*/
public function decrypt(
string $data,
Key|KeyProtectedByPassword|string $securedKey,
?string $password = null
): string;
}

View File

@@ -0,0 +1,33 @@
<?php
/*
* sysPass
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2022, 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\Exceptions;
/**
* Class CryptException
*/
final class CryptException extends SPException
{
}

View File

@@ -4,7 +4,7 @@
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org
* @copyright 2012-2022, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
@@ -33,18 +33,12 @@ use JsonSerializable;
*/
final class TaskMessage implements MessageInterface, JsonSerializable
{
protected string $taskId;
protected string $task;
protected ?string $message = null;
protected int $time = 0;
protected int $progress = 0;
protected int $end = 0;
protected ?string $message = null;
protected int $time = 0;
protected int $progress = 0;
protected int $end = 0;
public function __construct(string $taskId, string $task)
{
$this->taskId = $taskId;
$this->task = $task;
}
public function __construct(private string $taskId, private string $task) {}
public function getTask(): string
{
@@ -120,12 +114,12 @@ final class TaskMessage implements MessageInterface, JsonSerializable
public function composeText(string $delimiter = ';'): string
{
return implode($delimiter, [
'taskId' => $this->taskId,
'task' => $this->task,
'message' => $this->message,
'time' => $this->time,
'taskId' => $this->taskId,
'task' => $this->task,
'message' => $this->message,
'time' => $this->time,
'progress' => $this->progress,
'end' => $this->end
'end' => $this->end,
]);
}
@@ -134,7 +128,7 @@ final class TaskMessage implements MessageInterface, JsonSerializable
*
* @throws \JsonException
*/
public function composeJson()
public function composeJson(): bool|string
{
return json_encode($this, JSON_THROW_ON_ERROR);
}
@@ -163,4 +157,4 @@ final class TaskMessage implements MessageInterface, JsonSerializable
return $this;
}
}
}

View File

@@ -22,7 +22,7 @@
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Domain\Account\Services;
namespace SP\Domain\Account\Dtos;
/**
* Class AccountBulkRequest
@@ -31,9 +31,7 @@ namespace SP\Domain\Account\Services;
*/
final class AccountBulkRequest
{
private array $itemsId;
private AccountRequest $accountRequest;
private bool $deleteHistory = false;
private bool $deleteHistory = false;
/**
* AccountBulkRequest constructor.
@@ -41,11 +39,8 @@ final class AccountBulkRequest
* @param int[] $itemsId
* @param AccountRequest $accountRequest
*/
public function __construct(array $itemsId, AccountRequest $accountRequest)
public function __construct(private array $itemsId, private AccountRequest $accountRequest)
{
$this->itemsId = $itemsId;
$this->accountRequest = $accountRequest;
$this->setUp();
}
@@ -77,4 +72,4 @@ final class AccountBulkRequest
return $request;
}
}
}

View File

@@ -22,7 +22,7 @@
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Domain\Account\Services;
namespace SP\Domain\Account\Dtos;
/**
* Class AccountRequest
@@ -58,4 +58,4 @@ final class AccountRequest
public ?bool $changeUserGroup = false;
public ?bool $changePermissions = false;
public ?bool $updateTags = false;
}
}

View File

@@ -0,0 +1,43 @@
<?php
/*
* sysPass
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2022, 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\Domain\Account\Dtos;
/**
* Class EncryptedPassword
*/
final class EncryptedPassword
{
public function __construct(private string $pass, private string $key) {}
public function getPass(): string
{
return $this->pass;
}
public function getKey(): string
{
return $this->key;
}
}

View File

@@ -24,6 +24,7 @@
namespace SP\Domain\Account\Ports;
use SP\Domain\Account\Dtos\EncryptedPassword;
use SP\Domain\Common\Services\ServiceException;
use SP\Domain\Crypt\Services\UpdateMasterPassRequest;
@@ -47,4 +48,11 @@ interface AccountCryptServiceInterface
* @throws \SP\Domain\Common\Services\ServiceException
*/
public function updateHistoryMasterPassword(UpdateMasterPassRequest $updateMasterPassRequest): void;
/**
* Devolver los datos de la clave encriptados
*
* @throws \SP\Domain\Common\Services\ServiceException
*/
public function getPasswordEncrypted(string $pass, ?string $masterPass = null): EncryptedPassword;
}

View File

@@ -22,7 +22,7 @@
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Domain\Account\Services;
namespace SP\Domain\Account\Ports;
use Aura\SqlQuery\Common\SelectInterface;
@@ -40,4 +40,4 @@ interface AccountFilterUserInterface
* Devuelve el filtro para la consulta SQL de cuentas que un usuario puede acceder
*/
public function buildFilter(bool $useGlobalSearch = false, ?SelectInterface $query = null): SelectInterface;
}
}

View File

@@ -28,7 +28,7 @@ use SP\Core\Exceptions\ConstraintException;
use SP\Core\Exceptions\NoSuchPropertyException;
use SP\Core\Exceptions\QueryException;
use SP\Core\Exceptions\ValidationException;
use SP\Domain\Account\Services\AccountRequest;
use SP\Domain\Account\Dtos\AccountRequest;
/**
* Class AccountPreset

View File

@@ -29,8 +29,8 @@ use SP\Core\Exceptions\QueryException;
use SP\Core\Exceptions\SPException;
use SP\DataModel\AccountHistoryData;
use SP\DataModel\ItemSearchData;
use SP\Domain\Account\Dtos\AccountRequest;
use SP\Domain\Account\Services\AccountPasswordRequest;
use SP\Domain\Account\Services\AccountRequest;
use SP\Domain\Common\Adapters\SimpleModel;
use SP\Domain\Common\Ports\RepositoryInterface;
use SP\Infrastructure\Database\QueryResult;
@@ -82,7 +82,7 @@ interface AccountRepositoryInterface extends RepositoryInterface
/**
* Actualiza la clave de una cuenta en la BBDD.
*
* @param AccountRequest $accountRequest
* @param \SP\Domain\Account\Dtos\AccountRequest $accountRequest
*
* @return int
* @throws ConstraintException
@@ -175,7 +175,7 @@ interface AccountRepositoryInterface extends RepositoryInterface
/**
* Crea una nueva cuenta en la BBDD
*
* @param AccountRequest $accountRequest
* @param \SP\Domain\Account\Dtos\AccountRequest $accountRequest
*
* @return int
* @throws ConstraintException

View File

@@ -34,9 +34,9 @@ use SP\DataModel\Dto\AccountEnrichedDto;
use SP\DataModel\ItemSearchData;
use SP\Domain\Account\Adapters\AccountData;
use SP\Domain\Account\Adapters\AccountPassData;
use SP\Domain\Account\Services\AccountBulkRequest;
use SP\Domain\Account\Dtos\AccountBulkRequest;
use SP\Domain\Account\Dtos\AccountRequest;
use SP\Domain\Account\Services\AccountPasswordRequest;
use SP\Domain\Account\Services\AccountRequest;
use SP\Domain\Common\Services\ServiceException;
use SP\Infrastructure\Common\Repositories\NoSuchItemException;
use SP\Infrastructure\Database\QueryResult;
@@ -102,13 +102,6 @@ interface AccountServiceInterface
*/
public function create(AccountRequest $accountRequest): int;
/**
* Devolver los datos de la clave encriptados
*
* @throws \SP\Domain\Common\Services\ServiceException
*/
public function getPasswordEncrypted(string $pass, ?string $masterPass = null): array;
/**
* @throws QueryException
* @throws NoSuchItemException
@@ -119,7 +112,7 @@ interface AccountServiceInterface
/**
* Updates external items for the account
*
* @param \SP\Domain\Account\Services\AccountRequest $accountRequest
* @param \SP\Domain\Account\Dtos\AccountRequest $accountRequest
*
* @throws \SP\Domain\Common\Services\ServiceException
*/
@@ -128,14 +121,14 @@ interface AccountServiceInterface
/**
* Update accounts in bulk mode
*
* @param \SP\Domain\Account\Services\AccountBulkRequest $request
* @param \SP\Domain\Account\Dtos\AccountBulkRequest $request
*
* @throws \SP\Domain\Common\Services\ServiceException
*/
public function updateBulk(AccountBulkRequest $request): void;
/**
* @param \SP\Domain\Account\Services\AccountRequest $accountRequest
* @param \SP\Domain\Account\Dtos\AccountRequest $accountRequest
*
* @throws \SP\Domain\Common\Services\ServiceException
*/
@@ -147,7 +140,7 @@ interface AccountServiceInterface
* @throws ConstraintException
* @throws QueryException
*/
public function updatePasswordMasterPass(AccountPasswordRequest $accountRequest): bool;
public function updatePasswordMasterPass(AccountPasswordRequest $accountRequest): void;
/**
* @param int $historyId

View File

@@ -26,7 +26,7 @@ namespace SP\Domain\Account\Ports;
use SP\Core\Exceptions\ConstraintException;
use SP\Core\Exceptions\QueryException;
use SP\Domain\Account\Services\AccountRequest;
use SP\Domain\Account\Dtos\AccountRequest;
use SP\Domain\Common\Ports\RepositoryInterface;
use SP\Infrastructure\Database\QueryResult;
@@ -62,7 +62,7 @@ interface AccountToTagRepositoryInterface extends RepositoryInterface
/**
* Actualizar las etiquetas de una cuenta
*
* @param AccountRequest $accountRequest
* @param \SP\Domain\Account\Dtos\AccountRequest $accountRequest
*
* @throws ConstraintException
* @throws QueryException

View File

@@ -24,13 +24,14 @@
namespace SP\Domain\Account\Services;
use Defuse\Crypto\Exception\CryptoException;
use Exception;
use SP\Core\Application;
use SP\Core\Crypt\Crypt;
use SP\Core\Crypt\CryptInterface;
use SP\Core\Events\Event;
use SP\Core\Events\EventMessage;
use SP\Core\Exceptions\CryptException;
use SP\Core\Exceptions\SPException;
use SP\Domain\Account\Dtos\EncryptedPassword;
use SP\Domain\Account\Ports\AccountCryptServiceInterface;
use SP\Domain\Account\Ports\AccountHistoryServiceInterface;
use SP\Domain\Account\Ports\AccountServiceInterface;
@@ -39,6 +40,9 @@ use SP\Domain\Common\Services\ServiceException;
use SP\Domain\Crypt\Services\UpdateMasterPassRequest;
use SP\Domain\Task\Services\TaskFactory;
use SP\Util\Util;
use function SP\__;
use function SP\__u;
use function SP\logger;
/**
* Class AccountCryptService
@@ -47,19 +51,13 @@ use SP\Util\Util;
*/
final class AccountCryptService extends Service implements AccountCryptServiceInterface
{
private AccountService $accountService;
private AccountHistoryService $accountHistoryService;
private ?UpdateMasterPassRequest $request = null;
public function __construct(
Application $application,
AccountServiceInterface $accountService,
AccountHistoryServiceInterface $accountHistoryService
private AccountServiceInterface $accountService,
private AccountHistoryServiceInterface $accountHistoryService,
private CryptInterface $crypt
) {
parent::__construct($application);
$this->accountService = $accountService;
$this->accountHistoryService = $accountHistoryService;
}
/**
@@ -69,8 +67,6 @@ final class AccountCryptService extends Service implements AccountCryptServiceIn
*/
public function updateMasterPassword(UpdateMasterPassRequest $updateMasterPassRequest): void
{
$this->request = $updateMasterPassRequest;
try {
$this->eventDispatcher->notifyEvent(
'update.masterPassword.accounts.start',
@@ -81,9 +77,9 @@ final class AccountCryptService extends Service implements AccountCryptServiceIn
)
);
if ($this->request->useTask()) {
$task = $this->request->getTask();
$task = $updateMasterPassRequest->getTask();
if (null !== $task) {
TaskFactory::update(
$task,
TaskFactory::createMessage(
@@ -97,7 +93,8 @@ final class AccountCryptService extends Service implements AccountCryptServiceIn
$this->accountService->getAccountsPassData(),
function (AccountPasswordRequest $request) {
$this->accountService->updatePasswordMasterPass($request);
}
},
$updateMasterPassRequest
);
$this->eventDispatcher->notifyEvent(
@@ -119,7 +116,8 @@ final class AccountCryptService extends Service implements AccountCryptServiceIn
private function processAccounts(
array $accounts,
callable $passUpdater
callable $passUpdater,
UpdateMasterPassRequest $updateMasterPassRequest
): EventMessage {
set_time_limit(0);
@@ -140,11 +138,9 @@ final class AccountCryptService extends Service implements AccountCryptServiceIn
}
$configData = $this->config->getConfigData();
$currentMasterPassHash = $this->request->getCurrentHash();
$currentMasterPassHash = $updateMasterPassRequest->getCurrentHash();
if ($this->request->useTask()) {
$task = $this->request->getTask();
}
$task = $updateMasterPassRequest->getTask();
foreach ($accounts as $account) {
// No realizar cambios si está en modo demo
@@ -156,13 +152,13 @@ final class AccountCryptService extends Service implements AccountCryptServiceIn
if ($counter % 100 === 0) {
$eta = Util::getETA($startTime, $counter, $numAccounts);
if (isset($task)) {
if (null !== $task) {
$taskMessage = TaskFactory::createMessage(
$task->getTaskId(),
__('Update Master Password')
)->setMessage(sprintf(__('Accounts updated: %d / %d'), $counter, $numAccounts))
->setProgress(round(($counter * 100) / $numAccounts, 2))
->setTime(sprintf('ETA: %ds (%.2f/s)', $eta[0], $eta[1]));
)->setMessage(
sprintf(__('Accounts updated: %d / %d - ETA: %ds (%.2f/s)'), $counter, $numAccounts, ...$eta)
)->setProgress(round(($counter * 100) / $numAccounts, 2));
TaskFactory::update($task, $taskMessage);
@@ -187,24 +183,30 @@ final class AccountCryptService extends Service implements AccountCryptServiceIn
continue;
}
$request = new AccountPasswordRequest();
$request->id = $account->id;
try {
$passData = $this->accountService->getPasswordEncrypted(
Crypt::decrypt($account->pass, $account->key, $this->request->getCurrentMasterPass()),
$this->request->getNewMasterPass()
$encryptedPassword = $this->getPasswordEncrypted(
$this->crypt->decrypt(
$account->pass,
$account->key,
$updateMasterPassRequest->getCurrentMasterPass()
),
$updateMasterPassRequest->getNewMasterPass()
);
$request->key = $passData['key'];
$request->pass = $passData['pass'];
$request = new AccountPasswordRequest(
$account->id,
$encryptedPassword,
$updateMasterPassRequest->getHash()
);
// Call the specific updater
$passUpdater($request);
$accountsOk[] = $account->id;
$counter++;
} catch (SPException|CryptoException $e) {
} catch (SPException $e) {
$this->eventDispatcher->notifyEvent('exception', new Event($e));
$errorCount++;
$eventMessage->addDescription(__u('Error while updating the account\'s password'));
@@ -218,6 +220,39 @@ final class AccountCryptService extends Service implements AccountCryptServiceIn
return $eventMessage;
}
/**
* Devolver los datos de la clave encriptados
*
* @throws \SP\Domain\Common\Services\ServiceException
*/
public function getPasswordEncrypted(string $pass, ?string $masterPass = null): EncryptedPassword
{
try {
if ($masterPass === null) {
$masterPass = $this->getMasterKeyFromContext();
}
if (empty($masterPass)) {
throw new ServiceException(__u('Master password not set'));
}
$key = $this->crypt->makeSecuredKey($masterPass);
$encryptedPassword = new EncryptedPassword(
$this->crypt->encrypt($pass, $key, $masterPass),
$key
);
if (strlen($encryptedPassword->getPass()) > 1000 || strlen($encryptedPassword->getKey()) > 1000) {
throw new ServiceException(__u('Internal error'));
}
return $encryptedPassword;
} catch (CryptException $e) {
throw new ServiceException(__u('Internal error'), SPException::ERROR, null, $e->getCode(), $e);
}
}
/**
* Actualiza las claves de todas las cuentas con la nueva clave maestra.
*
@@ -226,8 +261,6 @@ final class AccountCryptService extends Service implements AccountCryptServiceIn
public function updateHistoryMasterPassword(
UpdateMasterPassRequest $updateMasterPassRequest
): void {
$this->request = $updateMasterPassRequest;
try {
$this->eventDispatcher->notifyEvent(
'update.masterPassword.accountsHistory.start',
@@ -238,9 +271,9 @@ final class AccountCryptService extends Service implements AccountCryptServiceIn
)
);
if ($this->request->useTask()) {
$task = $this->request->getTask();
$task = $updateMasterPassRequest->getTask();
if (null !== $task) {
TaskFactory::update(
$task,
TaskFactory::createMessage(
@@ -253,10 +286,9 @@ final class AccountCryptService extends Service implements AccountCryptServiceIn
$eventMessage = $this->processAccounts(
$this->accountHistoryService->getAccountsPassData(),
function (AccountPasswordRequest $request) {
$request->hash = $this->request->getHash();
$this->accountHistoryService->updatePasswordMasterPass($request);
}
},
$updateMasterPassRequest
);
$this->eventDispatcher->notifyEvent(

View File

@@ -28,6 +28,7 @@ use Aura\SqlQuery\Common\SelectInterface;
use Aura\SqlQuery\QueryFactory;
use SP\Core\Context\ContextInterface;
use SP\DataModel\ProfileData;
use SP\Domain\Account\Ports\AccountFilterUserInterface;
use SP\Domain\Account\Search\AccountSearchConstants;
use SP\Domain\Config\Ports\ConfigDataInterface;
use SP\Domain\User\Services\UserLoginResponse;

View File

@@ -27,7 +27,6 @@ namespace SP\Domain\Account\Services;
use SP\Core\Application;
use SP\Core\Exceptions\ConstraintException;
use SP\Core\Exceptions\QueryException;
use SP\Core\Exceptions\SPException;
use SP\DataModel\AccountHistoryData;
use SP\DataModel\Dto\AccountHistoryCreateDto;
use SP\DataModel\ItemData;
@@ -40,6 +39,7 @@ use SP\Domain\Common\Services\Service;
use SP\Domain\Common\Services\ServiceException;
use SP\Infrastructure\Common\Repositories\NoSuchItemException;
use SP\Infrastructure\Database\QueryResult;
use function SP\__u;
/**
* Class AccountHistoryService
@@ -208,13 +208,14 @@ final class AccountHistoryService extends Service implements AccountHistoryServi
}
/**
* @throws SPException
* @throws ConstraintException
* @param \SP\Domain\Account\Services\AccountPasswordRequest $accountRequest
*
* @throws \SP\Domain\Common\Services\ServiceException
*/
public function updatePasswordMasterPass(
AccountPasswordRequest $accountRequest
): void {
if ($this->accountHistoryRepository->updatePassword($accountRequest) !== 1) {
if (!$this->accountHistoryRepository->updatePassword($accountRequest)) {
throw new ServiceException(__u('Error while updating the password'));
}
}

View File

@@ -24,6 +24,8 @@
namespace SP\Domain\Account\Services;
use SP\Domain\Account\Dtos\EncryptedPassword;
/**
* Class AccountPasswordRequest
*
@@ -31,8 +33,29 @@ namespace SP\Domain\Account\Services;
*/
final class AccountPasswordRequest
{
public ?int $id = null;
public ?string $pass = null;
public ?string $key = null;
public ?string $hash = null;
}
/**
* @param int $id
* @param \SP\Domain\Account\Dtos\EncryptedPassword $encryptedPassword
* @param string|null $hash
*/
public function __construct(
private int $id,
private EncryptedPassword $encryptedPassword,
private ?string $hash = null
) {}
public function getId(): int
{
return $this->id;
}
public function getHash(): ?string
{
return $this->hash;
}
public function getEncryptedPassword(): EncryptedPassword
{
return $this->encryptedPassword;
}
}

View File

@@ -29,6 +29,7 @@ use SP\Core\Exceptions\NoSuchPropertyException;
use SP\Core\Exceptions\QueryException;
use SP\Core\Exceptions\ValidationException;
use SP\DataModel\ItemPreset\Password;
use SP\Domain\Account\Dtos\AccountRequest;
use SP\Domain\Account\Ports\AccountPresetServiceInterface;
use SP\Domain\Config\Ports\ConfigDataInterface;
use SP\Domain\ItemPreset\Ports\ItemPresetInterface;

View File

@@ -24,9 +24,7 @@
namespace SP\Domain\Account\Services;
use Defuse\Crypto\Exception\CryptoException;
use SP\Core\Application;
use SP\Core\Crypt\Crypt;
use SP\Core\Exceptions\ConstraintException;
use SP\Core\Exceptions\NoSuchPropertyException;
use SP\Core\Exceptions\QueryException;
@@ -41,6 +39,9 @@ use SP\DataModel\ItemSearchData;
use SP\DataModel\ProfileData;
use SP\Domain\Account\Adapters\AccountData;
use SP\Domain\Account\Adapters\AccountPassData;
use SP\Domain\Account\Dtos\AccountBulkRequest;
use SP\Domain\Account\Dtos\AccountRequest;
use SP\Domain\Account\Ports\AccountCryptServiceInterface;
use SP\Domain\Account\Ports\AccountHistoryServiceInterface;
use SP\Domain\Account\Ports\AccountRepositoryInterface;
use SP\Domain\Account\Ports\AccountServiceInterface;
@@ -67,32 +68,17 @@ final class AccountService extends Service implements AccountServiceInterface
{
use ServiceItemTrait;
private AccountRepositoryInterface $accountRepository;
private AccountToUserGroupRepositoryInterface $accountToUserGroupRepository;
private AccountToUserRepositoryInterface $accountToUserRepository;
private AccountToTagRepositoryInterface $accountToTagRepository;
private ItemPresetServiceInterface $itemPresetService;
private AccountHistoryServiceInterface $accountHistoryService;
private ConfigServiceInterface $configService;
public function __construct(
Application $application,
AccountRepositoryInterface $accountRepository,
AccountToUserGroupRepositoryInterface $accountToUserGroupRepository,
AccountToUserRepositoryInterface $accountToUserRepository,
AccountToTagRepositoryInterface $accountToTagRepository,
ItemPresetServiceInterface $itemPresetService,
AccountHistoryServiceInterface $accountHistoryService,
ConfigServiceInterface $configService,
private AccountRepositoryInterface $accountRepository,
private AccountToUserGroupRepositoryInterface $accountToUserGroupRepository,
private AccountToUserRepositoryInterface $accountToUserRepository,
private AccountToTagRepositoryInterface $accountToTagRepository,
private ItemPresetServiceInterface $itemPresetService,
private AccountHistoryServiceInterface $accountHistoryService,
private ConfigServiceInterface $configService,
private AccountCryptServiceInterface $accountCryptService
) {
$this->accountRepository = $accountRepository;
$this->accountToUserGroupRepository = $accountToUserGroupRepository;
$this->accountToUserRepository = $accountToUserRepository;
$this->accountToTagRepository = $accountToTagRepository;
$this->itemPresetService = $itemPresetService;
$this->accountHistoryService = $accountHistoryService;
$this->configService = $configService;
parent::__construct($application);
}
@@ -228,10 +214,10 @@ final class AccountService extends Service implements AccountServiceInterface
}
if (empty($accountRequest->key)) {
$pass = $this->getPasswordEncrypted($accountRequest->pass);
$encryptedPassword = $this->accountCryptService->getPasswordEncrypted($accountRequest->pass);
$accountRequest->pass = $pass['pass'];
$accountRequest->key = $pass['key'];
$accountRequest->pass = $encryptedPassword->getPass();
$accountRequest->key = $encryptedPassword->getKey();
}
$this->setPresetPrivate($accountRequest);
@@ -245,35 +231,6 @@ final class AccountService extends Service implements AccountServiceInterface
return $accountRequest->id;
}
/**
* Devolver los datos de la clave encriptados
*
* @throws \SP\Domain\Common\Services\ServiceException
*/
public function getPasswordEncrypted(string $pass, ?string $masterPass = null): array
{
try {
if ($masterPass === null) {
$masterPass = $this->getMasterKeyFromContext();
}
if (empty($masterPass)) {
throw new ServiceException(__u('Master password not set'));
}
$out['key'] = Crypt::makeSecuredKey($masterPass);
$out['pass'] = Crypt::encrypt($pass, $out['key'], $masterPass);
if (strlen($out['pass']) > 1000 || strlen($out['key']) > 1000) {
throw new ServiceException(__u('Internal error'));
}
return $out;
} catch (CryptoException $e) {
throw new ServiceException(__u('Internal error'));
}
}
/**
* @throws QueryException
* @throws ConstraintException
@@ -307,9 +264,10 @@ final class AccountService extends Service implements AccountServiceInterface
}
/**
* @throws QueryException
* @throws NoSuchItemException
* @throws ConstraintException
* @param int $id
*
* @return \SP\DataModel\Dto\AccountEnrichedDto
* @throws \SP\Infrastructure\Common\Repositories\NoSuchItemException
*/
public function getById(int $id): AccountEnrichedDto
{
@@ -406,7 +364,7 @@ final class AccountService extends Service implements AccountServiceInterface
/**
* Updates external items for the account
*
* @param \SP\Domain\Account\Services\AccountRequest $accountRequest
* @param \SP\Domain\Account\Dtos\AccountRequest $accountRequest
*
* @throws \SP\Domain\Common\Services\ServiceException
*/
@@ -557,7 +515,7 @@ final class AccountService extends Service implements AccountServiceInterface
/**
* Update accounts in bulk mode
*
* @param \SP\Domain\Account\Services\AccountBulkRequest $request
* @param \SP\Domain\Account\Dtos\AccountBulkRequest $request
*
* @throws \SP\Domain\Common\Services\ServiceException
*/
@@ -579,7 +537,7 @@ final class AccountService extends Service implements AccountServiceInterface
}
/**
* @param \SP\Domain\Account\Services\AccountRequest $accountRequest
* @param \SP\Domain\Account\Dtos\AccountRequest $accountRequest
*
* @throws \SP\Domain\Common\Services\ServiceException
*/
@@ -602,12 +560,18 @@ final class AccountService extends Service implements AccountServiceInterface
/**
* Updates an already encrypted password data from a master password changing action
*
* @throws ConstraintException
* @throws QueryException
* @param \SP\Domain\Account\Services\AccountPasswordRequest $accountRequest
*
* @return void
* @throws \SP\Core\Exceptions\ConstraintException
* @throws \SP\Core\Exceptions\QueryException
* @throws \SP\Domain\Common\Services\ServiceException
*/
public function updatePasswordMasterPass(AccountPasswordRequest $accountRequest): bool
public function updatePasswordMasterPass(AccountPasswordRequest $accountRequest): void
{
return $this->accountRepository->updatePassword($accountRequest);
if (!$this->accountRepository->updatePassword($accountRequest)) {
throw new ServiceException(__u('Error while updating the password'));
}
}
/**

View File

@@ -31,7 +31,7 @@ use SP\Core\Exceptions\SPException;
use SP\DataModel\ClientData;
use SP\DataModel\ItemData;
use SP\DataModel\ItemSearchData;
use SP\Domain\Account\Services\AccountFilterUserInterface;
use SP\Domain\Account\Ports\AccountFilterUserInterface;
use SP\Domain\Client\Ports\ClientRepositoryInterface;
use SP\Domain\Client\Ports\ClientServiceInterface;
use SP\Domain\Common\Services\Service;
@@ -49,8 +49,8 @@ final class ClientService extends Service implements ClientServiceInterface
{
use ServiceItemTrait;
private ClientRepositoryInterface $clientRepository;
private AccountFilterUserInterface $accountFilterUser;
private ClientRepositoryInterface $clientRepository;
private \SP\Domain\Account\Ports\AccountFilterUserInterface $accountFilterUser;
public function __construct(
Application $application,

View File

@@ -40,6 +40,20 @@ abstract class DataModel implements JsonSerializable
}
}
final public static function buildFromSimpleModel(SimpleModel $model): static
{
return new static($model->toArray());
}
final public function toArray(): array
{
if (count($this->properties) !== 0) {
return $this->properties;
}
return get_object_vars($this);
}
/**
* @param string $name
*
@@ -84,13 +98,4 @@ abstract class DataModel implements JsonSerializable
{
return $this->toArray();
}
final public function toArray(): array
{
if (count($this->properties) !== 0) {
return $this->properties;
}
return get_object_vars($this);
}
}

View File

@@ -24,7 +24,6 @@
namespace SP\Domain\Common\Services;
use SP\Core\Exceptions\SPException;
/**
@@ -35,4 +34,4 @@ use SP\Core\Exceptions\SPException;
final class ServiceException extends SPException
{
}
}

View File

@@ -25,8 +25,7 @@
namespace SP\Domain\Crypt\Services;
use SP\Core\Crypt\Hash;
use SP\Domain\Task\Services\Task;
use SP\Domain\Task\Ports\TaskInterface;
/**
* Class UpdateMasterPassRequest
@@ -35,11 +34,7 @@ use SP\Domain\Task\Services\Task;
*/
final class UpdateMasterPassRequest
{
private string $currentMasterPass;
private string $newMasterPass;
private ?Task $task;
private string $hash;
private string $currentHash;
/**
* UpdateMasterPassRequest constructor.
@@ -47,19 +42,15 @@ final class UpdateMasterPassRequest
* @param string $currentMasterPass
* @param string $newMasterPass
* @param string $currentHash
* @param \SP\Domain\Task\Services\Task|null $task
* @param TaskInterface|null $task
*/
public function __construct(
string $currentMasterPass,
string $newMasterPass,
string $currentHash,
?Task $task = null
private string $currentMasterPass,
private string $newMasterPass,
private string $currentHash,
private ?TaskInterface $task = null
) {
$this->currentMasterPass = $currentMasterPass;
$this->newMasterPass = $newMasterPass;
$this->task = $task;
$this->hash = Hash::hashKey($newMasterPass);
$this->currentHash = $currentHash;
}
public function getCurrentMasterPass(): string
@@ -72,7 +63,7 @@ final class UpdateMasterPassRequest
return $this->newMasterPass;
}
public function getTask(): ?Task
public function getTask(): ?TaskInterface
{
return $this->task;
}
@@ -91,5 +82,4 @@ final class UpdateMasterPassRequest
{
return $this->currentHash;
}
}
}

View File

@@ -32,7 +32,6 @@ use SP\Core\Events\EventMessage;
use SP\Core\Exceptions\SPException;
use SP\DataModel\CategoryData;
use SP\DataModel\ClientData;
use SP\Domain\Account\Services\AccountRequest;
use SP\Infrastructure\File\FileException;
defined('APP_ROOT') || die();
@@ -113,7 +112,7 @@ abstract class CsvImportBase
$categoryId = $this->addCategory(new CategoryData(null, $categoryName));
// Crear la nueva cuenta
$accountRequest = new AccountRequest();
$accountRequest = new \SP\Domain\Account\Dtos\AccountRequest();
$accountRequest->name = $accountName;
$accountRequest->login = $login;
$accountRequest->clientId = $clientId;

View File

@@ -33,8 +33,8 @@ use SP\Core\Exceptions\SPException;
use SP\DataModel\CategoryData;
use SP\DataModel\ClientData;
use SP\DataModel\TagData;
use SP\Domain\Account\Dtos\AccountRequest;
use SP\Domain\Account\Ports\AccountServiceInterface;
use SP\Domain\Account\Services\AccountRequest;
use SP\Domain\Category\Ports\CategoryServiceInterface;
use SP\Domain\Client\Ports\ClientServiceInterface;
use SP\Domain\Tag\Ports\TagServiceInterface;
@@ -80,7 +80,7 @@ trait ImportTrait
* @throws NoSuchPropertyException
* @throws QueryException
*/
protected function addAccount(AccountRequest $accountRequest): void
protected function addAccount(\SP\Domain\Account\Dtos\AccountRequest $accountRequest): void
{
if (empty($accountRequest->categoryId)) {
throw new ImportException(__u('Category Id not set. Unable to import account.'));

View File

@@ -32,7 +32,7 @@ use SP\Core\Events\EventMessage;
use SP\Core\Exceptions\SPException;
use SP\DataModel\CategoryData;
use SP\DataModel\ClientData;
use SP\Domain\Account\Services\AccountRequest;
use SP\Domain\Account\Dtos\AccountRequest;
use SP\Util\Filter;
defined('APP_ROOT') || die();
@@ -79,7 +79,7 @@ final class KeepassImport extends XmlImportBase implements ImportInterface
$this->getEntries();
/** @var AccountRequest[] $group */
/** @var \SP\Domain\Account\Dtos\AccountRequest[] $group */
foreach ($this->items as $group => $entry) {
try {
$categoryId = $this->addCategory(new CategoryData(null, $group, 'KeePass'));
@@ -172,9 +172,9 @@ final class KeepassImport extends XmlImportBase implements ImportInterface
}
}
private function mapEntryToAccount(array $entry): AccountRequest
private function mapEntryToAccount(array $entry): \SP\Domain\Account\Dtos\AccountRequest
{
$accountRequest = new AccountRequest();
$accountRequest = new \SP\Domain\Account\Dtos\AccountRequest();
$accountRequest->name = isset($entry['Title']) ? Filter::getString($entry['Title']) : '';
$accountRequest->login = isset($entry['UserName']) ? Filter::getString($entry['UserName']) : '';
$accountRequest->pass = $entry['Password'] ?? '';

View File

@@ -38,7 +38,6 @@ use SP\Core\Exceptions\SPException;
use SP\DataModel\CategoryData;
use SP\DataModel\ClientData;
use SP\DataModel\TagData;
use SP\Domain\Account\Services\AccountRequest;
use SP\Domain\Export\Services\XmlVerifyService;
use SP\Util\VersionUtil;
@@ -422,7 +421,7 @@ final class SyspassImport extends XmlImportBase implements ImportInterface
'Accounts',
'Account',
function (DOMElement $account) {
$accountRequest = new AccountRequest();
$accountRequest = new \SP\Domain\Account\Dtos\AccountRequest();
/** @var DOMElement $node */
foreach ($account->childNodes as $node) {

View File

@@ -0,0 +1,89 @@
<?php
/*
* sysPass
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2022, 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\Domain\Task\Ports;
use SP\Core\Messages\TaskMessage;
use SP\Infrastructure\File\FileException;
use SP\Infrastructure\File\FileHandlerInterface;
/**
* Class Task
*
* @package SP\Core
*/
interface TaskInterface
{
public function genUid(): string;
/**
* Escribir el tado de la tarea a un archivo
*/
public function writeStatusAndFlush(TaskMessage $message): bool;
/**
* Escribir un mensaje en el archivo de la tarea en formato JSON
*/
public function writeJsonStatusAndFlush(TaskMessage $message): void;
/**
* Iniciar la tarea
*/
public function end(): void;
/**
* Desregistrar la tarea en la sesión
*
* @throws FileException
*/
public function unregister(): void;
public function getInterval(): int;
public function setInterval(int $interval): TaskInterface;
public function getTaskId(): string;
public function getFileOut(): ?FileHandlerInterface;
/**
* Register a task
*
* @throws FileException
*/
public function register(): TaskInterface;
/**
* Register a task
*
* Session is locked in order to allow other scripts execution
*
* @throws FileException
*/
public function registerSession(): TaskInterface;
public function getUid(): string;
public function getFileTask(): ?FileHandlerInterface;
}

View File

@@ -27,26 +27,21 @@ namespace SP\Domain\Task\Services;
use JsonException;
use SP\Core\Context\SessionContext;
use SP\Core\Messages\TaskMessage;
use SP\Domain\Task\Ports\TaskInterface;
use SP\Infrastructure\File\FileException;
use SP\Infrastructure\File\FileHandler;
use SP\Infrastructure\File\FileHandlerInterface;
use SP\Util\Util;
use function SP\logger;
use function SP\processException;
/**
* Class Task
*
* @package SP\Core
*/
final class Task
final class Task implements TaskInterface
{
/**
* @var string Nombre de la tarea
*/
private string $name;
/**
* @var string ID de la tarea
*/
private string $taskId;
private ?FileHandler $fileOut = null;
private ?FileHandler $fileTask = null;
/**
@@ -63,12 +58,10 @@ final class Task
* Task constructor.
*
* @param string $name Nombre de la tarea
* @param string $id
* @param string $taskId
*/
public function __construct(string $name, string $id)
public function __construct(private string $name, private string $taskId)
{
$this->name = $name;
$this->taskId = $id;
$this->initialized = $this->checkFile();
$this->uid = $this->genUid();
}
@@ -202,7 +195,7 @@ final class Task
return $this->interval;
}
public function setInterval(int $interval): Task
public function setInterval(int $interval): TaskInterface
{
$this->interval = $interval;
@@ -224,7 +217,7 @@ final class Task
*
* @throws FileException
*/
public function register(): Task
public function register(): TaskInterface
{
logger("Register Task: $this->name");
@@ -240,7 +233,7 @@ final class Task
*
* @throws FileException
*/
public function registerSession(): Task
public function registerSession(): TaskInterface
{
logger("Register Task (session): $this->name");
@@ -260,4 +253,4 @@ final class Task
{
return $this->fileTask;
}
}
}

View File

@@ -26,6 +26,7 @@ namespace SP\Domain\Task\Services;
use RuntimeException;
use SP\Core\Messages\TaskMessage;
use SP\Domain\Task\Ports\TaskInterface;
use SP\Infrastructure\File\FileException;
/**
@@ -36,7 +37,7 @@ use SP\Infrastructure\File\FileException;
final class TaskFactory
{
/**
* @var Task[]
* @var TaskInterface[]
*/
private static array $tasks = [];
@@ -45,12 +46,9 @@ final class TaskFactory
*
* @throws FileException
*/
public static function create(
string $name,
string $id,
bool $hasSession = true
): Task {
$task = self::add((new Task($name, $id)));
public static function register(TaskInterface $task, bool $hasSession = true): TaskInterface
{
$task = self::add($task);
if ($hasSession) {
return $task->registerSession();
@@ -59,7 +57,7 @@ final class TaskFactory
return $task->register();
}
private static function add(Task $task): Task
private static function add(TaskInterface $task): TaskInterface
{
if (!isset(self::$tasks[$task->getUid()])) {
self::$tasks[$task->getUid()] = $task;
@@ -73,15 +71,14 @@ final class TaskFactory
/**
* Finalizar la tarea
*/
public static function end(Task $task): void
public static function end(TaskInterface $task): void
{
self::get($task->getUid())
->end();
self::get($task->getUid())->end();
self::delete($task->getUid());
}
private static function get(string $id): Task
private static function get(string $id): TaskInterface
{
if (isset(self::$tasks[$id])) {
return self::$tasks[$id];
@@ -97,19 +94,16 @@ final class TaskFactory
}
}
public static function createMessage(
string $taskId,
string $task
): TaskMessage {
public static function createMessage(string $taskId, string $task): TaskMessage
{
return new TaskMessage($taskId, $task);
}
/**
* Enviar un mensaje de actualización a la tarea
*/
public static function update(Task $task, TaskMessage $taskMessage): void
public static function update(TaskInterface $task, TaskMessage $taskMessage): void
{
self::get($task->getUid())
->writeJsonStatusAndFlush($taskMessage);
self::get($task->getUid())->writeJsonStatusAndFlush($taskMessage);
}
}
}

View File

@@ -394,12 +394,12 @@ final class AccountHistoryRepository extends Repository implements AccountHistor
->newUpdate()
->table('AccountHistory')
->cols([
'pass' => $request->pass,
'key' => $request->key,
'mPassHash' => $request->hash,
'pass' => $request->getEncryptedPassword()->getPass(),
'key' => $request->getEncryptedPassword()->getKey(),
'mPassHash' => $request->getHash(),
])
->where('id = :id')
->bindValues(['id' => $request->id]);
->bindValues(['id' => $request->getId()]);
$queryData = QueryData::build($query)->setOnErrorMessage(__u('Error while updating the password'));

View File

@@ -32,10 +32,10 @@ use SP\Core\Exceptions\QueryException;
use SP\Core\Exceptions\SPException;
use SP\DataModel\AccountHistoryData;
use SP\DataModel\ItemSearchData;
use SP\Domain\Account\Dtos\AccountRequest;
use SP\Domain\Account\Ports\AccountFilterUserInterface;
use SP\Domain\Account\Ports\AccountRepositoryInterface;
use SP\Domain\Account\Services\AccountFilterUserInterface;
use SP\Domain\Account\Services\AccountPasswordRequest;
use SP\Domain\Account\Services\AccountRequest;
use SP\Domain\Common\Adapters\SimpleModel;
use SP\Infrastructure\Common\Repositories\Repository;
use SP\Infrastructure\Common\Repositories\RepositoryItemTrait;
@@ -153,7 +153,7 @@ final class AccountRepository extends Repository implements AccountRepositoryInt
/**
* Crea una nueva cuenta en la BBDD
*
* @param AccountRequest $accountRequest
* @param \SP\Domain\Account\Dtos\AccountRequest $accountRequest
*
* @return int
* @throws ConstraintException
@@ -192,7 +192,7 @@ final class AccountRepository extends Repository implements AccountRepositoryInt
/**
* Actualiza la clave de una cuenta en la BBDD.
*
* @param AccountRequest $accountRequest
* @param \SP\Domain\Account\Dtos\AccountRequest $accountRequest
*
* @return int
* @throws ConstraintException
@@ -233,9 +233,14 @@ final class AccountRepository extends Repository implements AccountRepositoryInt
$query = $this->queryFactory
->newUpdate()
->table('Account')
->cols(['pass' => $request->pass, 'key' => $request->key])
->cols(
[
'pass' => $request->getEncryptedPassword()->getPass(),
'key' => $request->getEncryptedPassword()->getKey(),
]
)
->where('id = :id')
->bindValues(['id' => $request->id]);
->bindValues(['id' => $request->getId()]);
$queryData = QueryData::build($query)->setOnErrorMessage(__u('Error while updating the password'));
@@ -351,7 +356,7 @@ final class AccountRepository extends Repository implements AccountRepositoryInt
/**
* Updates an item for bulk action
*
* @param AccountRequest $itemData
* @param \SP\Domain\Account\Dtos\AccountRequest $itemData
*
* @return int
* @throws SPException

View File

@@ -30,10 +30,10 @@ use Aura\SqlQuery\QueryFactory;
use SP\Core\Context\ContextInterface;
use SP\Core\Events\EventDispatcherInterface;
use SP\DataModel\AccountSearchVData;
use SP\Domain\Account\Ports\AccountFilterUserInterface;
use SP\Domain\Account\Ports\AccountSearchRepositoryInterface;
use SP\Domain\Account\Search\AccountSearchConstants;
use SP\Domain\Account\Search\AccountSearchFilter;
use SP\Domain\Account\Services\AccountFilterUserInterface;
use SP\Infrastructure\Common\Repositories\Repository;
use SP\Infrastructure\Database\DatabaseInterface;
use SP\Infrastructure\Database\QueryData;

View File

@@ -24,8 +24,8 @@
namespace SP\Infrastructure\Account\Repositories;
use SP\Domain\Account\Dtos\AccountRequest;
use SP\Domain\Account\Ports\AccountToTagRepositoryInterface;
use SP\Domain\Account\Services\AccountRequest;
use SP\Infrastructure\Common\Repositories\Repository;
use SP\Infrastructure\Common\Repositories\RepositoryItemTrait;
use SP\Infrastructure\Database\QueryData;
@@ -92,7 +92,7 @@ final class AccountToTagRepository extends Repository implements AccountToTagRep
/**
* Actualizar las etiquetas de una cuenta
*
* @param AccountRequest $accountRequest
* @param \SP\Domain\Account\Dtos\AccountRequest $accountRequest
*
* @return void
* @throws \SP\Core\Exceptions\ConstraintException

View File

@@ -46,7 +46,7 @@ class AccountAdapterTest extends UnitaryTestCase
$this->config->getConfigData(),
$this->createStub(CustomFieldServiceInterface::class)
);
$accountData = $dataGenerator->getAccountData();
$accountData = $dataGenerator->buildAccountEnrichedData();
$out = $adapter->transform($accountData);
@@ -113,7 +113,7 @@ class AccountAdapterTest extends UnitaryTestCase
$fractal = new Manager();
$fractal->parseIncludes('customFields');
$out = $fractal->createData(
new Item(AccountDataGenerator::factory()->getAccountData(), $adapter)
new Item(AccountDataGenerator::factory()->buildAccountEnrichedData(), $adapter)
)->toArray();
$this->assertArrayHasKey('customFields', $out['data']);

View File

@@ -0,0 +1,370 @@
<?php
/*
* sysPass
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2022, 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\Domain\Account\Services;
use PHPUnit\Framework\MockObject\MockObject;
use SP\Core\Crypt\CryptInterface;
use SP\Core\Exceptions\SPException;
use SP\Domain\Account\Ports\AccountHistoryServiceInterface;
use SP\Domain\Account\Ports\AccountServiceInterface;
use SP\Domain\Account\Services\AccountCryptService;
use SP\Domain\Common\Services\ServiceException;
use SP\Domain\Crypt\Services\UpdateMasterPassRequest;
use SP\Domain\Task\Ports\TaskInterface;
use SP\Domain\Task\Services\TaskFactory;
use SP\Tests\Generators\AccountDataGenerator;
use SP\Tests\UnitaryTestCase;
/**
* Class AccountCryptServiceTest
*/
class AccountCryptServiceTest extends UnitaryTestCase
{
private MockObject|AccountServiceInterface $accountService;
private MockObject|AccountHistoryServiceInterface $accountHistoryService;
private AccountCryptService $accountCryptService;
private MockObject|CryptInterface $crypt;
/**
* @throws \SP\Domain\Common\Services\ServiceException
* @throws \SP\Infrastructure\File\FileException
*/
public function testUpdateMasterPassword(): void
{
$task = $this->createMock(TaskInterface::class);
$task->method('getUid')
->willReturn(self::$faker->uuid);
$task->method('getTaskId')
->willReturn((string)self::$faker->randomNumber());
$task->method('registerSession')
->willReturnSelf();
$request =
new UpdateMasterPassRequest(
self::$faker->password,
self::$faker->password,
self::$faker->sha1,
TaskFactory::register($task)
);
$accountData = array_map(static fn() => AccountDataGenerator::factory()->buildAccountData(), range(0, 9));
$this->accountService->expects(self::once())
->method('getAccountsPassData')
->willReturn($accountData);
$this->accountService->expects(self::exactly(10))
->method('updatePasswordMasterPass');
$this->crypt->expects(self::exactly(10))
->method('decrypt');
$this->crypt->expects(self::exactly(10))
->method('makeSecuredKey')
->willReturn(self::$faker->password);
$this->crypt->expects(self::exactly(10))
->method('encrypt')
->willReturn(self::$faker->password);
$task->expects(self::exactly(2))
->method('writeJsonStatusAndFlush');
$this->accountCryptService->updateMasterPassword($request);
}
/**
* @throws \SP\Domain\Common\Services\ServiceException
*/
public function testUpdateMasterPasswordWithNoAccounts(): void
{
$request =
new UpdateMasterPassRequest(
self::$faker->password,
self::$faker->password,
self::$faker->sha1
);
$this->accountService->expects(self::once())
->method('getAccountsPassData')
->willReturn([]);
$this->accountService->expects(self::never())
->method('updatePasswordMasterPass');
$this->crypt->expects(self::never())
->method('decrypt');
$this->crypt->expects(self::never())
->method('makeSecuredKey');
$this->crypt->expects(self::never())
->method('encrypt');
$this->accountCryptService->updateMasterPassword($request);
}
/**
* @throws \SP\Domain\Common\Services\ServiceException
*/
public function testUpdateMasterPasswordDoesNotThrowException(): void
{
$request = new UpdateMasterPassRequest(self::$faker->password, self::$faker->password, self::$faker->sha1);
$accountData = array_map(static fn() => AccountDataGenerator::factory()->buildAccountData(), range(0, 9));
$this->accountService->expects(self::once())
->method('getAccountsPassData')
->willReturn($accountData);
$this->crypt->expects(self::exactly(10))
->method('decrypt')
->willThrowException(new SPException('test'));
$this->accountCryptService->updateMasterPassword($request);
}
/**
* @throws \SP\Domain\Common\Services\ServiceException
*/
public function testUpdateMasterPasswordThrowException(): void
{
$request = new UpdateMasterPassRequest(self::$faker->password, self::$faker->password, self::$faker->sha1);
$this->accountService->expects(self::once())
->method('getAccountsPassData')
->willThrowException(new \RuntimeException('test'));
$this->expectException(ServiceException::class);
$this->expectExceptionMessage('Error while updating the accounts\' passwords');
$this->accountCryptService->updateMasterPassword($request);
}
/**
* @throws \SP\Domain\Common\Services\ServiceException
* @throws \SP\Infrastructure\File\FileException
*/
public function testUpdateHistoryMasterPassword(): void
{
$task = $this->createMock(TaskInterface::class);
$task->method('getUid')
->willReturn(self::$faker->uuid);
$task->method('getTaskId')
->willReturn((string)self::$faker->randomNumber());
$task->method('registerSession')
->willReturnSelf();
$request =
new UpdateMasterPassRequest(
self::$faker->password,
self::$faker->password,
self::$faker->sha1,
TaskFactory::register($task)
);
$accountData = array_map(static fn() => AccountDataGenerator::factory()->buildAccountData(), range(0, 9));
$this->accountHistoryService->expects(self::once())
->method('getAccountsPassData')
->willReturn($accountData);
$this->accountHistoryService->expects(self::exactly(10))
->method('updatePasswordMasterPass');
$this->crypt->expects(self::exactly(10))
->method('decrypt');
$task->expects(self::exactly(2))
->method('writeJsonStatusAndFlush');
$this->accountCryptService->updateHistoryMasterPassword($request);
}
/**
* @throws \SP\Domain\Common\Services\ServiceException
*/
public function testUpdateHistoryMasterPasswordWithNoAccounts(): void
{
$request =
new UpdateMasterPassRequest(
self::$faker->password,
self::$faker->password,
self::$faker->sha1
);
$this->accountHistoryService->expects(self::once())
->method('getAccountsPassData')
->willReturn([]);
$this->accountHistoryService->expects(self::never())
->method('updatePasswordMasterPass');
$this->crypt->expects(self::never())
->method('decrypt');
$this->crypt->expects(self::never())
->method('makeSecuredKey');
$this->crypt->expects(self::never())
->method('encrypt');
$this->accountCryptService->updateHistoryMasterPassword($request);
}
/**
* @throws \SP\Domain\Common\Services\ServiceException
*/
public function testUpdateHistoryMasterPasswordThrowException(): void
{
$request = new UpdateMasterPassRequest(self::$faker->password, self::$faker->password, self::$faker->sha1);
$this->accountHistoryService->expects(self::once())
->method('getAccountsPassData')
->willThrowException(new \RuntimeException('test'));
$this->expectException(ServiceException::class);
$this->expectExceptionMessage('Error while updating the accounts\' passwords in history');
$this->accountCryptService->updateHistoryMasterPassword($request);
}
/**
* @throws \SP\Domain\Common\Services\ServiceException
*/
public function testUpdateHistoryMasterPasswordDoesNotThrowException(): void
{
$request = new UpdateMasterPassRequest(self::$faker->password, self::$faker->password, self::$faker->sha1);
$accountData = array_map(static fn() => AccountDataGenerator::factory()->buildAccountData(), range(0, 9));
$this->accountHistoryService->expects(self::once())
->method('getAccountsPassData')
->willReturn($accountData);
$this->crypt->expects(self::exactly(10))
->method('decrypt')
->willThrowException(new SPException('test'));
$this->accountCryptService->updateHistoryMasterPassword($request);
}
/**
* @throws \SP\Domain\Common\Services\ServiceException
*/
public function testGetPasswordEncrypted(): void
{
$pass = self::$faker->password;
$key = self::$faker->password;
$masterPass = self::$faker->password;
$this->crypt->expects(self::once())
->method('makeSecuredKey')
->with($masterPass)
->willReturn($key);
$this->crypt->expects(self::once())
->method('encrypt')
->with($pass)
->willReturn($pass);
$out = $this->accountCryptService->getPasswordEncrypted($pass, $masterPass);
$this->assertEquals($pass, $out->getPass());
$this->assertEquals($key, $out->getKey());
}
/**
* @throws \SP\Domain\Common\Services\ServiceException
* @throws \SP\Core\Context\ContextException
*/
public function testGetPasswordEncryptedThrowsExceptionWithNoMasterPassword(): void
{
$this->context->setTrasientKey('_masterpass', '');
$this->crypt->expects(self::never())
->method('makeSecuredKey');
$this->crypt->expects(self::never())
->method('encrypt');
$this->expectException(ServiceException::class);
$this->expectExceptionMessage('Error while retrieving master password from context');
$this->accountCryptService->getPasswordEncrypted(self::$faker->password);
}
/**
* @throws \SP\Domain\Common\Services\ServiceException
*/
public function testGetPasswordEncryptedThrowsExceptionWithEmptyMasterPassword(): void
{
$this->crypt->expects(self::never())
->method('makeSecuredKey');
$this->crypt->expects(self::never())
->method('encrypt');
$this->expectException(ServiceException::class);
$this->expectExceptionMessage('Master password not set');
$this->accountCryptService->getPasswordEncrypted(self::$faker->password, '');
}
/**
* @throws \SP\Domain\Common\Services\ServiceException
*/
public function testGetPasswordEncryptedThrowsExceptionWithLongPass(): void
{
$this->crypt->expects(self::once())
->method('makeSecuredKey')
->willReturn(self::$faker->password);
$this->crypt->expects(self::once())
->method('encrypt')
->willReturn(self::$faker->text(1500));
$this->expectException(ServiceException::class);
$this->expectExceptionMessage('Internal error');
$this->accountCryptService->getPasswordEncrypted(self::$faker->password, self::$faker->password);
}
/**
* @throws \SP\Domain\Common\Services\ServiceException
*/
public function testGetPasswordEncryptedThrowsExceptionWithLongKey(): void
{
$this->crypt->expects(self::once())
->method('makeSecuredKey')
->willReturn(self::$faker->text(1500));
$this->crypt->expects(self::once())
->method('encrypt')
->willReturn(self::$faker->password);
$this->expectException(ServiceException::class);
$this->expectExceptionMessage('Internal error');
$this->accountCryptService->getPasswordEncrypted(self::$faker->password, self::$faker->password);
}
protected function setUp(): void
{
parent::setUp();
$this->accountService = $this->createMock(AccountServiceInterface::class);
$this->accountHistoryService = $this->createMock(AccountHistoryServiceInterface::class);
$this->crypt = $this->createMock(CryptInterface::class);
$this->accountCryptService =
new AccountCryptService(
$this->application,
$this->accountService,
$this->accountHistoryService,
$this->crypt
);
}
}

View File

@@ -27,15 +27,26 @@ namespace SP\Tests\Generators;
use SP\DataModel\AccountVData;
use SP\DataModel\Dto\AccountEnrichedDto;
use SP\DataModel\ItemData;
use SP\Domain\Common\Adapters\SimpleModel;
/**
* Class AccountDataGenerator
*/
final class AccountDataGenerator extends DataGenerator
{
public function getAccountData(): AccountEnrichedDto
public function buildAccountEnrichedData(): AccountEnrichedDto
{
$accountData = new AccountVData([
$out = new AccountEnrichedDto(AccountVData::buildFromSimpleModel($this->buildAccountData()));
$out->setUsers($this->buildItemData());
$out->setTags($this->buildItemData());
$out->setUserGroups($this->buildItemData());
return $out;
}
public function buildAccountData(): SimpleModel
{
return new SimpleModel([
'id' => $this->faker->randomNumber(),
'name' => $this->faker->name,
'clientId' => $this->faker->randomNumber(),
@@ -65,13 +76,9 @@ final class AccountDataGenerator extends DataGenerator
'passDateChange' => $this->faker->unixTime,
'parentId' => $this->faker->randomNumber(),
'publicLinkHash' => $this->faker->sha1,
'pass' => $this->faker->password,
'key' => $this->faker->sha1,
]);
$out = new AccountEnrichedDto($accountData);
$out->setUsers($this->buildItemData());
$out->setTags($this->buildItemData());
$out->setUserGroups($this->buildItemData());
return $out;
}
/**

View File

@@ -29,9 +29,9 @@ use PHPUnit\Framework\Constraint\Callback;
use PHPUnit\Framework\MockObject\MockObject;
use SP\DataModel\AccountHistoryData;
use SP\DataModel\ItemSearchData;
use SP\Domain\Account\Dtos\AccountRequest;
use SP\Domain\Account\Services\AccountFilterUser;
use SP\Domain\Account\Services\AccountPasswordRequest;
use SP\Domain\Account\Services\AccountRequest;
use SP\Domain\Common\Adapters\SimpleModel;
use SP\Infrastructure\Account\Repositories\AccountRepository;
use SP\Infrastructure\Database\DatabaseInterface;

View File

@@ -27,7 +27,7 @@ namespace SP\Tests\Infrastructure\Account\Repositories;
use Aura\SqlQuery\QueryFactory;
use PHPUnit\Framework\Constraint\Callback;
use PHPUnit\Framework\MockObject\MockObject;
use SP\Domain\Account\Services\AccountRequest;
use SP\Domain\Account\Dtos\AccountRequest;
use SP\Domain\Common\Adapters\SimpleModel;
use SP\Infrastructure\Account\Repositories\AccountToTagRepository;
use SP\Infrastructure\Database\DatabaseInterface;

View File

@@ -30,8 +30,8 @@ use SP\Core\Context\ContextException;
use SP\Core\Exceptions\ConstraintException;
use SP\Core\Exceptions\QueryException;
use SP\DataModel\ItemData;
use SP\Domain\Account\Dtos\AccountRequest;
use SP\Domain\Account\Ports\AccountToTagRepositoryInterface;
use SP\Domain\Account\Services\AccountRequest;
use SP\Infrastructure\Account\Repositories\AccountToTagRepository;
use SP\Tests\DatabaseTestCase;
use function SP\Tests\setupContext;

View File

@@ -30,8 +30,8 @@ use SP\Core\Context\ContextException;
use SP\Core\Exceptions\ConstraintException;
use SP\Core\Exceptions\QueryException;
use SP\DataModel\ItemData;
use SP\Domain\Account\Dtos\AccountRequest;
use SP\Domain\Account\Ports\AccountToUserGroupRepositoryInterface;
use SP\Domain\Account\Services\AccountRequest;
use SP\Infrastructure\Account\Repositories\AccountToUserGroupRepository;
use SP\Tests\DatabaseTestCase;
use function SP\Tests\setupContext;

View File

@@ -30,8 +30,8 @@ use SP\Core\Context\ContextException;
use SP\Core\Exceptions\ConstraintException;
use SP\Core\Exceptions\QueryException;
use SP\DataModel\ItemData;
use SP\Domain\Account\Dtos\AccountRequest;
use SP\Domain\Account\Ports\AccountToUserRepositoryInterface;
use SP\Domain\Account\Services\AccountRequest;
use SP\Infrastructure\Account\Repositories\AccountToUserRepository;
use SP\Tests\DatabaseTestCase;
use function SP\Tests\setupContext;

View File

@@ -40,12 +40,12 @@ use SP\DataModel\AccountVData;
use SP\DataModel\ItemSearchData;
use SP\DataModel\ProfileData;
use SP\Domain\Account\Adapters\AccountData;
use SP\Domain\Account\Dtos\AccountBulkRequest;
use SP\Domain\Account\Dtos\AccountRequest;
use SP\Domain\Account\Ports\AccountHistoryServiceInterface;
use SP\Domain\Account\Search\AccountSearchFilter;
use SP\Domain\Account\Services\AccountBulkRequest;
use SP\Domain\Account\Services\AccountHistoryService;
use SP\Domain\Account\Services\AccountPasswordRequest;
use SP\Domain\Account\Services\AccountRequest;
use SP\Domain\Account\Services\AccountService;
use SP\Domain\Common\Services\ServiceException;
use SP\Domain\User\Services\UserLoginResponse;

View File

@@ -1,10 +1,10 @@
<?php
/**
/*
* sysPass
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2022, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
@@ -19,7 +19,7 @@
* 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/>.
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Tests\Services\Task;
@@ -51,7 +51,7 @@ class TaskServiceTest extends TestCase
{
$this->markTestSkipped();
$task = TaskFactory::create(__FUNCTION__, Task::genTaskId(__FUNCTION__));
$task = TaskFactory::register(__FUNCTION__, Task::genTaskId(__FUNCTION__));
$this->assertFileExists($task->getFileTask()->getFile());