diff --git a/lib/SP/Repositories/Account/AccountRepository.php b/lib/SP/Repositories/Account/AccountRepository.php index 3ceb0c6c..0ba7dd83 100644 --- a/lib/SP/Repositories/Account/AccountRepository.php +++ b/lib/SP/Repositories/Account/AccountRepository.php @@ -41,7 +41,6 @@ use SP\DataModel\ItemSearchData; use SP\Mvc\Model\QueryAssignment; use SP\Mvc\Model\QueryCondition; use SP\Mvc\Model\QueryJoin; -use SP\Repositories\NoSuchItemException; use SP\Repositories\Repository; use SP\Repositories\RepositoryItemInterface; use SP\Repositories\RepositoryItemTrait; @@ -103,7 +102,7 @@ class AccountRepository extends Repository implements RepositoryItemInterface /** * @param QueryCondition $queryCondition * - * @return AccountPassData + * @return QueryResult * @throws ConstraintException * @throws QueryException */ @@ -126,7 +125,7 @@ class AccountRepository extends Repository implements RepositoryItemInterface $queryData->setQuery($query); $queryData->setParams($queryCondition->getParams()); - return $this->db->doSelect($queryData)->getData(); + return $this->db->doSelect($queryData); } /** @@ -399,8 +398,7 @@ class AccountRepository extends Repository implements RepositoryItemInterface * * @param int $id * - * @return AccountVData - * @throws NoSuchItemException + * @return QueryResult * @throws QueryException * @throws ConstraintException */ @@ -412,19 +410,13 @@ class AccountRepository extends Repository implements RepositoryItemInterface $queryData->addParam($id); $queryData->setOnErrorMessage(__u('No se pudieron obtener los datos de la cuenta')); - $result = $this->db->doSelect($queryData); - - if ($result->getNumRows() === 0) { - throw new NoSuchItemException(__u('La cuenta no existe')); - } - - return $result->getData(); + return $this->db->doSelect($queryData); } /** * Returns all the items * - * @return AccountData[] + * @return QueryResult * @throws ConstraintException * @throws QueryException */ @@ -434,7 +426,7 @@ class AccountRepository extends Repository implements RepositoryItemInterface $queryData->setMapClassName(AccountData::class); $queryData->setQuery('SELECT * FROM Account ORDER BY id'); - return $this->db->doSelect($queryData)->getDataAsArray(); + return $this->db->doSelect($queryData); } /** @@ -564,17 +556,18 @@ class AccountRepository extends Repository implements RepositoryItemInterface public function getDataForLink($id) { $query = /** @lang SQL */ - 'SELECT Account.name, + 'SELECT Account.id, + Account.name, Account.login, Account.pass, Account.key, Account.url, Account.notes, - C.name AS clientName, - C2.name AS categoryName + Client.name AS clientName, + Category.name AS categoryName FROM Account - INNER JOIN Client C ON Account.clientId = C.id - INNER JOIN Category C2 ON Account.categoryId = C2.id + INNER JOIN Client ON Account.clientId = Client.id + INNER JOIN Category ON Account.categoryId = Category.id WHERE Account.id = ? LIMIT 1'; $queryData = new QueryData(); @@ -583,7 +576,7 @@ class AccountRepository extends Repository implements RepositoryItemInterface $queryData->addParam($id); $queryData->setOnErrorMessage(__u('No se pudieron obtener los datos de la cuenta')); - return $this->db->doSelect($queryData, true); + return $this->db->doSelect($queryData); } /** @@ -672,7 +665,7 @@ class AccountRepository extends Repository implements RepositoryItemInterface /** * @param QueryCondition $queryFilter * - * @return array + * @return QueryResult * @throws ConstraintException * @throws QueryException */ @@ -689,29 +682,29 @@ class AccountRepository extends Repository implements RepositoryItemInterface $queryData->setQuery($query); $queryData->setParams($queryFilter->getParams()); - return $this->db->doSelect($queryData)->getDataAsArray(); + return $this->db->doSelect($queryData); } /** * @param QueryCondition $queryFilter * - * @return array + * @return QueryResult * @throws ConstraintException * @throws QueryException */ public function getLinked(QueryCondition $queryFilter) { $query = /** @lang SQL */ - 'SELECT Account.id, Account.name, C.name AS clientName + 'SELECT Account.id, Account.name, Client.name AS clientName FROM Account - INNER JOIN Client C ON Account.clientId = C.id - WHERE ' . $queryFilter->getFilters() . ' ORDER BY name'; + INNER JOIN Client ON Account.clientId = Client.id + WHERE ' . $queryFilter->getFilters() . ' ORDER BY Account.name'; $queryData = new QueryData(); $queryData->setQuery($query); $queryData->setParams($queryFilter->getParams()); - return $this->db->doSelect($queryData)->getDataAsArray(); + return $this->db->doSelect($queryData); } /** diff --git a/lib/SP/Services/Account/AccountService.php b/lib/SP/Services/Account/AccountService.php index 90cf1f67..2aea99c8 100644 --- a/lib/SP/Services/Account/AccountService.php +++ b/lib/SP/Services/Account/AccountService.php @@ -48,6 +48,7 @@ use SP\Services\Config\ConfigService; use SP\Services\Service; use SP\Services\ServiceException; use SP\Services\ServiceItemTrait; +use SP\Storage\Database\Database; use SP\Storage\Database\QueryResult; /** @@ -86,7 +87,13 @@ class AccountService extends Service implements AccountServiceInterface */ public function getById($id) { - return new AccountDetailsResponse($id, $this->accountRepository->getById($id)); + $result = $this->accountRepository->getById($id); + + if ($result->getNumRows() === 0) { + throw new NoSuchItemException(__u('La cuenta no existe')); + } + + return new AccountDetailsResponse($id, $result->getData()); } /** @@ -277,26 +284,36 @@ class AccountService extends Service implements AccountServiceInterface * * @param AccountRequest $accountRequest * - * @throws QueryException - * @throws SPException - * @throws \Psr\Container\ContainerExceptionInterface - * @throws \Psr\Container\NotFoundExceptionInterface - * @throws \SP\Core\Exceptions\ConstraintException - * @throws \SP\Services\Config\ParameterNotFoundException + * @throws ServiceException + * @throws \Exception */ public function update(AccountRequest $accountRequest) { - $accountRequest->changePermissions = AccountAclService::getShowPermission($this->context->getUserData(), $this->context->getUserProfile()); + $database = $this->dic->get(Database::class); - // Cambiar el grupo principal si el usuario es Admin - $accountRequest->changeUserGroup = ($accountRequest->userGroupId !== 0 - && ($this->context->getUserData()->getIsAdminApp() || $this->context->getUserData()->getIsAdminAcc())); + if ($database->beginTransaction()) { + try { + $accountRequest->changePermissions = AccountAclService::getShowPermission($this->context->getUserData(), $this->context->getUserProfile()); - $this->addHistory($accountRequest->id); + // Cambiar el grupo principal si el usuario es Admin + $accountRequest->changeUserGroup = ($accountRequest->userGroupId !== 0 + && ($this->context->getUserData()->getIsAdminApp() || $this->context->getUserData()->getIsAdminAcc())); - $this->accountRepository->update($accountRequest); + $this->addHistory($accountRequest->id); - $this->updateItems($accountRequest); + $this->accountRepository->update($accountRequest); + + $this->updateItems($accountRequest); + + $database->endTransaction(); + } catch (\Exception $e) { + $database->rollbackTransaction(); + + throw $e; + } + } else { + throw new ServiceException(__u('No es posible iniciar una transacción')); + } } /** @@ -315,7 +332,8 @@ class AccountService extends Service implements AccountServiceInterface $accountHistoryRepository = $this->dic->get(AccountHistoryService::class); $configService = $this->dic->get(ConfigService::class); - return $accountHistoryRepository->create(new AccountHistoryCreateDto( + return $accountHistoryRepository->create( + new AccountHistoryCreateDto( $accountId, $isDelete, !$isDelete, @@ -327,75 +345,81 @@ class AccountService extends Service implements AccountServiceInterface * Updates external items for the account * * @param AccountRequest $accountRequest + * + * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException */ protected function updateItems(AccountRequest $accountRequest) { - try { - - if ($accountRequest->changePermissions) { - if ($accountRequest->updateUserGroupPermissions) { - if (!empty($accountRequest->userGroupsView)) { - $this->accountToUserGroupRepository->update($accountRequest); - } else { - $this->accountToUserGroupRepository->deleteByAccountId($accountRequest->id); - } - - if (!empty($accountRequest->userGroupsEdit)) { - $this->accountToUserGroupRepository->updateEdit($accountRequest); - } else { - $this->accountToUserGroupRepository->deleteEditByAccountId($accountRequest->id); - } - } - - if ($accountRequest->updateUserPermissions) { - if (!empty($accountRequest->usersView)) { - $this->accountToUserRepository->update($accountRequest); - } else { - $this->accountToUserRepository->deleteByAccountId($accountRequest->id); - } - - if (!empty($accountRequest->usersEdit)) { - $this->accountToUserRepository->updateEdit($accountRequest); - } else { - $this->accountToUserRepository->deleteEditByAccountId($accountRequest->id); - } - } - } - - if ($accountRequest->updateTags) { - if (!empty($accountRequest->tags)) { - $this->accountToTagRepository->update($accountRequest); + if ($accountRequest->changePermissions) { + if ($accountRequest->updateUserGroupPermissions) { + if (!empty($accountRequest->userGroupsView)) { + $this->accountToUserGroupRepository->update($accountRequest); } else { - $this->accountToTagRepository->deleteByAccountId($accountRequest->id); + $this->accountToUserGroupRepository->deleteByAccountId($accountRequest->id); + } + + if (!empty($accountRequest->userGroupsEdit)) { + $this->accountToUserGroupRepository->updateEdit($accountRequest); + } else { + $this->accountToUserGroupRepository->deleteEditByAccountId($accountRequest->id); } } - } catch (SPException $e) { - processException($e); + + if ($accountRequest->updateUserPermissions) { + if (!empty($accountRequest->usersView)) { + $this->accountToUserRepository->update($accountRequest); + } else { + $this->accountToUserRepository->deleteByAccountId($accountRequest->id); + } + + if (!empty($accountRequest->usersEdit)) { + $this->accountToUserRepository->updateEdit($accountRequest); + } else { + $this->accountToUserRepository->deleteEditByAccountId($accountRequest->id); + } + } + } + + if ($accountRequest->updateTags) { + if (!empty($accountRequest->tags)) { + $this->accountToTagRepository->update($accountRequest); + } else { + $this->accountToTagRepository->deleteByAccountId($accountRequest->id); + } } } /** * @param AccountRequest $accountRequest - * @param bool $addHistory * - * @throws SPException - * @throws \Psr\Container\ContainerExceptionInterface - * @throws \Psr\Container\NotFoundExceptionInterface - * @throws \SP\Core\Exceptions\ConstraintException - * @throws \SP\Services\Config\ParameterNotFoundException + * @throws ServiceException + * @throws \Exception */ - public function editPassword(AccountRequest $accountRequest, $addHistory = true) + public function editPassword(AccountRequest $accountRequest) { - if ($addHistory) { - $this->addHistory($accountRequest->id); + $database = $this->dic->get(Database::class); + + if ($database->beginTransaction()) { + try { + $this->addHistory($accountRequest->id); + + $pass = $this->getPasswordEncrypted($accountRequest->pass); + + $accountRequest->pass = $pass['pass']; + $accountRequest->key = $pass['key']; + + $this->accountRepository->editPassword($accountRequest); + + $database->endTransaction(); + } catch (\Exception $e) { + $database->rollbackTransaction(); + + throw $e; + } + } else { + throw new ServiceException(__u('No es posible iniciar una transacción')); } - - $pass = $this->getPasswordEncrypted($accountRequest->pass); - - $accountRequest->pass = $pass['pass']; - $accountRequest->key = $pass['key']; - - $this->accountRepository->editPassword($accountRequest); } /** @@ -416,17 +440,30 @@ class AccountService extends Service implements AccountServiceInterface * @param $historyId * @param $accountId * - * @throws QueryException - * @throws \Psr\Container\ContainerExceptionInterface - * @throws \Psr\Container\NotFoundExceptionInterface - * @throws \SP\Core\Exceptions\ConstraintException - * @throws \SP\Services\Config\ParameterNotFoundException + * @throws ServiceException + * @throws \Exception */ public function editRestore($historyId, $accountId) { - $this->addHistory($accountId); + $database = $this->dic->get(Database::class); - $this->accountRepository->editRestore($historyId, $this->context->getUserData()->getId()); + if ($database->beginTransaction()) { + try { + $this->addHistory($accountId); + + if (!$this->accountRepository->editRestore($historyId, $this->context->getUserData()->getId())) { + throw new ServiceException(__u('Error al restaurar cuenta')); + } + + $database->endTransaction(); + } catch (\Exception $e) { + $database->rollbackTransaction(); + + throw $e; + } + } else { + throw new ServiceException(__u('No es posible iniciar una transacción')); + } } /** @@ -477,7 +514,7 @@ class AccountService extends Service implements AccountServiceInterface $queryFilter->addFilter('Account.id <> ? AND (Account.parentId = 0 OR Account.parentId IS NULL)', [$accountId]); } - return $this->accountRepository->getForUser($queryFilter); + return $this->accountRepository->getForUser($queryFilter)->getDataAsArray(); } /** @@ -492,7 +529,7 @@ class AccountService extends Service implements AccountServiceInterface $queryFilter = AccountUtil::getAccountFilterUser($this->context) ->addFilter('Account.parentId = ?', [$accountId]); - return $this->accountRepository->getLinked($queryFilter); + return $this->accountRepository->getLinked($queryFilter)->getDataAsArray(); } /** @@ -501,13 +538,20 @@ class AccountService extends Service implements AccountServiceInterface * @return AccountPassData * @throws QueryException * @throws \SP\Core\Exceptions\ConstraintException + * @throws NoSuchItemException */ public function getPasswordHistoryForId($id) { $queryFilter = AccountUtil::getAccountHistoryFilterUser($this->context) ->addFilter('AccountHistory.id = ?', [$id]); - return $this->accountRepository->getPasswordHistoryForId($queryFilter); + $result = $this->accountRepository->getPasswordHistoryForId($queryFilter); + + if ($result->getNumRows() === 0) { + throw new NoSuchItemException(__u('La cuenta no existe')); + } + + return $result->getData(); } /** @@ -517,7 +561,7 @@ class AccountService extends Service implements AccountServiceInterface */ public function getAllBasic() { - return $this->accountRepository->getAll(); + return $this->accountRepository->getAll()->getDataAsArray(); } /** diff --git a/lib/SP/Services/Crypt/MasterPassService.php b/lib/SP/Services/Crypt/MasterPassService.php index 8542493c..8bef9ac9 100644 --- a/lib/SP/Services/Crypt/MasterPassService.php +++ b/lib/SP/Services/Crypt/MasterPassService.php @@ -85,31 +85,31 @@ class MasterPassService extends Service { $db = $this->dic->get(Database::class); - try { - if (!$db->beginTransaction()) { - throw new ServiceException(__u('No es posible iniciar una transacción'), ServiceException::ERROR); + if (!$db->beginTransaction()) { + try { + $this->accountCryptService->updateMasterPassword($request); + + $this->accountCryptService->updateHistoryMasterPassword($request); + + $this->customFieldCryptService->updateMasterPassword($request); + + if (!$db->endTransaction()) { + throw new ServiceException(__u('No es posible finalizar una transacción')); + } + } catch (\Exception $e) { + if ($db->rollbackTransaction()) { + $this->eventDispatcher->notifyEvent('update.masterPassword.rollback', + new Event($this, EventMessage::factory() + ->addDescription(__u('Rollback'))) + ); + + debugLog('Rollback'); + } + + throw $e; } - - $this->accountCryptService->updateMasterPassword($request); - - $this->accountCryptService->updateHistoryMasterPassword($request); - - $this->customFieldCryptService->updateMasterPassword($request); - - if (!$db->endTransaction()) { - throw new ServiceException(__u('No es posible finalizar una transacción'), ServiceException::ERROR); - } - } catch (\Exception $e) { - if ($db->rollbackTransaction()) { - $this->eventDispatcher->notifyEvent('update.masterPassword.rollback', - new Event($this, EventMessage::factory() - ->addDescription(__u('Rollback'))) - ); - - debugLog('Rollback'); - } - - throw $e; + } else { + throw new ServiceException(__u('No es posible iniciar una transacción')); } } diff --git a/lib/SP/Storage/Database/DBStorageInterface.php b/lib/SP/Storage/Database/DBStorageInterface.php index 9d6ac3d8..c7092d7b 100644 --- a/lib/SP/Storage/Database/DBStorageInterface.php +++ b/lib/SP/Storage/Database/DBStorageInterface.php @@ -24,8 +24,6 @@ namespace SP\Storage\Database; -use SP\Core\Exceptions\SPException; - /** * Interface DBStorageInterface * @@ -37,7 +35,6 @@ interface DBStorageInterface * Obtener una conexión PDO * * @return \PDO - * @throws SPException */ public function getConnection(); @@ -45,7 +42,6 @@ interface DBStorageInterface * Obtener una conexión PDO sin seleccionar la BD * * @return \PDO - * @throws SPException */ public function getConnectionSimple(); diff --git a/lib/SP/Storage/Database/Database.php b/lib/SP/Storage/Database/Database.php index 828d01cb..fe9d6a47 100644 --- a/lib/SP/Storage/Database/Database.php +++ b/lib/SP/Storage/Database/Database.php @@ -26,6 +26,9 @@ namespace SP\Storage\Database; use PDO; use PDOStatement; +use SP\Core\Events\Event; +use SP\Core\Events\EventDispatcher; +use SP\Core\Events\EventMessage; use SP\Core\Exceptions\ConstraintException; use SP\Core\Exceptions\QueryException; use SP\Core\Exceptions\SPException; @@ -57,15 +60,21 @@ class Database implements DatabaseInterface * @var int Último Id de elemento insertado/actualizado */ private $lastId; + /** + * @var EventDispatcher + */ + private $eventDispatcher; /** * DB constructor. * * @param DBStorageInterface $dbHandler + * @param EventDispatcher $eventDispatcher */ - public function __construct(DBStorageInterface $dbHandler) + public function __construct(DBStorageInterface $dbHandler, EventDispatcher $eventDispatcher) { $this->dbHandler = $dbHandler; + $this->eventDispatcher = $eventDispatcher; } /** @@ -110,7 +119,7 @@ class Database implements DatabaseInterface /** * @param QueryData $queryData - * @param bool $fullCount + * @param bool $fullCount * * @return QueryResult * @throws ConstraintException @@ -169,15 +178,13 @@ class Database implements DatabaseInterface /** @var PDOStatement $stmt */ $stmt = $this->prepareQueryData($queryData); + $this->eventDispatcher->notifyEvent('database.query', + new Event($this, EventMessage::factory()->addDescription($queryData->getQuery()))); + if (preg_match("/^(select|show)\s/i", $queryData->getQuery())) { $this->numFields = $stmt->columnCount(); return new QueryResult($stmt->fetchAll()); - -// $this->lastResult = $stmt->fetchAll(); -// $this->numRows = count($this->lastResult); -// -// $queryData->setQueryNumRows($this->numRows); } return (new QueryResult()) @@ -311,38 +318,50 @@ class Database implements DatabaseInterface * Iniciar una transacción * * @return bool - * @throws SPException */ public function beginTransaction() { $conn = $this->dbHandler->getConnection(); - return !$conn->inTransaction() && $conn->beginTransaction(); + $result = !$conn->inTransaction() && $conn->beginTransaction(); + + $this->eventDispatcher->notifyEvent('database.transaction.begin', + new Event($this, EventMessage::factory()->addData('result', $result))); + + return $result; } /** * Finalizar una transacción * * @return bool - * @throws SPException */ public function endTransaction() { $conn = $this->dbHandler->getConnection(); - return $conn->inTransaction() && $conn->commit(); + $result = $conn->inTransaction() && $conn->commit(); + + $this->eventDispatcher->notifyEvent('database.transaction.end', + new Event($this, EventMessage::factory()->addData('result', $result))); + + return $result; } /** * Rollback de una transacción * * @return bool - * @throws SPException */ public function rollbackTransaction() { $conn = $this->dbHandler->getConnection(); - return $conn->inTransaction() && $conn->rollBack(); + $result = $conn->inTransaction() && $conn->rollBack(); + + $this->eventDispatcher->notifyEvent('database.transaction.rollback', + new Event($this, EventMessage::factory()->addData('result', $result))); + + return $result; } } \ No newline at end of file diff --git a/lib/SP/Storage/Database/DatabaseException.php b/lib/SP/Storage/Database/DatabaseException.php new file mode 100644 index 00000000..a30d1677 --- /dev/null +++ b/lib/SP/Storage/Database/DatabaseException.php @@ -0,0 +1,37 @@ +. + */ + +namespace SP\Storage\Database; + +use SP\Core\Exceptions\SPException; + +/** + * Class DatabaseException + * + * @package SP\Storage\Database + */ +class DatabaseException extends SPException +{ + +} \ No newline at end of file diff --git a/lib/SP/Storage/Database/DatabaseInterface.php b/lib/SP/Storage/Database/DatabaseInterface.php index d14dafda..ac0fb82b 100644 --- a/lib/SP/Storage/Database/DatabaseInterface.php +++ b/lib/SP/Storage/Database/DatabaseInterface.php @@ -87,4 +87,25 @@ interface DatabaseInterface * @return int */ public function getLastId(); + + /** + * Iniciar una transacción + * + * @return bool + */ + public function beginTransaction(); + + /** + * Finalizar una transacción + * + * @return bool + */ + public function endTransaction(); + + /** + * Rollback de una transacción + * + * @return bool + */ + public function rollbackTransaction(); } \ No newline at end of file diff --git a/lib/SP/Storage/Database/MySQLHandler.php b/lib/SP/Storage/Database/MySQLHandler.php index d1388680..fce95d34 100644 --- a/lib/SP/Storage/Database/MySQLHandler.php +++ b/lib/SP/Storage/Database/MySQLHandler.php @@ -2,8 +2,8 @@ /** * sysPass * - * @author nuxsmin - * @link https://syspass.org + * @author nuxsmin + * @link https://syspass.org * @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. @@ -25,7 +25,6 @@ namespace SP\Storage\Database; use PDO; -use SP\Core\Exceptions\SPException; defined('APP_ROOT') || die(); @@ -82,8 +81,8 @@ class MySQLHandler implements DBStorageInterface * Realizar la conexión con la BBDD. * Esta función utiliza PDO para conectar con la base de datos. * - * @throws \SP\Core\Exceptions\SPException * @return PDO + * @throws DatabaseException */ public function getConnection() { @@ -93,9 +92,9 @@ class MySQLHandler implements DBStorageInterface || null === $this->connectionData->getDbName() || (null === $this->connectionData->getDbHost() && null === $this->connectionData->getDbSocket()) ) { - throw new SPException( + throw new DatabaseException( __u('No es posible conectar con la BD'), - SPException::CRITICAL, + DatabaseException::CRITICAL, __u('Compruebe los datos de conexión')); } @@ -113,9 +112,9 @@ class MySQLHandler implements DBStorageInterface $this->dbStatus = self::STATUS_OK; } catch (\Exception $e) { - throw new SPException( + throw new DatabaseException( __u('No es posible conectar con la BD'), - SPException::CRITICAL, + DatabaseException::CRITICAL, sprintf('Error %s: %s', $e->getCode(), $e->getMessage()), $e->getCode(), $e @@ -158,15 +157,15 @@ class MySQLHandler implements DBStorageInterface * Obtener una conexión PDO sin seleccionar la BD * * @return \PDO - * @throws SPException + * @throws DatabaseException */ public function getConnectionSimple() { if (!$this->db) { if (null === $this->connectionData->getDbHost() && null === $this->connectionData->getDbSocket()) { - throw new SPException( + throw new DatabaseException( __u('No es posible conectar con la BD'), - SPException::CRITICAL, + DatabaseException::CRITICAL, __u('Compruebe los datos de conexión')); } @@ -176,9 +175,9 @@ class MySQLHandler implements DBStorageInterface $this->db = new PDO($this->getConnectionUri(), $this->connectionData->getDbUser(), $this->connectionData->getDbPass(), $opts); $this->dbStatus = self::STATUS_OK; } catch (\Exception $e) { - throw new SPException( + throw new DatabaseException( __u('No es posible conectar con la BD'), - SPException::CRITICAL, + DatabaseException::CRITICAL, sprintf('Error %s: %s', $e->getCode(), $e->getMessage()), $e->getCode(), $e diff --git a/tests/Repositories/AccountRepositoryTest.php b/tests/Repositories/AccountRepositoryTest.php index 6a5533ae..f7136e5a 100644 --- a/tests/Repositories/AccountRepositoryTest.php +++ b/tests/Repositories/AccountRepositoryTest.php @@ -29,6 +29,7 @@ use SP\Account\AccountRequest; use SP\Account\AccountSearchFilter; use SP\Core\Crypt\Crypt; use SP\Core\Exceptions\SPException; +use SP\DataModel\AccountData; use SP\DataModel\AccountVData; use SP\DataModel\Dto\AccountSearchResponse; use SP\DataModel\ItemSearchData; @@ -64,7 +65,7 @@ class AccountRepositoryTest extends DatabaseTestCase $dic = setupContext(); self::$dataset = 'syspass_account.xml'; - + // Datos de conexión a la BBDD self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); @@ -139,14 +140,17 @@ class AccountRepositoryTest extends DatabaseTestCase */ public function testGetById() { - $account = self::$repository->getById(1); + $result = self::$repository->getById(1); - $this->assertInstanceOf(AccountVData::class, $account); - $this->assertEquals(1, $account->getId()); + $this->assertEquals(1, $result->getNumRows()); - $this->expectException(SPException::class); + /** @var AccountVData $data */ + $data = $result->getData(); - self::$repository->getById(100); + $this->assertInstanceOf(AccountVData::class, $data); + $this->assertEquals(1, $data->getId()); + + $this->assertEquals(0, self::$repository->getById(10)->getNumRows()); } /** @@ -172,23 +176,29 @@ class AccountRepositoryTest extends DatabaseTestCase $this->assertEquals(1, self::$repository->update($accountRequest)); - $account = self::$repository->getById(1); + $result = self::$repository->getById(1); - $this->assertEquals($accountRequest->name, $account->getName()); - $this->assertEquals($accountRequest->login, $account->getLogin()); - $this->assertEquals($accountRequest->url, $account->getUrl()); - $this->assertEquals($accountRequest->notes, $account->getNotes()); - $this->assertEquals($accountRequest->userEditId, $account->getUserEditId()); - $this->assertEquals($accountRequest->passDateChange, $account->getPassDateChange()); - $this->assertEquals($accountRequest->clientId, $account->getClientId()); - $this->assertEquals($accountRequest->categoryId, $account->getCategoryId()); - $this->assertEquals($accountRequest->isPrivate, $account->getIsPrivate()); - $this->assertEquals($accountRequest->isPrivateGroup, $account->getIsPrivateGroup()); - $this->assertEquals($accountRequest->parentId, $account->getParentId()); + $this->assertEquals(1, $result->getNumRows()); + + /** @var AccountVData $data */ + $data = $result->getData(); + + $this->assertEquals(1, $data->getId()); + $this->assertEquals($accountRequest->name, $data->getName()); + $this->assertEquals($accountRequest->login, $data->getLogin()); + $this->assertEquals($accountRequest->url, $data->getUrl()); + $this->assertEquals($accountRequest->notes, $data->getNotes()); + $this->assertEquals($accountRequest->userEditId, $data->getUserEditId()); + $this->assertEquals($accountRequest->passDateChange, $data->getPassDateChange()); + $this->assertEquals($accountRequest->clientId, $data->getClientId()); + $this->assertEquals($accountRequest->categoryId, $data->getCategoryId()); + $this->assertEquals($accountRequest->isPrivate, $data->getIsPrivate()); + $this->assertEquals($accountRequest->isPrivateGroup, $data->getIsPrivateGroup()); + $this->assertEquals($accountRequest->parentId, $data->getParentId()); // El grupo no debe de cambiar si el usuario no tiene permisos - $this->assertNotEquals($accountRequest->userGroupId, $account->getUserGroupId()); - $this->assertEquals(1, $account->getUserGroupId()); + $this->assertNotEquals($accountRequest->userGroupId, $data->getUserGroupId()); + $this->assertEquals(1, $data->getUserGroupId()); } /** @@ -264,7 +274,7 @@ class AccountRepositoryTest extends DatabaseTestCase $filter = new QueryCondition(); $filter->addFilter('Account.parentId = 1'); - $this->assertCount(0, self::$repository->getLinked($filter)); + $this->assertEquals(1, self::$repository->getLinked($filter)->getNumRows()); } /** @@ -277,11 +287,13 @@ class AccountRepositoryTest extends DatabaseTestCase */ public function testIncrementViewCounter() { - $accountBefore = self::$repository->getById(1); + /** @var AccountVData $accountBefore */ + $accountBefore = self::$repository->getById(1)->getData(); $this->assertTrue(self::$repository->incrementViewCounter(1)); - $accountAfter = self::$repository->getById(1); + /** @var AccountVData $accountAfter */ + $accountAfter = self::$repository->getById(1)->getData(); $this->assertEquals($accountBefore->getCountView() + 1, $accountAfter->getCountView()); } @@ -294,7 +306,18 @@ class AccountRepositoryTest extends DatabaseTestCase */ public function testGetAll() { - $this->assertCount(2, self::$repository->getAll()); + $result = self::$repository->getAll(); + + $this->assertEquals(2, $result->getNumRows()); + + /** @var AccountData[] $data */ + $data = $result->getDataAsArray(); + + $this->assertCount(2, $data); + $this->assertInstanceOf(AccountData::class, $data[0]); + $this->assertEquals(1, $data[0]->getId()); + $this->assertInstanceOf(AccountData::class, $data[1]); + $this->assertEquals(2, $data[1]->getId()); } /** @@ -330,11 +353,13 @@ class AccountRepositoryTest extends DatabaseTestCase */ public function testIncrementDecryptCounter() { - $accountBefore = self::$repository->getById(1); + /** @var AccountVData $accountBefore */ + $accountBefore = self::$repository->getById(1)->getData(); $this->assertTrue(self::$repository->incrementDecryptCounter(1)); - $accountAfter = self::$repository->getById(1); + /** @var AccountVData $accountAfter */ + $accountAfter = self::$repository->getById(1)->getData(); $this->assertEquals($accountBefore->getCountDecrypt() + 1, $accountAfter->getCountDecrypt()); } @@ -347,15 +372,33 @@ class AccountRepositoryTest extends DatabaseTestCase */ public function testGetTotalNumAccounts() { - $this->assertEquals(2, self::$repository->getTotalNumAccounts()->num); + $this->assertEquals(7, self::$repository->getTotalNumAccounts()->num); } /** - * No implementado + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ public function testGetDataForLink() { - $this->markTestSkipped('Not implemented'); + $result = self::$repository->getDataForLink(1); + + $this->assertEquals(1, $result->getNumRows()); + + $data = $result->getData(); + + $this->assertEquals(1, $data->getId()); + $this->assertEquals(1, $data->getId()); + $this->assertEquals('Google', $data->getName()); + $this->assertEquals('admin', $data->getLogin()); + $this->assertEquals(pack('H*', '6465663530323030656135663361636362366237656462653536343938666234313231616635323237363539663162346532383963386361346565323732656530636238333632316436393736353665373631393435623033353236616164333730336662306531333535626437333638653033666137623565633364306365323634663863643436393436633365353234316534373338376130393133663935303736396364613365313234643432306636393834386434613262316231306138'), $data->getPass()); + $this->assertEquals(pack('H*', '6465663130303030646566353032303065646434636466636231333437613739616166313734343462343839626362643364353664376664356562373233363235653130316261666432323539343633336664626639326630613135373461653562613562323535353230393236353237623863633534313862653363376361376536366139356366353366356162663031623064343236613234336162643533643837643239636633643165326532663732626664396433366133653061343534656664373134633661366237616338363966636263366435303166613964316338386365623264303861333438626633656638653135356538633865353838623938636465653061306463313835646636366535393138393831653366303464323139386236383738333539616563653034376434643637663835313235636661313237633138373865643530616630393434613934616363356265316130323566623065633362663831613933626365366365343734336164363562656638353131343466343332323837356438323339303236656363613866643862376330396563356465373233666466313636656166386336356539666537353436333535333664393766383366316366663931396530386339373730636166633136376661656364306366656262323931666334343831333238333662366432'), $data->getKey()); + $this->assertEquals('http://google.com', $data->getUrl()); + $this->assertEquals('aaaa', $data->getNotes()); + $this->assertEquals('Google', $data->getClientName()); + $this->assertEquals('Web', $data->getCategoryName()); + + $this->assertEquals(0, self::$repository->getDataForLink(10)->getNumRows()); } /** @@ -369,7 +412,7 @@ class AccountRepositoryTest extends DatabaseTestCase $queryCondition = new QueryCondition(); $queryCondition->addFilter('Account.isPrivate = 1'); - $this->assertCount(0, self::$repository->getForUser($queryCondition)); + $this->assertCount(0, self::$repository->getForUser($queryCondition)->getDataAsArray()); } /** diff --git a/tests/Repositories/AccountToTagRepositoryTest.php b/tests/Repositories/AccountToTagRepositoryTest.php index 1c2d92cc..dc3a8bad 100644 --- a/tests/Repositories/AccountToTagRepositoryTest.php +++ b/tests/Repositories/AccountToTagRepositoryTest.php @@ -56,6 +56,8 @@ class AccountToTagRepositoryTest extends DatabaseTestCase { $dic = setupContext(); + self::$dataset = 'syspass.xml'; + // Datos de conexión a la BBDD self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); @@ -93,7 +95,7 @@ class AccountToTagRepositoryTest extends DatabaseTestCase $result = self::$repository->getTagsByAccountId($accountRequest->id); $data = $result->getDataAsArray(); - $this->assertCount(3, $result); + $this->assertCount(3, $data); $this->assertInstanceOf(ItemData::class, $data[0]); $this->assertInstanceOf(ItemData::class, $data[1]); $this->assertInstanceOf(ItemData::class, $data[2]); @@ -143,7 +145,7 @@ class AccountToTagRepositoryTest extends DatabaseTestCase $result = self::$repository->getTagsByAccountId($accountRequest->id); $data = $result->getDataAsArray(); - $this->assertEquals(2, $result); + $this->assertEquals(2, $result->getNumRows()); $this->assertInstanceOf(ItemData::class, $data[0]); $this->assertInstanceOf(ItemData::class, $data[1]); } diff --git a/tests/Repositories/AccountToUserGroupRepositoryTest.php b/tests/Repositories/AccountToUserGroupRepositoryTest.php index 9a2afe26..bba50176 100644 --- a/tests/Repositories/AccountToUserGroupRepositoryTest.php +++ b/tests/Repositories/AccountToUserGroupRepositoryTest.php @@ -56,6 +56,8 @@ class AccountToUserGroupRepositoryTest extends DatabaseTestCase { $dic = setupContext(); + self::$dataset = 'syspass.xml'; + // Datos de conexión a la BBDD self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); @@ -255,12 +257,16 @@ class AccountToUserGroupRepositoryTest extends DatabaseTestCase $this->assertEquals(3, self::$repository->add($accountRequest)); - $userGroups = self::$repository->getUserGroupsByAccountId($accountRequest->id); + $result = self::$repository->getUserGroupsByAccountId($accountRequest->id); - $this->assertCount(3, $userGroups); - $this->assertInstanceOf(ItemData::class, $userGroups[0]); - $this->assertInstanceOf(ItemData::class, $userGroups[1]); - $this->assertInstanceOf(ItemData::class, $userGroups[2]); + $this->assertEquals(3, $result->getNumRows()); + + $data = $result->getDataAsArray(); + + $this->assertCount(3, $data); + $this->assertInstanceOf(ItemData::class, $data[0]); + $this->assertInstanceOf(ItemData::class, $data[1]); + $this->assertInstanceOf(ItemData::class, $data[2]); $this->expectException(ConstraintException::class); @@ -301,11 +307,11 @@ class AccountToUserGroupRepositoryTest extends DatabaseTestCase */ public function testGetUserGroupsByUserGroupId() { - $this->assertCount(2, self::$repository->getUserGroupsByUserGroupId(2)->getNumRows()); + $this->assertEquals(2, self::$repository->getUserGroupsByUserGroupId(2)->getNumRows()); - $this->assertCount(0, self::$repository->getUserGroupsByUserGroupId(3)->getNumRows()); + $this->assertEquals(0, self::$repository->getUserGroupsByUserGroupId(3)->getNumRows()); - $this->assertCount(0, self::$repository->getUserGroupsByUserGroupId(10)->getNumRows()); + $this->assertEquals(0, self::$repository->getUserGroupsByUserGroupId(10)->getNumRows()); } /** diff --git a/tests/Repositories/AccountToUserRepositoryTest.php b/tests/Repositories/AccountToUserRepositoryTest.php index 3531f4bf..ef557520 100644 --- a/tests/Repositories/AccountToUserRepositoryTest.php +++ b/tests/Repositories/AccountToUserRepositoryTest.php @@ -56,6 +56,8 @@ class AccountToUserRepositoryTest extends DatabaseTestCase { $dic = setupContext(); + self::$dataset = 'syspass.xml'; + // Datos de conexión a la BBDD self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); diff --git a/tests/Repositories/AuthTokenRepositoryTest.php b/tests/Repositories/AuthTokenRepositoryTest.php index cfbbef63..c2325826 100644 --- a/tests/Repositories/AuthTokenRepositoryTest.php +++ b/tests/Repositories/AuthTokenRepositoryTest.php @@ -62,6 +62,8 @@ class AuthTokenRepositoryTest extends DatabaseTestCase { $dic = setupContext(); + self::$dataset = 'syspass.xml'; + // Datos de conexión a la BBDD self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); diff --git a/tests/Repositories/CategoryRepositoryTest.php b/tests/Repositories/CategoryRepositoryTest.php index dcd958ca..8b446ac5 100644 --- a/tests/Repositories/CategoryRepositoryTest.php +++ b/tests/Repositories/CategoryRepositoryTest.php @@ -57,6 +57,8 @@ class CategoryRepositoryTest extends DatabaseTestCase { $dic = setupContext(); + self::$dataset = 'syspass.xml'; + // Datos de conexión a la BBDD self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); diff --git a/tests/Repositories/ClientRepositoryTest.php b/tests/Repositories/ClientRepositoryTest.php index 60a39ce8..237aab39 100644 --- a/tests/Repositories/ClientRepositoryTest.php +++ b/tests/Repositories/ClientRepositoryTest.php @@ -58,6 +58,8 @@ class ClientRepositoryTest extends DatabaseTestCase { $dic = setupContext(); + self::$dataset = 'syspass.xml'; + // Datos de conexión a la BBDD self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); diff --git a/tests/Repositories/CustomFieldDefRepositoryTest.php b/tests/Repositories/CustomFieldDefRepositoryTest.php index ca3bd28d..9f2a356d 100644 --- a/tests/Repositories/CustomFieldDefRepositoryTest.php +++ b/tests/Repositories/CustomFieldDefRepositoryTest.php @@ -55,6 +55,8 @@ class CustomFieldDefRepositoryTest extends DatabaseTestCase { $dic = setupContext(); + self::$dataset = 'syspass.xml'; + // Datos de conexión a la BBDD self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); diff --git a/tests/Repositories/CustomFieldRepositoryTest.php b/tests/Repositories/CustomFieldRepositoryTest.php index e4d6ca72..f5035bb8 100644 --- a/tests/Repositories/CustomFieldRepositoryTest.php +++ b/tests/Repositories/CustomFieldRepositoryTest.php @@ -53,6 +53,8 @@ class CustomFieldRepositoryTest extends DatabaseTestCase { $dic = setupContext(); + self::$dataset = 'syspass.xml'; + // Datos de conexión a la BBDD self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); diff --git a/tests/Repositories/CustomFieldTypeRepositoryTest.php b/tests/Repositories/CustomFieldTypeRepositoryTest.php index db6bf63e..6ab6b044 100644 --- a/tests/Repositories/CustomFieldTypeRepositoryTest.php +++ b/tests/Repositories/CustomFieldTypeRepositoryTest.php @@ -53,6 +53,8 @@ class CustomFieldTypeRepositoryTest extends DatabaseTestCase { $dic = setupContext(); + self::$dataset = 'syspass.xml'; + // Datos de conexión a la BBDD self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); diff --git a/tests/Repositories/NotificationRepositoryTest.php b/tests/Repositories/NotificationRepositoryTest.php index b24e3ef7..04a172f0 100644 --- a/tests/Repositories/NotificationRepositoryTest.php +++ b/tests/Repositories/NotificationRepositoryTest.php @@ -56,6 +56,8 @@ class NotificationRepositoryTest extends DatabaseTestCase { $dic = setupContext(); + self::$dataset = 'syspass.xml'; + // Datos de conexión a la BBDD self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); diff --git a/tests/Repositories/PublicLinkRepositoryTest.php b/tests/Repositories/PublicLinkRepositoryTest.php index a75b9d77..92012957 100644 --- a/tests/Repositories/PublicLinkRepositoryTest.php +++ b/tests/Repositories/PublicLinkRepositoryTest.php @@ -58,6 +58,8 @@ class PublicLinkRepositoryTest extends DatabaseTestCase { $dic = setupContext(); + self::$dataset = 'syspass.xml'; + // Datos de conexión a la BBDD self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); diff --git a/tests/Repositories/TagRepositoryTest.php b/tests/Repositories/TagRepositoryTest.php index 2e2fa85c..5f7c6aad 100644 --- a/tests/Repositories/TagRepositoryTest.php +++ b/tests/Repositories/TagRepositoryTest.php @@ -56,6 +56,8 @@ class TagRepositoryTest extends DatabaseTestCase { $dic = setupContext(); + self::$dataset = 'syspass.xml'; + // Datos de conexión a la BBDD self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); diff --git a/tests/Repositories/UserGroupRepositoryTest.php b/tests/Repositories/UserGroupRepositoryTest.php index 4db5a25c..01410209 100644 --- a/tests/Repositories/UserGroupRepositoryTest.php +++ b/tests/Repositories/UserGroupRepositoryTest.php @@ -58,6 +58,8 @@ class UserGroupRepositoryTestCase extends DatabaseTestCase { $dic = setupContext(); + self::$dataset = 'syspass.xml'; + // Datos de conexión a la BBDD self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); diff --git a/tests/Repositories/UserPassRecoverRepositoryTest.php b/tests/Repositories/UserPassRecoverRepositoryTest.php index 79d6e360..ed26813c 100644 --- a/tests/Repositories/UserPassRecoverRepositoryTest.php +++ b/tests/Repositories/UserPassRecoverRepositoryTest.php @@ -53,6 +53,8 @@ class UserPassRecoverRepositoryTest extends DatabaseTestCase { $dic = setupContext(); + self::$dataset = 'syspass.xml'; + // Datos de conexión a la BBDD self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); diff --git a/tests/Repositories/UserProfileRepositoryTest.php b/tests/Repositories/UserProfileRepositoryTest.php index 509ae240..02bcf820 100644 --- a/tests/Repositories/UserProfileRepositoryTest.php +++ b/tests/Repositories/UserProfileRepositoryTest.php @@ -59,6 +59,8 @@ class UserProfileRepositoryTest extends DatabaseTestCase { $dic = setupContext(); + self::$dataset = 'syspass.xml'; + // Datos de conexión a la BBDD self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); diff --git a/tests/Repositories/UserRepositoryTest.php b/tests/Repositories/UserRepositoryTest.php index 49916448..0691617d 100644 --- a/tests/Repositories/UserRepositoryTest.php +++ b/tests/Repositories/UserRepositoryTest.php @@ -64,6 +64,8 @@ class UserRepositoryTest extends DatabaseTestCase { $dic = setupContext(); + self::$dataset = 'syspass.xml'; + // Datos de conexión a la BBDD self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); diff --git a/tests/Services/AccountCryptServiceTest.php b/tests/Services/AccountCryptServiceTest.php index ce97d4f6..b572d111 100644 --- a/tests/Services/AccountCryptServiceTest.php +++ b/tests/Services/AccountCryptServiceTest.php @@ -77,6 +77,7 @@ class AccountCryptServiceTest extends DatabaseTestCase * @throws \SP\Core\Exceptions\QueryException * @throws \SP\Services\ServiceException * @throws \Defuse\Crypto\Exception\CryptoException + * @throws \SP\Repositories\NoSuchItemException */ public function testUpdateMasterPassword() { @@ -109,6 +110,7 @@ class AccountCryptServiceTest extends DatabaseTestCase * @throws ServiceException * @throws \SP\Core\Exceptions\ConstraintException * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException */ public function testUpdateHistoryMasterPassword() { diff --git a/tests/Services/AccountServiceTest.php b/tests/Services/AccountServiceTest.php index 7b46be22..028f9f19 100644 --- a/tests/Services/AccountServiceTest.php +++ b/tests/Services/AccountServiceTest.php @@ -25,12 +25,20 @@ namespace SP\Tests\Services; use SP\Account\AccountRequest; +use SP\Account\AccountSearchFilter; use SP\Core\Crypt\Crypt; +use SP\Core\Exceptions\ConstraintException; +use SP\DataModel\AccountData; +use SP\DataModel\AccountVData; +use SP\DataModel\Dto\AccountSearchResponse; +use SP\DataModel\ItemSearchData; use SP\Repositories\NoSuchItemException; use SP\Services\Account\AccountPasswordRequest; use SP\Services\Account\AccountService; +use SP\Services\ServiceException; use SP\Storage\Database\DatabaseConnectionData; use SP\Tests\DatabaseTestCase; +use SP\Util\Util; use function SP\Tests\setupContext; /** @@ -198,7 +206,7 @@ class AccountServiceTest extends DatabaseTestCase */ public function testGetTotalNumAccounts() { - $this->assertEquals(2, self::$service->getTotalNumAccounts()); + $this->assertEquals(7, self::$service->getTotalNumAccounts()); } /** @@ -208,86 +216,431 @@ class AccountServiceTest extends DatabaseTestCase */ public function testGetDataForLink() { - self::$service->getDataForLink(1); + $data = self::$service->getDataForLink(1); + + $this->assertEquals(1, $data->getId()); + $this->assertEquals('Google', $data->getName()); + $this->assertEquals('admin', $data->getLogin()); + $this->assertEquals(pack('H*', '6465663530323030656135663361636362366237656462653536343938666234313231616635323237363539663162346532383963386361346565323732656530636238333632316436393736353665373631393435623033353236616164333730336662306531333535626437333638653033666137623565633364306365323634663863643436393436633365353234316534373338376130393133663935303736396364613365313234643432306636393834386434613262316231306138'), $data->getPass()); + $this->assertEquals(pack('H*', '6465663130303030646566353032303065646434636466636231333437613739616166313734343462343839626362643364353664376664356562373233363235653130316261666432323539343633336664626639326630613135373461653562613562323535353230393236353237623863633534313862653363376361376536366139356366353366356162663031623064343236613234336162643533643837643239636633643165326532663732626664396433366133653061343534656664373134633661366237616338363966636263366435303166613964316338386365623264303861333438626633656638653135356538633865353838623938636465653061306463313835646636366535393138393831653366303464323139386236383738333539616563653034376434643637663835313235636661313237633138373865643530616630393434613934616363356265316130323566623065633362663831613933626365366365343734336164363562656638353131343466343332323837356438323339303236656363613866643862376330396563356465373233666466313636656166386336356539666537353436333535333664393766383366316366663931396530386339373730636166633136376661656364306366656262323931666334343831333238333662366432'), $data->getKey()); + $this->assertEquals('http://google.com', $data->getUrl()); + $this->assertEquals('aaaa', $data->getNotes()); + $this->assertEquals('Google', $data->getClientName()); + $this->assertEquals('Web', $data->getCategoryName()); + + $this->expectException(NoSuchItemException::class); + + self::$service->getDataForLink(10); } + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ public function testGetAccountsPassData() { - + $this->assertCount(2, self::$service->getAccountsPassData()); } + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Services\Config\ParameterNotFoundException + * @throws \SP\Services\ServiceException + */ public function testEditRestore() { + self::$service->editRestore(3, 1); + $this->expectException(ServiceException::class); + + self::$service->editRestore(1, 1); + self::$service->editRestore(3, 10); + + $this->assertEquals(6, $this->conn->getRowCount('AccountHistory')); } + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ public function testGetLinked() { + $result = self::$service->getLinked(1); + $this->assertCount(1, $result); + $this->assertEquals(2, $result[0]->id); + $this->assertEquals('Apple', $result[0]->name); + + $this->assertCount(0, self::$service->getLinked(2)); } + /** + * @throws ServiceException + * @throws \Defuse\Crypto\Exception\CryptoException + */ public function testGetPasswordEncrypted() { + $data = self::$service->getPasswordEncrypted('123abc'); + $this->assertEquals('123abc', Crypt::decrypt($data['pass'], $data['key'], self::SECURE_KEY_PASSWORD)); + + $randomKeyPass = Util::generateRandomBytes(); + + $data = self::$service->getPasswordEncrypted('123abc', $randomKeyPass); + + $this->assertEquals('123abc', Crypt::decrypt($data['pass'], $data['key'], $randomKeyPass)); } + /** + * @covers \SP\Services\Account\AccountService::getPasswordForId() + * @throws NoSuchItemException + * @throws ServiceException + * @throws \Defuse\Crypto\Exception\CryptoException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ public function testEditPassword() { + $accountRequest = new AccountRequest(); + $accountRequest->pass = '123abc'; + $accountRequest->id = 2; + $accountRequest->userEditId = 1; + $accountRequest->passDateChange = time() + 3600; + // Comprobar que la modificación de la clave es correcta + self::$service->editPassword($accountRequest); + + $data = self::$service->getPasswordForId(2); + + $clearPassword = Crypt::decrypt($data->pass, $data->key, self::SECURE_KEY_PASSWORD); + + // Comprobar que la clave obtenida es igual a la encriptada anteriormente + $this->assertEquals('123abc', $clearPassword); + + $this->expectException(NoSuchItemException::class); + + // Comprobar que no devuelve resultados + self::$service->getPasswordForId(10); } - public function testGetPasswordForId() - { - - } - + /** + * @covers \SP\Services\Account\AccountService::getById() + * @throws NoSuchItemException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException + */ public function testUpdate() { + $accountRequest = new AccountRequest(); + $accountRequest->id = 1; + $accountRequest->name = 'Prueba 1'; + $accountRequest->login = 'admin'; + $accountRequest->url = 'http://syspass.org'; + $accountRequest->notes = 'notas'; + $accountRequest->userEditId = 1; + $accountRequest->passDateChange = time() + 3600; + $accountRequest->clientId = 1; + $accountRequest->categoryId = 1; + $accountRequest->isPrivate = 0; + $accountRequest->isPrivateGroup = 0; + $accountRequest->parentId = 0; + $accountRequest->userGroupId = 2; + $accountRequest->tags = [2, 3]; + $accountRequest->usersView = [2, 4]; + $accountRequest->usersEdit = [3, 4]; + $accountRequest->userGroupsView = [2, 3]; + $accountRequest->userGroupsEdit = [2]; + $accountRequest->updateTags = true; + $accountRequest->updateUserPermissions = true; + $accountRequest->updateUserGroupPermissions = true; + self::$service->update($accountRequest); + + $result = self::$service->getById(1); + + self::$service->withTagsById($result); + self::$service->withUsersById($result); + self::$service->withUserGroupsById($result); + + $data = $result->getAccountVData(); + + $this->assertEquals(1, $result->getId()); + $this->assertEquals($accountRequest->name, $data->getName()); + $this->assertEquals($accountRequest->login, $data->getLogin()); + $this->assertEquals($accountRequest->url, $data->getUrl()); + $this->assertEquals($accountRequest->notes, $data->getNotes()); + $this->assertEquals(1, $data->getUserId()); + $this->assertEquals($accountRequest->userGroupId, $data->getUserGroupId()); + $this->assertEquals($accountRequest->userEditId, $data->getUserEditId()); + $this->assertEquals($accountRequest->passDateChange, $data->getPassDateChange()); + $this->assertEquals($accountRequest->clientId, $data->getClientId()); + $this->assertEquals($accountRequest->categoryId, $data->getCategoryId()); + $this->assertEquals($accountRequest->isPrivate, $data->getIsPrivate()); + $this->assertEquals($accountRequest->isPrivateGroup, $data->getIsPrivateGroup()); + $this->assertEquals($accountRequest->parentId, $data->getParentId()); + + $tags = $result->getTags(); + + $this->assertEquals(3, $tags[0]->getId()); + $this->assertEquals(2, $tags[1]->getId()); + + $users = $result->getUsers(); + + $this->assertEquals(2, $users[0]->getId()); + $this->assertEquals(0, (int)$users[0]->isEdit); + $this->assertEquals(3, $users[1]->getId()); + $this->assertEquals(1, (int)$users[1]->isEdit); + $this->assertEquals(4, $users[2]->getId()); + $this->assertEquals(1, (int)$users[2]->isEdit); + + $groups = $result->getUserGroups(); + + $this->assertEquals(2, $groups[0]->getId()); + $this->assertEquals(1, (int)$groups[0]->isEdit); + $this->assertEquals(3, $groups[1]->getId()); + $this->assertEquals(0, (int)$groups[1]->isEdit); + + $accountRequest = new AccountRequest(); + $accountRequest->id = 3; + + self::$service->update($accountRequest); } + /** + * @throws ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ public function testGetForUser() { - + $this->assertCount(2, self::$service->getForUser()); + $this->assertCount(0, self::$service->getForUser(1)); } + /** + * @throws ConstraintException + * @throws NoSuchItemException + * @throws \SP\Core\Exceptions\QueryException + */ public function testGetById() { + $this->expectException(NoSuchItemException::class); + self::$service->getById(10); } + /** + * @throws ServiceException + * @throws \SP\Core\Exceptions\SPException + */ public function testDeleteByIdBatch() { + // Comprobar registros iniciales + $this->assertEquals(2, $this->conn->getRowCount('Account')); + self::$service->deleteByIdBatch([1, 2, 100]); + + // Comprobar registros tras eliminación + $this->assertEquals(0, $this->conn->getRowCount('Account')); + + $this->expectException(ServiceException::class); + + self::$service->deleteByIdBatch([100]); } + /** + * @throws ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException + */ public function testGetByFilter() { + $searchFilter = new AccountSearchFilter(); + $searchFilter->setLimitCount(10); + $searchFilter->setCategoryId(1); + // Comprobar un Id de categoría + $response = self::$service->getByFilter($searchFilter); + + $this->assertInstanceOf(AccountSearchResponse::class, $response); + $this->assertEquals(1, $response->getCount()); + $this->assertCount(1, $response->getData()); + + // Comprobar un Id de categoría no existente + $searchFilter->reset(); + $searchFilter->setLimitCount(10); + $searchFilter->setCategoryId(10); + + $response = self::$service->getByFilter($searchFilter); + + $this->assertInstanceOf(AccountSearchResponse::class, $response); + $this->assertEquals(0, $response->getCount()); + $this->assertCount(0, $response->getData()); + + // Comprobar un Id de cliente + $searchFilter->reset(); + $searchFilter->setLimitCount(10); + $searchFilter->setClientId(1); + + $response = self::$service->getByFilter($searchFilter); + + $this->assertInstanceOf(AccountSearchResponse::class, $response); + $this->assertEquals(1, $response->getCount()); + $this->assertCount(1, $response->getData()); + + // Comprobar un Id de cliente no existente + $searchFilter->reset(); + $searchFilter->setLimitCount(10); + $searchFilter->setClientId(10); + + $response = self::$service->getByFilter($searchFilter); + + $this->assertInstanceOf(AccountSearchResponse::class, $response); + $this->assertEquals(0, $response->getCount()); + $this->assertCount(0, $response->getData()); + + // Comprobar una cadena de texto + $searchFilter->reset(); + $searchFilter->setLimitCount(10); + $searchFilter->setCleanTxtSearch('apple.com'); + + $response = self::$service->getByFilter($searchFilter); + + $this->assertInstanceOf(AccountSearchResponse::class, $response); + $this->assertEquals(1, $response->getCount()); + $this->assertCount(1, $response->getData()); + $this->assertEquals(2, $response->getData()[0]->getId()); + + // Comprobar los favoritos + $searchFilter->reset(); + $searchFilter->setLimitCount(10); + $searchFilter->setSearchFavorites(true); + + $response = self::$service->getByFilter($searchFilter); + + $this->assertInstanceOf(AccountSearchResponse::class, $response); + $this->assertEquals(0, $response->getCount()); + $this->assertCount(0, $response->getData()); + + // Comprobar las etiquetas + $searchFilter->reset(); + $searchFilter->setLimitCount(10); + $searchFilter->setTagsId([1]); + + $response = self::$service->getByFilter($searchFilter); + + $this->assertInstanceOf(AccountSearchResponse::class, $response); + $this->assertEquals(1, $response->getCount()); + $this->assertCount(1, $response->getData()); + $this->assertEquals(1, $response->getData()[0]->getId()); } + /** + * @throws ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ public function testSearch() { + // Comprobar búsqueda con el texto Google Inc + $itemSearchData = new ItemSearchData(); + $itemSearchData->setSeachString('Google'); + $itemSearchData->setLimitCount(10); + $result = self::$service->search($itemSearchData); + $data = $result->getDataAsArray(); + + $this->assertCount(1, $data); + $this->assertEquals(1, $result->getNumRows()); + $this->assertInstanceOf(\stdClass::class, $data[0]); + $this->assertEquals(1, $data[0]->id); + $this->assertEquals('Google', $data[0]->name); + + // Comprobar búsqueda con el texto Apple + $itemSearchData = new ItemSearchData(); + $itemSearchData->setSeachString('Apple'); + $itemSearchData->setLimitCount(1); + + $result = self::$service->search($itemSearchData); + $data = $result->getDataAsArray(); + + $this->assertCount(1, $data); + $this->assertEquals(1, $result->getNumRows()); + $this->assertInstanceOf(\stdClass::class, $data[0]); + $this->assertEquals(2, $data[0]->id); + $this->assertEquals('Apple', $data[0]->name); } + /** + * @throws ConstraintException + * @throws NoSuchItemException + * @throws \SP\Core\Exceptions\QueryException + */ public function testIncrementDecryptCounter() { + /** @var AccountVData $accountBefore */ + $accountBefore = self::$service->getById(1)->getAccountVData(); + $this->assertTrue(self::$service->incrementDecryptCounter(1)); + + /** @var AccountVData $accountAfter */ + $accountAfter = self::$service->getById(1)->getAccountVData(); + + $this->assertEquals($accountBefore->getCountDecrypt() + 1, $accountAfter->getCountDecrypt()); } + /** + * @throws ConstraintException + * @throws NoSuchItemException + * @throws \SP\Core\Exceptions\QueryException + */ public function testIncrementViewCounter() { + /** @var AccountVData $accountBefore */ + $accountBefore = self::$service->getById(1)->getAccountVData(); + $this->assertTrue(self::$service->incrementViewCounter(1)); + + /** @var AccountVData $accountAfter */ + $accountAfter = self::$service->getById(1)->getAccountVData(); + + $this->assertEquals($accountBefore->getCountView() + 1, $accountAfter->getCountView()); } + /** + * @throws ConstraintException + * @throws NoSuchItemException + * @throws \SP\Core\Exceptions\QueryException + */ public function testGetPasswordHistoryForId() { + $data = self::$service->getPasswordHistoryForId(3); + $this->assertEquals(3, $data->getId()); + $this->assertEquals('Google', $data->getName()); + $this->assertEquals('admin', $data->getLogin()); + $this->assertNull($data->getParentId()); + $this->assertEquals(pack('H*', '646566353032303064396362643366376662646536326637663732663861383732623430613839386131643134333933663662623033316664343362366461643762626564643634386437363964346634616234386638336636653236396166623734636261383134313363626162326461393733343934613231653934666331616664633637313732316562356666396562646132613665313937626233333563613632383830393934333863643731333230383132316430366433303838'), $data->getPass()); + $this->assertEquals(pack('H*', '6465663130303030646566353032303032636635623034396437656539356531653838663166613438643061616132663133613163663766346238316165663837326134373665316461653661353865316666626438346130383166303062633138646136373265653935643234626564336565303063333262646262303433336633356534323263616337613238363532336233313666316137333462616337343839346631333632643863376430373861373862396135633064396239653061353537626562666336636566623766363166376330393734356461623536373762303436313865343936383434663932666364303634316330303935636239363938336361336631363161623134663339643536636233653938333833613062396464356365383736333334376364363933313563306436343362623937366139383831376632346431303364316533353133306262393862353034353262346334663934663162323531383632356530653331346438343430323362666334306264616265376437386238663632326535353338636537663431626261616461613138646333333662623762636565333030656565333734616537356365303131363731323239383132383964346634383661376635303136303835336138663335653366393230383632386162373332343335633037656432616234'), $data->getKey()); + $this->assertEquals(pack('H*', '24327924313024787473754E325055766753482F306D7266426C73624F4163745667436A596371447143364C3354395172614E785A43345258475961'), $data->getMPassHash()); + + $this->expectException(NoSuchItemException::class); + + self::$service->getPasswordHistoryForId(1); } + /** + * @throws ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ public function testGetAllBasic() { + $data = self::$service->getAllBasic(); + $this->assertCount(2, $data); + $this->assertInstanceOf(AccountData::class, $data[0]); + $this->assertEquals(1, $data[0]->getId()); + $this->assertInstanceOf(AccountData::class, $data[1]); + $this->assertEquals(2, $data[1]->getId()); } } diff --git a/tests/Services/AccountToTagServiceTest.php b/tests/Services/AccountToTagServiceTest.php index 8a02ec47..924b4901 100644 --- a/tests/Services/AccountToTagServiceTest.php +++ b/tests/Services/AccountToTagServiceTest.php @@ -50,6 +50,8 @@ class AccountToTagServiceTest extends DatabaseTestCase { $dic = setupContext(); + self::$dataset = 'syspass.xml'; + // Datos de conexión a la BBDD self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); diff --git a/tests/res/datasets/syspass_account.xml b/tests/res/datasets/syspass_account.xml index cdc2e156..6793cab1 100644 --- a/tests/res/datasets/syspass_account.xml +++ b/tests/res/datasets/syspass_account.xml @@ -1,6 +1,189 @@ + + + 1 + Web + Web sites + 3235363761356563393730356562376163326339383430333365303631383964 + + + 2 + Linux + Linux server + 6532303661353465393736393063636535306363383732646437306565383936 + + + 3 + SSH + SSH access + 3137383764373634363330346335643938376366346536346133393733646337 + + + + + 1 + Google + 6338323263316236333835336564323733623839363837616335303566396661 + Google Inc. + 0 + + + 2 + Apple + 3166333837306265323734663663343962336533316130633637323839353766 + Apple Inc. + 0 + + + 3 + Microsoft + 3566353332613366633466316561343033663337303730663539613761353361 + Microsoft Inc. + 1 + + + + + 1 + www + 3465616533356631623335393737613030656264383038366332353964346339 + + + 2 + windows + 3066343133376564313530326235303435643630383361613235386235633432 + + + 3 + Linux + 6532303661353465393736393063636535306363383732646437306565383936 + + + + + 1 + Admins + sysPass Admins + + + 2 + Demo + + + + 3 + Usuarios + Grupo Usuarios + + + + + 1 + sysPass Admin + 1 + admin + + 243279243130247635695230547A4933744E3036416A304C4A656B39755371496834356C70575539366E644A71444A704E6969713139306A444A486D + 64656635303230306330383635633335373637316233366261353266333137346134356466333633626135656431613962323261356461353965376134373930356664656239373436356462373934613831373635316133316432626363636266663836626233353235643930333932393734323535663937316261616239656436346637383266363066646465386539336637363164356663633436393031356433363164333234643436633533633138313335613334663739633039 + 6465663130303030646566353032303062316163626161346361643036643237386562323533616462643433613966376463636439343063656265313962343061383436643464633035303636306466653630613561653139363433643636353936643733333764646236386536363930336562383031373764356463386430663963623661643361663565643766303936376262393964663530373936316330656132373462663830346333663966373563336538643539396336326231623738333730303963616263373836383637366433636337376162383365386338323335336335626164396534656535333532656132346632653434653663316336656131643162313264393332386335303539623437656235343534666138356435626437343637353333383132636662313230316634633635383733316465323934613664643035396332613362373333613765343462633539306338363337393032306662303263363262303565613030623234646235323566653863303263323138666561356661353139306563396266333461316637613937633733396637343534323333316466323932343965323138656338343233306161623038373336346463353236363935383630656638623232313439626262656636656266373030366638376434343661333535353863323062353462376336623330 + + + 81 + 1 + 2018-04-19 23:46:48 + + 1521887152 + 1 + 0 + 0 + 0 + + 0 + 0 + 0 + 4F3A33323A2253505C446174614D6F64656C5C55736572507265666572656E63657344617461223A31303A7B733A373A22757365725F6964223B693A313B733A363A22757365324661223B623A303B733A343A226C616E67223B733A353A22656E5F5553223B733A353A227468656D65223B733A31333A226D6174657269616C2D626C7565223B733A31343A22726573756C747350657250616765223B693A34383B733A31313A226163636F756E744C696E6B223B623A313B733A393A22736F72745669657773223B623A303B733A393A22746F704E6176626172223B623A303B733A31353A226F7074696F6E616C416374696F6E73223B623A303B733A31343A22726573756C747341734361726473223B623A303B7D + + + 2 + sysPass demo + 2 + demo + demo + 2432792431302454726E69756C5763754361433635346F76566F35392E766B4C5433414E31624A6D726A79553462696335325069436A6B5572396669 + 64656635303230303231616533353730373263373165626239393534353966366236636164373235336534316336633534353036336339326136653730616366333930393165373934613865376662386662326664333931383932363562396466303133333631623063323732323339653465373165343839313030646534326265633737623966343238396635633936613837646531343864313963653663643338613131343932623163313765653630326430623532343564346566 + 6465663130303030646566353032303035643534316262633462653032333563313338626561366561333536626436663037353365313035653030333563653166316235336534663364343565366262353335626163396639646538653131316262356334383865336535633637323333666632626365313837626335386135353839373535373034386564353634366361646638623736396132323164363032353435653034306264613135663138323638383665373536313236353361313037306530333261323365636364336339616438323162306363383962643130333035303931653965626332653935313465656631373462663339343664656132393661346262366264343463646333363361643335623032373561356633323430313936346531633131663937313764313139633130633561373161666332356365346534366661623234646663626362326237303964336335316532623834326464303933653230353965373265356638376363366236626239306231346265376264373637663163303937366231313362393630613265636565336633313131663538656131346139353736623332653163303962636435313366383733656664653062373333366238643464646637616237323333373038613264393965633738356139393036306135643262316366306262663739346262663765 + demo@syspass.org + aaaa + 12 + 2 + 2018-04-01 21:29:47 + 2018-04-14 08:47:43 + 1522582852 + 0 + 0 + 0 + 0 + + 0 + 0 + 0 + + + + 3 + User A + 2 + user_a + user_a + 2432792431302469444B442E2F4F624D79742E6F43594F5249514D5065624454783966744D636A703034365A435976662E765479597A594F6A4C472E + + + user_a@syspass.org + + 0 + 1 + + 2018-04-14 08:48:08 + 0 + 0 + 0 + 0 + 0 + + 0 + 0 + 0 + + + + 4 + User B + 2 + user_b + + 243279243130244C37643658736A663955794F6E583662472E6F384E4F713961674B6F64536B4B5674485350462F6861414E657971517065372E6532 + + + user_b@syspass.org + + 0 + 1 + + 2018-03-30 18:38:32 + 0 + 0 + 0 + 0 + 0 + + 0 + 0 + 0 + + + 1 @@ -50,7 +233,7 @@ 0 1522341709 0 - 0 + 1 @@ -85,5 +268,152 @@ 0 + + + 3 + 2 + 1 + 1 + 1 + 1 + Google + 1 + admin + https://google.com + 646566353032303064396362643366376662646536326637663732663861383732623430613839386131643134333933663662623033316664343362366461643762626564643634386437363964346634616234386638336636653236396166623734636261383134313363626162326461393733343934613231653934666331616664633637313732316562356666396562646132613665313937626233333563613632383830393934333863643731333230383132316430366433303838 + 6465663130303030646566353032303032636635623034396437656539356531653838663166613438643061616132663133613163663766346238316165663837326134373665316461653661353865316666626438346130383166303062633138646136373265653935643234626564336565303063333262646262303433336633356534323263616337613238363532336233313666316137333462616337343839346631333632643863376430373861373862396135633064396239653061353537626562666336636566623766363166376330393734356461623536373762303436313865343936383434663932666364303634316330303935636239363938336361336631363161623134663339643536636233653938333833613062396464356365383736333334376364363933313563306436343362623937366139383831376632346431303364316533353133306262393862353034353262346334663934663162323531383632356530653331346438343430323362666334306264616265376437386238663632326535353338636537663431626261616461613138646333333662623762636565333030656565333734616537356365303131363731323239383132383964346634383661376635303136303835336138663335653366393230383632386162373332343335633037656432616234 + blablacar + 7 + 1 + 2018-06-05 22:49:34 + 2018-06-06 22:20:29 + 1 + 0 + 24327924313024787473754E325055766753482F306D7266426C73624F4163745667436A596371447143364C3354395172614E785A43345258475961 + 0 + 0 + + + + 0 + 0 + + + 4 + 1 + 1 + 1 + 1 + 1 + Google + 1 + admin + https://google.com + 64656635303230303864313263313434383662336363353938366164613564643563393465356664353138363635643062626362613938353236646336396662333833366537363635393931353336653262326533336339323232396663636336373139393662316631616432323839326539323332343633656164386262326234363033666565306630643666323364383337363661363363353139356334333330633139636634623664343131396362356136386232636332653465616232393561 + 6465663130303030646566353032303039326134383433323238376332636136626165313731363538316661316663393832356364653733316361623361316661343832646536626336663066646138623133323366396137626666643837386434623862633234653364363731626136613661393631343738633437653864626363656565333136343436346262623235623563633362663935363030653034346636326666636237303635343362333330616561363036336332383433383063303931383533653436616430396131393534653064393233643438313932393532646631353931623031333636356461373337646435653536623436653639396332613165363438653761623736653766383732653566376535623133303838666636663133313461376336353964373561386162323535346635653137626139626266396236363062613735306461313737626339303662316636633766343736383462346638353630356661663863323365646437393766333961303033666137653361366665383631373137613465333037366637393364356135326536646236363032663061373934373930383635336238616437333839646338653738383930303234633561623365336431373836396261626630363234326661306165663138396163376138616636313636323037313930333762666565 + + 11 + 0 + 2018-06-05 22:11:40 + + 1 + 0 + 24327924313024787473754E325055766753482F306D7266426C73624F4163745667436A596371447143364C3354395172614E785A43345258475961 + 0 + 0 + + + + 0 + 0 + + + 5 + 1 + 1 + 1 + 1 + 1 + Google + 1 + admin + https://google.com + 64656635303230303864313263313434383662336363353938366164613564643563393465356664353138363635643062626362613938353236646336396662333833366537363635393931353336653262326533336339323232396663636336373139393662316631616432323839326539323332343633656164386262326234363033666565306630643666323364383337363661363363353139356334333330633139636634623664343131396362356136386232636332653465616232393561 + 6465663130303030646566353032303039326134383433323238376332636136626165313731363538316661316663393832356364653733316361623361316661343832646536626336663066646138623133323366396137626666643837386434623862633234653364363731626136613661393631343738633437653864626363656565333136343436346262623235623563633362663935363030653034346636326666636237303635343362333330616561363036336332383433383063303931383533653436616430396131393534653064393233643438313932393532646631353931623031333636356461373337646435653536623436653639396332613165363438653761623736653766383732653566376535623133303838666636663133313461376336353964373561386162323535346635653137626139626266396236363062613735306461313737626339303662316636633766343736383462346638353630356661663863323365646437393766333961303033666137653361366665383631373137613465333037366637393364356135326536646236363032663061373934373930383635336238616437333839646338653738383930303234633561623365336431373836396261626630363234326661306165663138396163376138616636313636323037313930333762666565 + + 11 + 0 + 2018-06-05 22:11:40 + 2018-06-13 20:13:53 + 1 + 0 + 24327924313024787473754E325055766753482F306D7266426C73624F4163745667436A596371447143364C3354395172614E785A43345258475961 + 0 + 0 + + + + 0 + 0 + + + 6 + 1 + 1 + 1 + 1 + 1 + Google + 1 + admin + https://google.com + 64656635303230303864313263313434383662336363353938366164613564643563393465356664353138363635643062626362613938353236646336396662333833366537363635393931353336653262326533336339323232396663636336373139393662316631616432323839326539323332343633656164386262326234363033666565306630643666323364383337363661363363353139356334333330633139636634623664343131396362356136386232636332653465616232393561 + 6465663130303030646566353032303039326134383433323238376332636136626165313731363538316661316663393832356364653733316361623361316661343832646536626336663066646138623133323366396137626666643837386434623862633234653364363731626136613661393631343738633437653864626363656565333136343436346262623235623563633362663935363030653034346636326666636237303635343362333330616561363036336332383433383063303931383533653436616430396131393534653064393233643438313932393532646631353931623031333636356461373337646435653536623436653639396332613165363438653761623736653766383732653566376535623133303838666636663133313461376336353964373561386162323535346635653137626139626266396236363062613735306461313737626339303662316636633766343736383462346638353630356661663863323365646437393766333961303033666137653361366665383631373137613465333037366637393364356135326536646236363032663061373934373930383635336238616437333839646338653738383930303234633561623365336431373836396261626630363234326661306165663138396163376138616636313636323037313930333762666565 + + 11 + 0 + 2018-06-05 22:11:40 + 2018-06-13 20:13:58 + 1 + 0 + 24327924313024787473754E325055766753482F306D7266426C73624F4163745667436A596371447143364C3354395172614E785A43345258475961 + 0 + 0 + + + + 0 + 0 + + + 7 + 1 + 1 + 1 + 1 + 1 + Google + 1 + admin + https://google.com + 64656635303230303864313263313434383662336363353938366164613564643563393465356664353138363635643062626362613938353236646336396662333833366537363635393931353336653262326533336339323232396663636336373139393662316631616432323839326539323332343633656164386262326234363033666565306630643666323364383337363661363363353139356334333330633139636634623664343131396362356136386232636332653465616232393561 + 6465663130303030646566353032303039326134383433323238376332636136626165313731363538316661316663393832356364653733316361623361316661343832646536626336663066646138623133323366396137626666643837386434623862633234653364363731626136613661393631343738633437653864626363656565333136343436346262623235623563633362663935363030653034346636326666636237303635343362333330616561363036336332383433383063303931383533653436616430396131393534653064393233643438313932393532646631353931623031333636356461373337646435653536623436653639396332613165363438653761623736653766383732653566376535623133303838666636663133313461376336353964373561386162323535346635653137626139626266396236363062613735306461313737626339303662316636633766343736383462346638353630356661663863323365646437393766333961303033666137653361366665383631373137613465333037366637393364356135326536646236363032663061373934373930383635336238616437333839646338653738383930303234633561623365336431373836396261626630363234326661306165663138396163376138616636313636323037313930333762666565 + + 11 + 0 + 2018-06-05 22:11:40 + 2018-06-13 20:14:23 + 1 + 0 + 24327924313024787473754E325055766753482F306D7266426C73624F4163745667436A596371447143364C3354395172614E785A43345258475961 + 0 + 0 + + + + 0 + 0 + +