diff --git a/composer.json b/composer.json
index 1a79640c..3a9e205d 100644
--- a/composer.json
+++ b/composer.json
@@ -34,7 +34,8 @@
"autoload": {
"psr-4": {
"SP\\": "lib/SP/",
- "SP\\Modules\\Web\\": "app/modules/web/"
+ "SP\\Modules\\Web\\": "app/modules/web/",
+ "SP\\Modules\\Api\\": "app/modules/api/"
}
},
"config": {
diff --git a/composer.lock b/composer.lock
index 736cdd42..93ba9aee 100644
--- a/composer.lock
+++ b/composer.lock
@@ -756,20 +756,20 @@
},
{
"name": "php-di/phpdoc-reader",
- "version": "2.0.1",
+ "version": "2.1.0",
"source": {
"type": "git",
"url": "https://github.com/PHP-DI/PhpDocReader.git",
- "reference": "83f5ead159defccfa8e7092e5b6c1c533b326d68"
+ "reference": "7d0de60b9341933c8afd172a6255cd7557601e0e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/PHP-DI/PhpDocReader/zipball/83f5ead159defccfa8e7092e5b6c1c533b326d68",
- "reference": "83f5ead159defccfa8e7092e5b6c1c533b326d68",
+ "url": "https://api.github.com/repos/PHP-DI/PhpDocReader/zipball/7d0de60b9341933c8afd172a6255cd7557601e0e",
+ "reference": "7d0de60b9341933c8afd172a6255cd7557601e0e",
"shasum": ""
},
"require": {
- "php": ">=5.3.0"
+ "php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "~4.6"
@@ -789,7 +789,7 @@
"phpdoc",
"reflection"
],
- "time": "2015-11-29T10:34:25+00:00"
+ "time": "2018-02-18T17:39:01+00:00"
},
{
"name": "phpmailer/phpmailer",
@@ -859,16 +859,16 @@
},
{
"name": "phpseclib/phpseclib",
- "version": "2.0.9",
+ "version": "2.0.10",
"source": {
"type": "git",
"url": "https://github.com/phpseclib/phpseclib.git",
- "reference": "c9a3fe35e20eb6eeaca716d6a23cde03f52d1558"
+ "reference": "d305b780829ea4252ed9400b3f5937c2c99b51d4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/c9a3fe35e20eb6eeaca716d6a23cde03f52d1558",
- "reference": "c9a3fe35e20eb6eeaca716d6a23cde03f52d1558",
+ "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/d305b780829ea4252ed9400b3f5937c2c99b51d4",
+ "reference": "d305b780829ea4252ed9400b3f5937c2c99b51d4",
"shasum": ""
},
"require": {
@@ -876,7 +876,7 @@
},
"require-dev": {
"phing/phing": "~2.7",
- "phpunit/phpunit": "~4.0",
+ "phpunit/phpunit": "^4.8.35|^5.7|^6.0",
"sami/sami": "~2.0",
"squizlabs/php_codesniffer": "~2.0"
},
@@ -947,7 +947,7 @@
"x.509",
"x509"
],
- "time": "2017-11-29T06:38:08+00:00"
+ "time": "2018-02-19T04:29:13+00:00"
},
{
"name": "psr/container",
@@ -1004,17 +1004,19 @@
"source": {
"type": "git",
"url": "https://github.com/Roave/SecurityAdvisories.git",
- "reference": "3df94834c80037130b533703df4672785b6ea112"
+ "reference": "664836e89c7ecad3dbaabc1572ea752c0d532d80"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/3df94834c80037130b533703df4672785b6ea112",
- "reference": "3df94834c80037130b533703df4672785b6ea112",
+ "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/664836e89c7ecad3dbaabc1572ea752c0d532d80",
+ "reference": "664836e89c7ecad3dbaabc1572ea752c0d532d80",
"shasum": ""
},
"conflict": {
+ "3f/pygmentize": "<1.2",
"adodb/adodb-php": "<5.20.6",
"amphp/artax": "<1.0.6|>=2,<2.0.6",
+ "asymmetricrypt/asymmetricrypt": ">=0,<9.9.99",
"aws/aws-sdk-php": ">=3,<3.2.1",
"bugsnag/bugsnag-laravel": ">=2,<2.0.2",
"cakephp/cakephp": ">=1.3,<1.3.18|>=2,<2.4.99|>=2.5,<2.5.99|>=2.6,<2.6.12|>=2.7,<2.7.6|>=3,<3.0.15|>=3.1,<3.1.4",
@@ -1037,9 +1039,10 @@
"doctrine/mongodb-odm-bundle": ">=2,<3.0.1",
"doctrine/orm": ">=2,<2.4.8|>=2.5,<2.5.1",
"dompdf/dompdf": ">=0.6,<0.6.2",
- "drupal/core": ">=8,<8.3.7",
- "drupal/drupal": ">=8,<8.3.7",
- "ezsystems/ezpublish-legacy": ">=5.3,<5.3.12.2|>=5.4,<5.4.10.1|>=2017.8,<2017.8.1.1",
+ "drupal/core": ">=8,<8.4.5",
+ "drupal/drupal": ">=8,<8.4.5",
+ "erusev/parsedown": "<1.7",
+ "ezsystems/ezpublish-legacy": ">=5.3,<5.3.12.3|>=5.4,<5.4.11.3|>=2017.8,<2017.8.1.1|>=2017.12,<2017.12.2.1",
"firebase/php-jwt": "<2",
"friendsofsymfony/rest-bundle": ">=1.2,<1.2.2",
"friendsofsymfony/user-bundle": ">=1.2,<1.3.5",
@@ -1059,9 +1062,14 @@
"onelogin/php-saml": "<2.10.4",
"oro/crm": ">=1.7,<1.7.4",
"oro/platform": ">=1.7,<1.7.4",
+ "padraic/humbug_get_contents": "<1.1.2",
+ "pagarme/pagarme-php": ">=0,<3",
+ "paragonie/random_compat": "<2",
"phpmailer/phpmailer": ">=5,<5.2.24",
"phpunit/phpunit": ">=4.8.19,<4.8.28|>=5.0.10,<5.6.3",
"phpxmlrpc/extras": "<0.6.1",
+ "propel/propel": ">=2.0.0-alpha1,<=2.0.0-alpha7",
+ "propel/propel1": ">=1,<=1.7.1",
"pusher/pusher-php-server": "<2.2.1",
"sabre/dav": ">=1.6,<1.6.99|>=1.7,<1.7.11|>=1.8,<1.8.9",
"shopware/shopware": "<5.3.7",
@@ -1069,11 +1077,12 @@
"silverstripe/forum": "<=0.6.1|>=0.7,<=0.7.3",
"silverstripe/framework": ">=3,<3.3",
"silverstripe/userforms": "<3",
- "simplesamlphp/saml2": "<1.10.4|>=2,<2.3.5|>=3,<3.1.1",
+ "simplesamlphp/saml2": "<1.10.6|>=2,<2.3.8|>=3,<3.1.4",
"simplesamlphp/simplesamlphp": "<1.15.2",
"simplesamlphp/simplesamlphp-module-infocard": "<1.0.1",
"socalnick/scn-social-auth": "<1.15.2",
"squizlabs/php_codesniffer": ">=1,<2.8.1",
+ "stormpath/sdk": ">=0,<9.9.99",
"swiftmailer/swiftmailer": ">=4,<5.4.5",
"symfony/dependency-injection": ">=2,<2.0.17",
"symfony/form": ">=2.3,<2.3.35|>=2.4,<2.6.12|>=2.7,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13",
@@ -1093,16 +1102,17 @@
"symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4",
"symfony/yaml": ">=2,<2.0.22|>=2.1,<2.1.7",
"thelia/backoffice-default-template": ">=2.1,<2.1.2",
- "thelia/thelia": ">=2.1.0-beta1,<2.1.3|>=2.1,<2.1.2",
+ "thelia/thelia": ">=2.1,<2.1.2|>=2.1.0-beta1,<2.1.3",
+ "titon/framework": ">=0,<9.9.99",
"twig/twig": "<1.20",
"typo3/cms": ">=6.2,<6.2.30|>=7,<7.6.22|>=8,<8.7.5",
"typo3/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.10|>=3.1,<3.1.7|>=3.2,<3.2.7|>=3.3,<3.3.5",
"typo3/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4",
"willdurand/js-translation-bundle": "<2.1.1",
"yiisoft/yii": ">=1.1.14,<1.1.15",
- "yiisoft/yii2": "<2.0.5",
+ "yiisoft/yii2": "<2.0.14",
"yiisoft/yii2-bootstrap": "<2.0.4",
- "yiisoft/yii2-dev": "<2.0.4",
+ "yiisoft/yii2-dev": "<2.0.14",
"yiisoft/yii2-gii": "<2.0.4",
"yiisoft/yii2-jui": "<2.0.4",
"zendframework/zend-cache": ">=2.4,<2.4.8|>=2.5,<2.5.3",
@@ -1142,22 +1152,22 @@
}
],
"description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it",
- "time": "2018-02-04T22:09:50+00:00"
+ "time": "2018-03-07T15:45:44+00:00"
}
],
"packages-dev": [
{
"name": "squizlabs/php_codesniffer",
- "version": "3.2.2",
+ "version": "3.2.3",
"source": {
"type": "git",
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
- "reference": "d7c00c3000ac0ce79c96fcbfef86b49a71158cd1"
+ "reference": "4842476c434e375f9d3182ff7b89059583aa8b27"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/d7c00c3000ac0ce79c96fcbfef86b49a71158cd1",
- "reference": "d7c00c3000ac0ce79c96fcbfef86b49a71158cd1",
+ "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/4842476c434e375f9d3182ff7b89059583aa8b27",
+ "reference": "4842476c434e375f9d3182ff7b89059583aa8b27",
"shasum": ""
},
"require": {
@@ -1167,7 +1177,7 @@
"php": ">=5.4.0"
},
"require-dev": {
- "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0"
+ "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
},
"bin": [
"bin/phpcs",
@@ -1195,7 +1205,7 @@
"phpcs",
"standards"
],
- "time": "2017-12-19T21:44:46+00:00"
+ "time": "2018-02-20T21:35:23+00:00"
}
],
"aliases": [],
diff --git a/lib/Definitions.php b/lib/Definitions.php
index 01a380df..44b53a64 100644
--- a/lib/Definitions.php
+++ b/lib/Definitions.php
@@ -27,10 +27,17 @@ use function DI\object;
return [
\Klein\Klein::class => object(\Klein\Klein::class),
- \SP\Core\Context\SessionContext::class => object(\SP\Core\Context\SessionContext::class),
+ \SP\Core\Context\ContextInterface::class => function (\Interop\Container\ContainerInterface $c) {
+ switch (APP_MODULE) {
+ case 'web':
+ return $c->get(\SP\Core\Context\SessionContext::class);
+ default:
+ return $c->get(\SP\Core\Context\StatelessContext::class);
+ }
+ },
\SP\Config\Config::class => object(\SP\Config\Config::class)
->constructor(object(\SP\Storage\XmlHandler::class)
- ->constructor(CONFIG_FILE), get(\SP\Core\Context\SessionContext::class)),
+ ->constructor(CONFIG_FILE), get(\SP\Core\Context\ContextInterface::class)),
\SP\Core\Language::class => object(\SP\Core\Language::class),
\SP\Config\ConfigData::class => function (\SP\Config\Config $config) {
return $config->getConfigData();
@@ -46,9 +53,9 @@ return [
->constructor(ACTIONS_FILE)),
\SP\Core\Events\EventDispatcher::class => object(\SP\Core\Events\EventDispatcher::class),
\SP\Core\Acl\Acl::class => object(\SP\Core\Acl\Acl::class)
- ->constructor(get(\SP\Core\Context\SessionContext::class), get(\SP\Core\Events\EventDispatcher::class), get(\SP\Core\Acl\Actions::class)),
+ ->constructor(get(\SP\Core\Context\ContextInterface::class), get(\SP\Core\Events\EventDispatcher::class), get(\SP\Core\Acl\Actions::class)),
\SP\Core\UI\Theme::class => object(\SP\Core\UI\Theme::class)
- ->constructor(APP_MODULE, get(\SP\Config\Config::class), get(\SP\Core\Context\SessionContext::class)),
+ ->constructor(APP_MODULE, get(\SP\Config\Config::class), get(\SP\Core\Context\ContextInterface::class)),
\PHPMailer\PHPMailer\PHPMailer::class => object(\PHPMailer\PHPMailer\PHPMailer::class)
->constructor(true)
];
\ No newline at end of file
diff --git a/lib/SP/Account/Account.php b/lib/SP/Account/Account.php
deleted file mode 100644
index 808ff563..00000000
--- a/lib/SP/Account/Account.php
+++ /dev/null
@@ -1,516 +0,0 @@
-.
- */
-
-namespace SP\Account;
-
-use Defuse\Crypto\Exception\CryptoException;
-use SP\Core\Crypt\Crypt;
-use SP\Core\Crypt\Session as CryptSession;
-use SP\Core\Exceptions\QueryException;
-use SP\Core\Exceptions\SPException;
-use SP\DataModel\AccountData;
-use SP\DataModel\AccountExtData;
-use SP\DataModel\AccountToUserGroupData;
-use SP\Log\Log;
-use SP\Mgmt\Groups\GroupAccounts;
-use SP\Mgmt\Groups\GroupAccountsUtil;
-use SP\Storage\DbWrapper;
-use SP\Storage\QueryData;
-
-defined('APP_ROOT') || die();
-
-/**
- * Esta clase es la encargada de realizar las operaciones sobre las cuentas de sysPass.
- */
-class Account extends AccountBase implements AccountInterface
-{
- /**
- * Actualiza los datos de una cuenta en la BBDD.
- *
- * @return bool
- * @throws \SP\Core\Exceptions\SPException
- */
- public function updateAccount()
- {
- $Acl = $this->session->getAccountAcl($this->accountData->getId());
-
- // Guardamos una copia de la cuenta en el histórico
- AccountHistory::addHistory($this->accountData->getId(), false);
-
- try {
- if ($Acl->getStoredAcl()->isShowPermission()) {
- $GroupAccountsData = new AccountToUserGroupData();
- $GroupAccountsData->setAccountId($this->accountData->getId());
- $GroupAccountsData->setGroups($this->accountData->getUserGroupsId());
-
- GroupAccounts::getItem($GroupAccountsData)->update();
- UserAccounts::updateUsersForAccount($this->accountData->getId(), $this->accountData->getUsersId());
- }
- } catch (SPException $e) {
- Log::writeNewLog(__FUNCTION__, $e->getMessage(), Log::ERROR);
- }
-
- if (is_array($this->accountData->getTags())) {
- $AccountTags = new AccountTags();
- $AccountTags->addTags($this->accountData, true);
- }
-
- $Data = new QueryData();
-
- $fields = [
- 'account_customerId = :accountCustomerId',
- 'account_categoryId = :accountCategoryId',
- 'account_name = :accountName',
- 'account_login = :accountLogin',
- 'account_url = :accountUrl',
- 'account_notes = :accountNotes',
- 'account_userEditId = :accountUserEditId',
- 'account_dateEdit = NOW()',
- 'account_passDateChange = :accountPassDateChange',
- 'account_isPrivate = :accountIsPrivate',
- 'account_isPrivateGroup = :accountIsPrivateGroup',
- 'account_parentId = :accountParentId'
- ];
-
- if ($this->accountData->getUserGroupId()) {
- $fields[] = 'account_userGroupId = :accountUserGroupId';
-
- $Data->addParam($this->accountData->getUserGroupId(), 'accountUserGroupId');
- }
-
- if ($Acl->getStoredAcl()->isShowPermission()) {
- $fields[] = 'account_otherUserEdit = :accountOtherUserEdit';
- $fields[] = 'account_otherGroupEdit = :accountOtherGroupEdit';
-
- $Data->addParam($this->accountData->getOtherUserEdit(), 'accountOtherUserEdit');
- $Data->addParam($this->accountData->getOtherUserGroupEdit(), 'accountOtherGroupEdit');
- }
-
- $query = /** @lang SQL */
- 'UPDATE Account SET ' . implode(',', $fields) . ' WHERE account_id = :accountId';
-
- $Data->setQuery($query);
- $Data->addParam($this->accountData->getClientId(), 'accountCustomerId');
- $Data->addParam($this->accountData->getCategoryId(), 'accountCategoryId');
- $Data->addParam($this->accountData->getName(), 'accountName');
- $Data->addParam($this->accountData->getLogin(), 'accountLogin');
- $Data->addParam($this->accountData->getUrl(), 'accountUrl');
- $Data->addParam($this->accountData->getNotes(), 'accountNotes');
- $Data->addParam($this->accountData->getUserEditId(), 'accountUserEditId');
- $Data->addParam($this->accountData->getPassDateChange(), 'accountPassDateChange');
- $Data->addParam($this->accountData->getIsPrivate(), 'accountIsPrivate');
- $Data->addParam($this->accountData->getIsPrivateGroup(), 'accountIsPrivateGroup');
- $Data->addParam($this->accountData->getParentId(), 'accountParentId');
- $Data->addParam($this->accountData->getId(), 'accountId');
- $Data->setOnErrorMessage(__('Error al modificar la cuenta', false));
-
- DbWrapper::getQuery($Data);
-
- return true;
- }
-
- /**
- * Restaurar una cuenta desde el histórico.
- *
- * @param $id int El Id del registro en el histórico
- * @return bool
- * @throws \SP\Core\Exceptions\SPException
- */
- public function restoreFromHistory($id)
- {
- // Guardamos una copia de la cuenta en el histórico
- AccountHistory::addHistory($this->accountData->getId(), false);
-
- $query = /** @lang SQL */
- 'UPDATE Account dst, '
- . '(SELECT * FROM accHistory WHERE acchistory_id = :id) src SET '
- . 'dst.account_customerId = src.acchistory_customerId,'
- . 'dst.account_categoryId = src.acchistory_categoryId,'
- . 'dst.account_name = src.acchistory_name,'
- . 'dst.account_login = src.acchistory_login,'
- . 'dst.account_url = src.acchistory_url,'
- . 'dst.account_notes = src.acchistory_notes,'
- . 'dst.account_userGroupId = src.acchistory_userGroupId,'
- . 'dst.account_userEditId = :accountUserEditId,'
- . 'dst.account_dateEdit = NOW(),'
- . 'dst.account_otherUserEdit = src.acchistory_otherUserEdit + 0,'
- . 'dst.account_otherGroupEdit = src.acchistory_otherGroupEdit + 0,'
- . 'dst.account_pass = src.acchistory_pass,'
- . 'dst.account_key = src.acchistory_key,'
- . 'dst.account_passDate = src.acchistory_passDate,'
- . 'dst.account_passDateChange = src.acchistory_passDateChange, '
- . 'dst.account_parentId = src.acchistory_parentId, '
- . 'dst.account_isPrivate = src.accHistory_isPrivate, '
- . 'dst.account_isPrivateGroup = src.accHistory_isPrivateGroup '
- . 'WHERE dst.account_id = src.acchistory_accountId';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($id, 'id');
- $Data->addParam($this->session->getUserData()->getId(), 'accountUserEditId');
- $Data->setOnErrorMessage(__('Error al restaurar cuenta', false));
-
- DbWrapper::getQuery($Data);
-
- return true;
- }
-
- /**
- * Obtener los datos de una cuenta.
- * Esta funcion realiza la consulta a la BBDD y guarda los datos en las variables de la clase.
- *
- * @return AccountExtData
- * @throws \SP\Core\Exceptions\SPException
- */
- public function getData()
- {
- $query = /** @lang SQL */
- 'SELECT * FROM account_data_v WHERE account_id = ? LIMIT 1';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->setMapClass($this->accountData);
- $Data->addParam($this->accountData->getId());
-
- /** @var AccountExtData|array $queryRes */
- $queryRes = DbWrapper::getResults($Data);
-
- if ($queryRes === false) {
- throw new SPException(__('No se pudieron obtener los datos de la cuenta', false), SPException::CRITICAL);
- } elseif (is_array($queryRes) && count($queryRes) === 0) {
- throw new SPException(__('La cuenta no existe', false), SPException::CRITICAL);
- }
-
- // Obtener los usuarios y grupos secundarios y las etiquetas
- $this->accountData->setUsersId(UserAccounts::getUsersForAccount($this->accountData->getId()));
- $this->accountData->setUserGroupsId(GroupAccountsUtil::getGroupsForAccount($this->accountData->getId()));
- $this->accountData->setTags(AccountTags::getTags($queryRes));
-
- return $this->accountData;
- }
-
- /**
- * Crea una nueva cuenta en la BBDD
- *
- * @param bool $encryptPass Encriptar la clave?
- * @return $this
- * @throws \SP\Core\Exceptions\ConstraintException
- * @throws \SP\Core\Exceptions\QueryException
- * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
- * @throws \Defuse\Crypto\Exception\CryptoException
- * @throws \Defuse\Crypto\Exception\BadFormatException
- * @throws SPException
- */
- public function createAccount($encryptPass = true)
- {
- if ($encryptPass === true) {
- $this->setPasswordEncrypted();
- }
-
- $query = /** @lang SQL */
- 'INSERT INTO Account SET '
- . 'account_customerId = :accountCustomerId,'
- . 'account_categoryId = :accountCategoryId,'
- . 'account_name = :accountName,'
- . 'account_login = :accountLogin,'
- . 'account_url = :accountUrl,'
- . 'account_pass = :accountPass,'
- . 'account_key = :accountKey,'
- . 'account_notes = :accountNotes,'
- . 'account_dateAdd = NOW(),'
- . 'account_userId = :accountUserId,'
- . 'account_userGroupId = :accountUserGroupId,'
- . 'account_userEditId = :accountUserEditId,'
- . 'account_otherUserEdit = :accountOtherUserEdit,'
- . 'account_otherGroupEdit = :accountOtherGroupEdit,'
- . 'account_isPrivate = :accountIsPrivate,'
- . 'account_isPrivateGroup = :accountIsPrivateGroup,'
- . 'account_passDate = UNIX_TIMESTAMP(),'
- . 'account_passDateChange = :accountPassDateChange,'
- . 'account_parentId = :accountParentId';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($this->accountData->getClientId(), 'accountCustomerId');
- $Data->addParam($this->accountData->getCategoryId(), 'accountCategoryId');
- $Data->addParam($this->accountData->getName(), 'accountName');
- $Data->addParam($this->accountData->getLogin(), 'accountLogin');
- $Data->addParam($this->accountData->getUrl(), 'accountUrl');
- $Data->addParam($this->accountData->getPass(), 'accountPass');
- $Data->addParam($this->accountData->getKey(), 'accountKey');
- $Data->addParam($this->accountData->getNotes(), 'accountNotes');
- $Data->addParam($this->accountData->getUserId(), 'accountUserId');
- $Data->addParam($this->accountData->getUserGroupId() ?: $this->session->getUserData()->getUserGroupId(), 'accountUserGroupId');
- $Data->addParam($this->accountData->getUserId(), 'accountUserEditId');
- $Data->addParam($this->accountData->getOtherUserEdit(), 'accountOtherUserEdit');
- $Data->addParam($this->accountData->getOtherUserGroupEdit(), 'accountOtherGroupEdit');
- $Data->addParam($this->accountData->getIsPrivate(), 'accountIsPrivate');
- $Data->addParam($this->accountData->getIsPrivateGroup(), 'accountIsPrivateGroup');
- $Data->addParam($this->accountData->getPassDateChange(), 'accountPassDateChange');
- $Data->addParam($this->accountData->getParentId(), 'accountParentId');
- $Data->setOnErrorMessage(__('Error al crear la cuenta', false));
-
- DbWrapper::getQuery($Data);
-
- $this->accountData->setId(DbWrapper::$lastId);
-
- try {
- if (is_array($this->accountData->getAccountUserGroupsId())) {
- $GroupAccounsData = new AccountToUserGroupData();
- $GroupAccounsData->setAccountId($this->accountData->getId());
- $GroupAccounsData->setGroups($this->accountData->getAccountUserGroupsId());
-
- GroupAccounts::getItem($GroupAccounsData)->add();
- }
-
- if (is_array($this->accountData->getAccountUsersId())) {
- UserAccounts::addUsersForAccount($this->accountData->getId(), $this->accountData->getAccountUsersId());
- }
-
- if (is_array($this->accountData->getTags())) {
- $AccountTags = new AccountTags();
- $AccountTags->addTags($this->accountData);
- }
- } catch (SPException $e) {
- Log::writeNewLog(__FUNCTION__, $e->getMessage(), Log::ERROR);
- }
-
-
- return $this;
- }
-
- /**
- * Devolver los datos de la clave encriptados
- *
- * @param string $masterPass Clave maestra a utilizar
- * @throws \SP\Core\Exceptions\SPException
- * @throws \SP\Core\Exceptions\QueryException
- */
- public function setPasswordEncrypted($masterPass = null)
- {
- try {
- $masterPass = $masterPass ?: CryptSession::getSessionKey();
- $securedKey = Crypt::makeSecuredKey($masterPass);
-
- $this->accountData->setPass(Crypt::encrypt($this->accountData->getPass(), $securedKey, $masterPass));
- $this->accountData->setKey($securedKey);
-
- if (strlen($securedKey) > 1000 || strlen($this->accountData->getPass()) > 1000) {
- throw new QueryException(SPException::ERROR, __('Error interno', false));
- }
- } catch (CryptoException $e) {
- throw new SPException(__('Error interno', false), SPException::ERROR);
- }
- }
-
- /**
- * Elimina los datos de una cuenta en la BBDD.
- *
- * @param int|array $id
- * @return bool Los ids de las cuentas eliminadas
- * @throws SPException
- */
- public function deleteAccount($id)
- {
- if (is_array($id)) {
- foreach ($id as $accountId) {
- $this->deleteAccount($accountId);
- }
-
- return true;
- }
-
- // Guardamos una copia de la cuenta en el histórico
- AccountHistory::addHistory($id, true);
-
- $Data = new QueryData();
-
- $query = /** @lang SQL */
- 'DELETE FROM Account WHERE account_id = ? LIMIT 1';
-
- $Data->setQuery($query);
- $Data->addParam($id);
- $Data->setOnErrorMessage(__('Error al eliminar la cuenta', false));
-
- DbWrapper::getQuery($Data);
-
- return $Data->getQueryNumRows() === 1;
- }
-
- /**
- * Incrementa el contador de visitas de una cuenta en la BBDD
- *
- * @param int $id
- * @return bool
- * @throws \SP\Core\Exceptions\QueryException
- * @throws \SP\Core\Exceptions\ConstraintException
- */
- public function incrementViewCounter($id = null)
- {
- $query = /** @lang SQL */
- 'UPDATE Account SET account_countView = (account_countView + 1) WHERE account_id = ? LIMIT 1';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($id ?: $this->accountData->getId());
-
- return DbWrapper::getQuery($Data);
- }
-
- /**
- * Incrementa el contador de vista de clave de una cuenta en la BBDD
- *
- * @param null $id
- * @return bool
- * @throws \SP\Core\Exceptions\QueryException
- * @throws \SP\Core\Exceptions\ConstraintException
- */
- public function incrementDecryptCounter($id = null)
- {
- $query = /** @lang SQL */
- 'UPDATE Account SET account_countDecrypt = (account_countDecrypt + 1) WHERE account_id = ? LIMIT 1';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($id ?: $this->accountData->getId());
-
- return DbWrapper::getQuery($Data);
- }
-
- /**
- * Actualiza la clave de una cuenta en la BBDD.
- *
- * @param bool $isMassive para no actualizar el histórico ni enviar mensajes
- * @return bool
- * @throws \SP\Core\Exceptions\ConstraintException
- * @throws \SP\Core\Exceptions\QueryException
- * @throws \SP\Core\Exceptions\SPException
- */
- public function updateAccountPass($isMassive = false)
- {
- // No actualizar el histórico si es por cambio de clave maestra o restauración
- if (!$isMassive) {
- AccountHistory::addHistory($this->accountData->getId(), false);
-
- $this->setPasswordEncrypted();
- }
-
- $query = /** @lang SQL */
- 'UPDATE Account SET '
- . 'account_pass = :accountPass,'
- . 'account_key = :accountKey,'
- . 'account_userEditId = :accountUserEditId,'
- . 'account_dateEdit = NOW(), '
- . 'account_passDate = UNIX_TIMESTAMP(), '
- . 'account_passDateChange = :accountPassDateChange '
- . 'WHERE account_id = :accountId';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($this->accountData->getPass(), 'accountPass');
- $Data->addParam($this->accountData->getKey(), 'accountKey');
- $Data->addParam($this->accountData->getUserEditId(), 'accountUserEditId');
- $Data->addParam($this->accountData->getPassDateChange(), 'accountPassDateChange');
- $Data->addParam($this->accountData->getId(), 'accountId');
- $Data->setOnErrorMessage(__('Error al actualizar la clave', false));
-
- DbWrapper::getQuery($Data);
-
- return true;
- }
-
- /**
- * Obtener los datos de una cuenta para mostrar la clave
- * Esta funcion realiza la consulta a la BBDD y devuelve los datos.
- *
- * @return AccountData|false
- */
- public function getAccountPassData()
- {
- $query = /** @lang SQL */
- 'SELECT account_name,'
- . 'account_userId,'
- . 'account_userGroupId,'
- . 'account_login,'
- . 'account_pass,'
- . 'account_key,'
- . 'name '
- . 'FROM Account '
- . 'LEFT JOIN Client ON account_customerId = id '
- . 'WHERE account_id = ? LIMIT 1';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->setMapClass($this->accountData);
- $Data->addParam($this->accountData->getId());
-
- // Obtener los usuarios y grupos secundarios
- $this->accountData->setUsersId(UserAccounts::getUsersForAccount($this->accountData->getId()));
- $this->accountData->setUserGroupsId(GroupAccountsUtil::getGroupsForAccount($this->accountData->getId()));
-
- return DbWrapper::getResults($Data);
- }
-
- /**
- * Obtener los datos de una cuenta.
- * Esta funcion realiza la consulta a la BBDD y guarda los datos en las variables de la clase.
- *
- * @return AccountExtData
- * @throws \SP\Core\Exceptions\SPException
- */
- public function getDataForLink()
- {
- $query = /** @lang SQL */
- 'SELECT account_name,'
- . 'account_login,'
- . 'account_pass,'
- . 'account_key,'
- . 'account_url,'
- . 'account_notes,'
- . 'name,'
- . 'name '
- . 'FROM Account '
- . 'LEFT JOIN Client ON account_customerId = id '
- . 'LEFT JOIN categories ON account_categoryId = id '
- . 'WHERE account_id = ? LIMIT 1';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->setMapClass($this->accountData);
- $Data->addParam($this->accountData->getId());
-
- /** @var AccountExtData|array $queryRes */
- $queryRes = DbWrapper::getResults($Data);
-
- if ($queryRes === false) {
- throw new SPException(__('No se pudieron obtener los datos de la cuenta', false), SPException::CRITICAL);
- }
-
- if (is_array($queryRes) && count($queryRes) === 0) {
- throw new SPException(__('La cuenta no existe', false), SPException::CRITICAL);
- }
-
- return $this->accountData;
- }
-}
\ No newline at end of file
diff --git a/lib/SP/Account/AccountBase.php b/lib/SP/Account/AccountBase.php
deleted file mode 100644
index f7f809df..00000000
--- a/lib/SP/Account/AccountBase.php
+++ /dev/null
@@ -1,126 +0,0 @@
-.
- */
-
-namespace SP\Account;
-
-use SP\Core\Context\SessionContext;
-use SP\Core\Traits\InjectableTrait;
-use SP\DataModel\AccountData;
-use SP\DataModel\AccountExtData;
-use SP\DataModel\AccountHistoryData;
-
-defined('APP_ROOT') || die();
-
-/**
- * Clase abstracta para definición de métodos comunes a las cuentas
- */
-abstract class AccountBase
-{
- use InjectableTrait;
-
- /**
- * Tiempo de expiración de la caché de ACLde usuarios/grupos de cuentas
- */
- const CACHE_EXPIRE_TIME = 300;
- /**
- * @var AccountData|AccountExtData|AccountHistoryData
- */
- protected $accountData;
- /** @var SessionContext */
- protected $session;
- /**
- * @var int Id de la cuenta padre.
- */
- private $accountParentId;
- /**
- * @var int Indica si la cuenta es un registro del histórico.
- */
- private $accountIsHistory = 0;
-
- /**
- * Constructor
- *
- * @param AccountData $accountData
- */
- public function __construct(AccountData $accountData = null)
- {
- $this->injectDependencies();
-
- $this->accountData = (null !== $accountData) ? $accountData : new AccountData();
- }
-
- /**
- * @param SessionContext $session
- */
- public function inject(SessionContext $session)
- {
- $this->session = $session;
- }
-
- /**
- * @return int
- */
- public function getAccountIsHistory()
- {
- return $this->accountIsHistory;
- }
-
- /**
- * @param int $accountIsHistory
- */
- public function setAccountIsHistory($accountIsHistory)
- {
- $this->accountIsHistory = $accountIsHistory;
- }
-
- /**
- * @return int
- */
- public function getAccountParentId()
- {
- return $this->accountParentId;
- }
-
- /**
- * @param int $accountParentId
- */
- public function setAccountParentId($accountParentId)
- {
- $this->accountParentId = $accountParentId;
- }
-
- /**
- * @return AccountData|AccountExtData
- */
- public function getAccountData()
- {
- return $this->accountData;
- }
-
- /**
- * Obtener los datos de una cuenta para mostrar la clave
- * Esta funcion realiza la consulta a la BBDD y devuelve los datos.
- */
- protected abstract function getAccountPassData();
-}
\ No newline at end of file
diff --git a/lib/SP/Account/AccountCrypt.php b/lib/SP/Account/AccountCrypt.php
deleted file mode 100644
index 334bb1d3..00000000
--- a/lib/SP/Account/AccountCrypt.php
+++ /dev/null
@@ -1,318 +0,0 @@
-.
- */
-
-namespace SP\Account;
-
-use Defuse\Crypto\Exception\CryptoException;
-use SP\Config\Config;
-use SP\Config\ConfigData;
-use SP\Core\Context\SessionContext;
-use SP\Core\Crypt\Crypt;
-use SP\Core\Exceptions\QueryException;
-use SP\Core\Exceptions\SPException;
-use SP\Core\OldCrypt;
-use SP\Core\TaskFactory;
-use SP\Core\Traits\InjectableTrait;
-use SP\DataModel\AccountData;
-use SP\Log\Email;
-use SP\Log\Log;
-use SP\Storage\DbWrapper;
-use SP\Storage\QueryData;
-use SP\Util\Util;
-
-/**
- * Class AccountCrypt
- *
- * @package SP\Account
- */
-class AccountCrypt
-{
- use InjectableTrait;
- /**
- * @var Config
- */
- protected $config;
- /**
- * @var ConfigData
- */
- protected $configData;
- /**
- * @var SessionContext
- */
- protected $session;
- /**
- * @var Log
- */
- protected $log;
-
- /**
- * AccountCrypt constructor.
- */
- public function __construct()
- {
- $this->injectDependencies();
- }
-
- /**
- * @param Config $config
- * @param Log $log
- * @param SessionContext $session
- */
- public function inject(Config $config, Log $log, SessionContext $session)
- {
- $this->config = $config;
- $this->configData = $config->getConfigData();
- $this->log = $log;
- $this->session = $session;
- }
-
- /**
- * Actualiza las claves de todas las cuentas con la clave maestra actual
- * usando nueva encriptación.
- *
- * @param string $currentMasterPass
- * @return bool
- * @throws \PHPMailer\PHPMailer\Exception
- */
- public function updateOldPass(&$currentMasterPass)
- {
- set_time_limit(0);
-
- $accountsOk = [];
- $userId = $this->session->getUserData()->getId();
- $errorCount = 0;
-
- $LogMessage = $this->log->getLogMessage();
- $LogMessage->setAction(__('Actualizar Clave Maestra', false));
- $LogMessage->addDescription(__('Inicio', false));
- $this->log->writeLog(true);
-
- if (!OldCrypt::checkCryptModule()) {
- $LogMessage->addDescription(__('Error en el módulo de encriptación', false));
- $this->log->setLogLevel(Log::ERROR);
- $this->log->writeLog();
- return false;
- }
-
- $accountsPass = $this->getAccountsPassData();
- $numAccounts = count($accountsPass);
-
- if ($numAccounts === 0) {
- $LogMessage->addDescription(__('Error al obtener las claves de las cuentas', false));
- $this->log->setLogLevel(Log::ERROR);
- $this->log->writeLog();
- return false;
- }
-
- $AccountDataBase = new AccountData();
-
- TaskFactory::$Message->setTask(__('Actualizar Clave Maestra'));
- TaskFactory::update();
-
- $counter = 0;
- $startTime = time();
-
- foreach ($accountsPass as $account) {
- // No realizar cambios si está en modo demo
- if ($this->configData->isDemoEnabled()) {
- $accountsOk[] = $account->account_id;
- continue;
- }
-
- if ($LogMessage->getDetailsCounter() >= 100) {
- $this->log->writeLog(false, true);
- }
-
- if ($counter % 100 === 0) {
- $eta = Util::getETA($startTime, $counter, $numAccounts);
-
- TaskFactory::$Message->setMessage(__('Cuentas actualizadas') . ': ' . $counter . '/' . $numAccounts);
- TaskFactory::$Message->setProgress(round(($counter * 100) / $numAccounts, 2));
- TaskFactory::$Message->setTime(sprintf('ETA: %ds (%.2f/s)', $eta[0], $eta[1]));
- TaskFactory::update();
-
- debugLog(TaskFactory::$Message->composeText());
- }
-
- $AccountData = clone $AccountDataBase;
-
- $AccountData->setId($account->account_id);
- $AccountData->setUserEditId($userId);
-
-// } elseif (strlen($account->account_key) < 32) {
-// $LogMessage->addDetails(__('IV de encriptación incorrecto', false), sprintf('%s (%d)', $account->account_name, $account->account_id));
-// }
-
- try {
- $decryptedPass = OldCrypt::getDecrypt($account->account_pass, $account->account_key, $currentMasterPass);
-
- $securedKey = Crypt::makeSecuredKey($currentMasterPass);
-
- $AccountData->setPass(Crypt::encrypt($decryptedPass, $securedKey, $currentMasterPass));
- $AccountData->setKey($securedKey);
-
- if (strlen($securedKey) > 1000 || strlen($AccountData->getPass()) > 1000) {
- throw new QueryException(SPException::ERROR, __('Error interno', false));
- }
-
- $Account = new Account($AccountData);
- $Account->updateAccountPass(true);
-
- $accountsOk[] = $account->account_id;
- $counter++;
- } catch (SPException $e) {
- $errorCount++;
- $LogMessage->addDetails(__('Fallo al actualizar la clave de la cuenta', false), sprintf('%s (%d)', $account->account_name, $account->account_id));
- } catch (CryptoException $e) {
- $errorCount++;
- $LogMessage->addDetails(__('Fallo al actualizar la clave de la cuenta', false), sprintf('%s (%d)', $account->account_name, $account->account_id));
- }
- }
-
- $LogMessage->addDetails(__('Cuentas actualizadas', false), implode(',', $accountsOk));
- $LogMessage->addDetails(__('Errores', false), $errorCount);
- $this->log->writeLog();
-
- Email::sendEmail($LogMessage);
-
- return true;
- }
-
- /**
- * Obtener los datos relativos a la clave de todas las cuentas.
- *
- * @return array Con los datos de la clave
- */
- protected function getAccountsPassData()
- {
- $query = /** @lang SQL */
- 'SELECT account_id, account_name, account_pass, account_key
- FROM Account WHERE BIT_LENGTH(account_pass) > 0';
-
- $Data = new QueryData();
- $Data->setQuery($query);
-
- return DbWrapper::getResultsArray($Data);
- }
-
- /**
- * Actualiza las claves de todas las cuentas con la nueva clave maestra.
- *
- * @param string $currentMasterPass
- * @param string $newMasterPass
- * @return bool
- */
- public function updatePass($currentMasterPass, $newMasterPass)
- {
- set_time_limit(0);
-
- $accountsOk = [];
- $userId = $this->session->getUserData()->getId();
- $errorCount = 0;
-
- $LogMessage = $this->log->getLogMessage();
- $LogMessage->setAction(__('Actualizar Clave Maestra', false));
- $LogMessage->addDescription(__('Inicio', false));
- $this->log->writeLog(true);
-
- $accountsPass = $this->getAccountsPassData();
- $numAccounts = count($accountsPass);
-
- if ($numAccounts === 0) {
- $LogMessage->addDescription(__('Error al obtener las claves de las cuentas', false));
- $this->log->setLogLevel(Log::ERROR);
- $this->log->writeLog();
- return false;
- }
-
- $AccountDataBase = new AccountData();
-
- TaskFactory::$Message->setTask(__('Actualizar Clave Maestra'));
- TaskFactory::update();
-
- $counter = 0;
- $startTime = time();
-
- foreach ($accountsPass as $account) {
- // No realizar cambios si está en modo demo
- if ($this->configData->isDemoEnabled()) {
- $accountsOk[] = $account->account_id;
- continue;
- }
-
- if ($LogMessage->getDetailsCounter() >= 100) {
- $this->log->writeLog(false, true);
- }
-
- if ($counter % 100 === 0) {
- $eta = Util::getETA($startTime, $counter, $numAccounts);
-
- TaskFactory::$Message->setMessage(__('Cuentas actualizadas') . ': ' . $counter . '/' . $numAccounts);
- TaskFactory::$Message->setProgress(round(($counter * 100) / $numAccounts, 2));
- TaskFactory::$Message->setTime(sprintf('ETA: %ds (%.2f/s)', $eta[0], $eta[1]));
- TaskFactory::update();
-
- debugLog(TaskFactory::$Message->composeText());
- }
-
- $AccountData = clone $AccountDataBase;
-
- $AccountData->setId($account->account_id);
- $AccountData->setUserEditId($userId);
-
- try {
- $currentSecuredKey = Crypt::unlockSecuredKey($account->account_key, $currentMasterPass);
- $decryptedPass = Crypt::decrypt($account->account_pass, $currentSecuredKey);
-
- $newSecuredKey = Crypt::makeSecuredKey($newMasterPass);
- $AccountData->setPass(Crypt::encrypt($decryptedPass, $newSecuredKey, $newMasterPass));
- $AccountData->setKey($newSecuredKey);
-
- if (strlen($newSecuredKey) > 1000 || strlen($AccountData->getPass()) > 1000) {
- throw new QueryException(SPException::ERROR, __('Error interno', false));
- }
-
- $Account = new Account($AccountData);
- $Account->updateAccountPass(true);
-
- $accountsOk[] = $account->account_id;
- $counter++;
- } catch (SPException $e) {
- $errorCount++;
- $LogMessage->addDetails(__('Fallo al actualizar la clave de la cuenta', false), sprintf('%s (%d)', $account->account_name, $account->account_id));
- } catch (CryptoException $e) {
- $errorCount++;
- $LogMessage->addDetails(__('Fallo al actualizar la clave de la cuenta', false), sprintf('%s (%d)', $account->account_name, $account->account_id));
- }
- }
-
- $LogMessage->addDetails(__('Cuentas actualizadas', false), implode(',', $accountsOk));
- $LogMessage->addDetails(__('Errores', false), $errorCount);
- $this->log->writeLog();
-
- Email::sendEmail($LogMessage);
-
- return true;
- }
-}
\ No newline at end of file
diff --git a/lib/SP/Account/AccountFavorites.php b/lib/SP/Account/AccountFavorites.php
deleted file mode 100644
index 31aa27bb..00000000
--- a/lib/SP/Account/AccountFavorites.php
+++ /dev/null
@@ -1,106 +0,0 @@
-.
- */
-
-namespace SP\Account;
-
-use SP\Storage\DbWrapper;
-use SP\Storage\QueryData;
-
-/**
- * Class AccountFavorites para la gestión de las cuentas favoritas de los usuarios
- *
- * @package SP\Account
- */
-class AccountFavorites
-{
- /**
- * Obtener un array con los Ids de cuentas favoritas
- *
- * @param $userId int El Id de usuario
- * @return array
- */
- public static function getFavorites($userId)
- {
- $query = /** @lang SQL */
- 'SELECT accountId FROM AccountToFavorite WHERE userId = ?';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($userId);
-
- $queryRes = DbWrapper::getResultsArray($Data);
-
- $favorites = [];
-
- foreach($queryRes as $favorite){
- $favorites[] = (int)$favorite->accfavorite_accountId;
- }
-
- return $favorites;
- }
-
- /**
- * Añadir una cuenta a la lista de favoritos
- *
- * @param $accountId int El Id de la cuenta
- * @param $userId int El Id del usuario
- * @throws \SP\Core\Exceptions\SPException
- */
- public static function addFavorite($accountId, $userId)
- {
- $query = /** @lang SQL */
- 'INSERT INTO AccountToFavorite SET accountId = ?, userId = ?';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($accountId);
- $Data->addParam($userId);
- $Data->setOnErrorMessage(__('Error al añadir favorito', false));
-
- DbWrapper::getQuery($Data);
- }
-
- /**
- * Eliminar una cuenta de la lista de favoritos
- *
- * @param $accountId int El Id de la cuenta
- * @param $userId int El Id del usuario
- * @return void
- * @throws \SP\Core\Exceptions\ConstraintException
- * @throws \SP\Core\Exceptions\QueryException
- */
- public static function deleteFavorite($accountId, $userId)
- {
- $query = /** @lang SQL */
- 'DELETE FROM AccountToFavorite WHERE accountId = ? AND userId = ?';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($accountId);
- $Data->addParam($userId);
- $Data->setOnErrorMessage(__('Error al eliminar favorito', false));
-
- DbWrapper::getQuery($Data);
- }
-}
\ No newline at end of file
diff --git a/lib/SP/Account/AccountHistory.php b/lib/SP/Account/AccountHistory.php
deleted file mode 100644
index 86a6a3c6..00000000
--- a/lib/SP/Account/AccountHistory.php
+++ /dev/null
@@ -1,519 +0,0 @@
-.
- */
-
-namespace SP\Account;
-
-use SP\Config\ConfigDB;
-use SP\Core\Exceptions\SPException;
-use SP\Storage\DbWrapper;
-use SP\Storage\QueryData;
-
-defined('APP_ROOT') || die();
-
-/**
- * Class AccountHistory par el manejo del historial de cuentas
- *
- * @package SP
- */
-class AccountHistory extends AccountBase implements AccountInterface
-{
- protected $id;
- /**
- * @var bool
- */
- private $isDelete = false;
- /**
- * @var bool
- */
- private $isModify = false;
-
- /**
- * Obtiene el listado del histórico de una cuenta.
- *
- * @param $accountId
- * @return array|false Con los registros con id como clave y fecha - usuario como valor
- */
- public static function getAccountList($accountId)
- {
- $query = /** @lang SQL */
- 'SELECT acchistory_id,'
- . 'acchistory_dateEdit,'
- . 'u1.user_login as user_edit,'
- . 'u2.user_login as user_add,'
- . 'acchistory_dateAdd '
- . 'FROM accHistory '
- . 'LEFT JOIN usrData u1 ON acchistory_userEditId = u1.user_id '
- . 'LEFT JOIN usrData u2 ON acchistory_userId = u2.user_id '
- . 'WHERE acchistory_accountId = ? '
- . 'ORDER BY acchistory_id DESC';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($accountId);
-
- $arrHistory = [];
-
- foreach (DbWrapper::getResultsArray($Data) as $history) {
- // Comprobamos si la entrada en el historial es la primera (no tiene editor ni fecha de edición)
- if (empty($history->acchistory_dateEdit) || $history->acchistory_dateEdit === '0000-00-00 00:00:00') {
- $date = $history->acchistory_dateAdd . ' - ' . $history->user_add;
- } else {
- $date = $history->acchistory_dateEdit . ' - ' . $history->user_edit;
- }
-
- $arrHistory[$history->acchistory_id] = $date;
- }
-
- return $arrHistory;
- }
-
- /**
- * Crear un nuevo registro de histório de cuenta en la BBDD.
- *
- * @param int|array $id Id de la cuenta primaria
- * @param bool $isDelete indica que la cuenta es eliminada
- * @return bool
- * @throws \SP\Core\Exceptions\SPException
- */
- public static function addHistory($id, $isDelete = false)
- {
- $Data = new QueryData();
- $Data->addParam(($isDelete === false) ? 1 : 0);
- $Data->addParam(($isDelete === true) ? 1 : 0);
- $Data->addParam(ConfigDB::getValue('masterPwd'));
-
- if (is_array($id)) {
- $querySelect = /** @lang SQL */
- 'SELECT account_id,'
- . 'account_categoryId,'
- . 'account_customerId,'
- . 'account_name,'
- . 'account_login,'
- . 'account_url,'
- . 'account_pass,'
- . 'account_key,'
- . 'account_notes,'
- . 'account_countView,'
- . 'account_countDecrypt,'
- . 'account_dateAdd,'
- . 'account_dateEdit,'
- . 'account_userId,'
- . 'account_userGroupId,'
- . 'account_userEditId,'
- . 'account_otherUserEdit,'
- . 'account_otherGroupEdit,'
- . 'account_isPrivate,'
- . 'account_isPrivateGroup,'
- . '?,?,? '
- . 'FROM Account WHERE account_id IN (' . implode(',', array_fill(0, count($id), '?')) . ')';
-
- foreach ($id as $param) {
- $Data->addParam($param);
- }
- } else {
- $querySelect = /** @lang SQL */
- 'SELECT account_id,'
- . 'account_categoryId,'
- . 'account_customerId,'
- . 'account_name,'
- . 'account_login,'
- . 'account_url,'
- . 'account_pass,'
- . 'account_key,'
- . 'account_notes,'
- . 'account_countView,'
- . 'account_countDecrypt,'
- . 'account_dateAdd,'
- . 'account_dateEdit,'
- . 'account_userId,'
- . 'account_userGroupId,'
- . 'account_userEditId,'
- . 'account_otherUserEdit,'
- . 'account_otherGroupEdit,'
- . 'account_isPrivate,'
- . 'account_isPrivateGroup,'
- . '?,?,? '
- . 'FROM Account WHERE account_id = ?';
-
- $Data->addParam($id);
- }
-
- $query = /** @lang SQL */
- 'INSERT INTO accHistory '
- . '(acchistory_accountId,'
- . 'acchistory_categoryId,'
- . 'acchistory_customerId,'
- . 'acchistory_name,'
- . 'acchistory_login,'
- . 'acchistory_url,'
- . 'acchistory_pass,'
- . 'acchistory_key,'
- . 'acchistory_notes,'
- . 'acchistory_countView,'
- . 'acchistory_countDecrypt,'
- . 'acchistory_dateAdd,'
- . 'acchistory_dateEdit,'
- . 'acchistory_userId,'
- . 'acchistory_userGroupId,'
- . 'acchistory_userEditId,'
- . 'acchistory_otherUserEdit,'
- . 'acchistory_otherGroupEdit,'
- . 'accHistory_isPrivate,'
- . 'accHistory_isPrivateGroup,'
- . 'acchistory_isModify,'
- . 'acchistory_isDeleted,'
- . 'acchistory_mPassHash)';
-
- $Data->setQuery($query . ' ' . $querySelect);
- $Data->setOnErrorMessage(__('Error al actualizar el historial', false));
-
- return DbWrapper::getQuery($Data);
- }
-
- /**
- * Obtener el Id padre de una cuenta en el histórico.
- *
- * @param $historyId int El id de la cuenta en el histórico
- * @return int El id de la cuenta padre
- * @throws SPException
- */
- public static function getAccountIdFromId($historyId)
- {
- $query = /** @lang SQL */
- 'SELECT acchistory_accountId FROM accHistory WHERE acchistory_id = ? LIMIT 1';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($historyId);
-
- $queryRes = DbWrapper::getResults($Data);
-
- if ($queryRes === false) {
- throw new SPException(__('No se pudieron obtener los datos de la cuenta', false), SPException::CRITICAL, 0);
- }
-
- return $queryRes->acchistory_accountId;
- }
-
- /**
- * Actualiza el hash de las cuentas en el histórico.
- *
- * @param $newHash string El nuevo hash de la clave maestra
- * @return bool
- * @throws \SP\Core\Exceptions\QueryException
- * @throws \SP\Core\Exceptions\ConstraintException
- */
- public static function updateAccountsMPassHash($newHash)
- {
- $query = /** @lang SQL */
- 'UPDATE accHistory SET '
- . 'acchistory_mPassHash = ? '
- . 'WHERE acchistory_mPassHash = ?';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($newHash);
- $Data->addParam(ConfigDB::getValue('masterPwd'));
-
- return DbWrapper::getQuery($Data);
- }
-
- /**
- * Comprueba el hash de la clave maestra del registro de histórico de una cuenta.
- *
- * @param int $id opcional, con el Id del registro a comprobar
- * @return bool
- */
- public function checkAccountMPass($id = null)
- {
- $query = /** @lang SQL */
- 'SELECT acchistory_mPassHash ' .
- 'FROM accHistory ' .
- 'WHERE acchistory_id = ? ' .
- 'AND acchistory_mPassHash = ?';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam(null === $id ? $this->accountData->getId() : $id);
- $Data->addParam(ConfigDB::getValue('masterPwd'));
-
- return (DbWrapper::getResults($Data) !== false);
- }
-
- /**
- * Actualiza la clave del histórico de una cuenta en la BBDD.
- *
- * @param object $AccountData Objeto con los datos de la cuenta
- * @return bool
- * @throws \SP\Core\Exceptions\QueryException
- * @throws \SP\Core\Exceptions\ConstraintException
- */
- public function updateAccountPass($AccountData)
- {
- $query = /** @lang SQL */
- 'UPDATE accHistory SET '
- . 'acchistory_pass = :accountPass,'
- . 'acchistory_key = :accountKey,'
- . 'acchistory_mPassHash = :hash '
- . 'WHERE acchistory_id = :id';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($AccountData->id, 'id');
- $Data->addParam($AccountData->pass, 'accountPass');
- $Data->addParam($AccountData->key, 'accountKey');
- $Data->addParam($AccountData->hash, 'hash');
-
- return DbWrapper::getQuery($Data);
- }
-
- /**
- * Obtener los datos de una cuenta para mostrar la clave
- * Esta funcion realiza la consulta a la BBDD y devuelve los datos.
- *
- * @return object|false
- */
- public function getAccountPassData()
- {
- $query = /** @lang SQL */
- 'SELECT acchistory_name AS account_name,'
- . 'acchistory_userId AS account_userId,'
- . 'acchistory_userGroupId AS account_userGroupId,'
- . 'acchistory_login AS account_login,'
- . 'acchistory_pass AS account_pass,'
- . 'acchistory_key AS account_key,'
- . 'name '
- . 'FROM accHistory '
- . 'LEFT JOIN customers ON acchistory_customerId = id '
- . 'WHERE acchistory_id = ? LIMIT 1';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->setMapClass($this->accountData);
- $Data->addParam($this->getId());
-
- return DbWrapper::getResults($Data);
- }
-
- /**
- * @return mixed
- */
- public function getId()
- {
- return $this->id;
- }
-
- /**
- * @param mixed $id
- */
- public function setId($id)
- {
- $this->id = $id;
- }
-
- /**
- * Obtener los datos del histórico de una cuenta.
- * Esta funcion realiza la consulta a la BBDD y guarda los datos del histórico
- * en las variables de la clase.
- *
- * @return object
- * @throws SPException
- */
- public function getData()
- {
- $query = /** @lang SQL */
- 'SELECT acchistory_accountId as account_id,'
- . 'acchistory_customerId as account_customerId,'
- . 'acchistory_categoryId as account_categoryId,'
- . 'acchistory_name as account_name,'
- . 'acchistory_login as account_login,'
- . 'acchistory_url as account_url,'
- . 'acchistory_pass as account_pass,'
- . 'acchistory_key as account_key,'
- . 'acchistory_notes as account_notes,'
- . 'acchistory_countView as account_countView,'
- . 'acchistory_countDecrypt as account_countDecrypt,'
- . 'acchistory_dateAdd as account_dateAdd,'
- . 'acchistory_dateEdit as account_dateEdit,'
- . 'acchistory_userId as account_userId,'
- . 'acchistory_userGroupId as account_userGroupId,'
- . 'acchistory_userEditId as account_userEditId,'
- . 'acchistory_isModify,'
- . 'acchistory_isDeleted,'
- . 'acchistory_otherUserEdit + 0 AS account_otherUserEdit,'
- . 'acchistory_otherGroupEdit + 0 AS account_otherGroupEdit,'
- . 'acchistory_isPrivate + 0 AS account_isPrivate,'
- . 'acchistory_isPrivateGroup + 0 AS account_isPrivateGroup,'
- . 'u1.user_name,'
- . 'u1.user_login,'
- . 'usergroup_name,'
- . 'u2.user_name as user_editName,'
- . 'u2.user_login as user_editLogin,'
- . 'name, name '
- . 'FROM accHistory '
- . 'LEFT JOIN Category ON acchistory_categoryId = id '
- . 'LEFT JOIN usrGroups ON acchistory_userGroupId = usergroup_id '
- . 'LEFT JOIN usrData u1 ON acchistory_userId = u1.user_id '
- . 'LEFT JOIN usrData u2 ON acchistory_userEditId = u2.user_id '
- . 'LEFT JOIN customers ON acchistory_customerId = id '
- . 'WHERE acchistory_id = ? LIMIT 1';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->setMapClass($this->accountData);
- $Data->addParam($this->getId());
-
- $queryRes = DbWrapper::getResults($Data);
-
- if ($queryRes === false) {
- throw new SPException(__('No se pudieron obtener los datos de la cuenta', false), SPException::CRITICAL);
- }
-
- $this->accountData = $queryRes;
-
- return $queryRes;
- }
-
- /**
- * Crear una cuenta en el historial
- *
- * @param bool $encryptPass
- * @return bool
- * @throws \SP\Core\Exceptions\QueryException
- * @throws \SP\Core\Exceptions\ConstraintException
- */
- public function createAccount($encryptPass = true)
- {
- $query = /** @lang SQL */
- 'INSERT INTO accHistory SET '
- . 'acchistory_accountId = :account_id,'
- . 'acchistory_customerId = :accountCustomerId,'
- . 'acchistory_categoryId = :accountCategoryId,'
- . 'acchistory_name = :accountName,'
- . 'acchistory_login = :accountLogin,'
- . 'acchistory_url = :accountUrl,'
- . 'acchistory_pass = :accountPass,'
- . 'acchistory_key = :accountKey,'
- . 'acchistory_notes = :accountNotes,'
- . 'acchistory_dateAdd = :accountDateAdd,'
- . 'acchistory_dateEdit = :accountDateEdit,'
- . 'acchistory_countView = :accountCountView,'
- . 'acchistory_countDecrypt = :accountCountDecrypt,'
- . 'acchistory_userId = :accountUserId,'
- . 'acchistory_userGroupId = :accountUserGroupId,'
- . 'acchistory_otherUserEdit = :accountOtherUserEdit,'
- . 'acchistory_otherGroupEdit = :accountOtherGroupEdit,'
- . 'acchistory_isPrivate = :isPrivate,'
- . 'acchistory_isPrivateGroup = :isPrivateGroup,'
- . 'acchistory_isModify = :isModify,'
- . 'acchistory_isDeleted = :isDelete,'
- . 'acchistory_mPassHash = :masterPwd';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($this->accountData->getId(), 'account_id');
- $Data->addParam($this->accountData->getClientId(), 'accountCustomerId');
- $Data->addParam($this->accountData->getCategoryId(), 'accountCategoryId');
- $Data->addParam($this->accountData->getName(), 'accountName');
- $Data->addParam($this->accountData->getLogin(), 'accountLogin');
- $Data->addParam($this->accountData->getUrl(), 'accountUrl');
- $Data->addParam($this->accountData->getPass(), 'accountPass');
- $Data->addParam($this->accountData->getKey(), 'accountKey');
- $Data->addParam($this->accountData->getNotes(), 'accountNotes');
- $Data->addParam($this->accountData->getUserId(), 'accountUserId');
- $Data->addParam($this->accountData->getUserGroupId(), 'accountUserGroupId');
- $Data->addParam($this->accountData->getOtherUserEdit(), 'accountOtherUserEdit');
- $Data->addParam($this->accountData->getOtherUserGroupEdit(), 'accountOtherGroupEdit');
- $Data->addParam($this->accountData->getIsPrivate(), 'isPrivate');
- $Data->addParam($this->accountData->getIsPrivateGroup(), 'isPrivateGroup');
- $Data->addParam($this->isIsModify(), 'isModify');
- $Data->addParam($this->isIsDelete(), 'isDelete');
- $Data->addParam(ConfigDB::getValue('masterPwd'), 'masterPwd');
-
- return DbWrapper::getQuery($Data);
- }
-
- /**
- * @return boolean
- */
- public function isIsModify()
- {
- return $this->isModify;
- }
-
- /**
- * @param boolean $isModify
- */
- public function setIsModify($isModify)
- {
- $this->isModify = $isModify;
- }
-
- /**
- * @return boolean
- */
- public function isIsDelete()
- {
- return $this->isDelete;
- }
-
- /**
- * @param boolean $isDelete
- */
- public function setIsDelete($isDelete)
- {
- $this->isDelete = $isDelete;
- }
-
- /**
- * Eliminar una cuenta del historial
- *
- * @param $id
- * @return bool
- * @throws \SP\Core\Exceptions\QueryException
- * @throws \SP\Core\Exceptions\ConstraintException
- */
- public function deleteAccount($id)
- {
- if (is_array($id)) {
- foreach ($id as $accountId) {
- $this->deleteAccount($accountId);
- }
-
- return true;
- }
-
- $query = /** @lang SQL */
- 'DELETE FROM accHistory WHERE acchistory_id = ? LIMIT 1';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($id);
- $Data->setOnErrorMessage(__('Error al eliminar la cuenta', false));
-
- DbWrapper::getQuery($Data);
-
- return $Data->getQueryNumRows() === 1;
- }
-}
\ No newline at end of file
diff --git a/lib/SP/Account/AccountHistoryCrypt.php b/lib/SP/Account/AccountHistoryCrypt.php
deleted file mode 100644
index 9567c968..00000000
--- a/lib/SP/Account/AccountHistoryCrypt.php
+++ /dev/null
@@ -1,338 +0,0 @@
-.
- */
-
-namespace SP\Account;
-
-use Defuse\Crypto\Exception\CryptoException;
-use SP\Config\Config;
-use SP\Config\ConfigData;
-use SP\Core\Crypt\Crypt;
-use SP\Core\Crypt\Hash;
-use SP\Core\Exceptions\QueryException;
-use SP\Core\Exceptions\SPException;
-use SP\Core\OldCrypt;
-use SP\Core\SessionFactory;
-use SP\Core\TaskFactory;
-use SP\Core\Traits\InjectableTrait;
-use SP\Log\Email;
-use SP\Log\Log;
-use SP\Storage\DbWrapper;
-use SP\Storage\QueryData;
-use SP\Util\Util;
-
-/**
- * Class AccountHistoryCrypt
- *
- * @package SP\Account
- */
-class AccountHistoryCrypt
-{
- use InjectableTrait;
- /**
- * @var Config
- */
- protected $Config;
- /**
- * @var ConfigData
- */
- protected $ConfigData;
- /**
- * @var SessionFactory
- */
- protected $Session;
- /**
- * @var Log
- */
- protected $Log;
-
- /**
- * AccountCrypt constructor.
- */
- public function __construct()
- {
- $this->injectDependencies();
- }
-
- /**
- * @param Config $config
- * @param Log $log
- * @param SessionFactory $session
- */
- public function inject(Config $config, Log $log, SessionFactory $session)
- {
- $this->Config = $config;
- $this->ConfigData = $config->getConfigData();
- $this->Log = $log;
- $this->Session = $session;
- }
-
- /**
- * @var string
- */
- public static $currentMPassHash;
-
- /**
- * Actualiza las claves de todas las cuentas con la clave maestra actual
- * usando nueva encriptación.
- *
- * @param string $currentMasterPass
- * @return bool
- */
- public function updateOldPass(&$currentMasterPass)
- {
- set_time_limit(0);
-
- $accountsOk = [];
- $errorCount = 0;
-
- $LogMessage = $this->Log->getLogMessage();
- $LogMessage->setAction(__('Actualizar Clave Maestra (H)', false));
- $LogMessage->addDescription(__('Inicio', false));
- $this->Log->writeLog(true);
-
- if (!OldCrypt::checkCryptModule()) {
- $LogMessage->addDescription(__('Error en el módulo de encriptación', false));
- $this->Log->setLogLevel(Log::ERROR);
- $this->Log->writeLog();
- return false;
- }
-
- $accountsPass = $this->getAccountsPassData();
- $numAccounts = count($accountsPass);
-
- if ($numAccounts === 0) {
- $LogMessage->addDescription(__('No se encontraron registros', false));
- $this->Log->setLogLevel(Log::ERROR);
- $this->Log->writeLog();
- return true;
- }
-
- $AccountDataBase = new \stdClass();
- $AccountDataBase->id = 0;
- $AccountDataBase->pass = '';
- $AccountDataBase->key = '';
- $AccountDataBase->hash = Hash::hashKey($currentMasterPass);
-
- TaskFactory::$Message->setTask(__('Actualizar Clave Maestra (H)'));
- TaskFactory::update();
-
- $counter = 0;
- $startTime = time();
-
- foreach ($accountsPass as $account) {
- // No realizar cambios si está en modo demo
- if ($this->ConfigData->isDemoEnabled()) {
- $accountsOk[] = $account->acchistory_id;
- continue;
- }
-
- if ($LogMessage->getDetailsCounter() >= 100) {
- $this->Log->writeLog(false, true);
- }
-
- if ($counter % 100 === 0) {
- $eta = Util::getETA($startTime, $counter, $numAccounts);
-
- TaskFactory::$Message->setMessage(__('Cuentas actualizadas') . ': ' . $counter . '/' . $numAccounts);
- TaskFactory::$Message->setProgress(round(($counter * 100) / $numAccounts, 2));
- TaskFactory::$Message->setTime(sprintf('ETA: %ds (%.2f/s)', $eta[0], $eta[1]));
-
- TaskFactory::update();
-
- debugLog(TaskFactory::$Message->composeText());
- }
-
- $AccountData = clone $AccountDataBase;
-
- $AccountData->id = $account->acchistory_id;
-
- if (!self::$currentMPassHash === $account->acchistory_mPassHash
- && !hash_equals($currentMasterPass, $account->acchistory_mPassHash)
- ) {
- $errorCount++;
- $LogMessage->addDetails(__('La clave maestra del registro no coincide', false), sprintf('%s (%d)', $account->acchistory_name, $account->acchistory_id));
- continue;
- }
-
- try {
- $decryptedPass = OldCrypt::getDecrypt($account->acchistory_pass, $account->acchistory_key, $currentMasterPass);
-
- $securedKey = Crypt::makeSecuredKey($currentMasterPass);
-
- $AccountData->pass = Crypt::encrypt($decryptedPass, $securedKey, $currentMasterPass);
- $AccountData->key = $securedKey;
-
- if (strlen($securedKey) > 1000 || strlen($AccountData->pass) > 1000) {
- throw new QueryException(SPException::ERROR, __('Error interno', false));
- }
-
- $Account = new AccountHistory();
- $Account->updateAccountPass($AccountData);
-
- $accountsOk[] = $account->acchistory_id;
- $counter++;
- } catch (SPException $e) {
- $errorCount++;
- $LogMessage->addDetails(__('Fallo al actualizar la clave del histórico', false), sprintf('%s (%d)', $account->acchistory_name, $account->acchistory_id));
- } catch (CryptoException $e) {
- $errorCount++;
- $LogMessage->addDetails(__('Fallo al actualizar la clave del histórico', false), sprintf('%s (%d)', $account->acchistory_name, $account->acchistory_id));
- }
- }
-
- $LogMessage->addDetails(__('Cuentas actualizadas', false), implode(',', $accountsOk));
- $LogMessage->addDetails(__('Errores', false), $errorCount);
- $this->Log->writeLog();
-
- Email::sendEmail($LogMessage);
-
- return true;
- }
-
- /**
- * Obtener los datos relativos a la clave de todas las cuentas.
- *
- * @return array Con los datos de la clave
- */
- protected function getAccountsPassData()
- {
- $query = /** @lang SQL */
- 'SELECT acchistory_id, acchistory_name, acchistory_pass, acchistory_key, acchistory_mPassHash
- FROM accHistory WHERE BIT_LENGTH(acchistory_pass) > 0';
-
- $Data = new QueryData();
- $Data->setQuery($query);
-
- return DbWrapper::getResultsArray($Data);
- }
-
- /**
- * Actualiza las claves de todas las cuentas con la nueva clave maestra.
- *
- * @param string $currentMasterPass
- * @param string $newMasterPass
- * @return bool
- */
- public function updatePass($currentMasterPass, $newMasterPass)
- {
- set_time_limit(0);
-
- $accountsOk = [];
- $errorCount = 0;
-
- $LogMessage = $this->Log->getLogMessage();
- $LogMessage->setAction(__('Actualizar Clave Maestra (H)', false));
- $LogMessage->addDescription(__('Inicio', false));
- $this->Log->writeLog(true);
-
- $accountsPass = $this->getAccountsPassData();
- $numAccounts = count($accountsPass);
-
- if ($numAccounts === 0) {
- $LogMessage->addDescription(__('No se encontraron registros', false));
- $this->Log->setLogLevel(Log::ERROR);
- $this->Log->writeLog();
- return true;
- }
-
- $AccountDataBase = new \stdClass();
- $AccountDataBase->id = 0;
- $AccountDataBase->pass = '';
- $AccountDataBase->key = '';
- $AccountDataBase->hash = Hash::hashKey($newMasterPass);
-
- TaskFactory::$Message->setTask(__('Actualizar Clave Maestra (H)'));
- TaskFactory::update();
-
- $counter = 0;
- $startTime = time();
-
- foreach ($accountsPass as $account) {
- // No realizar cambios si está en modo demo
- if ($this->ConfigData->isDemoEnabled()) {
- $accountsOk[] = $account->acchistory_id;
- continue;
- }
-
- if ($LogMessage->getDetailsCounter() >= 100) {
- $this->Log->writeLog(false, true);
- }
-
- if ($counter % 100 === 0) {
- $eta = Util::getETA($startTime, $counter, $numAccounts);
-
- TaskFactory::$Message->setMessage(__('Cuentas actualizadas') . ': ' . $counter . '/' . $numAccounts);
- TaskFactory::$Message->setProgress(round(($counter * 100) / $numAccounts, 2));
- TaskFactory::$Message->setTime(sprintf('ETA: %ds (%.2f/s)', $eta[0], $eta[1]));
-
- TaskFactory::update();
-
- debugLog(TaskFactory::$Message->composeText());
- }
-
- $AccountData = clone $AccountDataBase;
-
- $AccountData->id = $account->acchistory_id;
-
- if (!Hash::checkHashKey($currentMasterPass, $account->acchistory_mPassHash)) {
- $errorCount++;
- $LogMessage->addDetails(__('La clave maestra del registro no coincide', false), sprintf('%s (%d)', $account->acchistory_name, $account->acchistory_id));
- continue;
- }
-
- try {
- $currentSecuredKey = Crypt::unlockSecuredKey($account->acchistory_key, $currentMasterPass);
- $decryptedPass = Crypt::decrypt($account->acchistory_pass, $currentSecuredKey);
-
- $newSecuredKey = Crypt::makeSecuredKey($newMasterPass);
- $AccountData->pass = Crypt::encrypt($decryptedPass, $newSecuredKey, $newMasterPass);
- $AccountData->key = $newSecuredKey;
-
- if (strlen($newSecuredKey) > 1000 || strlen($AccountData->pass) > 1000) {
- throw new QueryException(SPException::ERROR, __('Error interno', false));
- }
-
- $Account = new AccountHistory();
- $Account->updateAccountPass($AccountData);
-
- $accountsOk[] = $account->acchistory_id;
- $counter++;
- } catch (SPException $e) {
- $errorCount++;
- $LogMessage->addDetails(__('Fallo al actualizar la clave del histórico', false), sprintf('%s (%d)', $account->acchistory_name, $account->acchistory_id));
- } catch (CryptoException $e) {
- $errorCount++;
- $LogMessage->addDetails(__('Fallo al actualizar la clave del histórico', false), sprintf('%s (%d)', $account->acchistory_name, $account->acchistory_id));
- }
- }
-
- $LogMessage->addDetails(__('Cuentas actualizadas', false), implode(',', $accountsOk));
- $LogMessage->addDetails(__('Errores', false), $errorCount);
- $this->Log->writeLog();
-
- Email::sendEmail($LogMessage);
-
- return true;
- }
-}
\ No newline at end of file
diff --git a/lib/SP/Account/AccountHistoryUtil.php b/lib/SP/Account/AccountHistoryUtil.php
deleted file mode 100644
index e8fffb7d..00000000
--- a/lib/SP/Account/AccountHistoryUtil.php
+++ /dev/null
@@ -1,161 +0,0 @@
-.
- */
-
-namespace SP\Account;
-
-use SP\Core\Context\SessionContext;
-use SP\DataModel\ItemSearchData;
-use SP\Storage\DbWrapper;
-use SP\Storage\QueryData;
-
-defined('APP_ROOT') || die();
-
-/**
- * Class AccountUtil con utilidades para la gestión de cuentas
- *
- * @package SP
- */
-class AccountHistoryUtil
-{
- /**
- * Devolver el nombre de la cuenta a partir del Id
- *
- * @param int $accountId El Id de la cuenta
- * @return string|bool
- */
- public static function getAccountNameById($accountId)
- {
- $query = /** @lang SQL */
- 'SELECT acchistory_name FROM accHistory WHERE acchistory_id = ? LIMIT 1';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($accountId);
-
- $queryRes = DbWrapper::getResults($Data);
-
- return is_object($queryRes) ? $queryRes : false;
- }
-
- /**
- * Devolver el nombre de la cuenta a partir del Id
- *
- * @param array $ids Id de la cuenta
- * @return array
- * @internal param int $accountId El Id de la cuenta
- */
- public static function getAccountNameByIdBatch(array $ids)
- {
- $query = /** @lang SQL */
- 'SELECT acchistory_name FROM accHistory WHERE acchistory_id IN (' . implode(',', array_fill(0, count($ids), '?')) . ')';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->setParams($ids);
-
- return DbWrapper::getResultsArray($Data);
- }
-
- /**
- * Obtener los datos de todas las cuentas y el cliente mediante una búsqueda
- *
- * @param ItemSearchData $SearchData
- * @return array|bool
- */
- public static function getAccountsMgmtSearch(ItemSearchData $SearchData)
- {
- $Data = new QueryData();
- $Data->setSelect('acchistory_id, acchistory_name, name, IFNULL(acchistory_dateEdit,acchistory_dateAdd) as acchistory_date, BIN(acchistory_isModify) as acchistory_isModify, BIN(acchistory_isDeleted) as acchistory_isDeleted');
- $Data->setFrom('accHistory LEFT JOIN customers ON acchistory_customerId = id');
- $Data->setOrder('acchistory_name, name, acchistory_id DESC');
-
- if ($SearchData->getSeachString() !== '') {
- $Data->setWhere('acchistory_name LIKE ? OR name LIKE ?');
-
- $search = '%' . $SearchData->getSeachString() . '%';
- $Data->addParam($search);
- $Data->addParam($search);
- }
-
- $Data->setLimit('?,?');
- $Data->addParam($SearchData->getLimitStart());
- $Data->addParam($SearchData->getLimitCount());
-
- DbWrapper::setFullRowCount();
-
- $queryRes = DbWrapper::getResultsArray($Data);
-
- $queryRes['count'] = $Data->getQueryNumRows();
-
- return $queryRes;
- }
-
- /**
- * Restaurar una cuenta desde el histórico.
- *
- * @param $id int El Id del registro en el histórico
- * @param $accountId
- * @param SessionContext $session
- * @return bool
- * @throws \SP\Core\Exceptions\SPException
- */
- public static function restoreFromHistory($id, $accountId, SessionContext $session)
- {
- // Guardamos una copia de la cuenta en el histórico
- AccountHistory::addHistory($accountId, false);
-
- $query = /** @lang SQL */
- 'UPDATE Account dst, '
- . '(SELECT * FROM accHistory WHERE acchistory_id = :id LIMIT 1) src SET '
- . 'dst.account_customerId = src.acchistory_customerId,'
- . 'dst.account_categoryId = src.acchistory_categoryId,'
- . 'dst.account_name = src.acchistory_name,'
- . 'dst.account_login = src.acchistory_login,'
- . 'dst.account_url = src.acchistory_url,'
- . 'dst.account_notes = src.acchistory_notes,'
- . 'dst.account_userGroupId = src.acchistory_userGroupId,'
- . 'dst.account_userEditId = :accountUserEditId,'
- . 'dst.account_dateEdit = NOW(),'
- . 'dst.account_otherUserEdit = src.acchistory_otherUserEdit + 0,'
- . 'dst.account_otherGroupEdit = src.acchistory_otherGroupEdit + 0,'
- . 'dst.account_pass = src.acchistory_pass,'
- . 'dst.account_key = src.acchistory_key,'
- . 'dst.account_passDate = src.acchistory_passDate,'
- . 'dst.account_passDateChange = src.acchistory_passDateChange, '
- . 'dst.account_parentId = src.acchistory_parentId, '
- . 'dst.account_isPrivate = src.accHistory_isPrivate, '
- . 'dst.account_isPrivateGroup = src.accHistory_isPrivateGroup '
- . 'WHERE dst.account_id = src.acchistory_accountId';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($id, 'id');
- $Data->addParam($session->getUserData()->getId(), 'accountUserEditId');
- $Data->setOnErrorMessage(__('Error al restaurar cuenta', false));
-
- DbWrapper::getQuery($Data);
-
- return true;
- }
-}
\ No newline at end of file
diff --git a/lib/SP/Account/AccountTags.php b/lib/SP/Account/AccountTags.php
deleted file mode 100644
index 1bbba5e1..00000000
--- a/lib/SP/Account/AccountTags.php
+++ /dev/null
@@ -1,156 +0,0 @@
-.
- */
-
-namespace SP\Account;
-
-use SP\Core\Exceptions\SPException;
-use SP\DataModel\AccountData;
-use SP\DataModel\AccountExtData;
-use SP\Storage\DbWrapper;
-use SP\Storage\QueryData;
-
-defined('APP_ROOT') || die();
-
-/**
- * Class AccountTags
- *
- * @package SP\Account
- */
-class AccountTags
-{
- /**
- * Devolver las etiquetas de una cuenta
- *
- * @param AccountData $accountData
- * @return array
- */
- public static function getTags(AccountData $accountData)
- {
- $query = /** @lang SQL */
- 'SELECT T.id, T.name
- FROM AccountToTag AT
- INNER JOIN Tag T ON AT.tagId = T.id
- WHERE AT.accountId = ?
- ORDER BY T.name';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->setUseKeyPair(true);
- $Data->addParam($accountData->getId());
-
- return DbWrapper::getResultsArray($Data);
- }
-
- /**
- * Devolver las etiquetas de una cuenta por id
- *
- * @param int $id Id de la cuenta
- * @return array
- */
- public static function getTagsForId($id)
- {
- $query = /** @lang SQL */
- 'SELECT T.id, T.name
- FROM AccountToTag AT
- INNER JOIN Tag T ON AccountToTag.tagId = T.id
- WHERE AT.accountId = ?
- ORDER BY T.name';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->setUseKeyPair(true);
- $Data->addParam($id);
-
- return DbWrapper::getResultsArray($Data);
- }
-
- /**
- * Actualizar las etiquetas de una cuenta
- *
- * @param AccountExtData $accountData
- * @param bool $isUpdate
- * @return bool
- * @throws SPException
- */
- public function addTags(AccountExtData $accountData, $isUpdate = false)
- {
- if ($isUpdate === true) {
- $this->deleteTags($accountData);
- }
-
- $numTags = count($accountData->getTags());
-
- if ($numTags === 0) {
- return true;
- }
-
- $query = /** @lang SQL */
- 'INSERT INTO AccountToTag (accountId, tagId) VALUES ' . implode(',', array_fill(0, $numTags, '(?,?)'));
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->setOnErrorMessage(__('Error al añadir las etiquetas de la cuenta', false));
-
- foreach ($accountData->getTags() as $tag) {
- $Data->addParam($accountData->getId());
- $Data->addParam($tag);
- }
-
- return DbWrapper::getQuery($Data);
- }
-
- /**
- * Eliminar las etiquetas de una cuenta
- *
- * @param AccountExtData $accountData
- * @return bool
- * @throws \SP\Core\Exceptions\QueryException
- * @throws \SP\Core\Exceptions\ConstraintException
- */
- public function deleteTags(AccountExtData $accountData)
- {
- $numTags = count($accountData->getTags());
-
- $Data = new QueryData();
-
- if ($numTags > 0) {
- $params = implode(',', array_fill(0, $numTags, '?'));
-
- $query = /** @lang SQL */
- 'DELETE FROM AccountToTag WHERE accountId = ? AND tagId NOT IN (' . $params . ')';
-
- $Data->setParams(array_merge((array)$accountData->getId(), $accountData->getTags()));
- } else {
- $query = /** @lang SQL */
- 'DELETE FROM AccountToTag WHERE accountId = ?';
-
- $Data->addParam($accountData->getId());
- }
-
- $Data->setQuery($query);
- $Data->setOnErrorMessage(__('Error al eliminar las etiquetas de la cuenta', false));
-
- return DbWrapper::getQuery($Data);
- }
-}
\ No newline at end of file
diff --git a/lib/SP/Account/AccountUtil.php b/lib/SP/Account/AccountUtil.php
index 3fb2bc49..2ffee210 100644
--- a/lib/SP/Account/AccountUtil.php
+++ b/lib/SP/Account/AccountUtil.php
@@ -24,12 +24,8 @@
namespace SP\Account;
-use SP\Core\Context\SessionContext;
-use SP\Core\Exceptions\SPException;
-use SP\DataModel\ItemSearchData;
+use SP\Core\Context\ContextInterface;
use SP\Mvc\Model\QueryCondition;
-use SP\Storage\DbWrapper;
-use SP\Storage\QueryData;
defined('APP_ROOT') || die();
@@ -40,262 +36,23 @@ defined('APP_ROOT') || die();
*/
class AccountUtil
{
- /**
- * Obtener los datos de usuario y modificador de una cuenta.
- *
- * @param int $id con el Id de la cuenta
- * @return false|object con el id de usuario y modificador.
- */
- public static function getAccountRequestData($id)
- {
- $query = /** @lang SQL */
- 'SELECT A.userId,
- A.userEditId,
- A.name,
- C.name AS clientName
- FROM Account A
- LEFT JOIN Client C ON A.clientId = C.id
- WHERE A.id = ? LIMIT 1';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($id);
-
- $queryRes = DbWrapper::getResults($Data);
-
- if ($queryRes === false) {
- return false;
- }
-
- return $queryRes;
- }
-
- /**
- * Obtiene el listado con el nombre de los usuaios de una cuenta.
- *
- * @param int $accountId con el Id de la cuenta
- * @return false|array con los nombres de los usuarios ordenados
- */
- public static function getAccountUsersName($accountId)
- {
- $query = /** @lang SQL */
- 'SELECT U.name
- FROM AccountToUser AU
- INNER JOIN User U ON AU.userId = U.id
- WHERE AU.accountId = ?';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($accountId);
-
- $queryRes = DbWrapper::getResultsArray($Data);
-
- if ($queryRes === false) {
- return false;
- }
-
- foreach ($queryRes as $users) {
- $usersName[] = $users->user_name;
- }
-
- sort($usersName, SORT_STRING);
-
- return $usersName;
- }
-
- /**
- * Obtener los datos de todas las cuentas
- *
- * @return array
- * @throws \SP\Core\Exceptions\SPException
- */
- public static function getAccountsData()
- {
- $query = /** @lang SQL */
- 'SELECT account_id,
- account_name,
- account_categoryId,
- account_customerId,
- account_login,
- account_url,
- account_pass,
- account_key,
- account_notes
- FROM Account';
-
- $Data = new QueryData();
- $Data->setQuery($query);
-
- try {
- return DbWrapper::getResultsArray($Data);
- } catch (SPException $e) {
- throw new SPException(__('No se pudieron obtener los datos de las cuentas', false), SPException::CRITICAL);
- }
- }
-
- /**
- * Devolver el nombre de la cuenta a partir del Id
- *
- * @param int $accountId El Id de la cuenta
- * @return string|bool
- */
- public static function getAccountNameById($accountId)
- {
- $query = /** @lang SQL */
- 'SELECT account_name FROM Account WHERE account_id = ? LIMIT 1';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($accountId);
-
- $queryRes = DbWrapper::getResults($Data);
-
- return is_object($queryRes) ? $queryRes->account_name : false;
- }
-
- /**
- * Devolver el nombre de la cuenta a partir del Id
- *
- * @param array $ids Id de la cuenta
- * @return array
- * @internal param int $accountId El Id de la cuenta
- */
- public static function getAccountNameByIdBatch(array $ids)
- {
- $query = /** @lang SQL */
- 'SELECT account_name FROM Account WHERE account_id IN (' . implode(',', array_fill(0, count($ids), '?')) . ')';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->setParams($ids);
-
- return DbWrapper::getResultsArray($Data);
- }
-
- /**
- * Obtener los datos de todas las cuentas y el cliente mediante una búsqueda
- *
- * @param ItemSearchData $SearchData
- * @return array|bool
- */
- public static function getAccountsMgmtSearch(ItemSearchData $SearchData)
- {
- $Data = new QueryData();
- $Data->setSelect('account_id, account_name, name');
- $Data->setFrom('accounts LEFT JOIN customers ON account_customerId = id');
- $Data->setOrder('account_name');
-
- if ($SearchData->getSeachString() !== '') {
- $Data->setWhere('account_name LIKE ? OR name LIKE ?');
-
- $search = '%' . $SearchData->getSeachString() . '%';
- $Data->addParam($search);
- $Data->addParam($search);
- }
-
- $Data->setLimit('?,?');
- $Data->addParam($SearchData->getLimitStart());
- $Data->addParam($SearchData->getLimitCount());
-
- DbWrapper::setFullRowCount();
-
- $queryRes = DbWrapper::getResultsArray($Data);
-
- $queryRes['count'] = $Data->getQueryNumRows();
-
- return $queryRes;
- }
-
- /**
- * Devolver las cuentas enlazadas
- *
- * @param $accountId
- * @param SessionContext $session
- * @return array
- */
- public static function getLinkedAccounts($accountId, SessionContext $session)
- {
- if ($accountId === 0) {
- return [];
- }
-
- $queryFilter = self::getAccountFilterUser($session)
- ->addFilter('A.parentId = ?', [$accountId]);
-
- $query = /** @lang SQL */
- 'SELECT A.id, A.name, C.name AS clientName
- FROM Account A
- INNER JOIN Client C ON Account.clientId = C.id
- WHERE ' . $queryFilter->getFilters() . ' ORDER BY name';
-
- $queryData = new QueryData();
- $queryData->setParams($queryFilter->getParams());
- $queryData->setQuery($query);
-
- return DbWrapper::getResultsArray($queryData);
- }
-
/**
* Devuelve el filtro para la consulta SQL de cuentas que un usuario puede acceder
*
- * @param SessionContext $session
- * @param bool $useGlobalSearch
+ * @param ContextInterface $context
+ * @param bool $useGlobalSearch
* @return QueryCondition
*/
- public static function getAccountFilterUser(SessionContext $session, $useGlobalSearch = false)
+ public static function getAccountHistoryFilterUser(ContextInterface $context, $useGlobalSearch = false)
{
$queryFilter = new QueryCondition();
- $configData = $session->getConfig();
- $userData = $session->getUserData();
+ $configData = $context->getConfig();
+ $userData = $context->getUserData();
if (!$userData->getIsAdminApp()
&& !$userData->getIsAdminAcc()
- && !($useGlobalSearch && $session->getUserProfile()->isAccGlobalSearch() && $configData->isGlobalSearch())
- ) {
- // Filtro usuario y grupo
- $filter =
- /** @lang SQL */
- '(A.userId = ?
- OR A.userGroupId = ?
- OR A.id IN (SELECT accountId AS accountId FROM AccountToUser WHERE accountId = A.id AND userId = ? UNION ALL SELECT accountId FROM AccountToUserGroup WHERE accountId = A.id AND userGroupId = ?)
- OR A.userGroupId IN (SELECT userGroupId FROM UserToUserGroup WHERE userGroupId = A.userGroupId AND userId = ?))';
-
- $params = [$userData->getId(), $userData->getUserGroupId(), $userData->getId(), $userData->getUserGroupId(), $userData->getId()];
-
- if ($configData->isAccountFullGroupAccess()) {
- // Filtro de grupos secundarios en grupos que incluyen al usuario
- $filter .= /** @lang SQL */
- PHP_EOL . 'OR A.id = (SELECT accountId FROM AccountToUserGroup aug INNER JOIN UserToUserGroup uug ON uug.userGroupId = aug.userGroupId WHERE aug.accountId = A.id AND uug.userId = ? LIMIT 1)';
- $params[] = $userData->getId();
- }
-
- $queryFilter->addFilter($filter, $params);
- }
-
- $queryFilter->addFilter(/** @lang SQL */
- '(A.isPrivate IS NULL OR A.isPrivate = 0 OR (A.isPrivate = 1 AND A.userId = ?)) AND (A.isPrivateGroup IS NULL OR A.isPrivateGroup = 0 OR (A.isPrivateGroup = 1 AND A.userGroupId = ?))', [$userData->getId(), $userData->getUserGroupId()]);
-
- return $queryFilter;
- }
-
- /**
- * Devuelve el filtro para la consulta SQL de cuentas que un usuario puede acceder
- *
- * @param SessionContext $session
- * @param bool $useGlobalSearch
- * @return QueryCondition
- */
- public static function getAccountHistoryFilterUser(SessionContext $session, $useGlobalSearch = false)
- {
- $queryFilter = new QueryCondition();
-
- $configData = $session->getConfig();
- $userData = $session->getUserData();
-
- if (!$userData->getIsAdminApp()
- && !$userData->getIsAdminAcc()
- && !($useGlobalSearch && $session->getUserProfile()->isAccGlobalSearch() && $configData->isGlobalSearch())
+ && !($useGlobalSearch && $context->getUserProfile()->isAccGlobalSearch() && $configData->isGlobalSearch())
) {
// Filtro usuario y grupo
$filter =
@@ -324,47 +81,46 @@ class AccountUtil
}
/**
- * Obtiene los datos de las cuentas visibles por el usuario
+ * Devuelve el filtro para la consulta SQL de cuentas que un usuario puede acceder
*
- * @param SessionContext $session
- * @param int $accountId Cuenta actual
- * @return array
+ * @param ContextInterface $context
+ * @param bool $useGlobalSearch
+ * @return QueryCondition
*/
- public static function getAccountsForUser(SessionContext $session, $accountId = null)
+ public static function getAccountFilterUser(ContextInterface $context, $useGlobalSearch = false)
{
- $queryFilter = self::getAccountFilterUser($session);
+ $queryFilter = new QueryCondition();
- if (null !== $accountId) {
- $queryFilter->addFilter('A.id <> ? AND (A.parentId = 0 OR A.parentId IS NULL)', [$accountId]);
+ $configData = $context->getConfig();
+ $userData = $context->getUserData();
+
+ if (!$userData->getIsAdminApp()
+ && !$userData->getIsAdminAcc()
+ && !($useGlobalSearch && $context->getUserProfile()->isAccGlobalSearch() && $configData->isGlobalSearch())
+ ) {
+ // Filtro usuario y grupo
+ $filter =
+ /** @lang SQL */
+ '(A.userId = ?
+ OR A.userGroupId = ?
+ OR A.id IN (SELECT accountId AS accountId FROM AccountToUser WHERE accountId = A.id AND userId = ? UNION ALL SELECT accountId FROM AccountToUserGroup WHERE accountId = A.id AND userGroupId = ?)
+ OR A.userGroupId IN (SELECT userGroupId FROM UserToUserGroup WHERE userGroupId = A.userGroupId AND userId = ?))';
+
+ $params = [$userData->getId(), $userData->getUserGroupId(), $userData->getId(), $userData->getUserGroupId(), $userData->getId()];
+
+ if ($configData->isAccountFullGroupAccess()) {
+ // Filtro de grupos secundarios en grupos que incluyen al usuario
+ $filter .= /** @lang SQL */
+ PHP_EOL . 'OR A.id = (SELECT accountId FROM AccountToUserGroup aug INNER JOIN UserToUserGroup uug ON uug.userGroupId = aug.userGroupId WHERE aug.accountId = A.id AND uug.userId = ? LIMIT 1)';
+ $params[] = $userData->getId();
+ }
+
+ $queryFilter->addFilter($filter, $params);
}
- $query = /** @lang SQL */
- 'SELECT A.id, A.name, C.name AS clientName
- FROM Account A
- LEFT JOIN Client C ON A.clientId = C.id
- WHERE ' . $queryFilter->getFilters() . ' ORDER BY name';
+ $queryFilter->addFilter(/** @lang SQL */
+ '(A.isPrivate IS NULL OR A.isPrivate = 0 OR (A.isPrivate = 1 AND A.userId = ?)) AND (A.isPrivateGroup IS NULL OR A.isPrivateGroup = 0 OR (A.isPrivateGroup = 1 AND A.userGroupId = ?))', [$userData->getId(), $userData->getUserGroupId()]);
-
- $queryData = new QueryData();
- $queryData->setQuery($query);
- $queryData->setParams($queryFilter->getParams());
-
- return DbWrapper::getResultsArray($queryData);
- }
-
- /**
- * Devolver el número de cuentas a procesar
- *
- * @return int
- */
- public static function getTotalNumAccounts()
- {
- $query = /** @lang SQL */
- 'SELECT SUM(n) AS num FROM (SELECT COUNT(*) AS n FROM Account UNION SELECT COUNT(*) AS n FROM AccountHistory) a';
-
- $Data = new QueryData();
- $Data->setQuery($query);
-
- return (int)DbWrapper::getResults($Data)->num;
+ return $queryFilter;
}
}
\ No newline at end of file
diff --git a/lib/SP/Account/UserAccounts.php b/lib/SP/Account/UserAccounts.php
deleted file mode 100644
index 1f7260cf..00000000
--- a/lib/SP/Account/UserAccounts.php
+++ /dev/null
@@ -1,188 +0,0 @@
-.
- */
-
-namespace SP\Account;
-
-use SP\DataModel\UserData;
-use SP\Storage\DbWrapper;
-use SP\Storage\QueryData;
-
-defined('APP_ROOT') || die();
-
-/**
- * Class UserAccounts para la gestión de usuarios en las cuentas
- *
- * @package SP
- */
-class UserAccounts
-{
- /**
- * Actualizar la asociación de grupos con cuentas.
- *
- * @param int $accountId con el Id de la cuenta
- * @param array $usersId con los usuarios de la cuenta
- * @return bool
- * @throws \SP\Core\Exceptions\QueryException
- * @throws \SP\Core\Exceptions\ConstraintException
- */
- public static function updateUsersForAccount($accountId, $usersId)
- {
- if (self::deleteUsersForAccount($accountId, $usersId)) {
- return self::addUsersForAccount($accountId, $usersId);
- }
-
- return false;
- }
-
- /**
- * Eliminar la asociación de grupos con cuentas.
- *
- * @param int $accountId con el Id de la cuenta
- * @param array $usersId opcional con los grupos de la cuenta
- * @return bool
- * @throws \SP\Core\Exceptions\QueryException
- * @throws \SP\Core\Exceptions\ConstraintException
- */
- public static function deleteUsersForAccount($accountId, array $usersId = [])
- {
- $Data = new QueryData();
-
- $numUsers = count($usersId);
-
- // Excluimos los usuarios actuales
- if ($numUsers > 0) {
- $params = implode(',', array_fill(0, $numUsers, '?'));
-
- $query = /** @lang SQL */
- 'DELETE FROM AccountToUser WHERE accountId = ? AND userId NOT IN (' . $params . ')';
-
- $Data->setParams(array_merge((array)$accountId, $usersId));
- } else {
- $query = /** @lang SQL */
- 'DELETE FROM AccountToUser WHERE accountId = ?';
-
- $Data->addParam($accountId);
- }
-
- $Data->setQuery($query);
- $Data->setOnErrorMessage(__('Error al eliminar usuarios asociados a la cuenta', false));
-
- return DbWrapper::getQuery($Data);
- }
-
- /**
- * Crear asociación de usuarios con cuentas.
- *
- * @param int $accountId con el Id de la cuenta
- * @param array $usersId con los usuarios de la cuenta
- * @return bool
- * @throws \SP\Core\Exceptions\QueryException
- * @throws \SP\Core\Exceptions\ConstraintException
- */
- public static function addUsersForAccount($accountId, array $usersId = [])
- {
- $numUsers = count($usersId);
-
- if ($numUsers === 0) {
- return true;
- }
-
- // Obtenemos los usuarios actuales
- $usersExcluded = self::getUsersForAccount($accountId);
-
- // Excluimos los usuarios actuales
- if (count($usersExcluded) > 0) {
- $usersId = array_diff($usersId, $usersExcluded);
- }
-
- $params = array_fill(0, count($usersId), '(?,?)');
-
- if (count($params) === 0) {
- return true;
- }
-
- $query = /** @lang SQL */
- 'INSERT INTO AccountToUser (accountId, userId) VALUES ' . implode(',', $params);
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->setOnErrorMessage(__('Error al actualizar los usuarios de la cuenta', false));
-
- foreach ($usersId as $userId) {
- $Data->addParam($accountId);
- $Data->addParam($userId);
- }
-
- return DbWrapper::getQuery($Data);
- }
-
- /**
- * Obtiene el listado de usuarios de una cuenta.
- *
- * @param int $accountId con el id de la cuenta
- * @return array con los id de usuarios de la cuenta
- */
- public static function getUsersForAccount($accountId)
- {
- $query = /** @lang SQL */
- 'SELECT userId FROM AccountToUser WHERE accountId = ?';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($accountId);
-
- $users = [];
-
- foreach (DbWrapper::getResultsArray($Data) as $user) {
- $users[] = (int)$user->accuser_userId;
- }
-
- return $users;
- }
-
- /**
- * Obtiene el listado con el nombre de los usuarios de una cuenta.
- *
- * @param int $accountId con el id de la cuenta
- * @return UserData[]
- */
- public static function getUsersInfoForAccount($accountId)
- {
- $query = /** @lang SQL */
- 'SELECT U.id,
- U.login,
- U.name
- FROM AccountToUser AU
- INNER JOIN User U ON AU.userId = U.id
- WHERE AU.accountId = ?
- ORDER BY U.login';
-
- $Data = new QueryData();
- $Data->setMapClassName(UserData::class);
- $Data->setQuery($query);
- $Data->addParam($accountId);
-
- return DbWrapper::getResultsArray($Data);
- }
-}
\ No newline at end of file
diff --git a/lib/SP/Bootstrap.php b/lib/SP/Bootstrap.php
index f8651e2c..0c67fe70 100644
--- a/lib/SP/Bootstrap.php
+++ b/lib/SP/Bootstrap.php
@@ -39,9 +39,11 @@ use SP\Core\Exceptions\SPException;
use SP\Core\Language;
use SP\Core\UI\Theme;
use SP\Core\Upgrade\Upgrade;
-use SP\Log\Log;
use SP\Modules\Api\Init as InitApi;
use SP\Modules\Web\Init as InitWeb;
+use SP\Services\Api\ApiService;
+use SP\Services\Upgrade\UpgradeConfigService;
+use SP\Services\Upgrade\UpgradeUtil;
use SP\Util\Checks;
use SP\Util\HttpUtil;
use SP\Util\Util;
@@ -157,17 +159,50 @@ class Bootstrap
// Manejar URLs de módulo web
$this->router->respond(['GET', 'POST'],
- '@/(index\.php)?',
+ '@/api\.php',
+ function ($request, $response, $service) use ($oops) {
+ try {
+ $requesData = ApiService::getRequestData();
+
+ list($controller, $action) = explode('/', $requesData->method);
+
+ $controllerClass = 'SP\\Modules\\' . ucfirst(APP_MODULE) . '\\Controllers\\' . ucfirst($controller) . 'Controller';
+ $method = $action . 'Action';
+
+ if (!method_exists($controllerClass, $method)) {
+ debugLog($controllerClass . '::' . $method);
+
+ throw new RuntimeException($oops);
+ }
+
+ $this->initializeCommon();
+
+ self::$container->get(InitApi::class)->initialize($controller);
+
+ debugLog('Routing call: ' . $controllerClass . '::' . $method);
+
+ return call_user_func([new $controllerClass(self::$container, $method, $requesData), $method]);
+ } catch (\Exception $e) {
+ processException($e);
+
+ return $e->getMessage();
+ }
+ }
+ );
+
+ // Manejar URLs de módulo web
+ $this->router->respond(['GET', 'POST'],
+ '@/index\.php',
function ($request, $response, $service) use ($oops) {
try {
/** @var \Klein\Request $request */
$route = filter_var($request->param('r', 'index/index'), FILTER_SANITIZE_STRING);
- if (!preg_match_all('#(?P
web|api)?(?P[a-zA-Z]+)(?:/(?P[a-zA-Z]+))?(?P(/[a-zA-Z\d]+)+)?#', $route, $matches)) {
+ if (!preg_match_all('#(?P[a-zA-Z]+)(?:/(?P[a-zA-Z]+))?(?P(/[a-zA-Z\d]+)+)?#', $route, $matches)) {
throw new RuntimeException($oops);
}
- $app = $matches['app'][0] ?: 'web';
+// $app = $matches['app'][0] ?: 'web';
$controller = $matches['controller'][0];
$method = !empty($matches['action'][0]) ? $matches['action'][0] . 'Action' : 'indexAction';
$params = [];
@@ -192,15 +227,11 @@ class Bootstrap
$this->initializeCommon();
- switch ($app) {
+ switch (APP_MODULE) {
case 'web':
self::$container->get(InitWeb::class)
->initialize($controller);
break;
- case 'api':
- self::$container->get(InitApi::class)
- ->initialize($controller);
- break;
}
debugLog('Routing call: ' . $controllerClass . '::' . $method . '::' . print_r($params, true));
@@ -370,27 +401,25 @@ class Bootstrap
*/
private function checkConfigVersion()
{
+ $upgradeConfigService = self::$container->get(UpgradeConfigService::class);
+
$appVersion = Util::getVersionStringNormalized();
if (file_exists(OLD_CONFIG_FILE)
- && $this->upgrade->upgradeOldConfigFile($appVersion)
+ && $upgradeConfigService->upgradeOldConfigFile($appVersion)
) {
-// $this->logConfigUpgrade($appVersion);
-
self::$UPDATED = true;
return;
}
- $configVersion = Upgrade::fixVersionNumber($this->configData->getConfigVersion());
+ $configVersion = UpgradeUtil::fixVersionNumber($this->configData->getConfigVersion());
if ($this->configData->isInstalled()
&& Util::checkVersion($configVersion, Util::getVersionArrayNormalized())
- && $this->upgrade->needConfigUpgrade($configVersion)
- && $this->upgrade->upgradeConfig($configVersion)
+ && UpgradeConfigService::needConfigUpgrade($configVersion)
+ && $upgradeConfigService->upgradeConfig($configVersion)
) {
-// $this->logConfigUpgrade($appVersion);
-
self::$UPDATED = true;
}
}
@@ -405,7 +434,7 @@ class Bootstrap
/**
* @param Container $container
- * @param string $module
+ * @param string $module
* @throws InitializationException
* @throws \DI\DependencyException
* @throws \DI\NotFoundException
@@ -426,20 +455,33 @@ class Bootstrap
}
}
+ /**
+ * Comprobar si es necesario actualizar componentes
+ *
+ * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
+ */
+// private function checkUpgrade()
+// {
+// if (self::$SUBURI === '/index.php') {
+// $this->upgrade->checkDbVersion();
+// $this->upgrade->checkAppVersion();
+// }
+// }
+
/**
* Registrar la actualización de la configuración
*
* @deprecated
* @param $version
*/
- private function logConfigUpgrade($version)
- {
- $Log = new Log();
- $LogMessage = $Log->getLogMessage();
- $LogMessage->setAction(__('Actualización', false));
- $LogMessage->addDescription(__('Actualización de versión realizada.', false));
- $LogMessage->addDetails(__('Versión', false), $version);
- $LogMessage->addDetails(__('Tipo', false), 'config');
- $Log->writeLog();
- }
+// private function logConfigUpgrade($version)
+// {
+// $Log = new Log();
+// $LogMessage = $Log->getLogMessage();
+// $LogMessage->setAction(__('Actualización', false));
+// $LogMessage->addDescription(__('Actualización de versión realizada.', false));
+// $LogMessage->addDetails(__('Versión', false), $version);
+// $LogMessage->addDetails(__('Tipo', false), 'config');
+// $Log->writeLog();
+// }
}
\ No newline at end of file
diff --git a/lib/SP/Config/Config.php b/lib/SP/Config/Config.php
index d1805441..a1f86f9b 100644
--- a/lib/SP/Config/Config.php
+++ b/lib/SP/Config/Config.php
@@ -26,7 +26,7 @@ namespace SP\Config;
use DI\Container;
use ReflectionObject;
-use SP\Core\Context\SessionContext;
+use SP\Core\Context\ContextInterface;
use SP\Core\Exceptions\ConfigException;
use SP\Services\Config\ConfigBackupService;
use SP\Storage\XmlFileStorageInterface;
@@ -52,9 +52,9 @@ class Config
*/
private $fileStorage;
/**
- * @var SessionContext
+ * @var ContextInterface
*/
- private $session;
+ private $context;
/**
* @var Container
*/
@@ -64,15 +64,13 @@ class Config
* Config constructor.
*
* @param XmlFileStorageInterface $fileStorage
- * @param SessionContext $session
- * @param Container $dic
+ * @param ContextInterface $session
+ * @param Container $dic
* @throws ConfigException
- * @throws \Psr\Container\ContainerExceptionInterface
- * @throws \Psr\Container\NotFoundExceptionInterface
*/
- public function __construct(XmlFileStorageInterface $fileStorage, SessionContext $session, Container $dic)
+ public function __construct(XmlFileStorageInterface $fileStorage, ContextInterface $session, Container $dic)
{
- $this->session = $session;
+ $this->context = $session;
$this->fileStorage = $fileStorage;
if (!self::$configLoaded) {
@@ -121,19 +119,19 @@ class Config
/**
* Cargar la configuración desde el archivo
*
- * @param SessionContext $sessionContext
- * @param bool $reload
+ * @param ContextInterface $context
+ * @param bool $reload
* @return ConfigData
*/
- public function loadConfig(SessionContext $sessionContext, $reload = false)
+ public function loadConfig(ContextInterface $context, $reload = false)
{
- $configData = $sessionContext->getConfig();
+ $configData = $context->getConfig();
if ($reload === true
|| $configData === null
- || time() >= ($sessionContext->getConfigTime() + $configData->getSessionTimeout() / 2)
+ || time() >= ($context->getConfigTime() + $configData->getSessionTimeout() / 2)
) {
- return $this->saveConfigInSession($sessionContext);
+ return $this->saveConfigInSession($context);
}
return $configData;
@@ -141,13 +139,14 @@ class Config
/**
* Guardar la configuración en la sesión
- * @param SessionContext $sessionContext
+ *
+ * @param ContextInterface $context
* @return ConfigData
*/
- private function saveConfigInSession(SessionContext $sessionContext)
+ private function saveConfigInSession(ContextInterface $context)
{
- $sessionContext->setConfig($this->configData);
- $sessionContext->setConfigTime(time());
+ $context->setConfig($this->configData);
+ $context->setConfigTime(time());
return $this->configData;
}
@@ -169,7 +168,7 @@ class Config
}
$configData->setConfigDate(time());
- $configData->setConfigSaver($this->session->getUserData()->getLogin());
+ $configData->setConfigSaver($this->context->getUserData()->getLogin());
$configData->setConfigHash();
$this->fileStorage->setItems($configData);
diff --git a/lib/SP/Config/ConfigDB.php b/lib/SP/Config/ConfigDB.php
deleted file mode 100644
index 25494ec8..00000000
--- a/lib/SP/Config/ConfigDB.php
+++ /dev/null
@@ -1,234 +0,0 @@
-.
- */
-
-namespace SP\Config;
-
-use SP\Core\Exceptions\SPException;
-use SP\Log\Email;
-use SP\Log\Log;
-use SP\Storage\DbWrapper;
-use SP\Storage\QueryData;
-
-defined('APP_ROOT') || die();
-
-/**
- * Class ConfigDB para la gestión de la configuración en la BD
- *
- * @package SP
- */
-class ConfigDB implements ConfigInterface
-{
- /**
- * @var array
- */
- protected static $cache;
- /**
- * @var bool
- */
- protected static $init;
-
- /**
- * Obtener un array con la configuración almacenada en la BBDD.
- *
- * @return bool
- */
- public static function readConfig()
- {
- $query = 'SELECT parameter, value FROM Config';
-
- $Data = new QueryData();
- $Data->setUseKeyPair(true);
- $Data->setQuery($query);
-
- $queryRes = DbWrapper::getResults($Data);
-
- if ($queryRes === false) {
- return false;
- }
-
- self::$cache = $queryRes;
-
- return $queryRes;
- }
-
- /**
- * Guardar la configuración en la BBDD.
- *
- * @param bool $isInsert realizar un 'insert'?
- * @return bool
- * @throws \PHPMailer\PHPMailer\Exception
- */
- public static function writeConfig($isInsert = false)
- {
- foreach (self::$cache as $param => $value) {
- $Data = new QueryData();
-
- if ($isInsert) {
- $query = 'INSERT INTO Config VALUES (:param,:value) ON DUPLICATE KEY UPDATE value = :valuedup';
-
- $Data->addParam($value, 'valuedup');
- } else {
- $query = 'UPDATE Config SET value = :value WHERE parameter = :param';
- }
-
- $Data->setQuery($query);
- $Data->addParam($param, 'param');
- $Data->addParam($value, 'value');
-
- try {
- DbWrapper::getQuery($Data);
- } catch (SPException $e) {
- return false;
- }
- }
-
- $Log = new Log();
- $LogMessage = $Log->getLogMessage();
- $LogMessage->setAction(__('Configuración', false));
- $LogMessage->addDescription(__('Modificar configuración', false));
- $Log->writeLog();
-
- Email::sendEmail($LogMessage);
-
- return true;
- }
-
- /**
- * Guardar un parámetro de configuración en la BBDD.
- *
- * @param string $param con el parámetro a guardar
- * @param string $value con el valor a guardar
- * @param bool $email enviar email?
- * @param bool $hideValue Ocultar el valor del registro en el log
- * @return bool
- * @throws \PHPMailer\PHPMailer\Exception
- */
- public static function setValue($param, $value, $email = true, $hideValue = false)
- {
- $query = /** @lang SQL */
- 'INSERT INTO Config '
- . 'SET parameter = :param,'
- . 'value = :value '
- . 'ON DUPLICATE KEY UPDATE value = :valuedup';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($param, 'param');
- $Data->addParam($value, 'value');
- $Data->addParam($value, 'valuedup');
-
- try {
- DbWrapper::getQuery($Data);
- } catch (SPException $e) {
- return false;
- }
-
- $Log = new Log();
- $LogMessage = $Log->getLogMessage();
- $LogMessage->setAction(__('Configuración', false));
- $LogMessage->addDescription(__('Modificar configuración', false));
- $LogMessage->addDetails(__('Parámetro', false), $param);
-
- if ($hideValue === false) {
- $LogMessage->addDetails(__('Valor', false), $value);
- }
-
- $Log->writeLog();
-
- if ($email === true) {
- Email::sendEmail($LogMessage);
- }
-
- return true;
- }
-
- /**
- * Actualizar el array de parámetros de configuración
- *
- * @param $param string La clave a actualizar
- * @param $value mixed El valor a actualizar
- */
- public static function setCacheConfigValue($param, $value)
- {
- self::$cache[$param] = $value;
- }
-
- /**
- * Obtener un parámetro del el array de parámetros de configuración
- *
- * @param null $param La clave a obtener
- * @return mixed
- */
- public static function getCacheConfigValue($param = null)
- {
- if (null !== $param && isset(self::$cache[$param])) {
- return self::$cache[$param];
- }
-
- return self::$cache;
- }
-
- /**
- * Obtiene un valor desde la configuración en la BBDD.
- *
- * @param string $param con el parámetro de configuración
- * @param string $default El valor por defecto
- * @return false|string con el valor
- */
- public static function getValue($param, $default = null)
- {
- $query = 'SELECT value FROM Config WHERE parameter = :param LIMIT 1';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($param, 'param');
-
- $queryRes = DbWrapper::getResults($Data);
-
- if ($queryRes === false) {
- return false;
- }
-
- return is_object($queryRes) ? $queryRes->value : $default;
- }
-
- /**
- * Elimina un parámetro de la configuración.
- *
- * @param string $param clave
- * @return bool
- * @throws \SP\Core\Exceptions\QueryException
- * @throws \SP\Core\Exceptions\ConstraintException
- */
- public static function deleteParam($param)
- {
- $query = 'DELETE FROM Config WHERE parameter = :param LIMIT 1';
-
- $Data = new QueryData();
- $Data->setQuery($query);
- $Data->addParam($param, 'param');
-
- return DbWrapper::getQuery($Data);
- }
-}
\ No newline at end of file
diff --git a/lib/SP/Config/ConfigData.php b/lib/SP/Config/ConfigData.php
index 78666435..84db62ed 100644
--- a/lib/SP/Config/ConfigData.php
+++ b/lib/SP/Config/ConfigData.php
@@ -213,6 +213,10 @@ class ConfigData implements JsonSerializable
* @var bool
*/
private $logEnabled = true;
+ /**
+ * @var array
+ */
+ private $logEvents = [];
/**
* @var bool
*/
@@ -253,6 +257,10 @@ class ConfigData implements JsonSerializable
* @var array
*/
private $mailRecipients = [];
+ /**
+ * @var array
+ */
+ private $mailEvents = [];
/**
* @var bool
*/
@@ -370,6 +378,22 @@ class ConfigData implements JsonSerializable
*/
private $ssoDefaultProfile;
+ /**
+ * @return array
+ */
+ public function getLogEvents()
+ {
+ return (array)$this->logEvents;
+ }
+
+ /**
+ * @param array $logEvents
+ */
+ public function setLogEvents(array $logEvents)
+ {
+ $this->logEvents = $logEvents;
+ }
+
/**
* @return boolean
*/
@@ -1949,4 +1973,20 @@ class ConfigData implements JsonSerializable
{
$this->mailRecipients = $mailRecipients;
}
+
+ /**
+ * @return array
+ */
+ public function getMailEvents()
+ {
+ return (array)$this->mailEvents;
+ }
+
+ /**
+ * @param array $mailEvents
+ */
+ public function setMailEvents(array $mailEvents)
+ {
+ $this->mailEvents = $mailEvents;
+ }
}
\ No newline at end of file
diff --git a/lib/SP/Config/ConfigUtil.php b/lib/SP/Config/ConfigUtil.php
index 85e3b282..e64a7ecc 100644
--- a/lib/SP/Config/ConfigUtil.php
+++ b/lib/SP/Config/ConfigUtil.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.
@@ -37,7 +37,7 @@ class ConfigUtil
/**
* Adaptador para convertir una cadena de extensiones a un array
*
- * @param $filesAllowedExts
+ * @param string $filesAllowedExts
* @return array
*/
public static function filesExtsAdapter($filesAllowedExts)
@@ -54,7 +54,7 @@ class ConfigUtil
/**
* Adaptador para convertir una cadena de direcciones de email a un array
*
- * @param $mailAddresses
+ * @param string $mailAddresses
* @return array
*/
public static function mailAddressesAdapter($mailAddresses)
@@ -64,6 +64,19 @@ class ConfigUtil
}, explode(',', $mailAddresses));
}
+ /**
+ * Adaptador para convertir una cadena de eventos a un array
+ *
+ * @param array $events
+ * @return array
+ */
+ public static function eventsAdapter(array $events)
+ {
+ return array_map(function ($value) {
+ return preg_match('/^(?:[a-z]+(?:\.)?)+$/i', $value) ? $value : null;
+ }, $events);
+ }
+
/**
* Comprobar el archivo de configuración.
* Esta función comprueba que el archivo de configuración exista y los permisos sean correctos.
diff --git a/lib/SP/Controller/ConfigActionController.php b/lib/SP/Controller/ConfigActionController.php
index 537fb94a..4fc7f43b 100644
--- a/lib/SP/Controller/ConfigActionController.php
+++ b/lib/SP/Controller/ConfigActionController.php
@@ -37,8 +37,6 @@ use SP\Core\Init;
use SP\Core\Messages\LogMessage;
use SP\Core\Messages\NoticeMessage;
use SP\Core\SessionFactory;
-use SP\Core\TaskFactory;
-use SP\Core\Traits\InjectableTrait;
use SP\Core\XmlExport;
use SP\Http\Request;
use SP\Log\Email;
@@ -48,6 +46,7 @@ use SP\Mgmt\Users\UserPass;
use SP\Mgmt\Users\UserUtil;
use SP\Services\Import\ImportParams;
use SP\Services\Import\ImportService;
+use SP\Services\Task\TaskFactory;
use SP\Storage\DbWrapper;
use SP\Util\Json;
use SP\Util\Util;
@@ -60,7 +59,7 @@ use SP\Util\Util;
class ConfigActionController implements ItemControllerInterface
{
use RequestControllerTrait;
- use InjectableTrait;
+ use SP\Core\Dic\InjectableTrait;
/**
* ConfigActionController constructor.
diff --git a/lib/SP/Controller/ConfigController.php b/lib/SP/Controller/ConfigController.php
index 57df0f3e..d16ecac3 100644
--- a/lib/SP/Controller/ConfigController.php
+++ b/lib/SP/Controller/ConfigController.php
@@ -36,12 +36,12 @@ use SP\Core\Language;
use SP\Core\Plugin\PluginUtil;
use SP\Core\SessionFactory;
use SP\Core\SessionUtil;
-use SP\Core\Task;
use SP\Mgmt\Groups\Group;
use SP\Mgmt\Profiles\Profile;
use SP\Mgmt\Users\User;
use SP\Modules\Web\Controllers\ControllerBase;
use SP\Mvc\View\Template;
+use SP\Services\Task\Task;
use SP\Storage\DBUtil;
use SP\Util\Checks;
use SP\Util\Util;
diff --git a/lib/SP/Controller/ItemActionController.php b/lib/SP/Controller/ItemActionController.php
index 161354f0..24ecc6d1 100644
--- a/lib/SP/Controller/ItemActionController.php
+++ b/lib/SP/Controller/ItemActionController.php
@@ -33,7 +33,6 @@ use SP\Auth\AuthUtil;
use SP\Core\Acl\ActionsInterface;
use SP\Core\Messages\LogMessage;
use SP\Core\SessionFactory;
-use SP\Core\Traits\InjectableTrait;
use SP\DataModel\CustomFieldData;
use SP\DataModel\NotificationData;
use SP\DataModel\PluginData;
@@ -78,7 +77,7 @@ use SP\Util\Util;
*/
class ItemActionController implements ItemControllerInterface
{
- use InjectableTrait;
+ use SP\Core\Dic\InjectableTrait;
use RequestControllerTrait;
/**
@@ -134,9 +133,9 @@ class ItemActionController implements ItemControllerInterface
case ActionsInterface::CATEGORY_DELETE:
$this->categoryAction();
break;
- case ActionsInterface::APITOKEN_CREATE:
- case ActionsInterface::APITOKEN_EDIT:
- case ActionsInterface::APITOKEN_DELETE:
+ case ActionsInterface::AUTHTOKEN_CREATE:
+ case ActionsInterface::AUTHTOKEN_EDIT:
+ case ActionsInterface::AUTHTOKEN_DELETE:
$this->tokenAction();
break;
case ActionsInterface::CUSTOMFIELD_CREATE:
@@ -613,7 +612,7 @@ class ItemActionController implements ItemControllerInterface
$refresh = Request::analyze('refreshtoken', false, false, true);
switch ($this->actionId) {
- case ActionsInterface::APITOKEN_CREATE:
+ case ActionsInterface::AUTHTOKEN_CREATE:
$Form->validate($this->actionId);
if ($refresh === true) {
@@ -626,7 +625,7 @@ class ItemActionController implements ItemControllerInterface
$this->LogMessage->addDescription(__('Autorización creada', false));
$this->LogMessage->addDetails(__('Usuario', false), UserUtil::getUserLoginById($Form->getItemData()->getAuthtokenUserId()));
break;
- case ActionsInterface::APITOKEN_EDIT:
+ case ActionsInterface::AUTHTOKEN_EDIT:
$Form->validate($this->actionId);
if ($refresh === true) {
@@ -639,7 +638,7 @@ class ItemActionController implements ItemControllerInterface
$this->LogMessage->addDescription(__('Autorización actualizada', false));
$this->LogMessage->addDetails(__('Usuario', false), UserUtil::getUserLoginById($Form->getItemData()->getAuthtokenUserId()));
break;
- case ActionsInterface::APITOKEN_DELETE:
+ case ActionsInterface::AUTHTOKEN_DELETE:
if (is_array($this->itemId)) {
ApiToken::getItem()->deleteBatch($this->itemId);
diff --git a/lib/SP/Controller/ItemListController.php b/lib/SP/Controller/ItemListController.php
index c8f8d2a1..806d80cb 100644
--- a/lib/SP/Controller/ItemListController.php
+++ b/lib/SP/Controller/ItemListController.php
@@ -368,7 +368,7 @@ class ItemListController extends GridTabControllerBase implements ActionsInterfa
*/
public function getAPITokensList()
{
- $this->setAction(self::APITOKEN);
+ $this->setAction(self::AUTHTOKEN);
if (!$this->checkAccess()) {
return;
diff --git a/lib/SP/Controller/ItemSearchController.php b/lib/SP/Controller/ItemSearchController.php
index ca0c6099..5367054e 100644
--- a/lib/SP/Controller/ItemSearchController.php
+++ b/lib/SP/Controller/ItemSearchController.php
@@ -110,7 +110,7 @@ class ItemSearchController extends GridItemsSearchController implements ActionsI
case ActionsInterface::PROFILE_SEARCH:
$this->getProfiles();
break;
- case ActionsInterface::APITOKEN_SEARCH:
+ case ActionsInterface::AUTHTOKEN_SEARCH:
$this->getTokens();
break;
case ActionsInterface::PUBLICLINK_SEARCH:
@@ -250,7 +250,7 @@ class ItemSearchController extends GridItemsSearchController implements ActionsI
*/
public function getTokens()
{
- $this->setAction(self::APITOKEN_SEARCH);
+ $this->setAction(self::AUTHTOKEN_SEARCH);
if (!$this->checkAccess()) {
return;
diff --git a/lib/SP/Controller/ItemShowController.php b/lib/SP/Controller/ItemShowController.php
index e6d6a316..5db90d2d 100644
--- a/lib/SP/Controller/ItemShowController.php
+++ b/lib/SP/Controller/ItemShowController.php
@@ -191,16 +191,16 @@ class ItemShowController extends ControllerBase implements ActionsInterface, Ite
$this->view->assign('header', __('Nueva Categoría'));
$this->getCategory();
break;
- case self::APITOKEN_VIEW:
+ case self::AUTHTOKEN_VIEW:
$this->view->assign('header', __('Ver Autorización'));
$this->view->assign('isView', true);
$this->getToken();
break;
- case self::APITOKEN_CREATE:
+ case self::AUTHTOKEN_CREATE:
$this->view->assign('header', __('Nueva Autorización'));
$this->getToken();
break;
- case self::APITOKEN_EDIT:
+ case self::AUTHTOKEN_EDIT:
$this->view->assign('header', __('Editar Autorización'));
$this->getToken();
break;
@@ -393,7 +393,7 @@ class ItemShowController extends ControllerBase implements ActionsInterface, Ite
*/
protected function getToken()
{
- $this->module = self::APITOKEN;
+ $this->module = self::AUTHTOKEN;
$this->view->addTemplate('tokens');
$ApiTokenData = $this->itemId ? ApiToken::getItem()->getById($this->itemId) : new AuthTokenData();
@@ -401,7 +401,7 @@ class ItemShowController extends ControllerBase implements ActionsInterface, Ite
$this->view->assign('users', User::getItem()->getItemsForSelect());
$this->view->assign('actions', ApiTokensUtil::getTokenActions());
$this->view->assign('authTokenData', $ApiTokenData);
- $this->view->assign('isDisabled', ($this->view->actionId === self::APITOKEN_VIEW) ? 'disabled' : '');
+ $this->view->assign('isDisabled', ($this->view->actionId === self::AUTHTOKEN_VIEW) ? 'disabled' : '');
$this->view->assign('isReadonly', $this->view->isDisabled ? 'readonly' : '');
if ($this->view->isView === true) {
diff --git a/lib/SP/Controller/LoginController.php b/lib/SP/Controller/LoginController.php
index be72e79f..18b81045 100644
--- a/lib/SP/Controller/LoginController.php
+++ b/lib/SP/Controller/LoginController.php
@@ -44,7 +44,6 @@ use SP\Core\Language;
use SP\Core\Messages\LogMessage;
use SP\Core\SessionFactory;
use SP\Core\SessionUtil;
-use SP\Core\Traits\InjectableTrait;
use SP\Core\UI\Theme;
use SP\DataModel\TrackData;
use SP\DataModel\UserLoginData;
@@ -73,7 +72,7 @@ use SP\Util\Util;
*/
class LoginController
{
- use InjectableTrait;
+ use SP\Core\Dic\InjectableTrait;
/**
* Estados
diff --git a/lib/SP/Controller/MainActionController.php b/lib/SP/Controller/MainActionController.php
index 91c31af9..24f30683 100644
--- a/lib/SP/Controller/MainActionController.php
+++ b/lib/SP/Controller/MainActionController.php
@@ -28,12 +28,11 @@ use SP\Config\Config;
use SP\Config\ConfigData;
use SP\Core\Exceptions\ValidationException;
use SP\Core\SessionFactory;
-use SP\Core\TaskFactory;
-use SP\Core\Traits\InjectableTrait;
use SP\Core\Upgrade\Upgrade;
use SP\Http\JsonResponse;
use SP\Http\Request;
use SP\Log\Log;
+use SP\Services\Task\TaskFactory;
use SP\Util\Json;
use SP\Util\Util;
@@ -44,7 +43,7 @@ use SP\Util\Util;
*/
class MainActionController
{
- use InjectableTrait;
+ use SP\Core\Dic\InjectableTrait;
/**
* @var ConfigData
diff --git a/lib/SP/Controller/RequestControllerTrait.php b/lib/SP/Controller/RequestControllerTrait.php
index b937804c..e91f5d80 100644
--- a/lib/SP/Controller/RequestControllerTrait.php
+++ b/lib/SP/Controller/RequestControllerTrait.php
@@ -29,7 +29,6 @@ use SP\Config\ConfigData;
use SP\Core\Context\SessionContext;
use SP\Core\Messages\LogMessage;
use SP\Core\SessionUtil;
-use SP\Core\Traits\InjectableTrait;
use SP\Http\JsonResponse;
use SP\Http\Request;
use SP\Util\Checks;
@@ -43,7 +42,7 @@ use SP\Util\Util;
*/
trait RequestControllerTrait
{
- use InjectableTrait;
+ use SP\Core\Dic\InjectableTrait;
/**
* @var int
diff --git a/lib/SP/Controller/TaskController.php b/lib/SP/Controller/TaskController.php
index c38328cc..316c668b 100644
--- a/lib/SP/Controller/TaskController.php
+++ b/lib/SP/Controller/TaskController.php
@@ -25,8 +25,8 @@
namespace SP\Controller;
use SP\Core\Messages\TaskMessage;
-use SP\Core\Task;
use SP\Http\Request;
+use SP\Services\Task\Task;
use SP\Util\Util;
/**
diff --git a/lib/SP/Core/Acl/Acl.php b/lib/SP/Core/Acl/Acl.php
index f59a9de9..5e921524 100644
--- a/lib/SP/Core/Acl/Acl.php
+++ b/lib/SP/Core/Acl/Acl.php
@@ -25,6 +25,7 @@
namespace SP\Core\Acl;
+use SP\Core\Context\ContextInterface;
use SP\Core\Context\SessionContext;
use SP\Core\Events\Event;
use SP\Core\Events\EventDispatcher;
@@ -44,7 +45,7 @@ class Acl implements ActionsInterface
/**
* @var SessionContext
*/
- private $session;
+ private $context;
/**
* @var EventDispatcher
*/
@@ -53,13 +54,13 @@ class Acl implements ActionsInterface
/**
* Acl constructor.
*
- * @param SessionContext $session
- * @param EventDispatcher $eventDispatcher
- * @param Actions|null $action
+ * @param ContextInterface $context
+ * @param EventDispatcher $eventDispatcher
+ * @param Actions|null $action
*/
- public function __construct(SessionContext $session, EventDispatcher $eventDispatcher, Actions $action = null)
+ public function __construct(ContextInterface $context, EventDispatcher $eventDispatcher, Actions $action = null)
{
- $this->session = $session;
+ $this->context = $context;
$this->eventDispatcher = $eventDispatcher;
self::$action = $action;
@@ -114,11 +115,11 @@ class Acl implements ActionsInterface
*/
public function checkUserAccess($action, $userId = 0)
{
- if (!($userProfile = $this->session->getUserProfile())) {
+ if (!($userProfile = $this->context->getUserProfile())) {
return false;
}
- $userData = $this->session->getUserData();
+ $userData = $this->context->getUserData();
if ($userData->getIsAdminApp()) {
return true;
@@ -199,8 +200,8 @@ class Acl implements ActionsInterface
case self::PROFILE:
case self::PROFILE_SEARCH:
return $userProfile->isMgmProfiles();
- case self::APITOKEN:
- case self::APITOKEN_SEARCH:
+ case self::AUTHTOKEN:
+ case self::AUTHTOKEN_SEARCH:
return $userProfile->isMgmApiTokens();
case self::EVENTLOG:
case self::EVENTLOG_SEARCH:
diff --git a/lib/SP/Core/Acl/ActionsInterface.php b/lib/SP/Core/Acl/ActionsInterface.php
index aac8f9a3..4b78af6c 100644
--- a/lib/SP/Core/Acl/ActionsInterface.php
+++ b/lib/SP/Core/Acl/ActionsInterface.php
@@ -73,12 +73,12 @@ interface ActionsInterface
const CLIENT_EDIT = 622;
const CLIENT_DELETE = 623;
const CLIENT_SEARCH = 625;
- const APITOKEN = 63;
- const APITOKEN_CREATE = 630;
- const APITOKEN_VIEW = 631;
- const APITOKEN_EDIT = 632;
- const APITOKEN_DELETE = 633;
- const APITOKEN_SEARCH = 635;
+ const AUTHTOKEN = 63;
+ const AUTHTOKEN_CREATE = 630;
+ const AUTHTOKEN_VIEW = 631;
+ const AUTHTOKEN_EDIT = 632;
+ const AUTHTOKEN_DELETE = 633;
+ const AUTHTOKEN_SEARCH = 635;
const CUSTOMFIELD = 64;
const CUSTOMFIELD_CREATE = 640;
const CUSTOMFIELD_VIEW = 641;
diff --git a/lib/SP/Core/Backup.php b/lib/SP/Core/Backup.php
deleted file mode 100644
index 11ad57a1..00000000
--- a/lib/SP/Core/Backup.php
+++ /dev/null
@@ -1,322 +0,0 @@
-.
- */
-
-namespace SP\Core;
-
-use SP\Config\Config;
-use SP\Config\ConfigData;
-use SP\Core\Exceptions\SPException;
-use SP\Core\Traits\InjectableTrait;
-use SP\Log\Email;
-use SP\Log\Log;
-use SP\Storage\DBUtil;
-use SP\Storage\DbWrapper;
-use SP\Storage\QueryData;
-use SP\Util\Checks;
-use SP\Util\Util;
-
-defined('APP_ROOT') || die();
-
-/**
- * Esta clase es la encargada de realizar la copia y restauración de sysPass.
- */
-class Backup
-{
- use InjectableTrait;
-
- /**
- * @var ConfigData
- */
- protected $ConfigData;
- /**
- * @var Config
- */
- protected $Config;
-
- /**
- * Backup constructor.
- */
- public function __construct()
- {
- $this->injectDependencies();
- }
-
- /**
- * Realizar backup de la BBDD y aplicación.
- *
- * @return bool
- * @throws \phpmailer\phpmailerException
- * @throws \SP\Core\Exceptions\SPException
- */
- public function doBackup()
- {
- $Log = new Log();
- $LogMessage = $Log->getLogMessage();
- $LogMessage->setAction(__('Realizar Backup', false));
-
- $siteName = Util::getAppInfo('appname');
-
- // Generar hash unico para evitar descargas no permitidas
- $backupUniqueHash = sha1(uniqid('sysPassBackup', true));
- $this->ConfigData->setBackupHash($backupUniqueHash);
- $this->Config->saveConfig();
-
- $bakFileApp = BACKUP_PATH . DIRECTORY_SEPARATOR . $siteName . '-' . $backupUniqueHash . '.tar';
- $bakFileDB = BACKUP_PATH . DIRECTORY_SEPARATOR . $siteName . '_db-' . $backupUniqueHash . '.sql';
-
- try {
- $this->checkBackupDir();
- $this->deleteOldBackups();
- $this->backupTables('*', $bakFileDB);
- $this->backupApp($bakFileApp);
- } catch (\Exception $e) {
- $LogMessage->addDescription(__('Error al realizar el backup', false));
- $LogMessage->addDetails($e->getCode(), $e->getMessage());
- $Log->setLogLevel(Log::ERROR);
- $Log->writeLog();
-
- Email::sendEmail($LogMessage);
- return false;
- }
-
- $LogMessage->addDescription(__('Copia de la aplicación y base de datos realizada correctamente', false));
- $Log->writeLog();
-
- Email::sendEmail($LogMessage);
-
- return true;
- }
-
- /**
- * Comprobar y crear el directorio de backups.
- *
- * @throws SPException
- * @return bool
- */
- private function checkBackupDir()
- {
- if (@mkdir(BACKUP_PATH, 0750) === false && is_dir(BACKUP_PATH) === false) {
- throw new SPException(
- sprintf(__('No es posible crear el directorio de backups ("%s")'), BACKUP_PATH), SPException::ERROR);
- }
-
- if (!is_writable(BACKUP_PATH)) {
- throw new SPException(
- __('Compruebe los permisos del directorio de backups', false), SPException::ERROR);
- }
-
- return true;
- }
-
- /**
- * Eliminar las copias de seguridad anteriores
- */
- private function deleteOldBackups()
- {
- array_map('unlink', glob(BACKUP_PATH . DIRECTORY_SEPARATOR . '*.tar.gz'));
- array_map('unlink', glob(BACKUP_PATH . DIRECTORY_SEPARATOR . '*.sql'));
- }
-
- /**
- * Backup de las tablas de la BBDD.
- * Utilizar '*' para toda la BBDD o 'table1 table2 table3...'
- *
- * @param string|array $tables
- * @param string $backupFile
- * @throws SPException
- * @return bool
- */
- private function backupTables($tables = '*', $backupFile)
- {
- $dbname = $this->ConfigData->getDbName();
-
- try {
- $handle = fopen($backupFile, 'w');
-
- $Data = new QueryData();
-
- if ($tables === '*') {
- $resTables = DBUtil::$tables;
- } else {
- $resTables = is_array($tables) ? $tables : explode(',', $tables);
- }
-
- $sqlOut = '--' . PHP_EOL;
- $sqlOut .= '-- sysPass DB dump generated on ' . time() . ' (START)' . PHP_EOL;
- $sqlOut .= '--' . PHP_EOL;
- $sqlOut .= '-- Please, do not alter this file, it could break your DB' . PHP_EOL;
- $sqlOut .= '--' . PHP_EOL . PHP_EOL;
- $sqlOut .= 'CREATE DATABASE IF NOT EXISTS `' . $dbname . '`;' . PHP_EOL . PHP_EOL;
- $sqlOut .= 'USE `' . $dbname . '`;' . PHP_EOL . PHP_EOL;
- fwrite($handle, $sqlOut);
-
- $sqlOutViews = '';
- // Recorrer las tablas y almacenar los datos
- foreach ($resTables as $table) {
- $tableName = is_object($table) ? $table->{'Tables_in_' . $dbname} : $table;
-
- $Data->setQuery('SHOW CREATE TABLE ' . $tableName);
-
- // Consulta para crear la tabla
- $txtCreate = DbWrapper::getResults($Data);
-
- if (isset($txtCreate->{'Create Table'})) {
- $sqlOut = '-- ' . PHP_EOL;
- $sqlOut .= '-- Table ' . strtoupper($tableName) . PHP_EOL;
- $sqlOut .= '-- ' . PHP_EOL;
- $sqlOut .= 'DROP TABLE IF EXISTS `' . $tableName . '`;' . PHP_EOL . PHP_EOL;
- $sqlOut .= $txtCreate->{'Create Table'} . ';' . PHP_EOL . PHP_EOL;
- fwrite($handle, $sqlOut);
- } elseif ($txtCreate->{'Create View'}) {
- $sqlOutViews .= '-- ' . PHP_EOL;
- $sqlOutViews .= '-- View ' . strtoupper($tableName) . PHP_EOL;
- $sqlOutViews .= '-- ' . PHP_EOL;
- $sqlOutViews .= 'DROP TABLE IF EXISTS `' . $tableName . '`;' . PHP_EOL . PHP_EOL;
- $sqlOutViews .= $txtCreate->{'Create View'} . ';' . PHP_EOL . PHP_EOL;
- }
-
- fwrite($handle, PHP_EOL . PHP_EOL);
- }
-
- // Guardar las vistas
- fwrite($handle, $sqlOutViews);
-
- // Guardar los datos
- foreach ($resTables as $tableName) {
- // No guardar las vistas!
- if (strrpos($tableName, '_v') !== false) {
- continue;
- }
-
- $Data->setQuery('SELECT * FROM `' . $tableName . '`');
-
- // Consulta para obtener los registros de la tabla
- $queryRes = DbWrapper::getResultsRaw($Data);
-
- $numColumns = $queryRes->columnCount();
-
- while ($row = $queryRes->fetch(\PDO::FETCH_NUM)) {
- fwrite($handle, 'INSERT INTO `' . $tableName . '` VALUES(');
-
- $field = 1;
- foreach ($row as $value) {
- if (is_numeric($value)) {
- fwrite($handle, $value);
- } else {
- fwrite($handle, DBUtil::escape($value));
- }
-
- if ($field < $numColumns) {
- fwrite($handle, ',');
- }
-
- $field++;
- }
-
- fwrite($handle, ');' . PHP_EOL);
- }
- }
-
- $sqlOut = '--' . PHP_EOL;
- $sqlOut .= '-- sysPass DB dump generated on ' . time() . ' (END)' . PHP_EOL;
- $sqlOut .= '--' . PHP_EOL;
- $sqlOut .= '-- Please, do not alter this file, it could break your DB' . PHP_EOL;
- $sqlOut .= '--' . PHP_EOL . PHP_EOL;
- fwrite($handle, $sqlOut);
-
- fclose($handle);
- } catch (\Exception $e) {
- throw new SPException($e->getMessage(), SPException::CRITICAL);
- }
-
- return true;
- }
-
- /**
- * Realizar un backup de la aplicación y comprimirlo.
- *
- * @param string $backupFile nombre del archivo de backup
- * @throws SPException
- * @return bool
- */
- private function backupApp($backupFile)
- {
- if (!class_exists(\PharData::class)) {
- if (Checks::checkIsWindows()) {
- throw new SPException(
- __('Esta operación sólo es posible en entornos Linux', false), SPException::ERROR);
- }
-
- if (!$this->backupAppLegacyLinux($backupFile)) {
- throw new SPException(
- __('Error al realizar backup en modo compatibilidad', false), SPException::ERROR);
- }
-
- return true;
- }
-
- $compressedFile = $backupFile . '.gz';
-
- try {
- if (file_exists($compressedFile)) {
- unlink($compressedFile);
- }
-
- $archive = new \PharData($backupFile);
- $archive->buildFromDirectory(Init::$SERVERROOT, '/^(?!backup).*$/');
- $archive->compress(\Phar::GZ);
-
- unlink($backupFile);
- } catch (\Exception $e) {
- throw new SPException($e->getMessage(), SPException::CRITICAL);
- }
-
- return file_exists($backupFile);
- }
-
- /**
- * Realizar un backup de la aplicación y comprimirlo usando aplicaciones del SO Linux.
- *
- * @param string $backupFile nombre del archivo de backup
- * @return int Con el código de salida del comando ejecutado
- */
- private function backupAppLegacyLinux($backupFile)
- {
- $compressedFile = $backupFile . '.gz';
-
- $command = 'tar czf ' . $compressedFile . ' ' . BASE_PATH . ' --exclude "' . BACKUP_PATH . '" 2>&1';
- exec($command, $resOut, $resBakApp);
-
- return $resBakApp;
- }
-
- /**
- * @param Config $config
- */
- public function inject(Config $config)
- {
- $this->Config = $config;
- $this->ConfigData = $config->getConfigData();
- }
-}
\ No newline at end of file
diff --git a/lib/SP/Core/Context/ContextBase.php b/lib/SP/Core/Context/ContextBase.php
index 64fe4133..c9e5cc4b 100644
--- a/lib/SP/Core/Context/ContextBase.php
+++ b/lib/SP/Core/Context/ContextBase.php
@@ -26,6 +26,7 @@ namespace SP\Core\Context;
/**
* Class ContextBase
+ *
* @package SP\Core\Session
*/
abstract class ContextBase implements ContextInterface
@@ -36,35 +37,57 @@ abstract class ContextBase implements ContextInterface
const APP_STATUS_LOGGEDOUT = 'loggedout';
/**
- * @var array
+ * @var ContextCollection
*/
- private $context = [];
+ private $context;
/**
* @param $context
+ * @throws ContextException
*/
final protected function setContextReference(&$context)
{
- $this->context =& $context;
+ if ($this->context !== null) {
+ throw new ContextException(__u('Contexto ya inicializado'));
+ }
+
+ if (isset($context['context'])
+ && ($context['context'] instanceof ContextCollection) === false
+ ) {
+ throw new ContextException(__u('Contexto inválido'));
+ } elseif (!isset($context['context'])) {
+ $context['context'] = $this->context = new ContextCollection();
+ return;
+ }
+
+ $this->context =& $context['context'];
}
/**
- * @param $context
+ * @param ContextCollection $contextCollection
+ * @throws ContextException
*/
- final protected function setContext($context)
+ final protected function setContext(ContextCollection $contextCollection)
{
- $this->context = $context;
+ if ($this->context !== null) {
+ throw new ContextException(__u('Contexto ya inicializado'));
+ }
+
+ $this->context = $contextCollection;
}
/**
* Devolver una variable de contexto
*
* @param string $key
- * @param mixed $default
+ * @param mixed $default
* @return mixed
+ * @throws ContextException
*/
protected function getContextKey($key, $default = null)
{
+ $this->checkContext();
+
if (isset($this->context[$key])) {
return is_numeric($default) ? (int)$this->context[$key] : $this->context[$key];
}
@@ -75,14 +98,27 @@ abstract class ContextBase implements ContextInterface
/**
* Establecer una variable de contexto
*
- * @param string $key El nombre de la variable
- * @param mixed $value El valor de la variable
+ * @param string $key El nombre de la variable
+ * @param mixed $value El valor de la variable
* @return mixed
+ * @throws ContextException
*/
protected function setContextKey($key, $value)
{
+ $this->checkContext();
+
$this->context[$key] = $value;
return $value;
}
+
+ /**
+ * @throws ContextException
+ */
+ private function checkContext()
+ {
+ if ($this->context === null) {
+ throw new ContextException(__u('Contexto no inicializado'));
+ }
+ }
}
\ No newline at end of file
diff --git a/lib/SP/Core/Context/ContextCollection.php b/lib/SP/Core/Context/ContextCollection.php
new file mode 100644
index 00000000..6749715b
--- /dev/null
+++ b/lib/SP/Core/Context/ContextCollection.php
@@ -0,0 +1,37 @@
+.
+ */
+
+namespace SP\Core\Context;
+
+use SP\Core\DataCollection;
+
+/**
+ * Class ContextCollection
+ *
+ * @package SP\Core\Context
+ */
+class ContextCollection extends DataCollection
+{
+
+}
\ No newline at end of file
diff --git a/lib/SP/Core/Context/ContextException.php b/lib/SP/Core/Context/ContextException.php
new file mode 100644
index 00000000..759fc913
--- /dev/null
+++ b/lib/SP/Core/Context/ContextException.php
@@ -0,0 +1,37 @@
+.
+ */
+
+namespace SP\Core\Context;
+
+use SP\Core\Exceptions\SPException;
+
+/**
+ * Class ContextException
+ *
+ * @package SP\Core\Context
+ */
+class ContextException extends SPException
+{
+
+}
\ No newline at end of file
diff --git a/lib/SP/Core/Context/ContextInterface.php b/lib/SP/Core/Context/ContextInterface.php
index c20b8fc9..edec1689 100644
--- a/lib/SP/Core/Context/ContextInterface.php
+++ b/lib/SP/Core/Context/ContextInterface.php
@@ -25,19 +25,19 @@
namespace SP\Core\Context;
use SP\Config\ConfigData;
-use SP\Core\Exceptions\InitializationException;
use SP\DataModel\ProfileData;
use SP\Services\User\UserLoginResponse;
/**
* Class ContextInterface
+ *
* @package SP\Core\Session
*/
interface ContextInterface
{
/**
* @return void
- * @throws InitializationException
+ * @throws ContextException
*/
public function initialize();
@@ -48,6 +48,20 @@ interface ContextInterface
*/
public function setConfig(ConfigData $config);
+ /**
+ * Establecer la hora de carga de la configuración
+ *
+ * @param int $time
+ */
+ public function setConfigTime($time);
+
+ /**
+ * Devolver la hora de carga de la configuración
+ *
+ * @return int
+ */
+ public function getConfigTime();
+
/**
* Establece los datos del usuario en la sesión.
*
diff --git a/lib/SP/Core/Context/SessionContext.php b/lib/SP/Core/Context/SessionContext.php
index 52915002..9c510227 100644
--- a/lib/SP/Core/Context/SessionContext.php
+++ b/lib/SP/Core/Context/SessionContext.php
@@ -26,7 +26,7 @@ namespace SP\Core\Context;
use SP\Account\AccountSearchFilter;
use SP\Config\ConfigData;
-use SP\Core\Exceptions\InitializationException;
+use SP\Core\Crypt\Vault;
use SP\DataModel\ProfileData;
use SP\Services\User\UserLoginResponse;
@@ -86,12 +86,18 @@ class SessionContext extends ContextBase
* Devolver una variable de sesión
*
* @param string $key
- * @param mixed $default
+ * @param mixed $default
* @return mixed
*/
protected function getContextKey($key, $default = null)
{
- return parent::getContextKey($key, $default);
+ try {
+ return parent::getContextKey($key, $default);
+ } catch (ContextException $e) {
+ processException($e);
+ }
+
+ return $default;
}
/**
@@ -107,19 +113,25 @@ class SessionContext extends ContextBase
/**
* Establecer una variable de sesión
*
- * @param string $key El nombre de la variable
- * @param mixed $value El valor de la variable
+ * @param string $key El nombre de la variable
+ * @param mixed $value El valor de la variable
* @return mixed
*/
protected function setContextKey($key, $value)
{
- if (self::$isLocked) {
- debugLog('Session locked; key=' . $key);
- } else {
- parent::setContextKey($key, $value);
+ try {
+ if (self::$isLocked) {
+ debugLog('Session locked; key=' . $key);
+ } else {
+ parent::setContextKey($key, $value);
+ }
+
+ return $value;
+ } catch (ContextException $e) {
+ processException($e);
}
- return $value;
+ return null;
}
/**
@@ -135,11 +147,11 @@ class SessionContext extends ContextBase
/**
* Establecer la hora de carga de la configuración
*
- * @param $time
+ * @param int $time
*/
public function setConfigTime($time)
{
- $this->setContextKey('configTime', $time);
+ $this->setContextKey('configTime', (int)$time);
}
/**
@@ -477,14 +489,51 @@ class SessionContext extends ContextBase
}
/**
- * @return void
- * @throws InitializationException
+ * Devuelve la clave maestra encriptada
+ *
+ * @return Vault
+ */
+ public function getVault()
+ {
+ return $this->getContextKey('vault');
+ }
+
+ /**
+ * Establecer la clave maestra encriptada
+ *
+ * @param Vault $vault
+ */
+ public function setVault(Vault $vault)
+ {
+ $this->setContextKey('vault', $vault);
+ }
+
+ /**
+ * Establece la cache de cuentas
+ *
+ * @param array $accountsCache
+ */
+ public function setAccountsCache(array $accountsCache)
+ {
+ $this->setContextKey('accountsCache', $accountsCache);
+ }
+
+ /**
+ * Devuelve la cache de cuentas
+ */
+ public function getAccountsCache()
+ {
+ $this->getContextKey('accountsCache');
+ }
+
+ /**
+ * @throws ContextException
*/
public function initialize()
{
// Si la sesión no puede ser iniciada, devolver un error 500
if (session_start() === false) {
- throw new InitializationException(__u('La sesión no puede ser inicializada'));
+ throw new ContextException(__u('La sesión no puede ser inicializada'));
}
$this->setContextReference($_SESSION);
diff --git a/lib/SP/Core/Context/ApiContext.php b/lib/SP/Core/Context/StatelessContext.php
similarity index 74%
rename from lib/SP/Core/Context/ApiContext.php
rename to lib/SP/Core/Context/StatelessContext.php
index f9b9aa5f..d36d1895 100644
--- a/lib/SP/Core/Context/ApiContext.php
+++ b/lib/SP/Core/Context/StatelessContext.php
@@ -30,18 +30,11 @@ use SP\Services\User\UserLoginResponse;
/**
* Class ApiContext
+ *
* @package SP\Core\Context
*/
-class ApiContext extends ContextBase
+class StatelessContext extends ContextBase
{
- /**
- * @return void
- */
- public function initialize()
- {
- $this->setContext([]);
- }
-
/**
* Establecer la configuración
*
@@ -52,6 +45,26 @@ class ApiContext extends ContextBase
$this->setContextKey('config', $config);
}
+ /**
+ * Establecer una variable de sesión
+ *
+ * @param string $key El nombre de la variable
+ * @param mixed $value El valor de la variable
+ * @return mixed
+ */
+ protected function setContextKey($key, $value)
+ {
+ try {
+ parent::setContextKey($key, $value);
+
+ return $value;
+ } catch (ContextException $e) {
+ processException($e);
+ }
+
+ return null;
+ }
+
/**
* Establece los datos del usuario en la sesión.
*
@@ -72,6 +85,24 @@ class ApiContext extends ContextBase
return $this->getContextKey('userProfile');
}
+ /**
+ * Devolver una variable de sesión
+ *
+ * @param string $key
+ * @param mixed $default
+ * @return mixed
+ */
+ protected function getContextKey($key, $default = null)
+ {
+ try {
+ return parent::getContextKey($key, $default);
+ } catch (ContextException $e) {
+ processException($e);
+ }
+
+ return $default;
+ }
+
/**
* Establece el objeto de perfil de usuario en la sesión.
*
@@ -186,4 +217,33 @@ class ApiContext extends ContextBase
{
return $this->setContextKey('status', null);
}
+
+ /**
+ * @return void
+ * @throws ContextException
+ */
+ public function initialize()
+ {
+ $this->setContext(new ContextCollection());
+ }
+
+ /**
+ * Establecer la hora de carga de la configuración
+ *
+ * @param int $time
+ */
+ public function setConfigTime($time)
+ {
+ $this->setContextKey('configTime', (int)$time);
+ }
+
+ /**
+ * Devolver la hora de carga de la configuración
+ *
+ * @return int
+ */
+ public function getConfigTime()
+ {
+ return $this->getContextKey('configTime');
+ }
}
\ No newline at end of file
diff --git a/lib/SP/Core/CryptPKI.php b/lib/SP/Core/Crypt/CryptPKI.php
similarity index 98%
rename from lib/SP/Core/CryptPKI.php
rename to lib/SP/Core/Crypt/CryptPKI.php
index df010b1a..fbaf8edd 100644
--- a/lib/SP/Core/CryptPKI.php
+++ b/lib/SP/Core/Crypt/CryptPKI.php
@@ -22,14 +22,15 @@
* along with sysPass. If not, see .
*/
-namespace SP\Core;
+namespace SP\Core\Crypt;
defined('APP_ROOT') || die();
use phpseclib\Crypt\RSA;
+use SP\Core\Dic;
+use SP\Core\Dic\InjectableTrait;
use SP\Core\Exceptions\FileNotFoundException;
use SP\Core\Exceptions\SPException;
-use SP\Core\Traits\InjectableTrait;
/**
* Class CryptPKI para el manejo de las funciones para PKI
diff --git a/lib/SP/Core/OldCrypt.php b/lib/SP/Core/Crypt/OldCrypt.php
similarity index 96%
rename from lib/SP/Core/OldCrypt.php
rename to lib/SP/Core/Crypt/OldCrypt.php
index 814f9856..df181304 100644
--- a/lib/SP/Core/OldCrypt.php
+++ b/lib/SP/Core/Crypt/OldCrypt.php
@@ -22,7 +22,7 @@
* along with sysPass. If not, see .
*/
-namespace SP\Core;
+namespace SP\Core\Crypt;
use SP\Bootstrap;
use SP\Config\ConfigData;
@@ -203,10 +203,8 @@ class OldCrypt
* @param string $masterPwd con la clave maestra
* @return bool
*/
- public static function mkEncrypt($data, $masterPwd = null)
+ public static function mkEncrypt($data, $masterPwd)
{
- $masterPwd = empty($masterPwd) ? SessionUtil::getSessionMPass() : $masterPwd;
-
self::$strInitialVector = self::getIV();
return self::encrypt($data, $masterPwd, self::$strInitialVector);
@@ -220,12 +218,10 @@ class OldCrypt
* @param string $password La clave maestra
* @return string con los datos desencriptados
*/
- public static function getDecrypt($cryptData, $cryptIV, $password = null)
+ public static function getDecrypt($cryptData, $cryptIV, $password)
{
if (empty($cryptData) || empty($cryptIV)) {
return false;
- } elseif (null === $password) {
- $password = SessionUtil::getSessionMPass();
}
$mcryptRes = self::getMcryptResource();
diff --git a/lib/SP/Core/Crypt/Session.php b/lib/SP/Core/Crypt/Session.php
index 9c5a31a3..0b6cb90a 100644
--- a/lib/SP/Core/Crypt/Session.php
+++ b/lib/SP/Core/Crypt/Session.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.
@@ -24,7 +24,7 @@
namespace SP\Core\Crypt;
-use SP\Core\SessionFactory as CoreSession;
+use SP\Core\Context\SessionContext;
/**
* Class Session
@@ -36,43 +36,52 @@ class Session
/**
* Devolver la clave maestra de la sesión
*
+ * @param SessionContext $sessionContext
* @return string
* @throws \Defuse\Crypto\Exception\CryptoException
- * @todo Use session from DI
*/
- public static function getSessionKey()
+ public static function getSessionKey(SessionContext $sessionContext)
{
- return CoreSession::getVault()->getData();
+ return $sessionContext->getVault()->getData(self::getKey($sessionContext));
+ }
+
+ /**
+ * @param SessionContext $sessionContext
+ * @return string
+ */
+ private static function getKey(SessionContext $sessionContext)
+ {
+ return session_id() . $sessionContext->getSidStartTime();
}
/**
* Guardar la clave maestra en la sesión
*
- * @param $data
+ * @param $data
+ * @param SessionContext $sessionContext
* @throws \Defuse\Crypto\Exception\CryptoException
- * @todo Use session from DI
*/
- public static function saveSessionKey($data)
+ public static function saveSessionKey($data, SessionContext $sessionContext)
{
- CoreSession::setVault((new Vault())->saveData($data));
+ $sessionContext->setVault((new Vault())->saveData($data, self::getKey($sessionContext)));
}
/**
* Regenerar la clave de sesión
*
- * @param \SP\Core\Context\SessionContext $session
+ * @param SessionContext $sessionContext
* @throws \Defuse\Crypto\Exception\CryptoException
*/
- public static function reKey(\SP\Core\Context\SessionContext $session)
+ public static function reKey(SessionContext $sessionContext)
{
debugLog(__METHOD__);
- $oldSeed = session_id() . $session->getSidStartTime();
+ $oldSeed = session_id() . $sessionContext->getSidStartTime();
session_regenerate_id(true);
- $newSeed = session_id() . $session->setSidStartTime(time());
+ $newSeed = session_id() . $sessionContext->setSidStartTime(time());
- CoreSession::setVault(CoreSession::getVault()->reKey($newSeed, $oldSeed));
+ $sessionContext->setVault($sessionContext->getVault()->reKey($newSeed, $oldSeed));
}
}
\ No newline at end of file
diff --git a/lib/SP/Core/Crypt/Vault.php b/lib/SP/Core/Crypt/Vault.php
index fe496a9b..8267f743 100644
--- a/lib/SP/Core/Crypt/Vault.php
+++ b/lib/SP/Core/Crypt/Vault.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.
@@ -24,8 +24,6 @@
namespace SP\Core\Crypt;
-use SP\Core\SessionFactory as CoreSession;
-
/**
* Class Vault
*
@@ -75,23 +73,11 @@ class Vault
* @return string
* @throws \Defuse\Crypto\Exception\CryptoException
*/
- public function getData($key = null)
+ public function getData($key)
{
- $key = $key ?: $this->getKey();
-
return Crypt::decrypt($this->data, Crypt::unlockSecuredKey($this->key, $key), $key);
}
- /**
- * Devolver la clave utilizada para generar la llave segura
- *
- * @return string
- */
- private function getKey()
- {
- return session_id() . CoreSession::getSidStartTime();
- }
-
/**
* Guardar la clave maestra en la sesión
*
@@ -100,13 +86,12 @@ class Vault
* @return $this
* @throws \Defuse\Crypto\Exception\CryptoException
*/
- public function saveData($data, $key = null)
+ public function saveData($data, $key)
{
if ($this->timeSet === 0) {
$this->timeSet = time();
}
- $key = $key ?: $this->getKey();
$this->key = Crypt::makeSecuredKey($key);
$this->data = Crypt::encrypt($data, $this->key, $key);
diff --git a/lib/SP/Core/CryptMasterPass.php b/lib/SP/Core/CryptMasterPass.php
deleted file mode 100644
index c6a391db..00000000
--- a/lib/SP/Core/CryptMasterPass.php
+++ /dev/null
@@ -1,139 +0,0 @@
-.
- */
-
-namespace SP\Core;
-
-use SP\Config\ConfigDB;
-use SP\Core\Crypt\Crypt;
-use SP\Core\Crypt\Hash;
-use SP\Core\Crypt\Session as CryptSession;
-use SP\Log\Log;
-use SP\Util\Util;
-
-defined('APP_ROOT') || die();
-
-/**
- * Class CryptMasterPass para la gestión de la clave maestra
- *
- * @package SP
- */
-class CryptMasterPass
-{
- /**
- * Número máximo de intentos
- */
- const MAX_ATTEMPTS = 50;
-
- /**
- * Crea una clave temporal para encriptar la clave maestra y guardarla.
- *
- * @param int $maxTime El tiempo máximo de validez de la clave
- * @return bool|string
- * @throws \Defuse\Crypto\Exception\CryptoException
- * @throws \Defuse\Crypto\Exception\BadFormatException
- * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
- */
- public static function setTempMasterPass($maxTime = 14400)
- {
- // Encriptar la clave maestra con hash aleatorio generado
- $randomKey = Util::generateRandomBytes(32);
- $securedKey = Crypt::makeSecuredKey($randomKey);
-
- ConfigDB::setCacheConfigValue('tempmaster_pass', Crypt::encrypt(CryptSession::getSessionKey(), $securedKey, $randomKey));
- ConfigDB::setCacheConfigValue('tempmaster_passkey', $securedKey);
- ConfigDB::setCacheConfigValue('tempmaster_passhash', Hash::hashKey($randomKey));
- ConfigDB::setCacheConfigValue('tempmaster_passtime', time());
- ConfigDB::setCacheConfigValue('tempmaster_maxtime', time() + $maxTime);
- ConfigDB::setCacheConfigValue('tempmaster_attempts', 0);
-
- if (!ConfigDB::writeConfig(true)) {
- return false;
- }
-
- // Guardar la clave temporal hasta que finalice la sesión
- SessionFactory::setTemporaryMasterPass($randomKey);
-
- return $randomKey;
- }
-
- /**
- * Comprueba si la clave temporal es válida
- *
- * @param string $pass clave a comprobar
- * @return bool
- * @throws \SP\Core\Exceptions\SPException
- */
- public static function checkTempMasterPass($pass)
- {
- $passTime = (int)ConfigDB::getValue('tempmaster_passtime');
- $passMaxTime = (int)ConfigDB::getValue('tempmaster_maxtime');
- $attempts = (int)ConfigDB::getValue('tempmaster_attempts');
-
- // Comprobar si el tiempo de validez o los intentos se han superado
- if ($passMaxTime === 0) {
- Log::writeNewLog(__FUNCTION__, __('Clave temporal caducada', false), Log::INFO);
-
- return false;
- }
-
- if ((!empty($passTime) && time() > $passMaxTime)
- || $attempts >= self::MAX_ATTEMPTS
- ) {
- ConfigDB::setCacheConfigValue('tempmaster_pass', '');
- ConfigDB::setCacheConfigValue('tempmaster_passkey', '');
- ConfigDB::setCacheConfigValue('tempmaster_passhash', '');
- ConfigDB::setCacheConfigValue('tempmaster_maxtime', 0);
- ConfigDB::setCacheConfigValue('tempmaster_attempts', 0);
- ConfigDB::writeConfig();
-
- Log::writeNewLog(__FUNCTION__, __('Clave temporal caducada', false), Log::INFO);
-
- return false;
- }
-
- $isValid = Hash::checkHashKey($pass, ConfigDB::getValue('tempmaster_passhash'));
-
- if (!$isValid) {
- ConfigDB::setValue('tempmaster_attempts', $attempts + 1, false);
- }
-
- return $isValid;
- }
-
- /**
- * Devuelve la clave maestra que ha sido encriptada con la clave temporal
- *
- * @param $randomKey string con la clave utilizada para encriptar
- * @return string con la clave maestra desencriptada
- * @throws \Defuse\Crypto\Exception\CryptoException
- * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
- * @throws \Defuse\Crypto\Exception\BadFormatException
- */
- public static function getTempMasterPass($randomKey)
- {
- $securedKey = Crypt::unlockSecuredKey(ConfigDB::getValue('tempmaster_passkey'), $randomKey);
-
- return Crypt::decrypt(ConfigDB::getValue('tempmaster_pass'), $securedKey, $randomKey);
- }
-}
\ No newline at end of file
diff --git a/lib/SP/Core/DataCollection.php b/lib/SP/Core/DataCollection.php
new file mode 100644
index 00000000..84d25095
--- /dev/null
+++ b/lib/SP/Core/DataCollection.php
@@ -0,0 +1,291 @@
+.
+ */
+
+namespace SP\Core;
+
+use ArrayAccess;
+use ArrayIterator;
+use Countable;
+use IteratorAggregate;
+use Traversable;
+
+/**
+ * Class DataCollection
+ *
+ * @package SP\Core\Context
+ */
+abstract class DataCollection implements IteratorAggregate, ArrayAccess, Countable
+{
+ /**
+ * Collection of data attributes
+ *
+ * @type array
+ */
+ protected $attributes = [];
+
+ /**
+ * Retrieve an external iterator
+ *
+ * @link http://php.net/manual/en/iteratoraggregate.getiterator.php
+ * @return Traversable An instance of an object implementing Iterator or
+ * Traversable
+ * @since 5.0.0
+ */
+ public function getIterator()
+ {
+ return new ArrayIterator($this->attributes);
+ }
+
+ /**
+ * Whether a offset exists
+ *
+ * @link http://php.net/manual/en/arrayaccess.offsetexists.php
+ * @param mixed $offset
+ * An offset to check for.
+ *
+ * @return boolean true on success or false on failure.
+ *
+ *
+ * The return value will be casted to boolean if non-boolean was returned.
+ * @since 5.0.0
+ */
+ public function offsetExists($offset)
+ {
+ return $this->exists($offset);
+ }
+
+ /**
+ * See if an attribute exists in the collection
+ *
+ * @param string $key The name of the parameter
+ * @return boolean
+ */
+ public function exists($key)
+ {
+ // Don't use "isset", since it returns false for null values
+ return array_key_exists($key, $this->attributes);
+ }
+
+ /**
+ * Offset to retrieve
+ *
+ * @link http://php.net/manual/en/arrayaccess.offsetget.php
+ * @param mixed $offset
+ * The offset to retrieve.
+ *
+ * @return mixed Can return all value types.
+ * @since 5.0.0
+ */
+ public function offsetGet($offset)
+ {
+ return $this->get($offset);
+ }
+
+ /**
+ * Return an attribute of the collection
+ *
+ * Return a default value if the key doesn't exist
+ *
+ * @param string $key The name of the parameter to return
+ * @param mixed $default_val The default value of the parameter if it contains no value
+ * @return mixed
+ */
+ public function get($key, $default_val = null)
+ {
+ if (isset($this->attributes[$key])) {
+ return $this->attributes[$key];
+ }
+
+ return $default_val;
+ }
+
+ /**
+ * Offset to set
+ *
+ * @link http://php.net/manual/en/arrayaccess.offsetset.php
+ * @param mixed $offset
+ * The offset to assign the value to.
+ *
+ * @param mixed $value
+ * The value to set.
+ *
+ * @return void
+ * @since 5.0.0
+ */
+ public function offsetSet($offset, $value)
+ {
+ $this->set($offset, $value);
+ }
+
+ /**
+ * Set an attribute of the collection
+ *
+ * @param string $key The name of the parameter to set
+ * @param mixed $value The value of the parameter to set
+ * @return DataCollection
+ */
+ public function set($key, $value)
+ {
+ $this->attributes[$key] = $value;
+
+ return $this;
+ }
+
+ /**
+ * Offset to unset
+ *
+ * @link http://php.net/manual/en/arrayaccess.offsetunset.php
+ * @param mixed $offset
+ * The offset to unset.
+ *
+ * @return void
+ * @since 5.0.0
+ */
+ public function offsetUnset($offset)
+ {
+ $this->remove($offset);
+ }
+
+ /**
+ * Remove an attribute from the collection
+ *
+ * @param string $key The name of the parameter
+ * @return void
+ */
+ public function remove($key)
+ {
+ unset($this->attributes[$key]);
+ }
+
+ /**
+ * Count elements of an object
+ *
+ * @link http://php.net/manual/en/countable.count.php
+ * @return int The custom count as an integer.
+ *
+ *
+ * The return value is cast to an integer.
+ * @since 5.1.0
+ */
+ public function count()
+ {
+ return count($this->attributes);
+ }
+
+ /**
+ * Clear the collection's contents
+ *
+ * Semantic alias of a no-argument `$this->replace` call
+ *
+ * @return DataCollection
+ */
+ public function clear()
+ {
+ return $this->replace();
+ }
+
+ /**
+ * Replace the collection's attributes
+ *
+ * @param array $attributes The attributes to replace the collection's with
+ * @return DataCollection
+ */
+ public function replace(array $attributes = array())
+ {
+ $this->attributes = $attributes;
+
+ return $this;
+ }
+
+ /**
+ * Check if the collection is empty
+ *
+ * @return boolean
+ */
+ public function isEmpty()
+ {
+ return empty($this->attributes);
+ }
+
+ /**
+ * Magic "__get" method
+ *
+ * Allows the ability to arbitrarily request an attribute from
+ * this instance while treating it as an instance property
+ *
+ * @see get()
+ * @param string $key The name of the parameter to return
+ * @return mixed
+ */
+ public function __get($key)
+ {
+ return $this->get($key);
+ }
+
+ /**
+ * Magic "__set" method
+ *
+ * Allows the ability to arbitrarily set an attribute from
+ * this instance while treating it as an instance property
+ *
+ * @see set()
+ * @param string $key The name of the parameter to set
+ * @param mixed $value The value of the parameter to set
+ * @return void
+ */
+ public function __set($key, $value)
+ {
+ $this->set($key, $value);
+ }
+
+ /**
+ * Magic "__isset" method
+ *
+ * Allows the ability to arbitrarily check the existence of an attribute
+ * from this instance while treating it as an instance property
+ *
+ * @see exists()
+ * @param string $key The name of the parameter
+ * @return boolean
+ */
+ public function __isset($key)
+ {
+ return $this->exists($key);
+ }
+
+ /**
+ * Magic "__unset" method
+ *
+ * Allows the ability to arbitrarily remove an attribute from
+ * this instance while treating it as an instance property
+ *
+ * @see remove()
+ * @param string $key The name of the parameter
+ * @return void
+ */
+ public function __unset($key)
+ {
+ $this->remove($key);
+ }
+}
\ No newline at end of file
diff --git a/lib/SP/Core/Traits/InjectableTrait.php b/lib/SP/Core/Dic/InjectableTrait.php
similarity index 95%
rename from lib/SP/Core/Traits/InjectableTrait.php
rename to lib/SP/Core/Dic/InjectableTrait.php
index 49fc2797..89bc3009 100644
--- a/lib/SP/Core/Traits/InjectableTrait.php
+++ b/lib/SP/Core/Dic/InjectableTrait.php
@@ -22,10 +22,9 @@
* along with sysPass. If not, see .
*/
-namespace SP\Core\Traits;
+namespace SP\Core\Dic;
use SP\Bootstrap;
-use SP\Core\Dic\Injector;
/**
* Trait InjectTrait
diff --git a/lib/SP/Core/Install/Installer.php b/lib/SP/Core/Install/Installer.php
index 50fcff54..8d91aadd 100644
--- a/lib/SP/Core/Install/Installer.php
+++ b/lib/SP/Core/Install/Installer.php
@@ -31,7 +31,6 @@ use SP\Core\Crypt\Hash;
use SP\Core\Dic;
use SP\Core\Exceptions\InvalidArgumentException;
use SP\Core\Exceptions\SPException;
-use SP\Core\Traits\InjectableTrait;
use SP\DataModel\InstallData;
use SP\DataModel\ProfileData;
use SP\DataModel\UserData;
@@ -51,7 +50,7 @@ defined('APP_ROOT') || die();
*/
class Installer
{
- use InjectableTrait;
+ use Dic\InjectableTrait;
/**
* Versión y número de compilación de sysPass
diff --git a/lib/SP/Core/Install/MySQL.php b/lib/SP/Core/Install/MySQL.php
index bf84b892..55dd52bb 100644
--- a/lib/SP/Core/Install/MySQL.php
+++ b/lib/SP/Core/Install/MySQL.php
@@ -28,7 +28,6 @@ use PDOException;
use SP\Config\Config;
use SP\Config\ConfigData;
use SP\Core\Exceptions\SPException;
-use SP\Core\Traits\InjectableTrait;
use SP\DataModel\InstallData;
use SP\Storage\DatabaseConnectionData;
use SP\Storage\DBUtil;
@@ -42,7 +41,7 @@ use SP\Util\Util;
*/
class MySQL implements DatabaseSetupInterface
{
- use InjectableTrait;
+ use SP\Core\Dic\InjectableTrait;
/**
* @var InstallData
diff --git a/lib/SP/Core/Language.php b/lib/SP/Core/Language.php
index b41280e0..a88ae8f7 100644
--- a/lib/SP/Core/Language.php
+++ b/lib/SP/Core/Language.php
@@ -26,6 +26,7 @@ namespace SP\Core;
use SP\Config\Config;
use SP\Config\ConfigData;
+use SP\Core\Context\ContextInterface;
use SP\Core\Context\SessionContext;
use SP\Http\Request;
@@ -84,17 +85,17 @@ class Language
/**
* @var SessionContext
*/
- protected $session;
+ protected $context;
/**
* Language constructor.
*
- * @param SessionContext $session
- * @param Config $config
+ * @param ContextInterface $session
+ * @param Config $config
*/
- public function __construct(SessionContext $session, Config $config)
+ public function __construct(ContextInterface $session, Config $config)
{
- $this->session = $session;
+ $this->context = $session;
$this->configData = $config->getConfigData();
ksort(self::$langs);
@@ -117,7 +118,7 @@ class Language
*/
public function setLanguage($force = false)
{
- $lang = $this->session->getLocale();
+ $lang = $this->context->getLocale();
if (empty($lang) || $force === true) {
self::$userLang = $this->getUserLang();
@@ -125,7 +126,7 @@ class Language
$lang = self::$userLang ?: self::$globalLang;
- $this->session->setLocale($lang);
+ $this->context->setLocale($lang);
}
$this->setLocales($lang);
@@ -138,7 +139,7 @@ class Language
*/
private function getUserLang()
{
- $userData = $this->session->getUserData();
+ $userData = $this->context->getUserData();
return ($userData->getId() > 0) ? $userData->getPreferences()->getLang() : '';
}
@@ -212,7 +213,7 @@ class Language
*/
public function setAppLocales()
{
- if ($this->configData->getSiteLang() !== $this->session->getLocale()) {
+ if ($this->configData->getSiteLang() !== $this->context->getLocale()) {
$this->setLocales($this->configData->getSiteLang());
self::$appSet = true;
@@ -225,7 +226,7 @@ class Language
public function unsetAppLocales()
{
if (self::$appSet === true) {
- $this->setLocales($this->session->getLocale());
+ $this->setLocales($this->context->getLocale());
self::$appSet = false;
}
diff --git a/lib/SP/Core/ModuleBase.php b/lib/SP/Core/ModuleBase.php
index 92d04506..9b60a5ae 100644
--- a/lib/SP/Core/ModuleBase.php
+++ b/lib/SP/Core/ModuleBase.php
@@ -78,7 +78,7 @@ abstract class ModuleBase
}
/**
- * @param $controller
+ * @param string $controller
* @return mixed
*/
abstract public function initialize($controller);
@@ -89,7 +89,7 @@ abstract class ModuleBase
* Devuelve un error 503 y un reintento de 120s al cliente.
*
* @param ContextInterface $context
- * @param bool $check sólo comprobar si está activado el modo
+ * @param bool $check sólo comprobar si está activado el modo
* @throws InitializationException
*/
public function checkMaintenanceMode(ContextInterface $context, $check = false)
diff --git a/lib/SP/Core/SessionFactory.php b/lib/SP/Core/SessionFactory.php
index f6817d09..48e25988 100644
--- a/lib/SP/Core/SessionFactory.php
+++ b/lib/SP/Core/SessionFactory.php
@@ -31,6 +31,7 @@ defined('APP_ROOT') || die();
/**
* Clase para manejar la variable de sesion
+ * @deprecated
*/
class SessionFactory
{
diff --git a/lib/SP/Core/SessionUtil.php b/lib/SP/Core/SessionUtil.php
index cbbfd742..5784137d 100644
--- a/lib/SP/Core/SessionUtil.php
+++ b/lib/SP/Core/SessionUtil.php
@@ -24,15 +24,6 @@
namespace SP\Core;
-use Psr\Container\ContainerExceptionInterface;
-use Psr\Container\NotFoundExceptionInterface;
-use SP\Bootstrap;
-use SP\Config\ConfigData;
-use SP\Core\Context\SessionContext;
-use SP\Core\Crypt\Session as CryptSession;
-use SP\DataModel\UserData;
-use SP\Mgmt\Profiles\Profile;
-
defined('APP_ROOT') || die();
/**
@@ -42,87 +33,6 @@ defined('APP_ROOT') || die();
*/
class SessionUtil
{
- /**
- * Establece las variables de sesión del usuario.
- *
- * @param UserData $UserData
- * @param SessionContext $session
- */
- public static function loadUserSession(UserData $UserData, SessionContext $session)
- {
- $session->setUserData($UserData);
- $session->setUserProfile(Profile::getItem()->getById($UserData->getUserProfileId()));
- }
-
- /**
- * Establecer la clave pública RSA en la sessión
- *
- * @throws \SP\Core\Exceptions\SPException
- * @throws Dic\ContainerException
- */
- public static function loadPublicKey()
- {
- $CryptPKI = new CryptPKI();
- SessionFactory::setPublicKey($CryptPKI->getPublicKey());
- }
-
- /**
- * Desencriptar la clave maestra de la sesión.
- *
- * @return string con la clave maestra
- * @throws \Defuse\Crypto\Exception\CryptoException
- */
- public static function getSessionMPass()
- {
- return CryptSession::getSessionKey();
- }
-
- /**
- * Devuelve un hash para verificación de formularios.
- * Esta función genera un hash que permite verificar la autenticidad de un formulario
- *
- * @param bool $new si es necesrio regenerar el hash
- * @param ConfigData|null $configData
- * @return string con el hash de verificación
- * @deprecated
- */
- public static function getSessionKey($new = false, ConfigData $configData = null)
- {
- // FIXME
- if (null === $configData) {
- /** @var ConfigData $ConfigData */
- try {
- $configData = Bootstrap::getContainer()->get(ConfigData::class);
- } catch (NotFoundExceptionInterface $e) {
- return SessionFactory::getSecurityKey();
- } catch (ContainerExceptionInterface $e) {
- return SessionFactory::getSecurityKey();
- }
- }
-
- // Generamos un nuevo hash si es necesario y lo guardamos en la sesión
- if ($new === true || null === SessionFactory::getSecurityKey()) {
- $hash = sha1(time() . $configData->getPasswordSalt());
-
- SessionFactory::setSecurityKey($hash);
-
- return $hash;
- }
-
- return SessionFactory::getSecurityKey();
- }
-
- /**
- * Comprobar el hash de verificación de formularios.
- *
- * @param string $key con el hash a comprobar
- * @return bool|string si no es correcto el hash devuelve bool. Si lo es, devuelve el hash actual.
- */
- public static function checkSessionKey($key)
- {
- return (null !== SessionFactory::getSecurityKey() && SessionFactory::getSecurityKey() === $key);
- }
-
/**
* Limpiar la sesión del usuario
*/
@@ -132,18 +42,4 @@ class SessionUtil
unset($_SESSION[$key]);
}
}
-
- /**
- * Regenerad el ID de sesión
- *
- * @param SessionContext $session
- */
- public static function regenerate(SessionContext $session)
- {
- debugLog(__METHOD__);
-
- session_regenerate_id(true);
-
- $session->setSidStartTime(time());
- }
}
\ No newline at end of file
diff --git a/lib/SP/Core/UI/Theme.php b/lib/SP/Core/UI/Theme.php
index bf434b7d..3a775df8 100644
--- a/lib/SP/Core/UI/Theme.php
+++ b/lib/SP/Core/UI/Theme.php
@@ -27,11 +27,11 @@ namespace SP\Core\UI;
use SP\Bootstrap;
use SP\Config\Config;
use SP\Config\ConfigData;
+use SP\Core\Context\ContextInterface;
use SP\Core\Context\SessionContext;
use SP\Core\Exceptions\InvalidClassException;
use SP\Storage\FileCache;
use SP\Storage\FileException;
-use Theme\Icons;
defined('APP_ROOT') || die();
@@ -78,7 +78,7 @@ class Theme implements ThemeInterface
/**
* @var SessionContext
*/
- protected $session;
+ protected $context;
/**
* @var string
*/
@@ -91,19 +91,26 @@ class Theme implements ThemeInterface
/**
* Theme constructor.
*
- * @param string $module
- * @param Config $config
- * @param SessionContext $session
- * @param FileCache $fileCache
+ * @param string $module
+ * @param Config $config
+ * @param ContextInterface $context
+ * @param FileCache $fileCache
*/
- public function __construct($module, Config $config, SessionContext $session, FileCache $fileCache)
+ public function __construct($module, Config $config, ContextInterface $context, FileCache $fileCache)
{
$this->configData = $config->getConfigData();
- $this->session = $session;
+ $this->context = $context;
$this->fileCache = $fileCache;
+ }
+ /**
+ * @param bool $force
+ * @throws InvalidClassException
+ */
+ public function initialize($force = false)
+ {
if (is_dir(VIEW_PATH)) {
- $this->initTheme();
+ $this->initTheme($force);
$this->initIcons();
}
}
@@ -116,11 +123,8 @@ class Theme implements ThemeInterface
*/
public function initTheme($force = false)
{
- $this->themeName = $this->session->getTheme();
-
if (empty($this->themeName) || $force === true) {
$this->themeName = $this->getUserTheme() ?: $this->getGlobalTheme();
- $this->session->setTheme($this->themeName);
}
$this->themeUri = Bootstrap::$WEBURI . '/app/modules/' . $this->module . 'themes' . $this->themeName;
@@ -136,9 +140,7 @@ class Theme implements ThemeInterface
*/
protected function getUserTheme()
{
- $userData = $this->session->getUserData();
-
- return ($userData->getId() > 0) ? $userData->getPreferences()->getTheme() : '';
+ return $this->context->isLoggedIn() ? $this->context->getUserData()->getPreferences()->getTheme() : null;
}
/**
diff --git a/lib/SP/Core/Upgrade/Account.php b/lib/SP/Core/Upgrade/Account.php
index 4ec21fe4..ef7fc60d 100644
--- a/lib/SP/Core/Upgrade/Account.php
+++ b/lib/SP/Core/Upgrade/Account.php
@@ -25,7 +25,7 @@
namespace SP\Core\Upgrade;
use SP\Core\Exceptions\SPException;
-use SP\Core\TaskFactory;
+use SP\Services\Task\TaskFactory;
use SP\Storage\DbWrapper;
use SP\Storage\QueryData;
diff --git a/lib/SP/Core/Upgrade/Category.php b/lib/SP/Core/Upgrade/Category.php
index d64a9881..ee54c23a 100644
--- a/lib/SP/Core/Upgrade/Category.php
+++ b/lib/SP/Core/Upgrade/Category.php
@@ -25,7 +25,7 @@
namespace SP\Core\Upgrade;
use SP\Core\Exceptions\SPException;
-use SP\Core\TaskFactory;
+use SP\Services\Task\TaskFactory;
use SP\Storage\DbWrapper;
use SP\Storage\QueryData;
diff --git a/lib/SP/Core/Upgrade/Customer.php b/lib/SP/Core/Upgrade/Customer.php
index 9800e059..16866bbb 100644
--- a/lib/SP/Core/Upgrade/Customer.php
+++ b/lib/SP/Core/Upgrade/Customer.php
@@ -25,7 +25,7 @@
namespace SP\Core\Upgrade;
use SP\Core\Exceptions\SPException;
-use SP\Core\TaskFactory;
+use SP\Services\Task\TaskFactory;
use SP\Storage\DbWrapper;
use SP\Storage\QueryData;
diff --git a/lib/SP/Core/Upgrade/Group.php b/lib/SP/Core/Upgrade/Group.php
index b9cda93a..0dc2fb61 100644
--- a/lib/SP/Core/Upgrade/Group.php
+++ b/lib/SP/Core/Upgrade/Group.php
@@ -25,7 +25,7 @@
namespace SP\Core\Upgrade;
use SP\Core\Exceptions\SPException;
-use SP\Core\TaskFactory;
+use SP\Services\Task\TaskFactory;
use SP\Storage\DbWrapper;
use SP\Storage\QueryData;
diff --git a/lib/SP/Core/Upgrade/Profile.php b/lib/SP/Core/Upgrade/Profile.php
index 018f51c3..cf36e973 100644
--- a/lib/SP/Core/Upgrade/Profile.php
+++ b/lib/SP/Core/Upgrade/Profile.php
@@ -25,8 +25,8 @@
namespace SP\Core\Upgrade;
use SP\Core\Exceptions\SPException;
-use SP\Core\TaskFactory;
use SP\DataModel\ProfileData;
+use SP\Services\Task\TaskFactory;
use SP\Storage\DbWrapper;
use SP\Storage\QueryData;
diff --git a/lib/SP/Core/Upgrade/Upgrade.php b/lib/SP/Core/Upgrade/Upgrade.php
index cad1c7bd..cdf9d24a 100644
--- a/lib/SP/Core/Upgrade/Upgrade.php
+++ b/lib/SP/Core/Upgrade/Upgrade.php
@@ -27,11 +27,9 @@ namespace SP\Core\Upgrade;
use SP\Config\Config;
use SP\Config\ConfigData;
-use SP\Config\ConfigDB;
+use SP\Core\Dic\InjectableTrait;
use SP\Core\Exceptions\SPException;
use SP\Core\SessionFactory as CoreSession;
-use SP\Core\TaskFactory;
-use SP\Core\Traits\InjectableTrait;
use SP\Core\Upgrade\User as UserUpgrade;
use SP\Http\Request;
use SP\Log\Email;
@@ -41,6 +39,7 @@ use SP\Mgmt\Profiles\ProfileUtil;
use SP\Mgmt\Users\User;
use SP\Mgmt\Users\UserMigrate;
use SP\Mgmt\Users\UserPreferencesUtil;
+use SP\Services\Task\TaskFactory;
use SP\Storage\DbWrapper;
use SP\Storage\QueryData;
use SP\Util\Util;
@@ -82,12 +81,14 @@ class Upgrade
/**
* Upgrade constructor.
*
- * @throws \ReflectionException
+ * @param Config $config
+ * @param Log $log
* @throws \SP\Core\Dic\ContainerException
*/
- public function __construct()
+ public function __construct(Config $config, Log $log)
{
$this->injectDependencies();
+ $this->config = $config;
}
/**
@@ -99,7 +100,7 @@ class Upgrade
*/
public function doUpgrade($version)
{
- self::$currentDbVersion = self::fixVersionNumber(ConfigDB::getValue('version'));
+ self::$currentDbVersion = UserUpgrade::fixVersionNumber(ConfigDB::getValue('version'));
foreach (self::$dbUpgrade as $dbVersion) {
if (Util::checkVersion($version, $dbVersion)) {
@@ -132,24 +133,6 @@ class Upgrade
return true;
}
- /**
- * Normalizar un número de versión
- *
- * @param $version
- * @return string
- */
- public static function fixVersionNumber($version)
- {
- if (strpos($version, '.') === false) {
- if (strlen($version) === 10) {
- return substr($version, 0, 2) . '0.' . substr($version, 2);
- }
-
- return substr($version, 0, 3) . '.' . substr($version, 3);
- }
-
- return $version;
- }
/**
* Aplicar actualizaciones auxiliares antes de actualizar la BBDD
@@ -505,7 +488,7 @@ class Upgrade
public function checkDbVersion()
{
$appVersion = Util::getVersionStringNormalized();
- $databaseVersion = self::fixVersionNumber(ConfigDB::getValue('version'));
+ $databaseVersion = UserUpgrade::fixVersionNumber(ConfigDB::getValue('version'));
if (Util::checkVersion($databaseVersion, $appVersion)
&& Request::analyze('nodbupgrade', 0) === 0
@@ -549,7 +532,7 @@ class Upgrade
*/
public function checkAppVersion()
{
- $appVersion = self::fixVersionNumber($this->configData->getConfigVersion());
+ $appVersion = UserUpgrade::fixVersionNumber($this->configData->getConfigVersion());
if (Util::checkVersion($appVersion, self::$appUpgrade) && !$this->configData->isMaintenance()) {
$this->setUpgradeKey('app');
diff --git a/lib/SP/Core/Upgrade/User.php b/lib/SP/Core/Upgrade/User.php
index 1c08f27e..5f62377c 100644
--- a/lib/SP/Core/Upgrade/User.php
+++ b/lib/SP/Core/Upgrade/User.php
@@ -25,10 +25,10 @@
namespace SP\Core\Upgrade;
use Defuse\Crypto\Exception\CryptoException;
+use SP\Core\Crypt\OldCrypt;
use SP\Core\Exceptions\SPException;
-use SP\Core\OldCrypt;
-use SP\Core\TaskFactory;
use SP\DataModel\UserLoginData;
+use SP\Services\Task\TaskFactory;
use SP\Services\User\UserPassService;
use SP\Storage\DbWrapper;
use SP\Storage\QueryData;
diff --git a/lib/SP/Core/XmlExport.php b/lib/SP/Core/XmlExport.php
deleted file mode 100644
index 4ca8cae1..00000000
--- a/lib/SP/Core/XmlExport.php
+++ /dev/null
@@ -1,571 +0,0 @@
-.
- */
-
-namespace SP\Core;
-
-use Defuse\Crypto\Exception\CryptoException;
-use SP\Account\AccountTags;
-use SP\Account\AccountUtil;
-use SP\Config\Config;
-use SP\Config\ConfigData;
-use SP\Core\Crypt\Crypt;
-use SP\Core\Crypt\Hash;
-use SP\Core\Exceptions\SPException;
-use SP\Core\Traits\InjectableTrait;
-use SP\DataModel\CategoryData;
-use SP\Log\Email;
-use SP\Log\Log;
-use SP\Mgmt\Categories\Category;
-use SP\Mgmt\Customers\Customer;
-use SP\Mgmt\Tags\Tag;
-use SP\Util\Util;
-
-defined('APP_ROOT') || die();
-
-/**
- * Clase XmlExport para realizar la exportación de las cuentas de sysPass a formato XML
- *
- * @package SP
- */
-class XmlExport
-{
- use InjectableTrait;
- /**
- * @var ConfigData
- */
- protected $ConfigData;
- /**
- * @var Config
- */
- protected $Config;
- /**
- * @var \DOMDocument
- */
- private $xml;
- /**
- * @var \DOMElement
- */
- private $root;
- /**
- * @var string
- */
- private $exportPass;
- /**
- * @var bool
- */
- private $encrypted = false;
- /**
- * @var string
- */
- private $exportDir = '';
- /**
- * @var string
- */
- private $exportFile = '';
-
- /**
- * Constructor
- */
- public function __construct()
- {
- $this->injectDependencies();
-
- $this->xml = new \DOMDocument('1.0', 'UTF-8');
- }
-
- /**
- * Realiza la exportación de las cuentas a XML
- *
- * @param null $pass string La clave de exportación
- * @return bool
- */
- public static function doExport($pass = null)
- {
- $xml = new self();
-
- if (null !== $pass && !empty($pass)) {
- $xml->setExportPass($pass);
- $xml->setEncrypted(true);
- }
-
- $xml->setExportDir(Init::$SERVERROOT . DIRECTORY_SEPARATOR . 'backup');
- $xml->setExportFile();
- $xml->deleteOldExports();
-
- return $xml->makeXML();
- }
-
- /**
- * Establecer la clave de exportación
- *
- * @param string $exportPass
- */
- public function setExportPass($exportPass)
- {
- $this->exportPass = $exportPass;
- }
-
- /**
- * @param boolean $encrypted
- */
- public function setEncrypted($encrypted)
- {
- $this->encrypted = $encrypted;
- }
-
- /**
- * @param string $exportDir
- */
- public function setExportDir($exportDir)
- {
- $this->exportDir = $exportDir;
- }
-
- /**
- * Genera el nombre del archivo usado para la exportación.
- */
- private function setExportFile()
- {
- // Generar hash unico para evitar descargas no permitidas
- $exportUniqueHash = sha1(uniqid('sysPassExport', true));
- $this->ConfigData->setExportHash($exportUniqueHash);
- $this->Config->saveConfig();
-
- $this->exportFile = $this->exportDir . DIRECTORY_SEPARATOR . Util::getAppInfo('appname') . '-' . $exportUniqueHash . '.xml';
- }
-
- /**
- * Eliminar los archivos de exportación anteriores
- */
- private function deleteOldExports()
- {
- array_map('unlink', glob($this->exportDir . DIRECTORY_SEPARATOR . '*.xml'));
- }
-
- /**
- * Crear el documento XML y guardarlo
- *
- * @return bool
- * @throws \phpmailer\phpmailerException
- */
- public function makeXML()
- {
- $Log = new Log();
- $LogMessage = $Log->getLogMessage();
- $LogMessage->setAction(__('Exportar XML', false));
-
- try {
- $this->checkExportDir();
- $this->createRoot();
- $this->createMeta();
- $this->createCategories();
- $this->createCustomers();
- $this->createTags();
- $this->createAccounts();
- $this->createHash();
- $this->writeXML();
- } catch (SPException $e) {
- $LogMessage->addDescription(__('Error al realizar la exportación de cuentas', false));
- $LogMessage->addDetails($e->getMessage(), $e->getHint());
- $Log->setLogLevel(Log::ERROR);
- $Log->writeLog();
-
- Email::sendEmail($LogMessage);
- return false;
- }
-
- $LogMessage->addDescription(__('Exportación de cuentas realizada correctamente', false));
- $Log->writeLog();
-
- Email::sendEmail($LogMessage);
-
- return true;
- }
-
- /**
- * Comprobar y crear el directorio de exportación.
- *
- * @throws SPException
- * @return bool
- */
- private function checkExportDir()
- {
- if (@mkdir($this->exportDir, 0750) === false && is_dir($this->exportDir) === false) {
- throw new SPException(sprintf(__('No es posible crear el directorio de backups ("%s")'), $this->exportDir), SPException::CRITICAL);
- }
-
- clearstatcache(true, $this->exportDir);
-
- if (!is_writable($this->exportDir)) {
- throw new SPException(__('Compruebe los permisos del directorio de backups', false), SPException::CRITICAL);
- }
-
- return true;
- }
-
- /**
- * Crear el nodo raíz
- *
- * @throws SPException
- */
- private function createRoot()
- {
- try {
- $root = $this->xml->createElement('Root');
- $this->root = $this->xml->appendChild($root);
- } catch (\DOMException $e) {
- throw new SPException($e->getMessage(), SPException::WARNING, __FUNCTION__);
- }
- }
-
- /**
- * Crear el nodo con metainformación del archivo XML
- *
- * @throws SPException
- */
- private function createMeta()
- {
- try {
- $nodeMeta = $this->xml->createElement('Meta');
- $metaGenerator = $this->xml->createElement('Generator', 'sysPass');
- $metaVersion = $this->xml->createElement('Version', Util::getVersionStringNormalized());
- $metaTime = $this->xml->createElement('Time', time());
- $metaUser = $this->xml->createElement('User', SessionFactory::getUserData()->getLogin());
- $metaUser->setAttribute('id', SessionFactory::getUserData()->getId());
- $metaGroup = $this->xml->createElement('Group', SessionFactory::getUserData()->getUserGroupName());
- $metaGroup->setAttribute('id', SessionFactory::getUserData()->getUserGroupId());
-
- $nodeMeta->appendChild($metaGenerator);
- $nodeMeta->appendChild($metaVersion);
- $nodeMeta->appendChild($metaTime);
- $nodeMeta->appendChild($metaUser);
- $nodeMeta->appendChild($metaGroup);
-
- $this->root->appendChild($nodeMeta);
- } catch (\DOMException $e) {
- throw new SPException($e->getMessage(), SPException::WARNING, __FUNCTION__);
- }
- }
-
- /**
- * Crear el nodo con los datos de las categorías
- *
- * @throws SPException
- */
- private function createCategories()
- {
- $Category = new Category();
- $categories = $Category->getAll();
-
- if (count($categories) === 0) {
- return;
- }
-
- try {
- // Crear el nodo de categorías
- $nodeCategories = $this->xml->createElement('Categories');
-
- foreach ($categories as $CategoryData) {
- /** @var $CategoryData CategoryData */
- $categoryName = $this->xml->createElement('name', $this->escapeChars($CategoryData->getName()));
- $categoryDescription = $this->xml->createElement('description', $this->escapeChars($CategoryData->getDescription()));
-
- // Crear el nodo de categoría
- $nodeCategory = $this->xml->createElement('Category');
- $nodeCategory->setAttribute('id', $CategoryData->getId());
- $nodeCategory->appendChild($categoryName);
- $nodeCategory->appendChild($categoryDescription);
-
- // Añadir categoría al nodo de categorías
- $nodeCategories->appendChild($nodeCategory);
- }
-
- $this->appendNode($nodeCategories);
- } catch (\DOMException $e) {
- throw new SPException($e->getMessage(), SPException::WARNING, __FUNCTION__);
- }
- }
-
- /**
- * Escapar carácteres no válidos en XML
- *
- * @param $data string Los datos a escapar
- * @return mixed
- */
- private function escapeChars($data)
- {
- $arrStrFrom = ['&', '<', '>', '"', '\''];
- $arrStrTo = ['&', '<', '>', '"', '''];
-
- return str_replace($arrStrFrom, $arrStrTo, $data);
- }
-
- /**
- * Añadir un nuevo nodo al árbol raíz
- *
- * @param \DOMElement $node El nodo a añadir
- * @throws SPException
- */
- private function appendNode(\DOMElement $node)
- {
- try {
- // Si se utiliza clave de encriptación los datos se encriptan en un nuevo nodo:
- // Encrypted -> Data
- if ($this->encrypted === true) {
- // Obtener el nodo en formato XML
- $nodeXML = $this->xml->saveXML($node);
-
- // Crear los datos encriptados con la información del nodo
- $securedKey = Crypt::makeSecuredKey($this->exportPass);
- $encrypted = Crypt::encrypt($nodeXML, $securedKey, $this->exportPass);
-
- // Buscar si existe ya un nodo para el conjunto de datos encriptados
- $encryptedNode = $this->root->getElementsByTagName('Encrypted')->item(0);
-
- if (!$encryptedNode instanceof \DOMElement) {
- $encryptedNode = $this->xml->createElement('Encrypted');
- $encryptedNode->setAttribute('hash', Hash::hashKey($this->exportPass));
- }
-
- // Crear el nodo hijo con los datos encriptados
- $encryptedData = $this->xml->createElement('Data', base64_encode($encrypted));
-
- $encryptedDataIV = $this->xml->createAttribute('key');
- $encryptedDataIV->value = $securedKey;
-
- // Añadir nodos de datos
- $encryptedData->appendChild($encryptedDataIV);
- $encryptedNode->appendChild($encryptedData);
-
- // Añadir el nodo encriptado
- $this->root->appendChild($encryptedNode);
- } else {
- $this->root->appendChild($node);
- }
- } catch (\DOMException $e) {
- throw new SPException($e->getMessage(), SPException::WARNING, __FUNCTION__);
- } catch (CryptoException $e) {
- throw new SPException($e->getMessage(), SPException::WARNING, __FUNCTION__);
- }
- }
-
- /**
- * Crear el nodo con los datos de los clientes
- *
- * #@throws SPException
- */
- private function createCustomers()
- {
- $customers = Customer::getItem()->getAll();
-
- if (count($customers) === 0) {
- return;
- }
-
- try {
- // Crear el nodo de clientes
- $nodeCustomers = $this->xml->createElement('Customers');
-
- foreach ($customers as $CustomerData) {
- $customerName = $this->xml->createElement('name', $this->escapeChars($CustomerData->getName()));
- $customerDescription = $this->xml->createElement('description', $this->escapeChars($CustomerData->getDescription()));
-
- // Crear el nodo de clientes
- $nodeCustomer = $this->xml->createElement('Customer');
- $nodeCustomer->setAttribute('id', $CustomerData->getId());
- $nodeCustomer->appendChild($customerName);
- $nodeCustomer->appendChild($customerDescription);
-
- // Añadir cliente al nodo de clientes
- $nodeCustomers->appendChild($nodeCustomer);
- }
-
- $this->appendNode($nodeCustomers);
- } catch (\DOMException $e) {
- throw new SPException($e->getMessage(), SPException::WARNING, __FUNCTION__);
- }
- }
-
- /**
- * Crear el nodo con los datos de las etiquetas
- *
- * #@throws SPException
- */
- private function createTags()
- {
- $Tags = Tag::getItem()->getAll();
-
- if (count($Tags) === 0) {
- return;
- }
-
- try {
- // Crear el nodo de etiquetas
- $nodeTags = $this->xml->createElement('Tags');
-
- foreach ($Tags as $TagData) {
- $tagName = $this->xml->createElement('name', $this->escapeChars($TagData->getName()));
-
- // Crear el nodo de etiquetas
- $nodeTag = $this->xml->createElement('Tag');
- $nodeTag->setAttribute('id', $TagData->getId());
- $nodeTag->appendChild($tagName);
-
- // Añadir etiqueta al nodo de etiquetas
- $nodeTags->appendChild($nodeTag);
- }
-
- $this->appendNode($nodeTags);
- } catch (\DOMException $e) {
- throw new SPException($e->getMessage(), SPException::WARNING, __FUNCTION__);
- }
- }
-
- /**
- * Crear el nodo con los datos de las cuentas
- *
- * @throws SPException
- */
- private function createAccounts()
- {
- $accounts = AccountUtil::getAccountsData();
-
- if (count($accounts) === 0) {
- return;
- }
-
- try {
- // Crear el nodo de cuentas
- $nodeAccounts = $this->xml->createElement('Accounts');
-
- foreach ($accounts as $account) {
- $accountName = $this->xml->createElement('name', $this->escapeChars($account->account_name));
- $accountCustomerId = $this->xml->createElement('customerId', $account->account_customerId);
- $accountCategoryId = $this->xml->createElement('categoryId', $account->account_categoryId);
- $accountLogin = $this->xml->createElement('login', $this->escapeChars($account->account_login));
- $accountUrl = $this->xml->createElement('url', $this->escapeChars($account->account_url));
- $accountNotes = $this->xml->createElement('notes', $this->escapeChars($account->account_notes));
- $accountPass = $this->xml->createElement('pass', $this->escapeChars($account->account_pass));
- $accountIV = $this->xml->createElement('key', $this->escapeChars($account->account_key));
- $tags = $this->xml->createElement('tags');
-
- foreach (AccountTags::getTagsForId($account->account_id) as $id => $name) {
- $tag = $this->xml->createElement('tag');
- $tag->setAttribute('id', $id);
-
- $tags->appendChild($tag);
- }
-
- // Crear el nodo de cuenta
- $nodeAccount = $this->xml->createElement('Account');
- $nodeAccount->setAttribute('id', $account->account_id);
- $nodeAccount->appendChild($accountName);
- $nodeAccount->appendChild($accountCustomerId);
- $nodeAccount->appendChild($accountCategoryId);
- $nodeAccount->appendChild($accountLogin);
- $nodeAccount->appendChild($accountUrl);
- $nodeAccount->appendChild($accountNotes);
- $nodeAccount->appendChild($accountPass);
- $nodeAccount->appendChild($accountIV);
- $nodeAccount->appendChild($tags);
-
- // Añadir cuenta al nodo de cuentas
- $nodeAccounts->appendChild($nodeAccount);
- }
-
- $this->appendNode($nodeAccounts);
- } catch (\DOMException $e) {
- throw new SPException($e->getMessage(), SPException::WARNING, __FUNCTION__);
- }
- }
-
- /**
- * Crear el hash del archivo XML e insertarlo en el árbol DOM
- *
- * @throws \SP\Core\Exceptions\SPException
- */
- private function createHash()
- {
- try {
- if ($this->encrypted === true) {
- $hash = sha1($this->getNodeXML('Encrypted'));
- } else {
- $hash = sha1($this->getNodeXML('Categories') . $this->getNodeXML('Customers') . $this->getNodeXML('Accounts'));
- }
-
- $metaHash = $this->xml->createElement('Hash', $hash);
-
- $nodeMeta = $this->root->getElementsByTagName('Meta')->item(0);
- $nodeMeta->appendChild($metaHash);
- } catch (\DOMException $e) {
- throw new SPException($e->getMessage(), SPException::WARNING, __FUNCTION__);
- }
- }
-
- /**
- * Devuelve el código XML de un nodo
- *
- * @param $node string El nodo a devolver
- * @return string
- * @throws SPException
- */
- private function getNodeXML($node)
- {
- try {
- $nodeXML = $this->xml->saveXML($this->root->getElementsByTagName($node)->item(0));
- return $nodeXML;
- } catch (\DOMException $e) {
- throw new SPException($e->getMessage(), SPException::WARNING, __FUNCTION__);
- }
- }
-
- /**
- * Generar el archivo XML
- *
- * @return bool
- * @throws SPException
- */
- private function writeXML()
- {
- try {
- $this->xml->formatOutput = true;
- $this->xml->preserveWhiteSpace = false;
-
- if (!$this->xml->save($this->exportFile)) {
- throw new SPException(__('Error al crear el archivo XML', false), SPException::CRITICAL);
- }
- } catch (\DOMException $e) {
- throw new SPException($e->getMessage(), SPException::WARNING, __FUNCTION__);
- }
- }
-
- /**
- * @param Config $config
- */
- public function inject(Config $config)
- {
- $this->Config = $config;
- $this->ConfigData = $config->getConfigData();
- }
-}
\ No newline at end of file
diff --git a/lib/SP/Crypt/TemporaryMasterPass.php b/lib/SP/Crypt/TemporaryMasterPass.php
deleted file mode 100644
index 4d192456..00000000
--- a/lib/SP/Crypt/TemporaryMasterPass.php
+++ /dev/null
@@ -1,197 +0,0 @@
-.
- */
-
-namespace SP\Crypt;
-
-use SP\Core\Context\SessionContext;
-use SP\Core\Crypt\Crypt;
-use SP\Core\Crypt\Hash;
-use SP\Core\Crypt\Session as CryptSession;
-use SP\Core\Events\Event;
-use SP\Core\Events\EventDispatcher;
-use SP\Core\Traits\InjectableTrait;
-use SP\DataModel\Dto\ConfigRequest;
-use SP\Services\Config\ConfigService;
-use SP\Services\Config\ParameterNotFoundException;
-use SP\Services\ServiceException;
-use SP\Util\Util;
-
-/**
- * Class MasterPass
- *
- * @package SP\Crypt
- */
-class TemporaryMasterPass
-{
- /**
- * Número máximo de intentos
- */
- const MAX_ATTEMPTS = 50;
- /**
- * @var ConfigService
- */
- protected $configService;
- /**
- * @var SessionContext
- */
- protected $session;
- /**
- * @var EventDispatcher
- */
- protected $eventDispatcher;
-
- use InjectableTrait;
-
- /**
- * MasterPass constructor.
- *
- * @throws \SP\Core\Dic\ContainerException
- */
- public function __construct()
- {
- $this->injectDependencies();
- }
-
- /**
- * Comprueba si la clave temporal es válida
- *
- * @param string $pass clave a comprobar
- * @return bool
- * @throws \SP\Core\Exceptions\SPException
- */
- public function check($pass)
- {
- try {
- $passMaxTime = (int)$this->configService->getByParam('tempmaster_maxtime');
-
- // Comprobar si el tiempo de validez o los intentos se han superado
- if ($passMaxTime === 0 || time() > $passMaxTime) {
- $this->expire();
-
- return false;
- }
-
- $passTime = (int)$this->configService->getByParam('tempmaster_passtime');
- $attempts = (int)$this->configService->getByParam('tempmaster_attempts');
-
- if ($attempts >= self::MAX_ATTEMPTS
- || (!empty($passTime) && time() > $passMaxTime)
- ) {
- $this->expire();
-
- return false;
- }
-
- $isValid = Hash::checkHashKey($pass, $this->configService->getByParam('tempmaster_passhash'));
-
- if (!$isValid) {
- $this->configService->save('tempmaster_attempts', $attempts + 1);
- }
-
- return $isValid;
- } catch (ParameterNotFoundException $e) {
- return false;
- }
- }
-
- /**
- * @throws ServiceException
- * @throws \SP\Core\Exceptions\InvalidArgumentException
- */
- private function expire()
- {
- $configRequest = new ConfigRequest();
- $configRequest->add('tempmaster_pass', '');
- $configRequest->add('tempmaster_passkey', '');
- $configRequest->add('tempmaster_passhash', '');
- $configRequest->add('tempmaster_maxtime', 0);
- $configRequest->add('tempmaster_attempts', 0);
-
- // Guardar la configuración
- $this->configService->saveBatch($configRequest);
-
- $this->eventDispatcher->notifyEvent('temporaryMasterPass.expired', new Event($this));
-
- // Log::writeNewLog(__FUNCTION__, __u('Clave temporal caducada'), Log::INFO);
- }
-
- /**
- * Devuelve la clave maestra que ha sido encriptada con la clave temporal
- *
- * @param $key string con la clave utilizada para encriptar
- * @return string con la clave maestra desencriptada
- * @throws \Defuse\Crypto\Exception\CryptoException
- * @throws \SP\Services\Config\ParameterNotFoundException
- */
- public function getUsingKey($key)
- {
- $securedKey = Crypt::unlockSecuredKey($this->configService->getByParam('tempmaster_passkey'), $key);
-
- return Crypt::decrypt($this->configService->getByParam('tempmaster_pass'), $securedKey, $key);
- }
-
- /**
- * @param ConfigService $configService
- * @param SessionContext $session
- * @param EventDispatcher $eventDispatcher
- */
- public function inject(ConfigService $configService, SessionContext $session, EventDispatcher $eventDispatcher)
- {
- $this->configService = $configService;
- $this->session = $session;
- $this->eventDispatcher = $eventDispatcher;
- }
-
- /**
- * Crea una clave temporal para encriptar la clave maestra y guardarla.
- *
- * @param int $maxTime El tiempo máximo de validez de la clave
- * @return string
- * @throws ServiceException
- * @throws \Defuse\Crypto\Exception\CryptoException
- * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
- */
- public function create($maxTime = 14400)
- {
- // Encriptar la clave maestra con hash aleatorio generado
- $randomKey = Util::generateRandomBytes(32);
- $securedKey = Crypt::makeSecuredKey($randomKey);
-
- $configRequest = new ConfigRequest();
- $configRequest->add('tempmaster_pass', Crypt::encrypt(CryptSession::getSessionKey(), $securedKey, $randomKey));
- $configRequest->add('tempmaster_passkey', $securedKey);
- $configRequest->add('tempmaster_passhash', Hash::hashKey($randomKey));
- $configRequest->add('tempmaster_passtime', time());
- $configRequest->add('tempmaster_maxtime', time() + $maxTime);
- $configRequest->add('tempmaster_attempts', 0);
-
- // Guardar la configuración
- $this->configService->saveBatch($configRequest);
-
- // Guardar la clave temporal hasta que finalice la sesión
- $this->session->setTemporaryMasterPass($randomKey);
-
- return $randomKey;
- }
-}
\ No newline at end of file
diff --git a/lib/SP/Html/Minify.php b/lib/SP/Html/Minify.php
index 8a383272..095d10ff 100644
--- a/lib/SP/Html/Minify.php
+++ b/lib/SP/Html/Minify.php
@@ -26,7 +26,6 @@ namespace SP\Html;
use Klein\Klein;
use SP\Core\Exceptions\SPException;
-use SP\Core\Traits\InjectableTrait;
use SP\Http\Request;
use SP\Util\Util;
@@ -39,8 +38,6 @@ defined('APP_ROOT') || die();
*/
class Minify
{
- use InjectableTrait;
-
/**
* Constantes para tipos de archivos
*/
diff --git a/lib/SP/Http/Request.php b/lib/SP/Http/Request.php
index 0eee33e6..f4606d40 100644
--- a/lib/SP/Http/Request.php
+++ b/lib/SP/Http/Request.php
@@ -25,8 +25,7 @@
namespace SP\Http;
use Klein\Klein;
-use SP\Core\CryptPKI;
-use SP\Core\Init;
+use SP\Core\Crypt\CryptPKI;
use SP\Html\Html;
use SP\Util\Util;
@@ -40,27 +39,7 @@ class Request
/**
* @var array Directorios seguros para include
*/
- private static $secureDirs = ['css', 'js'];
-
- /**
- * Comprobar el método utilizado para enviar un formulario.
- *
- * @param string $method con el método utilizado.
- * @throws \SP\Core\Exceptions\FileNotFoundException
- * @throws \SP\Core\Exceptions\SPException
- */
- public static function checkReferer($method)
- {
- $referer = self::getRequestHeaders('HTTP_REFERER');
-
- if (!$referer
- || $_SERVER['REQUEST_METHOD'] !== strtoupper($method)
- || !preg_match('#' . Init::$WEBROOT . '/.*$#', $referer)
- ) {
- Init::initError(__('No es posible acceder directamente a este archivo'));
- exit();
- }
- }
+ const SECURE_DIRS = ['css', 'js'];
/**
* Devolver las cabeceras enviadas desde el cliente.
@@ -172,6 +151,7 @@ class Request
* @param mixed $force valor devuelto si el parámeto está definido
* @param bool $sanitize escapar/eliminar carácteres especiales
* @return mixed si está presente el parámeto en la petición devuelve bool. Si lo está, devuelve el valor.
+ * @deprecated
*/
public static function analyze($param, $default = '', $check = false, $force = false, $sanitize = true)
{
@@ -197,6 +177,7 @@ class Request
* @param $default mixed tipo por defecto a devolver
* @param $sanitize bool limpiar una cadena de caracteres
* @return mixed
+ * @deprecated
*/
public static function parse(&$value, $default, $sanitize)
{
@@ -223,12 +204,17 @@ class Request
}
/**
- * @param $param
+ * @param string $param
+ * @param callable|null $mapper
* @return mixed
*/
- public static function analyzeArray($param)
+ public static function analyzeArray($param, callable $mapper = null)
{
if (isset($_REQUEST[$param]) && is_array($_REQUEST[$param])) {
+ if (is_callable($mapper)) {
+ return $mapper($_REQUEST[$param]);
+ }
+
return array_map(function ($value) {
if (is_numeric($value)) {
return (int)filter_var($value, FILTER_SANITIZE_NUMBER_INT);
@@ -336,7 +322,7 @@ class Request
{
if ($base === null) {
$base = APP_ROOT;
- } elseif (!in_array(basename($base), self::$secureDirs, true)) {
+ } elseif (!in_array(basename($base), self::SECURE_DIRS, true)) {
return '';
}
diff --git a/lib/SP/Log/ActionLog.php b/lib/SP/Log/ActionLog.php
index 7c42c9d1..2a963d18 100644
--- a/lib/SP/Log/ActionLog.php
+++ b/lib/SP/Log/ActionLog.php
@@ -29,7 +29,6 @@ use SP\Config\ConfigData;
use SP\Core\Context\SessionContext;
use SP\Core\Language;
use SP\Core\Messages\LogMessage;
-use SP\Core\Traits\InjectableTrait;
use SP\Storage\Database;
/**
@@ -39,8 +38,6 @@ use SP\Storage\Database;
*/
abstract class ActionLog extends LogLevel
{
- use InjectableTrait;
-
/**
* Constante de nueva línea para descripciones
*/
diff --git a/lib/SP/Log/Syslog.php b/lib/SP/Log/Syslog.php
index 28529721..308ae3ab 100644
--- a/lib/SP/Log/Syslog.php
+++ b/lib/SP/Log/Syslog.php
@@ -27,7 +27,6 @@ namespace SP\Log;
use SP\Config\Config;
use SP\Config\ConfigData;
use SP\Core\Exceptions\SPException;
-use SP\Core\Traits\InjectableTrait;
use SP\Util\Connection;
/**
@@ -37,7 +36,7 @@ use SP\Util\Connection;
*/
class Syslog extends AbstractLogger
{
- use InjectableTrait;
+ use SP\Core\Dic\InjectableTrait;
/**
* @var ConfigData
diff --git a/lib/SP/Mgmt/CustomFields/CustomFieldsUtil.php b/lib/SP/Mgmt/CustomFields/CustomFieldsUtil.php
index 6f946eaf..5910017b 100644
--- a/lib/SP/Mgmt/CustomFields/CustomFieldsUtil.php
+++ b/lib/SP/Mgmt/CustomFields/CustomFieldsUtil.php
@@ -28,9 +28,9 @@ defined('APP_ROOT') || die();
use Defuse\Crypto\Exception\CryptoException;
use SP\Core\Crypt\Crypt;
+use SP\Core\Crypt\OldCrypt;
use SP\Core\Exceptions\QueryException;
use SP\Core\Exceptions\SPException;
-use SP\Core\OldCrypt;
use SP\DataModel\CustomFieldData;
use SP\DataModel\CustomFieldDefinitionData;
use SP\Log\Log;
diff --git a/lib/SP/Mgmt/ItemBaseTrait.php b/lib/SP/Mgmt/ItemBaseTrait.php
index f2cdda3a..d5f5b408 100644
--- a/lib/SP/Mgmt/ItemBaseTrait.php
+++ b/lib/SP/Mgmt/ItemBaseTrait.php
@@ -29,7 +29,6 @@ use SP\Core\Context\SessionContext;
use SP\Core\DiFactory;
use SP\Core\Exceptions\InvalidClassException;
use SP\Core\Exceptions\SPException;
-use SP\Core\Traits\InjectableTrait;
use SP\DataModel\DataModelInterface;
use SP\Storage\Database;
@@ -40,7 +39,7 @@ use SP\Storage\Database;
*/
trait ItemBaseTrait
{
- use InjectableTrait;
+ use SP\Core\Dic\InjectableTrait;
/**
* @var string
diff --git a/lib/SP/Mvc/Controller/ControllerTrait.php b/lib/SP/Mvc/Controller/ControllerTrait.php
index ef5d2083..b3469519 100644
--- a/lib/SP/Mvc/Controller/ControllerTrait.php
+++ b/lib/SP/Mvc/Controller/ControllerTrait.php
@@ -25,7 +25,7 @@
namespace SP\Mvc\Controller;
use Klein\Klein;
-use SP\Core\Context\SessionContext;
+use SP\Core\Context\ContextInterface;
use SP\Http\JsonResponse;
use SP\Http\Request;
use SP\Util\Checks;
@@ -53,12 +53,12 @@ trait ControllerTrait
/**
* Comprobar si la sesión está activa
*
- * @param SessionContext $session
- * @param Klein $router
+ * @param ContextInterface $context
+ * @param Klein $router
*/
- protected function checkLoggedInSession(SessionContext $session, Klein $router)
+ protected function checkLoggedInSession(ContextInterface $context, Klein $router)
{
- if (!$session->isLoggedIn()) {
+ if (!$context->isLoggedIn()) {
if (Checks::isJson($router)) {
$JsonResponse = new JsonResponse();
$JsonResponse->setDescription(__u('La sesión no se ha iniciado o ha caducado'));
@@ -71,12 +71,12 @@ trait ControllerTrait
}
/**
- * @param SessionContext $session
+ * @param ContextInterface $context
*/
- protected function checkSecurityToken(SessionContext $session)
+ protected function checkSecurityToken(ContextInterface $context)
{
$sk = Request::analyzeString('sk');
- $sessionKey = $session->getSecurityKey();
+ $sessionKey = $context->getSecurityKey();
if (!$sk || (null !== $sessionKey && $sessionKey !== $sk)) {
$this->invalidAction();
diff --git a/lib/SP/Mvc/View/Components/SelectItemAdapter.php b/lib/SP/Mvc/View/Components/SelectItemAdapter.php
index 37d539e8..5105b3da 100644
--- a/lib/SP/Mvc/View/Components/SelectItemAdapter.php
+++ b/lib/SP/Mvc/View/Components/SelectItemAdapter.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.
@@ -164,14 +164,17 @@ class SelectItemAdapter implements ItemAdapterInterface
* Returns a collection of items for a select component and set selected ones from an array
*
* @param array $selected
+ * @param bool $useValueAsKey
* @return SelectItem[]
*/
- public function getItemsFromArraySelected(array $selected)
+ public function getItemsFromArraySelected(array $selected, $useValueAsKey = false)
{
$items = $this->getItemsFromArray();
foreach ($items as $item) {
- if ($selected !== null && in_array($item->getId(), $selected, false)) {
+ if (($useValueAsKey === false && in_array($item->getId(), $selected, false))
+ || ($useValueAsKey === true && in_array($item->getName(), $selected, false))
+ ) {
$item->setSelected(true);
}
}
@@ -182,7 +185,7 @@ class SelectItemAdapter implements ItemAdapterInterface
/**
* Returns a collection of items for a select component
*
- * @return array
+ * @return SelectItem[]
*/
public function getItemsFromArray()
{
diff --git a/lib/SP/Providers/Auth/Database/Database.php b/lib/SP/Providers/Auth/Database/Database.php
index 96cc6726..49159e10 100644
--- a/lib/SP/Providers/Auth/Database/Database.php
+++ b/lib/SP/Providers/Auth/Database/Database.php
@@ -104,7 +104,7 @@ class Database implements AuthInterface
protected function authUser()
{
try {
- $userLoginResponse = $this->userService->getByLogin($this->userLoginData->getLoginUser());
+ $userLoginResponse = UserService::mapUserLoginResponse($this->userService->getByLogin($this->userLoginData->getLoginUser()));
$this->userLoginData->setUserLoginResponse($userLoginResponse);
diff --git a/lib/SP/Providers/EventsTrait.php b/lib/SP/Providers/EventsTrait.php
new file mode 100644
index 00000000..62d85362
--- /dev/null
+++ b/lib/SP/Providers/EventsTrait.php
@@ -0,0 +1,42 @@
+.
+ */
+
+namespace SP\Providers;
+
+/**
+ * Trait EventsTrait
+ *
+ * @package SP\Providers
+ */
+trait EventsTrait
+{
+ /**
+ * @param array $events
+ * @return mixed
+ */
+ protected function parseEventsToRegex(array $events)
+ {
+ return str_replace('.', '\\.', implode('|', $events));
+ }
+}
\ No newline at end of file
diff --git a/lib/SP/Providers/Log/LogHandler.php b/lib/SP/Providers/Log/LogHandler.php
index 40cd3437..200f5e52 100644
--- a/lib/SP/Providers/Log/LogHandler.php
+++ b/lib/SP/Providers/Log/LogHandler.php
@@ -27,6 +27,7 @@ namespace SP\Providers\Log;
use SP\Core\Events\Event;
use SP\Core\Events\EventReceiver;
use SP\DataModel\EventlogData;
+use SP\Providers\EventsTrait;
use SP\Providers\Provider;
use SP\Services\EventLog\EventlogService;
use SplSubject;
@@ -38,6 +39,8 @@ use SplSubject;
*/
class LogHandler extends Provider implements EventReceiver
{
+ use EventsTrait;
+
const EVENTS = [
'create.',
'delete.',
@@ -58,7 +61,8 @@ class LogHandler extends Provider implements EventReceiver
'update.',
'import.ldap.',
'run.',
- 'send.mail'
+ 'send.mail',
+ 'show.authToken'
];
/**
@@ -144,6 +148,12 @@ class LogHandler extends Provider implements EventReceiver
{
$this->eventlogService = $this->dic->get(EventlogService::class);
- $this->events = str_replace('.', '\\.', implode('|', self::EVENTS));
+ $configEvents = $this->config->getConfigData()->getLogEvents();
+
+ if (count($configEvents) === 0) {
+ $this->events = $this->parseEventsToRegex(self::EVENTS);
+ } else {
+ $this->events = $this->parseEventsToRegex($configEvents);
+ }
}
}
\ No newline at end of file
diff --git a/lib/SP/Providers/Mail/MailHandler.php b/lib/SP/Providers/Mail/MailHandler.php
index 557acf31..f9e9edf0 100644
--- a/lib/SP/Providers/Mail/MailHandler.php
+++ b/lib/SP/Providers/Mail/MailHandler.php
@@ -27,6 +27,7 @@ namespace SP\Providers\Mail;
use SP\Core\Events\Event;
use SP\Core\Events\EventReceiver;
use SP\Core\Messages\MailMessage;
+use SP\Providers\EventsTrait;
use SP\Providers\Provider;
use SP\Services\MailService;
use SP\Util\HttpUtil;
@@ -39,6 +40,8 @@ use SplSubject;
*/
class MailHandler extends Provider implements EventReceiver
{
+ use EventsTrait;
+
const EVENTS = [
'create.',
'delete.',
@@ -80,7 +83,7 @@ class MailHandler extends Provider implements EventReceiver
if (($eventMessage = $event->getEventMessage()) !== null) {
try {
$configData = $this->config->getConfigData();
- $userData = $this->session->getUserData();
+ $userData = $this->context->getUserData();
$mailMessage = new MailMessage();
$mailMessage->addDescription($eventMessage->composeText());
@@ -133,6 +136,12 @@ class MailHandler extends Provider implements EventReceiver
{
$this->mailService = $this->dic->get(MailService::class);
- $this->events = str_replace('.', '\\.', implode('|', self::EVENTS));
+ $configEvents = $this->config->getConfigData()->getMailEvents();
+
+ if (count($configEvents) === 0) {
+ $this->events = $this->parseEventsToRegex(self::EVENTS);
+ } else {
+ $this->events = $this->parseEventsToRegex($configEvents);
+ }
}
}
\ No newline at end of file
diff --git a/lib/SP/Providers/Provider.php b/lib/SP/Providers/Provider.php
index c6e559e5..ff803bfd 100644
--- a/lib/SP/Providers/Provider.php
+++ b/lib/SP/Providers/Provider.php
@@ -27,7 +27,7 @@ namespace SP\Providers;
use DI\Container;
use Psr\Container\ContainerInterface;
use SP\Config\Config;
-use SP\Core\Context\SessionContext;
+use SP\Core\Context\ContextInterface;
use SP\Core\Events\EventDispatcher;
/**
@@ -44,9 +44,9 @@ abstract class Provider
*/
protected $config;
/**
- * @var SessionContext
+ * @var ContextInterface
*/
- protected $session;
+ protected $context;
/**
* @var EventDispatcher
*/
@@ -67,7 +67,7 @@ abstract class Provider
{
$this->dic = $dic;
$this->config = $dic->get(Config::class);
- $this->session = $dic->get(SessionContext::class);
+ $this->context = $dic->get(ContextInterface::class);
$this->eventDispatcher = $dic->get(EventDispatcher::class);
if (method_exists($this, 'initialize')) {
diff --git a/lib/SP/Repositories/Account/AccountHistoryRepository.php b/lib/SP/Repositories/Account/AccountHistoryRepository.php
index be48e39c..5f565a7c 100644
--- a/lib/SP/Repositories/Account/AccountHistoryRepository.php
+++ b/lib/SP/Repositories/Account/AccountHistoryRepository.php
@@ -99,7 +99,7 @@ class AccountHistoryRepository extends Repository implements RepositoryItemInter
$queryData->setSelect('AH.id, AH.name, AH.login, AH.pass, AH.key, AH.parentId');
$queryData->setFrom('AccountHistory AH');
- $queryWhere = AccountUtil::getAccountHistoryFilterUser($this->session);
+ $queryWhere = AccountUtil::getAccountHistoryFilterUser($this->context);
$queryWhere[] = 'AH.id = ?';
$queryData->addParam($id);
diff --git a/lib/SP/Repositories/Account/AccountRepository.php b/lib/SP/Repositories/Account/AccountRepository.php
index 6b7b31c6..71c0a295 100644
--- a/lib/SP/Repositories/Account/AccountRepository.php
+++ b/lib/SP/Repositories/Account/AccountRepository.php
@@ -78,7 +78,7 @@ class AccountRepository extends Repository implements RepositoryItemInterface
*/
public function getPasswordForId($id)
{
- $queryFilter = AccountUtil::getAccountFilterUser($this->session)
+ $queryFilter = AccountUtil::getAccountFilterUser($this->context)
->addFilter('A.id = ?', [$id]);
$queryData = new QueryData();
@@ -286,7 +286,7 @@ class AccountRepository extends Repository implements RepositoryItemInterface
$Data = new QueryData();
$Data->setQuery($query);
$Data->addParam($historyId, 'id');
- $Data->addParam($this->session->getUserData()->getId(), 'userEditId');
+ $Data->addParam($this->context->getUserData()->getId(), 'userEditId');
$Data->setOnErrorMessage(__u('Error al restaurar cuenta'));
return DbWrapper::getQuery($Data, $this->db);
@@ -623,7 +623,7 @@ class AccountRepository extends Repository implements RepositoryItemInterface
$where[] = $queryFilterSelect->getFilters();
}
- $queryFilterUser = AccountUtil::getAccountFilterUser($this->session, $accountSearchFilter->getGlobalSearch());
+ $queryFilterUser = AccountUtil::getAccountFilterUser($this->context, $accountSearchFilter->getGlobalSearch());
if ($queryFilterUser->hasFilters()) {
$where[] = $queryFilterUser->getFilters();
@@ -633,7 +633,7 @@ class AccountRepository extends Repository implements RepositoryItemInterface
if ($accountSearchFilter->isSearchFavorites() === true) {
$join['query'][] = 'INNER JOIN AccountToFavorite AF ON (AF.accountId = A.id AND AF.userId = ?)';
- $join['param'][] = $this->session->getUserData()->getId();
+ $join['param'][] = $this->context->getUserData()->getId();
}
$queryData = new QueryData();
diff --git a/lib/SP/Repositories/AuthToken/AuthTokenRepository.php b/lib/SP/Repositories/AuthToken/AuthTokenRepository.php
index cf1bea9b..56edf1da 100644
--- a/lib/SP/Repositories/AuthToken/AuthTokenRepository.php
+++ b/lib/SP/Repositories/AuthToken/AuthTokenRepository.php
@@ -415,7 +415,7 @@ class AuthTokenRepository extends Repository implements RepositoryItemInterface
public function getTokenByToken($actionId, $token)
{
$query = /** @lang SQL */
- 'SELECT userId, vault, `hash`
+ 'SELECT actionId, userId, vault, `hash`
FROM AuthToken
WHERE actionId = ?
AND token = ? LIMIT 1';
diff --git a/lib/SP/Repositories/Repository.php b/lib/SP/Repositories/Repository.php
index 1d8eaed8..9f824412 100644
--- a/lib/SP/Repositories/Repository.php
+++ b/lib/SP/Repositories/Repository.php
@@ -25,7 +25,7 @@
namespace SP\Repositories;
use SP\Config\Config;
-use SP\Core\Context\SessionContext;
+use SP\Core\Context\ContextInterface;
use SP\Core\Dic\Container;
use SP\Core\Events\EventDispatcher;
use SP\Storage\Database;
@@ -43,9 +43,9 @@ abstract class Repository
*/
protected $config;
/**
- * @var SessionContext
+ * @var ContextInterface
*/
- protected $session;
+ protected $context;
/**
* @var EventDispatcher
*/
@@ -62,20 +62,18 @@ abstract class Repository
/**
* Repository constructor.
*
- * @param Container $dic
- * @param Config $config
- * @param Database $database
- * @param SessionContext $session
- * @param EventDispatcher $eventDispatcher
- * @throws \Psr\Container\ContainerExceptionInterface
- * @throws \Psr\Container\NotFoundExceptionInterface
+ * @param Container $dic
+ * @param Config $config
+ * @param Database $database
+ * @param ContextInterface $session
+ * @param EventDispatcher $eventDispatcher
*/
- final public function __construct(Container $dic, Config $config, Database $database, SessionContext $session, EventDispatcher $eventDispatcher)
+ final public function __construct(Container $dic, Config $config, Database $database, ContextInterface $session, EventDispatcher $eventDispatcher)
{
$this->dic = $dic;
$this->config = $config;
$this->db = $database;
- $this->session = $session;
+ $this->context = $session;
$this->eventDispatcher = $eventDispatcher;
if (method_exists($this, 'initialize')) {
diff --git a/lib/SP/Repositories/User/UserRepository.php b/lib/SP/Repositories/User/UserRepository.php
index ed6f9570..244cf652 100644
--- a/lib/SP/Repositories/User/UserRepository.php
+++ b/lib/SP/Repositories/User/UserRepository.php
@@ -382,7 +382,7 @@ class UserRepository extends Repository implements RepositoryItemInterface
$queryData->setOrder('U.name');
if ($SearchData->getSeachString() !== '') {
- if ($this->session->getUserData()->getIsAdminApp()) {
+ if ($this->context->getUserData()->getIsAdminApp()) {
$queryData->setWhere('U.name LIKE ? OR U.login LIKE ?');
} else {
$queryData->setWhere('U.name LIKE ? OR U.login LIKE ? AND U.isAdminApp = 0');
@@ -391,7 +391,7 @@ class UserRepository extends Repository implements RepositoryItemInterface
$search = '%' . $SearchData->getSeachString() . '%';
$queryData->addParam($search);
$queryData->addParam($search);
- } elseif (!$this->session->getUserData()->getIsAdminApp()) {
+ } elseif (!$this->context->getUserData()->getIsAdminApp()) {
$queryData->setWhere('U.isAdminApp = 0');
}
diff --git a/lib/SP/Services/Account/AccountAclService.php b/lib/SP/Services/Account/AccountAclService.php
index 1b793509..14c83121 100644
--- a/lib/SP/Services/Account/AccountAclService.php
+++ b/lib/SP/Services/Account/AccountAclService.php
@@ -88,7 +88,7 @@ class AccountAclService extends Service
{
$this->accountAcl = new AccountAcl($actionId, $isHistory);
- $this->accountAcl->showPermission = self::getShowPermission($this->session->getUserData(), $this->session->getUserProfile());
+ $this->accountAcl->showPermission = self::getShowPermission($this->context->getUserData(), $this->context->getUserProfile());
if ($accountAclDto !== null) {
$this->accountAclDto = $accountAclDto;
@@ -149,7 +149,7 @@ class AccountAclService extends Service
*/
public function getCacheFileForAcl($accountId, $actionId)
{
- $userId = $this->session->getUserData()->getId();
+ $userId = $this->context->getUserData()->getId();
return self::ACL_PATH . $userId . DIRECTORY_SEPARATOR . $accountId . DIRECTORY_SEPARATOR . md5($userId . $accountId . $actionId) . '.cache';
}
@@ -196,7 +196,7 @@ class AccountAclService extends Service
*/
protected function compileAccountAccess()
{
- $userData = $this->session->getUserData();
+ $userData = $this->context->getUserData();
if ($userData->getIsAdminApp()
|| $userData->getIsAdminAcc()
@@ -229,7 +229,7 @@ class AccountAclService extends Service
*/
protected function getIsUserInGroups()
{
- $userData = $this->session->getUserData();
+ $userData = $this->context->getUserData();
$userToUserGroupService = $this->dic->get(UserToUserGroupService::class);
// Comprobar si el usuario está vinculado desde el grupo principal de la cuenta
diff --git a/lib/SP/Services/Account/AccountCryptService.php b/lib/SP/Services/Account/AccountCryptService.php
index a748888b..b93636e8 100644
--- a/lib/SP/Services/Account/AccountCryptService.php
+++ b/lib/SP/Services/Account/AccountCryptService.php
@@ -26,14 +26,14 @@ namespace SP\Services\Account;
use Defuse\Crypto\Exception\CryptoException;
use SP\Core\Crypt\Crypt;
+use SP\Core\Crypt\OldCrypt;
use SP\Core\Events\Event;
use SP\Core\Events\EventMessage;
use SP\Core\Exceptions\SPException;
-use SP\Core\OldCrypt;
-use SP\Core\TaskFactory;
use SP\Services\Crypt\UpdateMasterPassRequest;
use SP\Services\Service;
use SP\Services\ServiceException;
+use SP\Services\Task\TaskFactory;
use SP\Util\Util;
/**
diff --git a/lib/SP/Services/Account/AccountFileService.php b/lib/SP/Services/Account/AccountFileService.php
index 9f82ad8b..bc94506b 100644
--- a/lib/SP/Services/Account/AccountFileService.php
+++ b/lib/SP/Services/Account/AccountFileService.php
@@ -25,7 +25,6 @@
namespace SP\Services\Account;
use SP\Core\Exceptions\SPException;
-use SP\Core\Traits\InjectableTrait;
use SP\DataModel\FileData;
use SP\DataModel\FileExtData;
use SP\DataModel\ItemSearchData;
@@ -42,8 +41,6 @@ use SP\Util\ImageUtil;
*/
class AccountFileService extends Service
{
- use InjectableTrait;
-
/**
* @var AccountFileRepository
*/
diff --git a/lib/SP/Services/Account/AccountSearchService.php b/lib/SP/Services/Account/AccountSearchService.php
index 11732e99..ea923b82 100644
--- a/lib/SP/Services/Account/AccountSearchService.php
+++ b/lib/SP/Services/Account/AccountSearchService.php
@@ -59,7 +59,7 @@ class AccountSearchService extends Service
* Cache expire time
*/
const CACHE_EXPIRE = 86400;
-
+
/**
* Colores para resaltar las cuentas
*/
@@ -130,8 +130,8 @@ class AccountSearchService extends Service
// Variables de configuración
$maxTextLength = $this->configData->isResultsAsCards() ? 40 : 60;
- $accountLinkEnabled = $this->session->getUserData()->getPreferences()->isAccountLink() || $this->configData->isAccountLink();
- $favorites = $this->dic->get(AccountFavoriteService::class)->getForUserId($this->session->getUserData()->getId());
+ $accountLinkEnabled = $this->context->getUserData()->getPreferences()->isAccountLink() || $this->configData->isAccountLink();
+ $favorites = $this->dic->get(AccountFavoriteService::class)->getForUserId($this->context->getUserData()->getId());
$accountAclService = $this->dic->get(AccountAclService::class);
@@ -256,7 +256,7 @@ class AccountSearchService extends Service
return [
'type' => 'private',
'query' => '(A.isPrivate = 1 AND A.userId = ?) OR (A.isPrivateGroup = 1 AND A.userGroupId = ?)',
- 'values' => [$this->session->getUserData()->getId(), $this->session->getUserData()->getUserGroupId()]
+ 'values' => [$this->context->getUserData()->getId(), $this->context->getUserData()->getUserGroupId()]
];
break;
default:
@@ -275,7 +275,7 @@ class AccountSearchService extends Service
$accountId = $accountSearchData->getId();
/** @var AccountCache[] $cache */
- $cache =& $_SESSION['accountsCache'];
+ $cache = $this->context->getAccountsCache();
if (!isset($cache[$accountId])
|| $cache[$accountId]->getTime() < (int)strtotime($accountSearchData->getDateEdit())
@@ -284,6 +284,8 @@ class AccountSearchService extends Service
$accountId,
$this->accountToUserRepository->getUsersByAccountId($accountId),
$this->accountToUserGroupRepository->getUserGroupsByAccountId($accountId));
+
+ $this->context->setAccountsCache($cache);
}
return $cache[$accountId];
diff --git a/lib/SP/Services/Account/AccountService.php b/lib/SP/Services/Account/AccountService.php
index b2a3aa3f..6263e90d 100644
--- a/lib/SP/Services/Account/AccountService.php
+++ b/lib/SP/Services/Account/AccountService.php
@@ -26,6 +26,7 @@ namespace SP\Services\Account;
use Defuse\Crypto\Exception\CryptoException;
use SP\Account\AccountRequest;
+use SP\Account\AccountSearchFilter;
use SP\Account\AccountUtil;
use SP\Core\Crypt\Crypt;
use SP\Core\Crypt\Session as CryptSession;
@@ -33,6 +34,7 @@ use SP\Core\Exceptions\QueryException;
use SP\Core\Exceptions\SPException;
use SP\DataModel\AccountData;
use SP\DataModel\Dto\AccountDetailsResponse;
+use SP\DataModel\Dto\AccountSearchResponse;
use SP\DataModel\ItemSearchData;
use SP\Repositories\Account\AccountRepository;
use SP\Repositories\Account\AccountToTagRepository;
@@ -166,8 +168,8 @@ class AccountService extends Service implements AccountServiceInterface
*/
public function create(AccountRequest $accountRequest)
{
- $accountRequest->changePermissions = AccountAclService::getShowPermission($this->session->getUserData(), $this->session->getUserProfile());
- $accountRequest->userGroupId = $accountRequest->userGroupId ?: $this->session->getUserData()->getUserGroupId();
+ $accountRequest->changePermissions = AccountAclService::getShowPermission($this->context->getUserData(), $this->context->getUserProfile());
+ $accountRequest->userGroupId = $accountRequest->userGroupId ?: $this->context->getUserData()->getUserGroupId();
$pass = $this->getPasswordEncrypted($accountRequest->pass);
@@ -191,7 +193,7 @@ class AccountService extends Service implements AccountServiceInterface
public function getPasswordEncrypted($pass, $masterPass = null)
{
try {
- $masterPass = $masterPass ?: CryptSession::getSessionKey();
+ $masterPass = $masterPass ?: CryptSession::getSessionKey($this->context);
$out['key'] = Crypt::makeSecuredKey($masterPass);
$out['pass'] = Crypt::encrypt($pass, $out['key'], $masterPass);
@@ -245,11 +247,11 @@ class AccountService extends Service implements AccountServiceInterface
*/
public function update(AccountRequest $accountRequest)
{
- $accountRequest->changePermissions = AccountAclService::getShowPermission($this->session->getUserData(), $this->session->getUserProfile());
+ $accountRequest->changePermissions = AccountAclService::getShowPermission($this->context->getUserData(), $this->context->getUserProfile());
// Cambiar el grupo principal si el usuario es Admin
$accountRequest->changeUserGroup = ($accountRequest->userGroupId !== 0
- && ($this->session->getUserData()->getIsAdminApp() || $this->session->getUserData()->getIsAdminAcc()));
+ && ($this->context->getUserData()->getIsAdminApp() || $this->context->getUserData()->getIsAdminAcc()));
$this->addHistory($accountRequest->id);
@@ -400,7 +402,7 @@ class AccountService extends Service implements AccountServiceInterface
*/
public function getForUser($accountId = null)
{
- $queryFilter = AccountUtil::getAccountFilterUser($this->session);
+ $queryFilter = AccountUtil::getAccountFilterUser($this->context);
if (null !== $accountId) {
$queryFilter->addFilter('A.id <> ? AND (A.parentId = 0 OR A.parentId IS NULL)', [$accountId]);
@@ -415,7 +417,7 @@ class AccountService extends Service implements AccountServiceInterface
*/
public function getLinked($accountId)
{
- $queryFilter = AccountUtil::getAccountFilterUser($this->session)
+ $queryFilter = AccountUtil::getAccountFilterUser($this->context)
->addFilter('A.parentId = ?', [$accountId]);
return $this->accountRepository->getLinked($queryFilter);
@@ -427,7 +429,7 @@ class AccountService extends Service implements AccountServiceInterface
*/
public function getPasswordHistoryForId($id)
{
- $queryFilter = AccountUtil::getAccountHistoryFilterUser($this->session)
+ $queryFilter = AccountUtil::getAccountHistoryFilterUser($this->context)
->addFilter('AH.id = ?', [$id]);
return $this->accountRepository->getPasswordHistoryForId($queryFilter);
@@ -481,4 +483,15 @@ class AccountService extends Service implements AccountServiceInterface
{
return $this->accountRepository->getAccountsPassData();
}
+
+ /**
+ * Obtener las cuentas de una búsqueda.
+ *
+ * @param AccountSearchFilter $accountSearchFilter
+ * @return AccountSearchResponse
+ */
+ public function getByFilter(AccountSearchFilter $accountSearchFilter)
+ {
+ return $this->accountRepository->getByFilter($accountSearchFilter);
+ }
}
\ No newline at end of file
diff --git a/lib/SP/Services/Api/ApiService.php b/lib/SP/Services/Api/ApiService.php
new file mode 100644
index 00000000..c5499ae7
--- /dev/null
+++ b/lib/SP/Services/Api/ApiService.php
@@ -0,0 +1,324 @@
+.
+ */
+
+namespace SP\Services\Api;
+
+use Defuse\Crypto\Exception\CryptoException;
+use SP\Core\Acl\ActionsInterface;
+use SP\Core\Crypt\Hash;
+use SP\Core\Crypt\Vault;
+use SP\DataModel\AuthTokenData;
+use SP\Html\Html;
+use SP\Repositories\Track\TrackRequest;
+use SP\Services\Auth\AuthException;
+use SP\Services\AuthToken\AuthTokenService;
+use SP\Services\Service;
+use SP\Services\ServiceException;
+use SP\Services\Track\TrackService;
+use SP\Services\User\UserService;
+
+/**
+ * Class ApiService
+ *
+ * @package SP\Services\ApiService
+ */
+class ApiService extends Service
+{
+ /**
+ * @var AuthTokenService
+ */
+ protected $authTokenService;
+ /**
+ * @var TrackService
+ */
+ protected $trackService;
+ /**
+ * @var mixed
+ */
+ protected $requestData;
+ /**
+ * @var TrackRequest
+ */
+ protected $trackRequest;
+ /**
+ * @var AuthTokenData
+ */
+ protected $authTokenData;
+ /**
+ * @var bool
+ */
+ protected $passIsNeeded = false;
+
+ /**
+ * Obtener los datos de la petición
+ *
+ * Comprueba que el JSON esté bien formado
+ *
+ * @throws ServiceException
+ */
+ public static function getRequestData()
+ {
+ $request = file_get_contents('php://input');
+ $data = json_decode(Html::sanitize($request));
+
+ if (!is_object($data) || json_last_error() !== JSON_ERROR_NONE) {
+ throw new ServiceException(__u('Datos inválidos'), ServiceException::WARNING, null, -32700);
+ }
+
+ if (!isset($data->jsonrpc, $data->method, $data->params, $data->id, $data->params->authToken)) {
+ throw new ServiceException(__u('Formato incorrecto'), ServiceException::WARNING, null, -32600);
+ }
+
+ if (!isset($data->params->authToken)) {
+ throw new ServiceException(__u('Formato incorrecto'), ServiceException::WARNING, null, -32602);
+ }
+
+ return $data;
+ }
+
+ /**
+ * @param $actionId
+ * @throws ServiceException
+ * @throws \Exception
+ */
+ public function authenticate($actionId)
+ {
+ if ($this->trackService->checkTracking($this->trackRequest)) {
+ $this->addTracking();
+
+ throw new ServiceException(
+ __u('Intentos excedidos'),
+ AuthException::INFO,
+ null,
+ -32601
+ );
+ }
+
+ if (($this->authTokenData = $this->authTokenService->getTokenByToken($actionId, $this->getParam('authToken'))) === false
+ || $this->authTokenData->getActionId() !== $actionId
+ ) {
+ $this->addTracking();
+
+ throw new ServiceException(__u('Acceso no permitido'));
+ }
+
+ $this->context->setUserData(UserService::mapUserLoginResponse($this->dic->get(UserService::class)->getById($this->authTokenData->getUserId())));
+
+ $this->passIsNeeded = $actionId === ActionsInterface::ACCOUNT_VIEW_PASS
+ || $actionId === ActionsInterface::ACCOUNT_CREATE;
+ }
+
+ /**
+ * Añadir un seguimiento
+ *
+ * @throws ServiceException
+ */
+ private function addTracking()
+ {
+ try {
+ $this->trackService->add($this->trackRequest);
+ } catch (\Exception $e) {
+ throw new ServiceException(
+ __u('Error interno'),
+ ServiceException::ERROR,
+ null,
+ -32601
+ );
+ }
+ }
+
+ /**
+ * Devolver el valor de un parámetro
+ *
+ * @param string $param
+ * @param bool $required Si es requerido
+ * @param mixed $default Valor por defecto
+ * @return int|string
+ * @throws ServiceException
+ */
+ public function getParam($param, $required = false, $default = null)
+ {
+ if (null !== $this->requestData
+ && isset($this->requestData->params->{$param})
+ ) {
+ return $this->requestData->params->{$param};
+ } elseif ($required === true) {
+ throw new ServiceException(__u('Parámetros incorrectos'), ServiceException::ERROR, $this->getHelp($this->requestData->method), -32602);
+ }
+
+ return $default;
+ }
+
+ /**
+ * Devuelve la ayuda para una acción
+ *
+ * @param string $action
+ * @return array
+ */
+ public function getHelp($action)
+ {
+ return $this->getActions()[$action]['help'];
+ }
+
+ /**
+ * Devuelve las acciones que implementa la API
+ *
+ * @return array
+ */
+ public function getActions()
+ {
+ return [
+ 'getAccountPassword' => [
+ 'help' => [
+ 'id' => __('Id de la cuenta'),
+ 'tokenPass' => __('Clave del token'),
+ 'details' => __('Devolver detalles en la respuesta')
+ ]
+ ],
+ 'getAccountSearch' => [
+ 'help' => [
+ 'text' => __('Texto a buscar'),
+ 'count' => __('Número de resultados a mostrar'),
+ 'categoryId' => __('Id de categoría a filtrar'),
+ 'customerId' => __('Id de cliente a filtrar')
+ ]
+ ],
+ 'getAccountData' => [
+ 'help' => [
+ 'id' => __('Id de la cuenta')
+ ]
+ ],
+ 'deleteAccount' => [
+ 'help' => [
+ 'id' => __('Id de la cuenta')
+ ]
+ ],
+ 'addAccount' => [
+ 'help' => [
+ 'tokenPass' => __('Clave del token'),
+ 'name' => __('Nombre de cuenta'),
+ 'categoryId' => __('Id de categoría'),
+ 'customerId' => __('Id de cliente'),
+ 'pass' => __('Clave'),
+ 'login' => __('Usuario de acceso'),
+ 'url' => __('URL o IP de acceso'),
+ 'notes' => __('Notas sobre la cuenta')
+ ]
+ ],
+ 'backup' => [
+ 'help' => ''
+ ],
+ 'getCategories' => [
+ 'help' => [
+ 'name' => __('Nombre de categoría a buscar'),
+ 'count' => __('Número de resultados a mostrar')
+ ]
+ ],
+ 'addCategory' => [
+ 'help' => [
+ 'name' => __('Nombre de la categoría'),
+ 'description' => __('Descripción de la categoría')
+ ]
+ ],
+ 'deleteCategory' => [
+ 'help' => [
+ 'id' => __('Id de categoría')
+ ]
+ ],
+ 'getCustomers' => [
+ 'help' => [
+ 'name' => __('Nombre de cliente a buscar'),
+ 'count' => __('Número de resultados a mostrar')
+ ]
+ ],
+ 'addCustomer' => [
+ 'help' => [
+ 'name' => __('Nombre del cliente'),
+ 'description' => __('Descripción del cliente')
+ ]
+ ],
+ 'deleteCustomer' => [
+ 'help' => [
+ 'id' => __('Id de cliente')
+ ]
+ ]
+ ];
+ }
+
+ /**
+ * @param mixed $requestData
+ */
+ public function setRequestData($requestData)
+ {
+ $this->requestData = $requestData;
+ }
+
+ /**
+ * @throws \SP\Core\Exceptions\InvalidArgumentException
+ */
+ protected function initialize()
+ {
+ $this->authTokenService = $this->dic->get(AuthTokenService::class);
+ $this->trackService = $this->dic->get(TrackService::class);
+ $this->trackRequest = TrackService::getTrackRequest('api');
+ }
+
+ /**
+ * Realizar la autentificación del usuario
+ *
+ * @throws ServiceException
+ */
+ protected function doAuth()
+ {
+ if ($this->context->getUserData()->getIsDisabled()
+ || !Hash::checkHashKey($this->getParam('tokenPass', true), $this->authTokenData->getHash())
+ ) {
+ $this->addTracking();
+
+ throw new ServiceException(__u('Acceso no permitido'), ServiceException::ERROR);
+ }
+ }
+
+ /**
+ * Devolver la clave maestra
+ *
+ * @return string
+ * @throws ServiceException
+ */
+ private function getMasterPass()
+ {
+ try {
+ /** @var Vault $vault */
+ $vault = unserialize($this->authTokenData->getVault());
+
+ if ($vault && ($pass = $vault->getData($this->getParam('tokenPass') . $this->getParam('authToken')))) {
+ return $pass;
+ } else {
+ throw new ServiceException(__u('Error interno'), ServiceException::ERROR, __u('Datos inválidos'));
+ }
+ } catch (CryptoException $e) {
+ throw new ServiceException(__u('Error interno'), ServiceException::ERROR, $e->getMessage());
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/SP/Services/ApiService/ApiService.php b/lib/SP/Services/ApiService/ApiService.php
deleted file mode 100644
index a2a9f30f..00000000
--- a/lib/SP/Services/ApiService/ApiService.php
+++ /dev/null
@@ -1,102 +0,0 @@
-.
- */
-
-namespace SP\Services\ApiService;
-
-use SP\Services\Auth\AuthException;
-use SP\Services\AuthToken\AuthTokenService;
-use SP\Services\Service;
-use SP\Services\ServiceException;
-use SP\Services\Track\TrackService;
-
-/**
- * Class ApiService
- * @package SP\Services\ApiService
- */
-class ApiService extends Service
-{
- /**
- * @var AuthTokenService
- */
- protected $authTokenService;
- /**
- * @var TrackService
- */
- protected $trackService;
-
- /**
- * @param $actionId
- * @param $authToken
- * @throws ServiceException
- * @throws AuthException
- */
- public function authenticate($actionId, $authToken)
- {
- if (($authToken = $this->authTokenService->getTokenByToken($actionId, $authToken)) === false) {
- $this->addTracking();
-
- throw new ServiceException(__u('Acceso no permitido'));
- }
-
-
-// $this->data = $data;
-//
-// $this->userId = $this->ApiTokenData->getUserId();
-//
-// $this->loadUserData();
-//
-// if ($this->passIsNeeded()) {
-// $this->doAuth();
-// }
-//
-// SessionFactory::setSessionType(SessionFactory::SESSION_API);
-//
-// $this->Log = new Log();
- }
-
- /**
- * Añadir un seguimiento
- *
- * @throws AuthException
- */
- protected function addTracking()
- {
- try {
- $this->trackService->add(TrackService::getTrackRequest('api'));
- } catch (\Exception $e) {
- throw new AuthException(
- __u('Error interno'),
- AuthException::ERROR,
- null,
- -32601
- );
- }
- }
-
- protected function initialize()
- {
- $this->authTokenService = $this->dic->get(AuthTokenService::class);
- $this->trackService = $this->dic->get(TrackService::class);
- }
-}
\ No newline at end of file
diff --git a/lib/SP/Services/Auth/LoginService.php b/lib/SP/Services/Auth/LoginService.php
index 905a9a9c..05993c5f 100644
--- a/lib/SP/Services/Auth/LoginService.php
+++ b/lib/SP/Services/Auth/LoginService.php
@@ -366,8 +366,8 @@ class LoginService extends Service
$this->userService->updateLastLoginById($userLoginResponse->getId());
// Cargar las variables de ussuario en la sesión
- $this->session->setUserData($userLoginResponse);
- $this->session->setUserProfile($this->dic->get(UserProfileService::class)->getById($userLoginResponse->getUserProfileId())->getProfile());
+ $this->context->setUserData($userLoginResponse);
+ $this->context->setUserProfile($this->dic->get(UserProfileService::class)->getById($userLoginResponse->getUserProfileId())->getProfile());
if ($this->configData->isDemoEnabled()) {
$userLoginResponse->setPreferences(new UserPreferencesData());
@@ -387,7 +387,7 @@ class LoginService extends Service
$this->theme->initTheme(true);
- $this->session->setAuthCompleted(true);
+ $this->context->setAuthCompleted(true);
$this->eventDispatcher->notifyEvent('login.preferences.load', new Event($this));
}
diff --git a/lib/SP/Services/AuthToken/AuthTokenService.php b/lib/SP/Services/AuthToken/AuthTokenService.php
index d5d93ff2..30773149 100644
--- a/lib/SP/Services/AuthToken/AuthTokenService.php
+++ b/lib/SP/Services/AuthToken/AuthTokenService.php
@@ -145,7 +145,7 @@ class AuthTokenService extends Service
}
$authTokenData->setToken($token);
- $authTokenData->setCreatedBy($this->session->getUserData()->getId());
+ $authTokenData->setCreatedBy($this->context->getUserData()->getId());
}
/**
@@ -170,7 +170,7 @@ class AuthTokenService extends Service
private function getSecureData($token, $hash)
{
$Vault = new Vault();
- $Vault->saveData(CryptSession::getSessionKey(), $hash . $token);
+ $Vault->saveData(CryptSession::getSessionKey($this->context), $hash . $token);
return $Vault;
}
diff --git a/lib/SP/Services/Client/ClientService.php b/lib/SP/Services/Client/ClientService.php
index 9140c31f..0933b8d2 100644
--- a/lib/SP/Services/Client/ClientService.php
+++ b/lib/SP/Services/Client/ClientService.php
@@ -148,7 +148,7 @@ class ClientService extends Service
*/
public function getAllForUser()
{
- return $this->clientRepository->getAllForFilter(AccountUtil::getAccountFilterUser($this->session));
+ return $this->clientRepository->getAllForFilter(AccountUtil::getAccountFilterUser($this->context));
}
/**
diff --git a/lib/SP/Services/Config/ConfigBackupService.php b/lib/SP/Services/Config/ConfigBackupService.php
index a5852620..e8b6c088 100644
--- a/lib/SP/Services/Config/ConfigBackupService.php
+++ b/lib/SP/Services/Config/ConfigBackupService.php
@@ -45,7 +45,7 @@ class ConfigBackupService extends Service
public function backup()
{
try {
- $this->configService->save('config_backup', json_encode($this->config->getConfigData()));
+ $this->configService->save('config_backup', bin2hex(gzcompress(serialize($this->config->getConfigData()))));
$this->configService->save('config_backup_date', time());
} catch (\Exception $e) {
processException($e);
diff --git a/lib/SP/Services/Config/ConfigService.php b/lib/SP/Services/Config/ConfigService.php
index e2fd349f..4b450384 100644
--- a/lib/SP/Services/Config/ConfigService.php
+++ b/lib/SP/Services/Config/ConfigService.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.
@@ -26,8 +26,6 @@ namespace SP\Services\Config;
use SP\Core\Exceptions\ConstraintException;
use SP\Core\Exceptions\QueryException;
-use SP\Core\Exceptions\SPException;
-use SP\Core\Traits\InjectableTrait;
use SP\DataModel\ConfigData;
use SP\DataModel\Dto\ConfigRequest;
use SP\Repositories\Config\ConfigRepository;
@@ -41,22 +39,11 @@ use SP\Services\ServiceException;
*/
class ConfigService extends Service
{
- use InjectableTrait;
-
/**
* @var ConfigRepository
*/
protected $configRepository;
- /**
- * @throws \Psr\Container\ContainerExceptionInterface
- * @throws \Psr\Container\NotFoundExceptionInterface
- */
- protected function initialize()
- {
- $this->configRepository = $this->dic->get(ConfigRepository::class);
- }
-
/**
* @param string $param
* @param null $default
@@ -74,7 +61,7 @@ class ConfigService extends Service
throw new ParameterNotFoundException(
sprintf(__('Parámetro no encontrado (%s)'),
- SPException::ERROR,
+ ParameterNotFoundException::ERROR,
$param)
);
}
@@ -150,4 +137,13 @@ class ConfigService extends Service
{
return $this->configRepository->deleteByParam($param);
}
+
+ /**
+ * @throws \Psr\Container\ContainerExceptionInterface
+ * @throws \Psr\Container\NotFoundExceptionInterface
+ */
+ protected function initialize()
+ {
+ $this->configRepository = $this->dic->get(ConfigRepository::class);
+ }
}
\ No newline at end of file
diff --git a/lib/SP/Services/Crypt/TemporaryMasterPassService.php b/lib/SP/Services/Crypt/TemporaryMasterPassService.php
index f7f1792c..d2a409ca 100644
--- a/lib/SP/Services/Crypt/TemporaryMasterPassService.php
+++ b/lib/SP/Services/Crypt/TemporaryMasterPassService.php
@@ -75,7 +75,7 @@ class TemporaryMasterPassService extends Service
$this->configService->save('tempmaster_attempts', 0);
// Guardar la clave temporal hasta que finalice la sesión
- $this->session->setTemporaryMasterPass($randomKey);
+ $this->context->setTemporaryMasterPass($randomKey);
$this->eventDispatcher->notifyEvent('create.tempMasterPassword',
new Event($this, EventMessage::factory()
diff --git a/lib/SP/Services/Crypt/UpdateMasterPassRequest.php b/lib/SP/Services/Crypt/UpdateMasterPassRequest.php
index d38708ba..156b4265 100644
--- a/lib/SP/Services/Crypt/UpdateMasterPassRequest.php
+++ b/lib/SP/Services/Crypt/UpdateMasterPassRequest.php
@@ -25,7 +25,7 @@
namespace SP\Services\Crypt;
use SP\Core\Crypt\Hash;
-use SP\Core\Task;
+use SP\Services\Task\Task;
/**
diff --git a/lib/SP/Services/CustomField/CustomFieldCryptService.php b/lib/SP/Services/CustomField/CustomFieldCryptService.php
index 2989539e..e2dacb0d 100644
--- a/lib/SP/Services/CustomField/CustomFieldCryptService.php
+++ b/lib/SP/Services/CustomField/CustomFieldCryptService.php
@@ -27,14 +27,14 @@ namespace SP\Services\CustomField;
defined('APP_ROOT') || die();
use SP\Core\Crypt\Crypt;
+use SP\Core\Crypt\OldCrypt;
use SP\Core\Events\Event;
use SP\Core\Events\EventMessage;
-use SP\Core\OldCrypt;
-use SP\Core\TaskFactory;
use SP\DataModel\CustomFieldData;
use SP\Services\Crypt\UpdateMasterPassRequest;
use SP\Services\Service;
use SP\Services\ServiceException;
+use SP\Services\Task\TaskFactory;
/**
* Class CustomFieldCryptService
diff --git a/lib/SP/Services/CustomField/CustomFieldService.php b/lib/SP/Services/CustomField/CustomFieldService.php
index 551aa8de..69e0e477 100644
--- a/lib/SP/Services/CustomField/CustomFieldService.php
+++ b/lib/SP/Services/CustomField/CustomFieldService.php
@@ -25,6 +25,7 @@
namespace SP\Services\CustomField;
use Defuse\Crypto\Exception\CryptoException;
+use SP\Core\Context\SessionContext;
use SP\Core\Crypt\Crypt;
use SP\Core\Crypt\Session as CryptSession;
use SP\Core\Exceptions\QueryException;
@@ -61,13 +62,14 @@ class CustomFieldService extends Service
* Desencriptar y formatear los datos del campo
*
* @param CustomFieldData $CustomFieldData
+ * @param SessionContext $sessionContext
* @return string
- * @throws \Defuse\Crypto\Exception\CryptoException
+ * @throws CryptoException
*/
- public static function decryptData(CustomFieldData $CustomFieldData)
+ public static function decryptData(CustomFieldData $CustomFieldData, SessionContext $sessionContext)
{
if ($CustomFieldData->getData() !== '') {
- $securedKey = Crypt::unlockSecuredKey($CustomFieldData->getKey(), CryptSession::getSessionKey());
+ $securedKey = Crypt::unlockSecuredKey($CustomFieldData->getKey(), CryptSession::getSessionKey($sessionContext));
return self::formatValue(Crypt::decrypt($CustomFieldData->getData(), $securedKey));
}
@@ -173,7 +175,7 @@ class CustomFieldService extends Service
*/
protected function setSecureData(CustomFieldData $customFieldData, $key = null)
{
- $key = $key ?: CryptSession::getSessionKey();
+ $key = $key ?: CryptSession::getSessionKey($this->context);
$securedKey = Crypt::makeSecuredKey($key);
if (strlen($securedKey) > 1000) {
diff --git a/lib/SP/Services/EventLog/EventlogService.php b/lib/SP/Services/EventLog/EventlogService.php
index 8a7f00ee..cd45cf61 100644
--- a/lib/SP/Services/EventLog/EventlogService.php
+++ b/lib/SP/Services/EventLog/EventlogService.php
@@ -70,7 +70,7 @@ class EventlogService extends Service
*/
public function create(EventlogData $eventlogData)
{
- $userData = $this->session->getUserData();
+ $userData = $this->context->getUserData();
$eventlogData->setUserId($userData->getId());
$eventlogData->setLogin($userData->getLogin() ?: '-');
diff --git a/lib/SP/Services/Export/XmlExportService.php b/lib/SP/Services/Export/XmlExportService.php
index 1f70f808..fceaef01 100644
--- a/lib/SP/Services/Export/XmlExportService.php
+++ b/lib/SP/Services/Export/XmlExportService.php
@@ -223,7 +223,7 @@ class XmlExportService extends Service
private function createMeta()
{
try {
- $userData = $this->session->getUserData();
+ $userData = $this->context->getUserData();
$nodeMeta = $this->xml->createElement('Meta');
$metaGenerator = $this->xml->createElement('Generator', 'sysPass');
diff --git a/lib/SP/Services/Import/ImportTrait.php b/lib/SP/Services/Import/ImportTrait.php
index 614c1823..b1a74429 100644
--- a/lib/SP/Services/Import/ImportTrait.php
+++ b/lib/SP/Services/Import/ImportTrait.php
@@ -26,8 +26,8 @@ namespace SP\Services\Import;
use SP\Account\AccountRequest;
use SP\Core\Crypt\Crypt;
+use SP\Core\Crypt\OldCrypt;
use SP\Core\Exceptions\SPException;
-use SP\Core\OldCrypt;
use SP\DataModel\CategoryData;
use SP\DataModel\ClientData;
use SP\DataModel\TagData;
diff --git a/lib/SP/Services/Import/SyspassImport.php b/lib/SP/Services/Import/SyspassImport.php
index 580f5b43..44a2296d 100644
--- a/lib/SP/Services/Import/SyspassImport.php
+++ b/lib/SP/Services/Import/SyspassImport.php
@@ -30,9 +30,9 @@ use SP\Account\AccountRequest;
use SP\Config\ConfigDB;
use SP\Core\Crypt\Crypt;
use SP\Core\Crypt\Hash;
+use SP\Core\Crypt\OldCrypt;
use SP\Core\Events\Event;
use SP\Core\Events\EventMessage;
-use SP\Core\OldCrypt;
use SP\DataModel\CategoryData;
use SP\DataModel\ClientData;
use SP\DataModel\TagData;
diff --git a/lib/SP/Services/Notification/NotificationService.php b/lib/SP/Services/Notification/NotificationService.php
index 8b287702..e635d9e5 100644
--- a/lib/SP/Services/Notification/NotificationService.php
+++ b/lib/SP/Services/Notification/NotificationService.php
@@ -223,7 +223,7 @@ class NotificationService extends Service
*/
public function search(ItemSearchData $itemSearchData)
{
- $userData = $this->session->getUserData();
+ $userData = $this->context->getUserData();
if ($userData->getIsAdminApp()) {
return $this->notificationRepository->search($itemSearchData);
diff --git a/lib/SP/Services/PublicLink/PublicLinkService.php b/lib/SP/Services/PublicLink/PublicLinkService.php
index d6a15cdb..400c04db 100644
--- a/lib/SP/Services/PublicLink/PublicLinkService.php
+++ b/lib/SP/Services/PublicLink/PublicLinkService.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.
@@ -146,7 +146,7 @@ class PublicLinkService extends Service
/**
* Obtener los datos de una cuenta y encriptarlos para el enlace
*
- * @param int $itemId
+ * @param int $itemId
* @param string $linkKey
* @return Vault
* @throws \Defuse\Crypto\Exception\CryptoException
@@ -160,7 +160,7 @@ class PublicLinkService extends Service
$accountData = $this->dic->get(AccountService::class)->getDataForLink($itemId);
// Desencriptar la clave de la cuenta
- $key = CryptSession::getSessionKey();
+ $key = CryptSession::getSessionKey($this->context);
$securedKey = Crypt::unlockSecuredKey($accountData->getKey(), $key);
$accountData->setPass(Crypt::decrypt($accountData->getPass(), $securedKey, $key));
$accountData->setKey(null);
@@ -229,13 +229,13 @@ class PublicLinkService extends Service
$itemData->setData($this->getSecuredLinkData($itemData->getItemId(), self::getKeyForHash($this->config->getConfigData()->getPasswordSalt(), $itemData)));
$itemData->setDateExpire(self::calcDateExpire($this->config));
$itemData->setMaxCountViews($this->config->getConfigData()->getPublinksMaxViews());
- $itemData->setUserId($this->session->getUserData()->getId());
+ $itemData->setUserId($this->context->getUserData()->getId());
return $this->publicLinkRepository->create($itemData);
}
/**
- * @param string $salt
+ * @param string $salt
* @param PublicLinkData $publicLinkData
* @return string
*/
diff --git a/lib/SP/Services/Service.php b/lib/SP/Services/Service.php
index 23397dc0..3a927e80 100644
--- a/lib/SP/Services/Service.php
+++ b/lib/SP/Services/Service.php
@@ -28,6 +28,8 @@ use DI\Container;
use Psr\Container\ContainerInterface;
use SP\Config\Config;
use SP\Core\Context\ContextInterface;
+use SP\Core\Context\SessionContext;
+use SP\Core\Context\StatelessContext;
use SP\Core\Events\EventDispatcher;
/**
@@ -44,9 +46,9 @@ abstract class Service
*/
protected $config;
/**
- * @var ContextInterface
+ * @var SessionContext|StatelessContext
*/
- protected $session;
+ protected $context;
/**
* @var EventDispatcher
*/
@@ -67,7 +69,7 @@ abstract class Service
{
$this->dic = $dic;
$this->config = $dic->get(Config::class);
- $this->session = $dic->get(ContextInterface::class);
+ $this->context = $dic->get(ContextInterface::class);
$this->eventDispatcher = $dic->get(EventDispatcher::class);
if (method_exists($this, 'initialize')) {
diff --git a/lib/SP/Core/Task.php b/lib/SP/Services/Task/Task.php
similarity index 98%
rename from lib/SP/Core/Task.php
rename to lib/SP/Services/Task/Task.php
index 150416b1..608f1286 100644
--- a/lib/SP/Core/Task.php
+++ b/lib/SP/Services/Task/Task.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.
@@ -22,7 +22,7 @@
* along with sysPass. If not, see .
*/
-namespace SP\Core;
+namespace SP\Services\Task;
use SP\Core\Context\SessionContext;
use SP\Core\Messages\TaskMessage;
diff --git a/lib/SP/Core/TaskFactory.php b/lib/SP/Services/Task/TaskFactory.php
similarity index 99%
rename from lib/SP/Core/TaskFactory.php
rename to lib/SP/Services/Task/TaskFactory.php
index 9b63b67d..ef116294 100644
--- a/lib/SP/Core/TaskFactory.php
+++ b/lib/SP/Services/Task/TaskFactory.php
@@ -22,7 +22,7 @@
* along with sysPass. If not, see .
*/
-namespace SP\Core;
+namespace SP\Services\Task;
use SP\Core\Messages\TaskMessage;
diff --git a/lib/SP/Services/Task/TaskService.php b/lib/SP/Services/Task/TaskService.php
index d50e896f..404be8bf 100644
--- a/lib/SP/Services/Task/TaskService.php
+++ b/lib/SP/Services/Task/TaskService.php
@@ -24,8 +24,6 @@
namespace SP\Services\Task;
-use SP\Core\Task;
-use SP\Core\TaskFactory;
use SP\Services\Service;
use SP\Services\ServiceException;
use SP\Util\Util;
diff --git a/lib/SP/Services/Upgrade/UpgradeConfigService.php b/lib/SP/Services/Upgrade/UpgradeConfigService.php
new file mode 100644
index 00000000..911cebd5
--- /dev/null
+++ b/lib/SP/Services/Upgrade/UpgradeConfigService.php
@@ -0,0 +1,222 @@
+.
+ */
+
+namespace SP\Services\Upgrade;
+
+use SP\Core\Events\Event;
+use SP\Core\Events\EventMessage;
+use SP\Services\Service;
+use SP\Util\Util;
+
+/**
+ * Class UpgradeService
+ *
+ * @package SP\Services\Upgrade
+ */
+class UpgradeConfigService extends Service
+{
+ /**
+ * @var array Versiones actualizables
+ */
+ const UPGRADES = ['112.4', '130.16020501', '200.17011202'];
+
+ /**
+ * Comprueba si es necesario actualizar la configuración.
+ *
+ * @param int $version con el número de versión actual
+ * @returns bool
+ */
+ public static function needConfigUpgrade($version)
+ {
+ return Util::checkVersion($version, self::UPGRADES);
+ }
+
+ /**
+ * Migrar valores de configuración.
+ *
+ * @param int $version El número de versión
+ * @return bool
+ */
+ public function upgradeConfig($version)
+ {
+ $message = EventMessage::factory()->addDescription(__u('Actualizar Configuración'));
+
+ $this->eventDispatcher->notifyEvent('upgrade.config.start', new Event($this, $message));
+
+ $configData = $this->config->getConfigData();
+ $count = 0;
+
+ foreach (self::UPGRADES as $upgradeVersion) {
+ if (Util::checkVersion($version, $upgradeVersion)) {
+ switch ($upgradeVersion) {
+ case '200.17011202':
+ $message->addDetail(__u('Versión'), $version);
+
+ $configData->setSiteTheme('material-blue');
+ $configData->setConfigVersion($upgradeVersion);
+
+ $this->config->saveConfig($configData, false);
+ $count++;
+ break;
+ }
+ }
+ }
+
+ $this->eventDispatcher->notifyEvent('upgrade.config.end', new Event($this, $message));
+
+ return $count > 0;
+ }
+
+ /**
+ * Actualizar el archivo de configuración a formato XML
+ *
+ * @param $version
+ * @return bool
+ */
+ public function upgradeOldConfigFile($version)
+ {
+ $message = EventMessage::factory()->addDescription(__u('Actualizar Configuración'));
+
+ $this->eventDispatcher->notifyEvent('upgrade.config.old.start', new Event($this, $message));
+
+ // Include the file, save the data from $CONFIG
+ include OLD_CONFIG_FILE;
+
+ $configData = $this->config->getConfigData();
+ $message = EventMessage::factory();
+
+ if (isset($CONFIG) && is_array($CONFIG)) {
+ $paramMapper = function ($mapFrom, $mapTo) use ($CONFIG, $message, $configData) {
+ if (isset($CONFIG[$mapFrom])) {
+ $message->addDetail(__u('Parámetro'), $mapFrom);
+ $configData->{$mapTo}($CONFIG[$mapFrom]);
+ }
+ };
+
+ foreach (self::getConfigParams() as $mapTo => $mapFrom) {
+ if (method_exists($configData, $mapTo)) {
+ if (is_array($mapFrom)) {
+ /** @var array $mapFrom */
+ foreach ($mapFrom as $param) {
+ $paramMapper($mapFrom, $param);
+ }
+ } else {
+ if (isset($CONFIG[$mapFrom])) {
+ $paramMapper($mapFrom, $mapTo);
+ }
+ }
+ }
+ }
+ }
+
+ $oldFile = OLD_CONFIG_FILE . '.old.' . time();
+
+ try {
+ $configData->setSiteTheme('material-blue');
+ $configData->setConfigVersion($version);
+
+ $this->config->saveConfig($configData, false);
+
+ rename(OLD_CONFIG_FILE, $oldFile);
+
+ $message->addDetail(__u('Versión'), $version);
+
+ $this->eventDispatcher->notifyEvent('upgrade.config.old.end', new Event($this, $message));
+
+ return true;
+ } catch (\Exception $e) {
+ $this->eventDispatcher->notifyEvent('exception',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('Error al actualizar la configuración'))
+ ->addDetail(__u('Archivo'), $oldFile))
+ );
+ }
+
+ // We are here...wrong
+ return false;
+ }
+
+ /**
+ * Devuelve array de métodos y parámetros de configuración
+ *
+ * @return array
+ */
+ private static function getConfigParams()
+ {
+ return [
+ 'setAccountCount' => 'account_count',
+ 'setAccountLink' => 'account_link',
+ 'setCheckUpdates' => 'checkupdates',
+ 'setCheckNotices' => 'checknotices',
+ 'setDbHost' => 'dbhost',
+ 'setDbName' => 'dbname',
+ 'setDbPass' => 'dbpass',
+ 'setDbUser' => 'dbuser',
+ 'setDebug' => 'debug',
+ 'setDemoEnabled' => 'demo_enabled',
+ 'setGlobalSearch' => 'globalsearch',
+ 'setInstalled' => 'installed',
+ 'setMaintenance' => 'maintenance',
+ 'setPasswordSalt' => 'passwordsalt',
+ 'setSessionTimeout' => 'session_timeout',
+ 'setSiteLang' => 'sitelang',
+ 'setConfigVersion' => 'version',
+ 'setConfigHash' => 'config_hash',
+ 'setProxyEnabled' => 'proxy_enabled',
+ 'setProxyPass' => 'proxy_pass',
+ 'setProxyPort' => 'proxy_port',
+ 'setProxyServer' => 'proxy_server',
+ 'setProxyUser' => 'proxy_user',
+ 'setResultsAsCards' => 'resultsascards',
+ 'setSiteTheme' => 'sitetheme',
+ 'setAccountPassToImage' => 'account_passtoimage',
+ 'setFilesAllowedExts' => ['allowed_exts', 'files_allowed_exts'],
+ 'setFilesAllowedSize' => ['allowed_size', 'files_allowed_size'],
+ 'setFilesEnabled' => ['filesenabled', 'files_enabled'],
+ 'setLdapBase' => ['ldapbase', 'ldap_base'],
+ 'setLdapBindPass' => ['ldapbindpass', 'ldap_bindpass'],
+ 'setLdapBindUser' => ['ldapbinduser', 'ldap_binduser'],
+ 'setLdapEnabled' => ['ldapenabled', 'ldap_enabled'],
+ 'setLdapGroup' => ['ldapgroup', 'ldap_group'],
+ 'setLdapServer' => ['ldapserver', 'ldap_server'],
+ 'setLdapAds' => 'ldap_ads',
+ 'setLdapDefaultGroup' => 'ldap_defaultgroup',
+ 'setLdapDefaultProfile' => 'ldap_defaultprofile',
+ 'setLogEnabled' => ['logenabled', 'log_enabled'],
+ 'setMailEnabled' => ['mailenabled', 'mail_enabled'],
+ 'setMailFrom' => ['mailfrom', 'mail_from'],
+ 'setMailPass' => ['mailpass', 'mail_pass'],
+ 'setMailPort' => ['mailport', 'mail_port'],
+ 'setMailRequestsEnabled' => ['mailrequestsenabled', 'mail_requestsenabled'],
+ 'setMailAuthenabled' => 'mail_authenabled',
+ 'setMailSecurity' => ['mailsecurity', 'mail_security'],
+ 'setMailServer' => ['mailserver', 'mail_server'],
+ 'setMailUser' => ['mailuser', 'mail_user'],
+ 'setWikiEnabled' => ['wikienabled', 'wiki_enabled'],
+ 'setWikiFilter' => ['wikifilter', 'wiki_filter'],
+ 'setWikiPageUrl' => ['wikipageurl' . 'wiki_pageurl'],
+ 'setWikiSearchUrl' => ['wikisearchurl', 'wiki_searchurl']
+ ];
+ }
+}
\ No newline at end of file
diff --git a/lib/SP/Services/Upgrade/UpgradeDatabaseService.php b/lib/SP/Services/Upgrade/UpgradeDatabaseService.php
new file mode 100644
index 00000000..67022c1a
--- /dev/null
+++ b/lib/SP/Services/Upgrade/UpgradeDatabaseService.php
@@ -0,0 +1,323 @@
+.
+ */
+
+namespace SP\Services\Upgrade;
+
+use SP\Core\Events\Event;
+use SP\Core\Events\EventMessage;
+use SP\Services\Config\ConfigService;
+use SP\Services\Service;
+use SP\Storage\Database;
+use SP\Storage\DbWrapper;
+use SP\Storage\QueryData;
+use SP\Util\Util;
+
+/**
+ * Class UpgradeDatabaseService
+ *
+ * @package SP\Services\Upgrade
+ */
+class UpgradeDatabaseService extends Service
+{
+ /**
+ * @var array Versiones actualizables
+ */
+ const DB_UPGRADES = ['110', '112.1', '112.2', '112.3', '112.13', '112.19', '112.20', '120.01', '120.02', '130.16011001', '130.16100601', '200.17011302', '200.17011701', '210.17022601', '213.17031402', '220.17050101'];
+ const AUX_UPGRADES = ['120.01', '120.02', '200.17010901', '200.17011202'];
+ const APP_UPGRADES = ['210.17022601'];
+ /**
+ * @var string Versión de la BBDD
+ */
+ private static $currentDbVersion;
+ /**
+ * @var ConfigService
+ */
+ protected $configService;
+ /**
+ * @var Database
+ */
+ protected $db;
+
+ /**
+ * Inicia el proceso de actualización de la BBDD.
+ *
+ * @param int $version con la versión de la BBDD actual
+ * @return bool
+ * @throws UpgradeException
+ * @throws \SP\Core\Exceptions\SPException
+ * @throws \SP\Services\Config\ParameterNotFoundException
+ */
+ public function doUpgrade($version)
+ {
+ $this->eventDispatcher->notifyEvent('upgrade.db.start',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('Actualizar BBDD')))
+ );
+
+ self::$currentDbVersion = UpgradeUtil::fixVersionNumber($this->configService->getByParam('version'));
+
+ foreach (self::DB_UPGRADES as $dbVersion) {
+ if (Util::checkVersion($version, $dbVersion)) {
+ if ($this->auxPreDbUpgrade($dbVersion) === false) {
+ throw new UpgradeException(
+ __u('Error al aplicar la actualización auxiliar'),
+ UpgradeException::CRITICAL,
+ __u('Compruebe el registro de eventos para más detalles')
+ );
+ }
+
+ if ($this->upgradeDB($dbVersion) === false) {
+ throw new UpgradeException(
+ __u('Error al aplicar la actualización de la Base de Datos'),
+ UpgradeException::CRITICAL,
+ __u('Compruebe el registro de eventos para más detalles')
+ );
+ }
+ }
+ }
+
+ foreach (self::AUX_UPGRADES as $appVersion) {
+ if (Util::checkVersion($version, $appVersion)
+ && $this->appUpgrades($appVersion) === false
+ ) {
+ throw new UpgradeException(
+ __u('Error al aplicar la actualización de la aplicación'),
+ UpgradeException::CRITICAL,
+ __u('Compruebe el registro de eventos para más detalles')
+ );
+ }
+ }
+
+ foreach (self::APP_UPGRADES as $auxVersion) {
+ if (Util::checkVersion($version, $auxVersion)
+ && $this->auxUpgrades($auxVersion) === false
+ ) {
+ throw new UpgradeException(
+ __u('Error al aplicar la actualización auxiliar'),
+ UpgradeException::CRITICAL,
+ __u('Compruebe el registro de eventos para más detalles')
+ );
+ }
+ }
+
+ $this->eventDispatcher->notifyEvent('upgrade.db.end',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('Actualizar BBDD')))
+ );
+
+ return true;
+ }
+
+ /**
+ * Aplicar actualizaciones auxiliares antes de actualizar la BBDD
+ *
+ * @param $version
+ * @return bool
+ * @throws UpgradeException
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ private function auxPreDbUpgrade($version)
+ {
+ switch ($version) {
+ case '130.16011001':
+ debugLog(__FUNCTION__ . ': ' . $version);
+
+ return $this->upgradeDB('130.00000000');
+ case '130.16100601':
+ debugLog(__FUNCTION__ . ': ' . $version);
+
+ return
+ Account::fixAccountsId()
+ && UserUpgrade::fixUsersId(Request::analyze('userid', 0))
+ && Group::fixGroupId(Request::analyze('groupid', 0))
+ && Profile::fixProfilesId(Request::analyze('profileid', 0))
+ && Category::fixCategoriesId(Request::analyze('categoryid', 0))
+ && Customer::fixCustomerId(Request::analyze('customerid', 0));
+ }
+
+ return true;
+ }
+
+ /**
+ * Actualiza la BBDD según la versión.
+ *
+ * @param int $version con la versión a actualizar
+ * @returns bool
+ * @throws UpgradeException
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ private function upgradeDB($version)
+ {
+ $this->eventDispatcher->notifyEvent('upgrade.db.process',
+ new Event($this, EventMessage::factory()
+ ->addDetail(__u('Versión'), $version))
+ );
+
+ $queries = $this->getQueriesFromFile($version);
+
+ if (count($queries) === 0 || Util::checkVersion(self::$currentDbVersion, $version) === false) {
+ debugLog(__('No es necesario actualizar la Base de Datos.'));
+
+ $this->eventDispatcher->notifyEvent('upgrade.db.process',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('No es necesario actualizar la Base de Datos.')))
+ );
+
+ return true;
+ }
+
+// TaskFactory::$Message->setTask(__('Actualizar BBDD'));
+// TaskFactory::$Message->setMessage(sprintf('%s : %s', __('Versión'), $version));
+// TaskFactory::update();
+
+ foreach ($queries as $query) {
+ try {
+ $queryData = new QueryData();
+ $queryData->setQuery($query);
+ DbWrapper::getQuery($queryData, $this->db);
+ } catch (\Exception $e) {
+ processException($e);
+
+ $this->eventDispatcher->notifyEvent('exception',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('Error al aplicar la actualización de la Base de Datos'))
+ ->addDetail('ERROR', sprintf('%s (%s)', $e->getMessage(), $e->getCode())))
+ );
+
+ throw new UpgradeException(__u('Error al aplicar la actualización de la Base de Datos'));
+ }
+ }
+
+ $this->configService->save('version', $version);
+
+ self::$currentDbVersion = $version;
+
+
+ $this->eventDispatcher->notifyEvent('upgrade.db.process', new Event($this, EventMessage::factory()
+ ->addDescription(__u('Actualización de la Base de Datos realizada correctamente.'))));
+
+ return true;
+ }
+
+ /**
+ * Obtener las consultas de actualización desde un archivo
+ *
+ * @param $filename
+ * @return array|bool
+ */
+ private function getQueriesFromFile($filename)
+ {
+ $file = SQL_PATH . DIRECTORY_SEPARATOR . str_replace('.', '', $filename) . '.sql';
+
+ $queries = [];
+
+ if (file_exists($file) && $handle = fopen($file, 'rb')) {
+ while (!feof($handle)) {
+ $buffer = stream_get_line($handle, 1000000, ";\n");
+
+ if (strlen(trim($buffer)) > 0) {
+ $queries[] = str_replace("\n", '', $buffer);
+ }
+ }
+ }
+
+ return $queries;
+ }
+
+ /**
+ * Actualizaciones de la aplicación
+ *
+ * @param $version
+ * @return bool
+ * @throws \SP\Core\Exceptions\SPException
+ */
+ private function appUpgrades($version)
+ {
+ switch ($version) {
+ case '210.17022601':
+ $dbResult = true;
+
+ if (Util::checkVersion(self::$currentDbVersion, $version)) {
+ $dbResult = $this->upgradeDB($version);
+ }
+
+ $masterPass = Request::analyzeEncrypted('masterkey');
+ $UserData = User::getItem()->getByLogin(Request::analyze('userlogin'));
+
+ if (!is_object($UserData)) {
+ throw new SPException(__('Error al obtener los datos del usuario', false), SPException::ERROR);
+ }
+
+ CoreSession::setUserData($UserData);
+
+ return $dbResult === true
+ && !empty($masterPass)
+ && Crypt::migrate($masterPass);
+ }
+
+ return false;
+ }
+
+ /**
+ * Aplicar actualizaciones auxiliares.
+ *
+ * @param $version int El número de versión
+ * @return bool
+ */
+ private function auxUpgrades($version)
+ {
+ try {
+ switch ($version) {
+ case '120.01':
+ debugLog(__FUNCTION__ . ': ' . $version);
+
+ return (ProfileUtil::migrateProfiles() && UserMigrate::migrateUsersGroup());
+ case '120.02':
+ debugLog(__FUNCTION__ . ': ' . $version);
+
+ return UserMigrate::setMigrateUsers();
+ case '200.17010901':
+ debugLog(__FUNCTION__ . ': ' . $version);
+
+ return CustomFieldsUtil::migrateCustomFields() && UserPreferencesUtil::migrate();
+ case '200.17011202':
+ debugLog(__FUNCTION__ . ': ' . $version);
+
+ return UserPreferencesUtil::migrate();
+ }
+ } catch (SPException $e) {
+ return false;
+ }
+
+ return true;
+ }
+
+ protected function initialize()
+ {
+ $this->configService = $this->dic->get(ConfigService::class);
+ $this->db = $this->dic->get(Database::class);
+ }
+}
\ No newline at end of file
diff --git a/lib/SP/Services/Upgrade/UpgradeException.php b/lib/SP/Services/Upgrade/UpgradeException.php
new file mode 100644
index 00000000..410a9c02
--- /dev/null
+++ b/lib/SP/Services/Upgrade/UpgradeException.php
@@ -0,0 +1,37 @@
+.
+ */
+
+namespace SP\Services\Upgrade;
+
+use SP\Core\Exceptions\SPException;
+
+/**
+ * Class UpgradeException
+ *
+ * @package SP\Services\Upgrade
+ */
+class UpgradeException extends SPException
+{
+
+}
\ No newline at end of file
diff --git a/lib/SP/Services/Upgrade/UpgradeUtil.php b/lib/SP/Services/Upgrade/UpgradeUtil.php
new file mode 100644
index 00000000..71f734b7
--- /dev/null
+++ b/lib/SP/Services/Upgrade/UpgradeUtil.php
@@ -0,0 +1,118 @@
+.
+ */
+
+namespace SP\Services\Upgrade;
+use SP\Config\Config;
+use SP\Util\Util;
+
+/**
+ * Class UpgradeUtil
+ *
+ * @package SP\Services\Upgrade
+ */
+class UpgradeUtil
+{
+ /**
+ * Normalizar un número de versión
+ *
+ * @param $version
+ * @return string
+ */
+ public static function fixVersionNumber($version)
+ {
+ if (strpos($version, '.') === false) {
+ if (strlen($version) === 10) {
+ return substr($version, 0, 2) . '0.' . substr($version, 2);
+ }
+
+ return substr($version, 0, 3) . '.' . substr($version, 3);
+ }
+
+ return $version;
+ }
+
+ /**
+ * Establecer la key de actualización
+ *
+ * @param Config $config
+ * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
+ */
+ public static function setUpgradeKey(Config $config)
+ {
+ $configData = $config->getConfigData();
+ $upgradeKey = $configData->getUpgradeKey();
+
+ if (empty($upgradeKey)) {
+ $configData->setUpgradeKey(Util::generateRandomBytes(32));
+ }
+
+ $configData->setMaintenance(true);
+ $config->saveConfig($configData, false);
+
+// Init::initError(
+// __('La aplicación necesita actualizarse'),
+// sprintf(__('Si es un administrador pulse en el enlace: %s'), '' . __('Actualizar') . ''));
+ }
+
+ /**
+ * Comrpueba y actualiza la versión de la BBDD.
+ *
+ * @return void
+ * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
+ */
+ public function checkDbVersion()
+ {
+ $appVersion = Util::getVersionStringNormalized();
+ $databaseVersion = UserUpgrade::fixVersionNumber(ConfigDB::getValue('version'));
+
+ if (Util::checkVersion($databaseVersion, $appVersion)
+ && Request::analyze('nodbupgrade', 0) === 0
+ && Util::checkVersion($databaseVersion, self::$dbUpgrade)
+ && !$this->configData->isMaintenance()
+ ) {
+ $this->setUpgradeKey('db');
+
+ // FIXME: send link for upgrading
+ throw new \RuntimeException('Needs upgrade');
+ }
+ }
+
+ /**
+ * Comrpueba y actualiza la versión de la aplicación.
+ *
+ * @return void
+ * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException
+ */
+ public function checkAppVersion()
+ {
+ $appVersion = UserUpgrade::fixVersionNumber($this->configData->getConfigVersion());
+
+ if (Util::checkVersion($appVersion, self::$appUpgrade) && !$this->configData->isMaintenance()) {
+ $this->setUpgradeKey('app');
+
+ // FIXME: send link for upgrading
+ throw new \RuntimeException('Needs upgrade');
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/SP/Services/User/UserPassService.php b/lib/SP/Services/User/UserPassService.php
index e04aad79..0288318b 100644
--- a/lib/SP/Services/User/UserPassService.php
+++ b/lib/SP/Services/User/UserPassService.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.
@@ -68,17 +68,6 @@ class UserPassService extends Service
*/
protected $configService;
- /**
- * @throws \Psr\Container\ContainerExceptionInterface
- * @throws \Psr\Container\NotFoundExceptionInterface
- */
- protected function initialize()
- {
- $this->configData = $this->config->getConfigData();
- $this->userRepository = $this->dic->get(UserRepository::class);
- $this->configService = $this->dic->get(ConfigService::class);;
- }
-
/**
* Actualizar la clave maestra con la clave anterior del usuario
*
@@ -142,7 +131,7 @@ class UserPassService extends Service
// Comprobamos el hash de la clave del usuario con la guardada
if (Hash::checkHashKey($clearMPass, $configHashMPass)) {
- CryptSession::saveSessionKey($clearMPass);
+ CryptSession::saveSessionKey($clearMPass, $this->context);
$response = new UserPassResponse(self::MPASS_OK, $clearMPass);
$response->setCryptMasterPass($userLoginResponse->getMPass());
@@ -204,7 +193,7 @@ class UserPassService extends Service
$this->userRepository->updateMasterPassById($userData->getId(), $response->getCryptMasterPass(), $response->getCryptSecuredKey());
- CryptSession::saveSessionKey($userMPass);
+ CryptSession::saveSessionKey($userMPass, $this->context);
return $response;
}
@@ -254,4 +243,15 @@ class UserPassService extends Service
{
return $this->userRepository->updatePassById($id, new UpdatePassRequest(Hash::hashKey($userPass)));
}
+
+ /**
+ * @throws \Psr\Container\ContainerExceptionInterface
+ * @throws \Psr\Container\NotFoundExceptionInterface
+ */
+ protected function initialize()
+ {
+ $this->configData = $this->config->getConfigData();
+ $this->userRepository = $this->dic->get(UserRepository::class);
+ $this->configService = $this->dic->get(ConfigService::class);;
+ }
}
\ No newline at end of file
diff --git a/lib/SP/Services/User/UserService.php b/lib/SP/Services/User/UserService.php
index 7277aba8..3760e112 100644
--- a/lib/SP/Services/User/UserService.php
+++ b/lib/SP/Services/User/UserService.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.
@@ -53,6 +53,49 @@ class UserService extends Service
*/
protected $userPassService;
+ /**
+ * @param UserData $userData
+ * @return UserLoginResponse
+ */
+ public static function mapUserLoginResponse(UserData $userData)
+ {
+ return (new UserLoginResponse())->setId($userData->getId())
+ ->setName($userData->getName())
+ ->setLogin($userData->getLogin())
+ ->setSsoLogin($userData->getSsoLogin())
+ ->setEmail($userData->getEmail())
+ ->setPass($userData->getPass())
+ ->setHashSalt($userData->getHashSalt())
+ ->setMPass($userData->getMPass())
+ ->setMKey($userData->getMKey())
+ ->setLastUpdateMPass($userData->getLastUpdateMPass())
+ ->setUserGroupId($userData->getUserGroupId())
+ ->setUserProfileId($userData->getUserProfileId())
+ ->setPreferences(self::getUserPreferences($userData->getPreferences()))
+ ->setIsLdap($userData->isLdap())
+ ->setIsAdminAcc($userData->isAdminAcc())
+ ->setIsAdminApp($userData->isAdminApp())
+ ->setIsMigrate($userData->isMigrate())
+ ->setIsChangedPass($userData->isIsChangedPass())
+ ->setIsChangePass($userData->isChangePass())
+ ->setIsDisabled($userData->isDisabled());
+ }
+
+ /**
+ * Returns user's preferences object
+ *
+ * @param string $preferences
+ * @return UserPreferencesData
+ */
+ public static function getUserPreferences($preferences)
+ {
+ if (!empty($preferences)) {
+ return Util::unserialize(UserPreferencesData::class, $preferences, 'SP\UserPreferences');
+ }
+
+ return new UserPreferencesData();
+ }
+
/**
* Actualiza el último inicio de sesión del usuario en la BBDD.
*
@@ -93,51 +136,12 @@ class UserService extends Service
* Returns the item for given id
*
* @param $login
- * @return UserLoginResponse
+ * @return UserData
* @throws SPException
*/
public function getByLogin($login)
{
- $userData = $this->userRepository->getByLogin($login);
-
- $userLoginResponse = new UserLoginResponse();
- $userLoginResponse->setId($userData->getId())
- ->setName($userData->getName())
- ->setLogin($userData->getLogin())
- ->setSsoLogin($userData->getSsoLogin())
- ->setEmail($userData->getEmail())
- ->setPass($userData->getPass())
- ->setHashSalt($userData->getHashSalt())
- ->setMPass($userData->getMPass())
- ->setMKey($userData->getMKey())
- ->setLastUpdateMPass($userData->getLastUpdateMPass())
- ->setUserGroupId($userData->getUserGroupId())
- ->setUserProfileId($userData->getUserProfileId())
- ->setPreferences(self::getUserPreferences($userData->getPreferences()))
- ->setIsLdap($userData->isLdap())
- ->setIsAdminAcc($userData->isAdminAcc())
- ->setIsAdminApp($userData->isAdminApp())
- ->setIsMigrate($userData->isMigrate())
- ->setIsChangedPass($userData->isIsChangedPass())
- ->setIsChangePass($userData->isChangePass())
- ->setIsDisabled($userData->isDisabled());
-
- return $userLoginResponse;
- }
-
- /**
- * Returns user's preferences object
- *
- * @param string $preferences
- * @return UserPreferencesData
- */
- public static function getUserPreferences($preferences)
- {
- if (!empty($preferences)) {
- return Util::unserialize(UserPreferencesData::class, $preferences, 'SP\UserPreferences');
- }
-
- return new UserPreferencesData();
+ return $this->userRepository->getByLogin($login);
}
/**
@@ -211,8 +215,8 @@ class UserService extends Service
* Creates an item
*
* @param UserData $itemData
- * @param string $userPass
- * @param string $masterPass
+ * @param string $userPass
+ * @param string $masterPass
* @return int
* @throws SPException
* @throws \Defuse\Crypto\Exception\CryptoException
@@ -257,7 +261,7 @@ class UserService extends Service
/**
* Updates an user's pass
*
- * @param int $userId
+ * @param int $userId
* @param string $pass
* @return bool
* @throws \SP\Core\Exceptions\ConstraintException
@@ -273,7 +277,7 @@ class UserService extends Service
}
/**
- * @param $userId
+ * @param $userId
* @param UserPreferencesData $userPreferencesData
* @return bool
* @throws \SP\Core\Exceptions\ConstraintException
diff --git a/lib/SP/Services/UserProfile/UserProfileService.php b/lib/SP/Services/UserProfile/UserProfileService.php
index f33551e3..9732f189 100644
--- a/lib/SP/Services/UserProfile/UserProfileService.php
+++ b/lib/SP/Services/UserProfile/UserProfileService.php
@@ -25,7 +25,6 @@
namespace SP\Services\UserProfile;
use SP\Core\Exceptions\SPException;
-use SP\Core\Traits\InjectableTrait;
use SP\DataModel\ItemSearchData;
use SP\DataModel\ProfileData;
use SP\DataModel\UserProfileData;
@@ -42,7 +41,6 @@ use SP\Util\Util;
*/
class UserProfileService extends Service
{
- use InjectableTrait;
use ServiceItemTrait;
/**
diff --git a/lib/SP/Util/Util.php b/lib/SP/Util/Util.php
index 8dad47f6..8ebf2862 100644
--- a/lib/SP/Util/Util.php
+++ b/lib/SP/Util/Util.php
@@ -28,7 +28,7 @@ use Defuse\Crypto\Core;
use Defuse\Crypto\Encoding;
use SP\Bootstrap;
use SP\Config\ConfigData;
-use SP\Core\Context\SessionContext;
+use SP\Core\Context\ContextInterface;
use SP\Core\Exceptions\SPException;
use SP\Core\Init;
use SP\Core\Install\Installer;
@@ -760,13 +760,13 @@ class Util
/**
* Comprobar si el usuario está logado.
*
- * @param SessionContext $session
+ * @param ContextInterface $context
* @return bool
* @internal param Database $db
*/
- public static function isLoggedIn(SessionContext $session)
+ public static function isLoggedIn(ContextInterface $context)
{
- $userData = $session->getUserData();
+ $userData = $context->getUserData();
return ($userData->getLogin()
&& is_object($userData->getPreferences()));
diff --git a/lib/SP/Util/Wiki/DokuWikiApiBase.php b/lib/SP/Util/Wiki/DokuWikiApiBase.php
index b8102917..b91150a1 100644
--- a/lib/SP/Util/Wiki/DokuWikiApiBase.php
+++ b/lib/SP/Util/Wiki/DokuWikiApiBase.php
@@ -29,7 +29,6 @@ use DOMException;
use SP\Config\Config;
use SP\Config\ConfigData;
use SP\Core\Exceptions\SPException;
-use SP\Core\Traits\InjectableTrait;
use SP\Http\XMLRPCResponseParse;
use SP\Log\Log;
use SP\Log\LogLevel;
@@ -42,7 +41,7 @@ use SP\Util\Util;
*/
abstract class DokuWikiApiBase
{
- use InjectableTrait;
+ use SP\Core\Dic\InjectableTrait;
/**
* @var string
diff --git a/public/js/app-actions.js b/public/js/app-actions.js
index 3281b02b..6b9b8116 100644
--- a/public/js/app-actions.js
+++ b/public/js/app-actions.js
@@ -847,11 +847,9 @@ sysPass.Actions = function (Common) {
log.info("config:mailCheck");
const $form = $($obj.data("src"));
- $form.find("[name='sk']").val(Common.sk.get());
-
const opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.entrypoint + '?r=' + $obj.data("action-route");
- opts.data = $form.serialize();
+ opts.data = $form.serialize() + "&sk=" + Common.sk.get();
Common.appRequests().getActionCall(opts, function (json) {
Common.msg.out(json);
@@ -1470,11 +1468,9 @@ sysPass.Actions = function (Common) {
log.info("ldap:check");
const $form = $($obj.data("src"));
- $form.find("[name='sk']").val(Common.sk.get());
-
const opts = Common.appRequests().getRequestOpts();
opts.url = ajaxUrl.entrypoint + '?r=' + $obj.data("action-route");
- opts.data = $form.serialize();
+ opts.data = $form.serialize() + "&sk=" + Common.sk.get();
Common.appRequests().getActionCall(opts, function (json) {
Common.msg.out(json);
diff --git a/public/js/app-actions.min.js b/public/js/app-actions.min.js
index 7fa80423..0c3e16ef 100644
--- a/public/js/app-actions.min.js
+++ b/public/js/app-actions.min.js
@@ -30,15 +30,15 @@ negative:{title:b.config().LANG[44],onClick:function(a){a.preventDefault();b.msg
var c=b.appRequests().getRequestOpts();c.url=f.entrypoint;c.data=a.serialize();b.appRequests().getActionCall(c,function(a){b.msg.out(a);0===a.status&&$("#dokuWikiResCheck").html(a.data)})}},config:{save:function(a){e.info("config:save");k.save(a)},masterpass:function(a){var c='
";mdlDialog().show({text:c,negative:{title:b.config().LANG[44],onClick:function(c){c.preventDefault();b.msg.error(b.config().LANG[44]);a.find(":input[type=password]").val("")}},
positive:{title:b.config().LANG[43],onClick:function(c){var d;(c=a.find("input[name='taskId']").val())&&(d=t(c));var e=b.appRequests().getRequestOpts();e.url=f.entrypoint;e.useFullLoading=!!c;e.data=a.serialize();b.appRequests().getActionCall(e,function(c){b.msg.out(c);a.find(":input[type=password]").val("");void 0!==d&&d.close()})}}})},backup:function(a){e.info("config:backup");k.state.update(a);var c=b.appRequests().getRequestOpts();c.url=f.entrypoint+"?r="+a.data("action-route");c.useFullLoading=
!0;c.data=a.serialize();b.appRequests().getActionCall(c,function(a){b.msg.out(a);0===a.status&&h({r:k.state.tab.route,tabIndex:k.state.tab.index})})},"export":function(a){e.info("config:export");k.save(a)},"import":function(a){e.info("config:import");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint+"?r="+a.data("action-route");c.data=a.serialize();b.appRequests().getActionCall(c,function(a){b.msg.out(a)})},refreshMpass:function(a){e.info("config:import");var c=b.appRequests().getRequestOpts();
-c.url=f.entrypoint+"?r="+a.data("action-route");c.data={sk:a.data("sk"),isAjax:1};b.appRequests().getActionCall(c,function(a){b.msg.out(a)})},mailCheck:function(a){e.info("config:mailCheck");var c=$(a.data("src"));c.find("[name='sk']").val(b.sk.get());var d=b.appRequests().getRequestOpts();d.url=f.entrypoint+"?r="+a.data("action-route");d.data=c.serialize();b.appRequests().getActionCall(d,function(a){b.msg.out(a)})}},main:u,user:{showSettings:function(a){e.info("user:showSettings");h({r:a.data("action-route")},
-"userSettings")},saveSettings:function(a){e.info("user:saveSettings");k.save(a)},password:function(a){e.info("user:password");var c=b.appRequests().getRequestOpts();c.type="html";c.method="get";c.url=f.entrypoint;c.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(c,function(a){0===a.length?u.logout():m(a)})},passreset:function(a){e.info("user:passreset");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint+"/?r="+a.data("action-route");
-c.data=a.serialize();b.appRequests().getActionCall(c,function(a){b.msg.out(a);0===a.status&&setTimeout(function(){b.redirect("index.php")},2E3)})}},link:{save:function(a){e.info("link:save");var c=function(c){var d=a.data("item-id"),e=b.appRequests().getRequestOpts();d?e.url=f.entrypoint+"?r="+a.data("action-route")+"/"+d+"/"+c:(e.url=f.entrypoint+"?r="+a.data("action-route"),e.data=a.serialize());b.appRequests().getActionCall(e,function(c){b.msg.out(c);0===c.status&&h({r:a.data("action-next")+"/"+
-d})})},d='";mdlDialog().show({text:d,negative:{title:b.config().LANG[44],onClick:function(a){a.preventDefault();c(0)}},positive:{title:b.config().LANG[43],onClick:function(a){a.preventDefault();c(1)}}})},refresh:function(a){e.info("link:refresh");k.state.update(a);var c=a.data("item-id"),d=b.appRequests().getRequestOpts();d.url=f.entrypoint;d.method="get";d.data={r:a.data("action-route")+"/"+c,sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(d,
-function(d){b.msg.out(d);0===d.status&&((d=a.data("action-next"))?h({r:d+"/"+c}):h({r:k.state.tab.route,tabIndex:k.state.tab.index}))})}},eventlog:{search:function(a){e.info("eventlog:search");n.search(a)},nav:function(a){e.info("eventlog:nav");n.nav(a)},clear:function(a){var c='";mdlDialog().show({text:c,negative:{title:b.config().LANG[44],onClick:function(a){a.preventDefault();b.msg.error(b.config().LANG[44])}},positive:{title:b.config().LANG[43],
-onClick:function(c){c.preventDefault();c=b.appRequests().getRequestOpts();c.url=f.entrypoint+"?r="+a.data("action-route");c.method="get";c.data={sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(c,function(c){b.msg.out(c);0===c.status&&h({r:a.data("nextaction")});b.sk.set(c.csrf)})}}})}},ajaxUrl:f,plugin:{toggle:function(a){e.info("plugin:enable");k.save(a,function(){setTimeout(function(){b.redirect("index.php")},2E3)})},reset:function(a){e.info("plugin:reset");var c=''+
-b.config().LANG[58]+"
";mdlDialog().show({text:c,negative:{title:b.config().LANG[44],onClick:function(a){a.preventDefault();b.msg.error(b.config().LANG[44])}},positive:{title:b.config().LANG[43],onClick:function(b){b.preventDefault();k.save(a)}}})}},notification:{check:function(a){e.info("notification:check");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint;c.method="get";c.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(c,
-function(c){b.msg.out(c);0===c.status&&h({r:a.data("nextaction")});b.sk.set(c.csrf)})},search:function(a){e.info("notification:search");n.search(a)},show:function(a){e.info("notification:show");v.show(a)},save:function(a){e.info("notification:save");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint+"?r="+a.data("route");c.data=a.serialize();b.appRequests().getActionCall(c,function(c){b.msg.out(c);0===c.status&&(h({r:a.data("nextaction")}),$.magnificPopup.close())})},"delete":function(a){e.info("notification:delete");
-n["delete"](a,function(c){var d=a.data("item-id"),e=b.appRequests().getRequestOpts();e.url=f.entrypoint;e.method="get";e.data={r:a.data("action-route")+(d?"/"+d:""),items:c,sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(e,function(c){b.msg.out(c);h({r:a.data("nextaction")})})})},getActive:function(){e.info("notification:getActive");var a=b.appRequests().getRequestOpts();a.url=f.entrypoint;a.method="get";a.data={r:"items/notifications",sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(a,
-function(a){return a})},nav:function(a){e.info("eventlog:nav");n.nav(a)}},wiki:{show:function(a){e.info("wiki:show");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint;c.method="get";c.data={pageName:a.data("pagename"),actionId:a.data("action-id"),sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(c,function(a){0!==a.status?b.msg.out(a):m(a.data.html)})}},items:r,ldap:{check:function(a){e.info("ldap:check");var c=$(a.data("src"));c.find("[name='sk']").val(b.sk.get());var d=b.appRequests().getRequestOpts();
-d.url=f.entrypoint+"?r="+a.data("action-route");d.data=c.serialize();b.appRequests().getActionCall(d,function(a){b.msg.out(a);0===a.status&&void 0!==a.data.template&&void 0!==a.data.items&&m(a.data.template,{open:function(){var c=$("#ldap-results").find(".list-wrap").empty();a.data.items.forEach(function(a){c.append(b.appTheme().html.getList(a.items,a.icon))})}})})},"import":function(a){e.info("ldap:import");var c='";mdlDialog().show({text:c,
-negative:{title:b.config().LANG[44],onClick:function(a){a.preventDefault();b.msg.error(b.config().LANG[44])}},positive:{title:b.config().LANG[43],onClick:function(c){c=$(a.data("src"));c.find("[name='sk']").val(b.sk.get());var d=b.appRequests().getRequestOpts();d.url=f.entrypoint+"?r="+a.data("action-route");d.data=c.serialize();b.appRequests().getActionCall(d,function(a){b.msg.out(a)})}}})}}}};
+c.url=f.entrypoint+"?r="+a.data("action-route");c.data={sk:a.data("sk"),isAjax:1};b.appRequests().getActionCall(c,function(a){b.msg.out(a)})},mailCheck:function(a){e.info("config:mailCheck");var c=$(a.data("src")),d=b.appRequests().getRequestOpts();d.url=f.entrypoint+"?r="+a.data("action-route");d.data=c.serialize()+"&sk="+b.sk.get();b.appRequests().getActionCall(d,function(a){b.msg.out(a)})}},main:u,user:{showSettings:function(a){e.info("user:showSettings");h({r:a.data("action-route")},"userSettings")},
+saveSettings:function(a){e.info("user:saveSettings");k.save(a)},password:function(a){e.info("user:password");var c=b.appRequests().getRequestOpts();c.type="html";c.method="get";c.url=f.entrypoint;c.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(c,function(a){0===a.length?u.logout():m(a)})},passreset:function(a){e.info("user:passreset");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint+"/?r="+a.data("action-route");c.data=a.serialize();
+b.appRequests().getActionCall(c,function(a){b.msg.out(a);0===a.status&&setTimeout(function(){b.redirect("index.php")},2E3)})}},link:{save:function(a){e.info("link:save");var c=function(c){var d=a.data("item-id"),e=b.appRequests().getRequestOpts();d?e.url=f.entrypoint+"?r="+a.data("action-route")+"/"+d+"/"+c:(e.url=f.entrypoint+"?r="+a.data("action-route"),e.data=a.serialize());b.appRequests().getActionCall(e,function(c){b.msg.out(c);0===c.status&&h({r:a.data("action-next")+"/"+d})})},d=''+
+b.config().LANG[48]+"
";mdlDialog().show({text:d,negative:{title:b.config().LANG[44],onClick:function(a){a.preventDefault();c(0)}},positive:{title:b.config().LANG[43],onClick:function(a){a.preventDefault();c(1)}}})},refresh:function(a){e.info("link:refresh");k.state.update(a);var c=a.data("item-id"),d=b.appRequests().getRequestOpts();d.url=f.entrypoint;d.method="get";d.data={r:a.data("action-route")+"/"+c,sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(d,function(d){b.msg.out(d);0===
+d.status&&((d=a.data("action-next"))?h({r:d+"/"+c}):h({r:k.state.tab.route,tabIndex:k.state.tab.index}))})}},eventlog:{search:function(a){e.info("eventlog:search");n.search(a)},nav:function(a){e.info("eventlog:nav");n.nav(a)},clear:function(a){var c='";mdlDialog().show({text:c,negative:{title:b.config().LANG[44],onClick:function(a){a.preventDefault();b.msg.error(b.config().LANG[44])}},positive:{title:b.config().LANG[43],onClick:function(c){c.preventDefault();
+c=b.appRequests().getRequestOpts();c.url=f.entrypoint+"?r="+a.data("action-route");c.method="get";c.data={sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(c,function(c){b.msg.out(c);0===c.status&&h({r:a.data("nextaction")});b.sk.set(c.csrf)})}}})}},ajaxUrl:f,plugin:{toggle:function(a){e.info("plugin:enable");k.save(a,function(){setTimeout(function(){b.redirect("index.php")},2E3)})},reset:function(a){e.info("plugin:reset");var c='";
+mdlDialog().show({text:c,negative:{title:b.config().LANG[44],onClick:function(a){a.preventDefault();b.msg.error(b.config().LANG[44])}},positive:{title:b.config().LANG[43],onClick:function(b){b.preventDefault();k.save(a)}}})}},notification:{check:function(a){e.info("notification:check");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint;c.method="get";c.data={r:a.data("action-route")+"/"+a.data("item-id"),sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(c,function(c){b.msg.out(c);0===c.status&&
+h({r:a.data("nextaction")});b.sk.set(c.csrf)})},search:function(a){e.info("notification:search");n.search(a)},show:function(a){e.info("notification:show");v.show(a)},save:function(a){e.info("notification:save");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint+"?r="+a.data("route");c.data=a.serialize();b.appRequests().getActionCall(c,function(c){b.msg.out(c);0===c.status&&(h({r:a.data("nextaction")}),$.magnificPopup.close())})},"delete":function(a){e.info("notification:delete");n["delete"](a,
+function(c){var d=a.data("item-id"),e=b.appRequests().getRequestOpts();e.url=f.entrypoint;e.method="get";e.data={r:a.data("action-route")+(d?"/"+d:""),items:c,sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(e,function(c){b.msg.out(c);h({r:a.data("nextaction")})})})},getActive:function(){e.info("notification:getActive");var a=b.appRequests().getRequestOpts();a.url=f.entrypoint;a.method="get";a.data={r:"items/notifications",sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(a,function(a){return a})},
+nav:function(a){e.info("eventlog:nav");n.nav(a)}},wiki:{show:function(a){e.info("wiki:show");var c=b.appRequests().getRequestOpts();c.url=f.entrypoint;c.method="get";c.data={pageName:a.data("pagename"),actionId:a.data("action-id"),sk:b.sk.get(),isAjax:1};b.appRequests().getActionCall(c,function(a){0!==a.status?b.msg.out(a):m(a.data.html)})}},items:r,ldap:{check:function(a){e.info("ldap:check");var c=$(a.data("src")),d=b.appRequests().getRequestOpts();d.url=f.entrypoint+"?r="+a.data("action-route");
+d.data=c.serialize()+"&sk="+b.sk.get();b.appRequests().getActionCall(d,function(a){b.msg.out(a);0===a.status&&void 0!==a.data.template&&void 0!==a.data.items&&m(a.data.template,{open:function(){var c=$("#ldap-results").find(".list-wrap").empty();a.data.items.forEach(function(a){c.append(b.appTheme().html.getList(a.items,a.icon))})}})})},"import":function(a){e.info("ldap:import");var c='";mdlDialog().show({text:c,negative:{title:b.config().LANG[44],
+onClick:function(a){a.preventDefault();b.msg.error(b.config().LANG[44])}},positive:{title:b.config().LANG[43],onClick:function(c){c=$(a.data("src"));c.find("[name='sk']").val(b.sk.get());var d=b.appRequests().getRequestOpts();d.url=f.entrypoint+"?r="+a.data("action-route");d.data=c.serialize();b.appRequests().getActionCall(d,function(a){b.msg.out(a)})}}})}}}};
diff --git a/schemas/30018010101.sql b/schemas/30018010101.sql
index 6b8e1ddd..8e8e1033 100644
--- a/schemas/30018010101.sql
+++ b/schemas/30018010101.sql
@@ -376,7 +376,7 @@ ON config;
ALTER TABLE config
CHANGE config_parameter parameter VARCHAR(50) NOT NULL;
ALTER TABLE config
- CHANGE config_value value VARCHAR(2000);
+ CHANGE config_value value VARCHAR(4000);
ALTER TABLE config
ADD PRIMARY KEY (parameter);
ALTER TABLE config