From 4d6104b839233b14aef7cf54b19e0a2db9d7c8f8 Mon Sep 17 00:00:00 2001 From: nuxsmin Date: Tue, 13 Mar 2018 02:01:09 +0100 Subject: [PATCH] * [ADD] API module. Work in progress. * [ADD] Upgrade service. Work in progress. * [MOD] Context based session data. Added collection class to manage session properties. * [MOD] Code refactoring. * [MOD] Improved theme icons load by caching objects. --- app/config/actions.xml | 24 +- .../api/Controllers/AccountController.php | 25 +- .../api/Controllers/ControllerBase.php | 67 +- app/modules/api/Init.php | 9 +- .../Controllers/AccessManagerController.php | 4 +- ...Controller.php => AuthTokenController.php} | 38 +- .../web/Controllers/BootstrapController.php | 2 +- .../ConfigEncryptionController.php | 4 +- .../Controllers/ConfigGeneralController.php | 9 +- .../web/Controllers/ConfigMailController.php | 7 +- .../Controllers/ConfigManagerController.php | 14 +- .../web/Controllers/ControllerBase.php | 3 +- .../web/Controllers/ErrorController.php | 3 +- .../Helpers/Account/AccountActionsHelper.php | 2 +- .../Helpers/Account/AccountHelper.php | 10 +- .../Helpers/Account/AccountHistoryHelper.php | 4 +- .../Helpers/Account/AccountPasswordHelper.php | 6 +- .../Helpers/Account/AccountSearchHelper.php | 16 +- .../web/Controllers/Helpers/HelperBase.php | 9 +- .../Controllers/Helpers/ItemsGridHelper.php | 30 +- .../web/Controllers/Helpers/LayoutHelper.php | 18 +- .../web/Controllers/MainController.php | 2 +- .../web/Controllers/SimpleControllerBase.php | 3 +- .../web/Controllers/TaskController.php | 4 +- .../web/Controllers/Traits/ItemTrait.php | 2 +- .../Controllers/UserPassResetController.php | 8 +- app/modules/web/Forms/AccountForm.php | 2 +- app/modules/web/Forms/AuthTokenForm.php | 4 +- app/modules/web/Forms/FormBase.php | 13 +- app/modules/web/Forms/NotificationForm.php | 2 +- app/modules/web/Forms/UserForm.php | 2 +- app/modules/web/Init.php | 40 +- .../views/account/account-editpass.inc | 2 +- .../views/account/account-request.inc | 2 +- .../material-blue/views/account/actions.inc | 2 +- .../views/account/files-list.inc | 2 +- .../views/common/aux-customfields.inc | 2 +- .../material-blue/views/config/accounts.inc | 2 +- .../material-blue/views/config/backup.inc | 2 +- .../material-blue/views/config/encryption.inc | 2 +- .../views/config/general-events.inc | 36 +- .../views/config/general-site.inc | 2 +- .../material-blue/views/config/general.inc | 2 +- .../material-blue/views/config/import.inc | 2 +- .../material-blue/views/config/ldap.inc | 2 +- .../material-blue/views/config/mail.inc | 22 +- .../material-blue/views/config/wiki.inc | 2 +- .../material-blue/views/itemshow/client.inc | 2 +- .../views/itemshow/customfield.inc | 2 +- .../views/itemshow/usergroup.inc | 2 +- .../material-blue/views/itemshow/userpass.inc | 2 +- .../views/itemshow/userprofile.inc | 2 +- .../views/userpassreset/request.inc | 2 +- .../views/userpassreset/reset.inc | 2 +- .../views/usersettings/general.inc | 2 +- composer.json | 3 +- composer.lock | 68 ++- lib/Definitions.php | 15 +- lib/SP/Account/Account.php | 516 ---------------- lib/SP/Account/AccountBase.php | 126 ---- lib/SP/Account/AccountCrypt.php | 318 ---------- lib/SP/Account/AccountFavorites.php | 106 ---- lib/SP/Account/AccountHistory.php | 519 ---------------- lib/SP/Account/AccountHistoryCrypt.php | 338 ----------- lib/SP/Account/AccountHistoryUtil.php | 161 ----- lib/SP/Account/AccountTags.php | 156 ----- lib/SP/Account/AccountUtil.php | 326 ++-------- lib/SP/Account/UserAccounts.php | 188 ------ lib/SP/Bootstrap.php | 98 ++- lib/SP/Config/Config.php | 39 +- lib/SP/Config/ConfigDB.php | 234 ------- lib/SP/Config/ConfigData.php | 40 ++ lib/SP/Config/ConfigUtil.php | 21 +- lib/SP/Controller/ConfigActionController.php | 5 +- lib/SP/Controller/ConfigController.php | 2 +- lib/SP/Controller/ItemActionController.php | 15 +- lib/SP/Controller/ItemListController.php | 2 +- lib/SP/Controller/ItemSearchController.php | 4 +- lib/SP/Controller/ItemShowController.php | 10 +- lib/SP/Controller/LoginController.php | 3 +- lib/SP/Controller/MainActionController.php | 5 +- lib/SP/Controller/RequestControllerTrait.php | 3 +- lib/SP/Controller/TaskController.php | 2 +- lib/SP/Core/Acl/Acl.php | 21 +- lib/SP/Core/Acl/ActionsInterface.php | 12 +- lib/SP/Core/Backup.php | 322 ---------- lib/SP/Core/Context/ContextBase.php | 54 +- lib/SP/Core/Context/ContextCollection.php | 37 ++ lib/SP/Core/Context/ContextException.php | 37 ++ lib/SP/Core/Context/ContextInterface.php | 18 +- lib/SP/Core/Context/SessionContext.php | 79 ++- .../{ApiContext.php => StatelessContext.php} | 78 ++- lib/SP/Core/{ => Crypt}/CryptPKI.php | 5 +- lib/SP/Core/{ => Crypt}/OldCrypt.php | 10 +- lib/SP/Core/Crypt/Session.php | 39 +- lib/SP/Core/Crypt/Vault.php | 23 +- lib/SP/Core/CryptMasterPass.php | 139 ----- lib/SP/Core/DataCollection.php | 291 +++++++++ .../Core/{Traits => Dic}/InjectableTrait.php | 3 +- lib/SP/Core/Install/Installer.php | 3 +- lib/SP/Core/Install/MySQL.php | 3 +- lib/SP/Core/Language.php | 21 +- lib/SP/Core/ModuleBase.php | 4 +- lib/SP/Core/SessionFactory.php | 1 + lib/SP/Core/SessionUtil.php | 104 ---- lib/SP/Core/UI/Theme.php | 32 +- lib/SP/Core/Upgrade/Account.php | 2 +- lib/SP/Core/Upgrade/Category.php | 2 +- lib/SP/Core/Upgrade/Customer.php | 2 +- lib/SP/Core/Upgrade/Group.php | 2 +- lib/SP/Core/Upgrade/Profile.php | 2 +- lib/SP/Core/Upgrade/Upgrade.php | 35 +- lib/SP/Core/Upgrade/User.php | 4 +- lib/SP/Core/XmlExport.php | 571 ------------------ lib/SP/Crypt/TemporaryMasterPass.php | 197 ------ lib/SP/Html/Minify.php | 3 - lib/SP/Http/Request.php | 38 +- lib/SP/Log/ActionLog.php | 3 - lib/SP/Log/Syslog.php | 3 +- lib/SP/Mgmt/CustomFields/CustomFieldsUtil.php | 2 +- lib/SP/Mgmt/ItemBaseTrait.php | 3 +- lib/SP/Mvc/Controller/ControllerTrait.php | 16 +- .../Mvc/View/Components/SelectItemAdapter.php | 13 +- lib/SP/Providers/Auth/Database/Database.php | 2 +- lib/SP/Providers/EventsTrait.php | 42 ++ lib/SP/Providers/Log/LogHandler.php | 14 +- lib/SP/Providers/Mail/MailHandler.php | 13 +- lib/SP/Providers/Provider.php | 8 +- .../Account/AccountHistoryRepository.php | 2 +- .../Account/AccountRepository.php | 8 +- .../AuthToken/AuthTokenRepository.php | 2 +- lib/SP/Repositories/Repository.php | 22 +- lib/SP/Repositories/User/UserRepository.php | 4 +- lib/SP/Services/Account/AccountAclService.php | 8 +- .../Services/Account/AccountCryptService.php | 4 +- .../Services/Account/AccountFileService.php | 3 - .../Services/Account/AccountSearchService.php | 12 +- lib/SP/Services/Account/AccountService.php | 29 +- lib/SP/Services/Api/ApiService.php | 324 ++++++++++ lib/SP/Services/ApiService/ApiService.php | 102 ---- lib/SP/Services/Auth/LoginService.php | 6 +- .../Services/AuthToken/AuthTokenService.php | 4 +- lib/SP/Services/Client/ClientService.php | 2 +- .../Services/Config/ConfigBackupService.php | 2 +- lib/SP/Services/Config/ConfigService.php | 28 +- .../Crypt/TemporaryMasterPassService.php | 2 +- .../Crypt/UpdateMasterPassRequest.php | 2 +- .../CustomField/CustomFieldCryptService.php | 4 +- .../CustomField/CustomFieldService.php | 10 +- lib/SP/Services/EventLog/EventlogService.php | 2 +- lib/SP/Services/Export/XmlExportService.php | 2 +- lib/SP/Services/Import/ImportTrait.php | 2 +- lib/SP/Services/Import/SyspassImport.php | 2 +- .../Notification/NotificationService.php | 2 +- .../Services/PublicLink/PublicLinkService.php | 12 +- lib/SP/Services/Service.php | 8 +- lib/SP/{Core => Services/Task}/Task.php | 6 +- .../{Core => Services/Task}/TaskFactory.php | 2 +- lib/SP/Services/Task/TaskService.php | 2 - .../Services/Upgrade/UpgradeConfigService.php | 222 +++++++ .../Upgrade/UpgradeDatabaseService.php | 323 ++++++++++ lib/SP/Services/Upgrade/UpgradeException.php | 37 ++ lib/SP/Services/Upgrade/UpgradeUtil.php | 118 ++++ lib/SP/Services/User/UserPassService.php | 30 +- lib/SP/Services/User/UserService.php | 98 +-- .../UserProfile/UserProfileService.php | 2 - lib/SP/Util/Util.php | 8 +- lib/SP/Util/Wiki/DokuWikiApiBase.php | 3 +- public/js/app-actions.js | 8 +- public/js/app-actions.min.js | 24 +- schemas/30018010101.sql | 2 +- 171 files changed, 2545 insertions(+), 5072 deletions(-) rename app/modules/web/Controllers/{ApiTokenController.php => AuthTokenController.php} (89%) delete mode 100644 lib/SP/Account/Account.php delete mode 100644 lib/SP/Account/AccountBase.php delete mode 100644 lib/SP/Account/AccountCrypt.php delete mode 100644 lib/SP/Account/AccountFavorites.php delete mode 100644 lib/SP/Account/AccountHistory.php delete mode 100644 lib/SP/Account/AccountHistoryCrypt.php delete mode 100644 lib/SP/Account/AccountHistoryUtil.php delete mode 100644 lib/SP/Account/AccountTags.php delete mode 100644 lib/SP/Account/UserAccounts.php delete mode 100644 lib/SP/Config/ConfigDB.php delete mode 100644 lib/SP/Core/Backup.php create mode 100644 lib/SP/Core/Context/ContextCollection.php create mode 100644 lib/SP/Core/Context/ContextException.php rename lib/SP/Core/Context/{ApiContext.php => StatelessContext.php} (74%) rename lib/SP/Core/{ => Crypt}/CryptPKI.php (98%) rename lib/SP/Core/{ => Crypt}/OldCrypt.php (96%) delete mode 100644 lib/SP/Core/CryptMasterPass.php create mode 100644 lib/SP/Core/DataCollection.php rename lib/SP/Core/{Traits => Dic}/InjectableTrait.php (95%) delete mode 100644 lib/SP/Core/XmlExport.php delete mode 100644 lib/SP/Crypt/TemporaryMasterPass.php create mode 100644 lib/SP/Providers/EventsTrait.php create mode 100644 lib/SP/Services/Api/ApiService.php delete mode 100644 lib/SP/Services/ApiService/ApiService.php rename lib/SP/{Core => Services/Task}/Task.php (98%) rename lib/SP/{Core => Services/Task}/TaskFactory.php (99%) create mode 100644 lib/SP/Services/Upgrade/UpgradeConfigService.php create mode 100644 lib/SP/Services/Upgrade/UpgradeDatabaseService.php create mode 100644 lib/SP/Services/Upgrade/UpgradeException.php create mode 100644 lib/SP/Services/Upgrade/UpgradeUtil.php diff --git a/app/config/actions.xml b/app/config/actions.xml index d4480928..33c647ea 100644 --- a/app/config/actions.xml +++ b/app/config/actions.xml @@ -57,9 +57,9 @@ 63 - APITOKEN + AUTHTOKEN Gestión Autorizaciones API - apiToken/index + authToken/index 64 @@ -339,33 +339,33 @@ 630 - APITOKEN_CREATE + AUTHTOKEN_CREATE Nuevo Token API - apiToken/create + authToken/create 631 - APITOKEN_VIEW + AUTHTOKEN_VIEW Ver Token API - apiToken/view + authToken/view 632 - APITOKEN_EDIT + AUTHTOKEN_EDIT Editar Token API - apiToken/edit + authToken/edit 633 - APITOKEN_DELETE + AUTHTOKEN_DELETE Eliminar Token API - apiToken/delete + authToken/delete 635 - APITOKEN_SEARCH + AUTHTOKEN_SEARCH Buscar Token API - apiToken/search + authToken/search 640 diff --git a/app/modules/api/Controllers/AccountController.php b/app/modules/api/Controllers/AccountController.php index e918d5b4..743022af 100644 --- a/app/modules/api/Controllers/AccountController.php +++ b/app/modules/api/Controllers/AccountController.php @@ -24,30 +24,29 @@ namespace SP\Modules\Api\Controllers; +use SP\Account\AccountSearchFilter; use SP\Api\ApiResponse; use SP\Core\Acl\ActionsInterface; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Core\Exceptions\ValidationException; -use SP\Modules\Api\Controllers\Traits\ResponseTrait; use SP\Modules\Web\Forms\AccountForm; use SP\Services\Account\AccountService; /** * Class AccountController + * * @package api\Controllers */ class AccountController extends ControllerBase { - use ResponseTrait; - /** * @var AccountService */ protected $accountService; /** - * Saves create action + * createAction */ public function createAction() { @@ -80,6 +79,24 @@ class AccountController extends ControllerBase } } + /** + * searchAction + */ + public function searchAction() + { + try { + $this->apiService->authenticate(ActionsInterface::ACCOUNT_SEARCH); + + $accountSearchFilter = new AccountSearchFilter(); + + $this->accountService->getByFilter($accountSearchFilter); + } catch (\Exception $e) { + $this->returnResponseException($e); + + processException($e); + } + } + /** * @throws \DI\DependencyException * @throws \DI\NotFoundException diff --git a/app/modules/api/Controllers/ControllerBase.php b/app/modules/api/Controllers/ControllerBase.php index dde00655..0326a329 100644 --- a/app/modules/api/Controllers/ControllerBase.php +++ b/app/modules/api/Controllers/ControllerBase.php @@ -25,11 +25,17 @@ namespace SP\Modules\Api\Controllers; use DI\Container; -use SP\Core\Context\ApiContext; +use Klein\Klein; +use SP\Api\ApiResponse; +use SP\Api\JsonRpcResponse; +use SP\Core\Context\StatelessContext; use SP\Core\Events\EventDispatcher; +use SP\Core\Exceptions\SPException; +use SP\Services\Api\ApiService; /** * Class ControllerBase + * * @package SP\Modules\Api\Controllers */ abstract class ControllerBase @@ -47,27 +53,40 @@ abstract class ControllerBase */ protected $actionName; /** - * @var ApiContext + * @var StatelessContext */ protected $context; /** * @var EventDispatcher */ protected $eventDispatcher; + /** + * @var ApiService + */ + protected $apiService; + /** + * @var Klein + */ + protected $router; /** * Constructor * * @param Container $container - * @param $actionName - * @throws \Psr\Container\ContainerExceptionInterface - * @throws \Psr\Container\NotFoundExceptionInterface + * @param string $actionName + * @param mixed $requesData + * @throws \DI\DependencyException + * @throws \DI\NotFoundException */ - public final function __construct(Container $container, $actionName) + public final function __construct(Container $container, $actionName, $requesData) { $this->dic = $container; - $this->context = $container->get(ApiContext::class); + $this->context = $container->get(StatelessContext::class); $this->eventDispatcher = $container->get(EventDispatcher::class); + $this->router = $container->get(Klein::class); + + $this->apiService = $container->get(ApiService::class); + $this->apiService->setRequestData($requesData); $this->controllerName = $this->getControllerName(); $this->actionName = $actionName; @@ -86,4 +105,38 @@ abstract class ControllerBase return substr($class, strrpos($class, '\\') + 1, -strlen('Controller')) ?: ''; } + + /** + * Devuelve una respuesta en formato JSON con el estado y el mensaje. + * + * {"jsonrpc": "2.0", "result": 19, "id": 3} + * + * @param ApiResponse $apiResponse + * @param int $id + * @return string La cadena en formato JSON + */ + protected function returnResponse(ApiResponse $apiResponse, $id = 0) + { + $this->router->response()->headers()->set('Content-type', 'application/json; charset=utf-8'); + + try { + exit(JsonRpcResponse::getResponse($apiResponse, $id)); + } catch (SPException $e) { + processException($e); + + exit(JsonRpcResponse::getResponseException($e, $id)); + } + } + + /** + * @param \Exception $e + * @param int $id + * @return string + */ + protected function returnResponseException(\Exception $e, $id = 0) + { + $this->router->response()->headers()->set('Content-type', 'application/json; charset=utf-8'); + + exit(JsonRpcResponse::getResponseException($e, $id)); + } } \ No newline at end of file diff --git a/app/modules/api/Init.php b/app/modules/api/Init.php index 8e95c2b6..97976f31 100644 --- a/app/modules/api/Init.php +++ b/app/modules/api/Init.php @@ -25,7 +25,7 @@ namespace SP\Modules\Api; use DI\Container; -use SP\Core\Context\ApiContext; +use SP\Core\Context\StatelessContext; use SP\Core\Exceptions\InitializationException; use SP\Core\Language; use SP\Core\ModuleBase; @@ -35,12 +35,13 @@ use SP\Util\HttpUtil; /** * Class Init + * * @package api */ class Init extends ModuleBase { /** - * @var ApiContext + * @var StatelessContext */ protected $context; /** @@ -59,12 +60,12 @@ class Init extends ModuleBase { parent::__construct($container); - $this->context = $container->get(ApiContext::class); + $this->context = $container->get(StatelessContext::class); $this->language = $container->get(Language::class); } /** - * @param $controller + * @param string $controller * @throws InitializationException * @throws \DI\DependencyException * @throws \DI\NotFoundException diff --git a/app/modules/web/Controllers/AccessManagerController.php b/app/modules/web/Controllers/AccessManagerController.php index 74b7e087..d9d1dfb3 100644 --- a/app/modules/web/Controllers/AccessManagerController.php +++ b/app/modules/web/Controllers/AccessManagerController.php @@ -92,7 +92,7 @@ class AccessManagerController extends ControllerBase $this->tabsGridHelper->addTab($this->getUsersProfileList()); } - if ($this->checkAccess(ActionsInterface::APITOKEN)) { + if ($this->checkAccess(ActionsInterface::AUTHTOKEN)) { $this->tabsGridHelper->addTab($this->getApiTokensList()); } @@ -153,7 +153,7 @@ class AccessManagerController extends ControllerBase */ protected function getApiTokensList() { - return $this->itemsGridHelper->getApiTokensGrid($this->dic->get(AuthTokenService::class)->search($this->itemSearchData))->updatePager(); + return $this->itemsGridHelper->getAuthTokensGrid($this->dic->get(AuthTokenService::class)->search($this->itemSearchData))->updatePager(); } /** diff --git a/app/modules/web/Controllers/ApiTokenController.php b/app/modules/web/Controllers/AuthTokenController.php similarity index 89% rename from app/modules/web/Controllers/ApiTokenController.php rename to app/modules/web/Controllers/AuthTokenController.php index 67272f21..f226b762 100644 --- a/app/modules/web/Controllers/ApiTokenController.php +++ b/app/modules/web/Controllers/AuthTokenController.php @@ -43,11 +43,11 @@ use SP\Services\AuthToken\AuthTokenService; use SP\Services\User\UserService; /** - * Class ApiTokenController + * Class AuthTokenController * * @package SP\Modules\Web\Controllers */ -class ApiTokenController extends ControllerBase implements CrudControllerInterface +class AuthTokenController extends ControllerBase implements CrudControllerInterface { use JsonTrait, ItemTrait; @@ -64,7 +64,7 @@ class ApiTokenController extends ControllerBase implements CrudControllerInterfa */ public function searchAction() { - if (!$this->acl->checkUserAccess(ActionsInterface::APITOKEN_SEARCH)) { + if (!$this->acl->checkUserAccess(ActionsInterface::AUTHTOKEN_SEARCH)) { return; } @@ -85,7 +85,7 @@ class ApiTokenController extends ControllerBase implements CrudControllerInterfa $itemsGridHelper = $this->dic->get(ItemsGridHelper::class); $itemSearchData = $this->getSearchData($this->configData->getAccountCount()); - return $itemsGridHelper->updatePager($itemsGridHelper->getApiTokensGrid($this->authTokenService->search($itemSearchData)), $itemSearchData); + return $itemsGridHelper->updatePager($itemsGridHelper->getAuthTokensGrid($this->authTokenService->search($itemSearchData)), $itemSearchData); } /** @@ -95,14 +95,14 @@ class ApiTokenController extends ControllerBase implements CrudControllerInterfa */ public function createAction() { - if (!$this->acl->checkUserAccess(ActionsInterface::APITOKEN_CREATE)) { + if (!$this->acl->checkUserAccess(ActionsInterface::AUTHTOKEN_CREATE)) { return; } $this->view->assign(__FUNCTION__, 1); $this->view->assign('header', __('Nueva Autorización')); $this->view->assign('isView', false); - $this->view->assign('route', 'apiToken/saveCreate'); + $this->view->assign('route', 'authToken/saveCreate'); try { $this->setViewData(); @@ -145,7 +145,7 @@ class ApiTokenController extends ControllerBase implements CrudControllerInterfa $this->view->assign('readonly'); } - $this->view->assign('customFields', $this->getCustomFieldsForItem(ActionsInterface::APITOKEN, $authTokenId)); + $this->view->assign('customFields', $this->getCustomFieldsForItem(ActionsInterface::AUTHTOKEN, $authTokenId)); } /** @@ -156,13 +156,13 @@ class ApiTokenController extends ControllerBase implements CrudControllerInterfa */ public function editAction($id) { - if (!$this->acl->checkUserAccess(ActionsInterface::APITOKEN_EDIT)) { + if (!$this->acl->checkUserAccess(ActionsInterface::AUTHTOKEN_EDIT)) { return; } $this->view->assign('header', __('Editar Autorización')); $this->view->assign('isView', false); - $this->view->assign('route', 'apiToken/saveEdit/' . $id); + $this->view->assign('route', 'authToken/saveEdit/' . $id); try { $this->setViewData($id); @@ -186,7 +186,7 @@ class ApiTokenController extends ControllerBase implements CrudControllerInterfa */ public function deleteAction($id = null) { - if (!$this->acl->checkUserAccess(ActionsInterface::APITOKEN_DELETE)) { + if (!$this->acl->checkUserAccess(ActionsInterface::AUTHTOKEN_DELETE)) { return; } @@ -194,7 +194,7 @@ class ApiTokenController extends ControllerBase implements CrudControllerInterfa if ($id === null) { $this->authTokenService->deleteByIdBatch($this->getItemsIdFromRequest()); - $this->deleteCustomFieldsForItem(ActionsInterface::APITOKEN, $id); + $this->deleteCustomFieldsForItem(ActionsInterface::AUTHTOKEN, $id); $this->eventDispatcher->notifyEvent('delete.authToken.selection', new Event($this, @@ -206,7 +206,7 @@ class ApiTokenController extends ControllerBase implements CrudControllerInterfa } else { $this->authTokenService->delete($id); - $this->deleteCustomFieldsForItem(ActionsInterface::APITOKEN, $id); + $this->deleteCustomFieldsForItem(ActionsInterface::AUTHTOKEN, $id); $this->eventDispatcher->notifyEvent('delete.authToken', new Event($this, @@ -229,19 +229,19 @@ class ApiTokenController extends ControllerBase implements CrudControllerInterfa */ public function saveCreateAction() { - if (!$this->acl->checkUserAccess(ActionsInterface::APITOKEN_CREATE)) { + if (!$this->acl->checkUserAccess(ActionsInterface::AUTHTOKEN_CREATE)) { return; } try { $form = new AuthTokenForm(); - $form->validate(ActionsInterface::APITOKEN_CREATE); + $form->validate(ActionsInterface::AUTHTOKEN_CREATE); $apiTokenData = $form->getItemData(); $id = $this->authTokenService->create($apiTokenData); - $this->addCustomFieldsForItem(ActionsInterface::APITOKEN, $id); + $this->addCustomFieldsForItem(ActionsInterface::AUTHTOKEN, $id); $this->eventDispatcher->notifyEvent('create.authToken', new Event($this)); @@ -264,13 +264,13 @@ class ApiTokenController extends ControllerBase implements CrudControllerInterfa */ public function saveEditAction($id) { - if (!$this->acl->checkUserAccess(ActionsInterface::APITOKEN_EDIT)) { + if (!$this->acl->checkUserAccess(ActionsInterface::AUTHTOKEN_EDIT)) { return; } try { $form = new AuthTokenForm($id); - $form->validate(ActionsInterface::APITOKEN_EDIT); + $form->validate(ActionsInterface::AUTHTOKEN_EDIT); if ($form->isRefresh()) { $this->authTokenService->refreshAndUpdate($form->getItemData()); @@ -292,7 +292,7 @@ class ApiTokenController extends ControllerBase implements CrudControllerInterfa ); } - $this->updateCustomFieldsForItem(ActionsInterface::APITOKEN, $id); + $this->updateCustomFieldsForItem(ActionsInterface::AUTHTOKEN, $id); $this->returnJsonResponse(JsonResponse::JSON_SUCCESS, __u('Autorización actualizada')); } catch (ValidationException $e) { @@ -312,7 +312,7 @@ class ApiTokenController extends ControllerBase implements CrudControllerInterfa */ public function viewAction($id) { - if (!$this->acl->checkUserAccess(ActionsInterface::APITOKEN_VIEW)) { + if (!$this->acl->checkUserAccess(ActionsInterface::AUTHTOKEN_VIEW)) { return; } diff --git a/app/modules/web/Controllers/BootstrapController.php b/app/modules/web/Controllers/BootstrapController.php index 7e02c558..fb54e916 100644 --- a/app/modules/web/Controllers/BootstrapController.php +++ b/app/modules/web/Controllers/BootstrapController.php @@ -25,7 +25,7 @@ namespace SP\Modules\Web\Controllers; use SP\Bootstrap; -use SP\Core\CryptPKI; +use SP\Core\Crypt\CryptPKI; use SP\Http\Cookies; use SP\Http\Response; use SP\Providers\Auth\Browser\Browser; diff --git a/app/modules/web/Controllers/ConfigEncryptionController.php b/app/modules/web/Controllers/ConfigEncryptionController.php index 8130945e..cff6be3d 100644 --- a/app/modules/web/Controllers/ConfigEncryptionController.php +++ b/app/modules/web/Controllers/ConfigEncryptionController.php @@ -33,7 +33,6 @@ use SP\Core\Crypt\Session as CryptSession; use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Core\Messages\MailMessage; -use SP\Core\TaskFactory; use SP\Http\JsonResponse; use SP\Http\Request; use SP\Modules\Web\Controllers\Traits\JsonTrait; @@ -42,6 +41,7 @@ use SP\Services\Crypt\MasterPassService; use SP\Services\Crypt\TemporaryMasterPassService; use SP\Services\Crypt\UpdateMasterPassRequest; use SP\Services\MailService; +use SP\Services\Task\TaskFactory; use SP\Services\User\UserService; use SP\Util\Util; @@ -162,7 +162,7 @@ class ConfigEncryptionController extends SimpleControllerBase try { $configService = $this->dic->get(ConfigService::class); - $configService->save('masterPwd', Hash::hashKey(CryptSession::getSessionKey())); + $configService->save('masterPwd', Hash::hashKey(CryptSession::getSessionKey($this->session))); $this->eventDispatcher->notifyEvent('refresh.masterPassword', new Event($this, EventMessage::factory()->addDescription(__u('Hash de clave maestra actualizado')))); diff --git a/app/modules/web/Controllers/ConfigGeneralController.php b/app/modules/web/Controllers/ConfigGeneralController.php index 9b4ebbbf..da045292 100644 --- a/app/modules/web/Controllers/ConfigGeneralController.php +++ b/app/modules/web/Controllers/ConfigGeneralController.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,6 +24,7 @@ namespace SP\Modules\Web\Controllers; +use SP\Config\ConfigUtil; use SP\Core\Acl\ActionsInterface; use SP\Core\Acl\UnauthorizedPageException; use SP\Core\Events\Event; @@ -78,6 +79,10 @@ class ConfigGeneralController extends SimpleControllerBase $syslogPort = Request::analyzeInt('remotesyslog_port', 0); $configData->setLogEnabled($logEnabled); + $configData->setLogEvents(Request::analyzeArray('log_events', function ($items) { + return ConfigUtil::eventsAdapter($items); + })); + $configData->setSyslogEnabled($syslogEnabled); if ($remoteSyslogEnabled) { diff --git a/app/modules/web/Controllers/ConfigMailController.php b/app/modules/web/Controllers/ConfigMailController.php index 3b4485fd..2efabc62 100644 --- a/app/modules/web/Controllers/ConfigMailController.php +++ b/app/modules/web/Controllers/ConfigMailController.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. @@ -77,6 +77,9 @@ class ConfigMailController extends SimpleControllerBase $configData->setMailSecurity($mailSecurity); $configData->setMailFrom($mailFrom); $configData->setMailRecipients($mailRecipients); + $configData->setMailEvents(Request::analyzeArray('mail_events', function ($items) { + return ConfigUtil::eventsAdapter($items); + })); if ($mailAuth) { $configData->setMailAuthenabled($mailAuth); diff --git a/app/modules/web/Controllers/ConfigManagerController.php b/app/modules/web/Controllers/ConfigManagerController.php index 208c58c7..b9efb526 100644 --- a/app/modules/web/Controllers/ConfigManagerController.php +++ b/app/modules/web/Controllers/ConfigManagerController.php @@ -32,13 +32,16 @@ use SP\Core\CryptMasterPass; use SP\Core\Events\Event; use SP\Core\Language; use SP\Core\Plugin\PluginUtil; -use SP\Core\Task; use SP\Http\Request; use SP\Modules\Web\Controllers\Helpers\TabsHelper; use SP\Mvc\View\Components\DataTab; use SP\Mvc\View\Components\SelectItemAdapter; +use SP\Providers\Log\LogHandler; +use SP\Providers\Mail\MailHandler; use SP\Services\Account\AccountService; use SP\Services\Config\ConfigService; +use SP\Services\Crypt\TemporaryMasterPassService; +use SP\Services\Task\Task; use SP\Services\User\UserService; use SP\Services\UserGroup\UserGroupService; use SP\Services\UserProfile\UserProfileService; @@ -146,6 +149,10 @@ class ConfigManagerController extends ControllerBase $template->assign('userGroups', SelectItemAdapter::factory(UserGroupService::getItemsBasic())->getItemsFromModel()); $template->assign('userProfiles', SelectItemAdapter::factory(UserProfileService::getItemsBasic())->getItemsFromModel()); + $template->assign('logEvents', SelectItemAdapter::factory(LogHandler::EVENTS) + ->getItemsFromArraySelected($this->configData->getLogEvents(), true) + ); + return new DataTab(__('General'), $template); } @@ -205,6 +212,9 @@ class ConfigManagerController extends ControllerBase $template->assign('mailSecurity', ['SSL', 'TLS']); $template->assign('userGroups', SelectItemAdapter::factory(UserGroupService::getItemsBasic())->getItemsFromModel()); $template->assign('userProfiles', SelectItemAdapter::factory(UserProfileService::getItemsBasic())->getItemsFromModel()); + $template->assign('mailEvents', SelectItemAdapter::factory(MailHandler::EVENTS) + ->getItemsFromArraySelected($this->configData->getMailEvents(), true) + ); return new DataTab(__('Correo'), $template); } @@ -234,7 +244,7 @@ class ConfigManagerController extends ControllerBase $template->assign('tempMasterPassTime', $configService->getByParam('tempmaster_passtime', 0)); $template->assign('tempMasterMaxTime', $configService->getByParam('tempmaster_maxtime', 0)); - $tempMasterAttempts = sprintf('%d/%d', $configService->getByParam('tempmaster_attempts', 0), CryptMasterPass::MAX_ATTEMPTS); + $tempMasterAttempts = sprintf('%d/%d', $configService->getByParam('tempmaster_attempts', 0), TemporaryMasterPassService::MAX_ATTEMPTS); $template->assign('tempMasterAttempts', $tempMasterAttempts); $template->assign('tempMasterPass', $this->session->getTemporaryMasterPass()); diff --git a/app/modules/web/Controllers/ControllerBase.php b/app/modules/web/Controllers/ControllerBase.php index 1dd9ba77..49a87284 100644 --- a/app/modules/web/Controllers/ControllerBase.php +++ b/app/modules/web/Controllers/ControllerBase.php @@ -32,6 +32,7 @@ use Psr\Container\ContainerInterface; use SP\Config\Config; use SP\Config\ConfigData; use SP\Core\Acl\Acl; +use SP\Core\Context\ContextInterface; use SP\Core\Context\SessionContext; use SP\Core\Events\EventDispatcher; use SP\Core\Exceptions\FileNotFoundException; @@ -144,7 +145,7 @@ abstract class ControllerBase $this->config = $this->dic->get(Config::class); $this->configData = $this->config->getConfigData(); - $this->session = $this->dic->get(SessionContext::class); + $this->session = $this->dic->get(ContextInterface::class); $this->theme = $this->dic->get(Theme::class); $this->eventDispatcher = $this->dic->get(EventDispatcher::class); $this->acl = $this->dic->get(Acl::class); diff --git a/app/modules/web/Controllers/ErrorController.php b/app/modules/web/Controllers/ErrorController.php index 5cd820f2..431d1f45 100644 --- a/app/modules/web/Controllers/ErrorController.php +++ b/app/modules/web/Controllers/ErrorController.php @@ -26,7 +26,6 @@ namespace SP\Modules\Web\Controllers; use Klein\Klein; use SP\Bootstrap; -use SP\Core\Traits\InjectableTrait; use SP\Mvc\View\Template; use SP\Util\Util; @@ -37,7 +36,7 @@ use SP\Util\Util; */ class ErrorController { - use InjectableTrait; + use SP\Core\Dic\InjectableTrait; /** * @var Template diff --git a/app/modules/web/Controllers/Helpers/Account/AccountActionsHelper.php b/app/modules/web/Controllers/Helpers/Account/AccountActionsHelper.php index bc51933d..bd394199 100644 --- a/app/modules/web/Controllers/Helpers/Account/AccountActionsHelper.php +++ b/app/modules/web/Controllers/Helpers/Account/AccountActionsHelper.php @@ -421,7 +421,7 @@ class AccountActionsHelper extends HelperBase */ protected function initialize() { - $this->sk = $this->session->generateSecurityKey(); + $this->sk = $this->context->generateSecurityKey(); $this->icons = $this->view->getTheme()->getIcons(); } } \ No newline at end of file diff --git a/app/modules/web/Controllers/Helpers/Account/AccountHelper.php b/app/modules/web/Controllers/Helpers/Account/AccountHelper.php index 93927354..e338ff70 100644 --- a/app/modules/web/Controllers/Helpers/Account/AccountHelper.php +++ b/app/modules/web/Controllers/Helpers/Account/AccountHelper.php @@ -146,8 +146,8 @@ class AccountHelper extends HelperBase $this->view->assign('publicLinkShow', false); } - $userData = $this->session->getUserData(); - $userProfileData = $this->session->getUserProfile(); + $userData = $this->context->getUserData(); + $userProfileData = $this->context->getUserProfile(); $this->view->assign('allowPrivate', $userProfileData->isAccPrivate() && $accountData->getUserId() === $userData->getId()); $this->view->assign('allowPrivateGroup', $userProfileData->isAccPrivateGroup() && $accountData->getUserGroupId() === $userData->getUserGroupId()); @@ -176,7 +176,7 @@ class AccountHelper extends HelperBase throw new UnauthorizedPageException(UnauthorizedPageException::INFO); } - if (!$this->dic->get(MasterPassService::class)->checkUserUpdateMPass($this->session->getUserData()->getLastUpdateMPass())) { + if (!$this->dic->get(MasterPassService::class)->checkUserUpdateMPass($this->context->getUserData()->getLastUpdateMPass())) { throw new UpdatedMasterPassException(UpdatedMasterPassException::INFO); } } @@ -277,7 +277,7 @@ class AccountHelper extends HelperBase $this->view->assign('userGroups', $selectUserGroups->getItemsFromModel()); $this->view->assign('tags', $selectTags->getItemsFromModel()); - $userProfileData = $this->session->getUserProfile(); + $userProfileData = $this->context->getUserProfile(); $this->view->assign('allowPrivate', $userProfileData->isAccPrivate()); $this->view->assign('allowPrivateGroup', $userProfileData->isAccPrivateGroup()); @@ -342,6 +342,6 @@ class AccountHelper extends HelperBase $this->view->assign('changesHash'); $this->view->assign('chkUserEdit'); $this->view->assign('chkGroupEdit'); - $this->view->assign('sk', $this->session->generateSecurityKey()); + $this->view->assign('sk', $this->context->generateSecurityKey()); } } \ No newline at end of file diff --git a/app/modules/web/Controllers/Helpers/Account/AccountHistoryHelper.php b/app/modules/web/Controllers/Helpers/Account/AccountHistoryHelper.php index c34dd5c5..c60f9079 100644 --- a/app/modules/web/Controllers/Helpers/Account/AccountHistoryHelper.php +++ b/app/modules/web/Controllers/Helpers/Account/AccountHistoryHelper.php @@ -121,7 +121,7 @@ class AccountHistoryHelper extends HelperBase throw new UnauthorizedPageException(UnauthorizedPageException::INFO); } - if (!$this->dic->get(MasterPassService::class)->checkUserUpdateMPass($this->session->getUserData()->getLastUpdateMPass())) { + if (!$this->dic->get(MasterPassService::class)->checkUserUpdateMPass($this->context->getUserData()->getLastUpdateMPass())) { throw new UpdatedMasterPassException(UpdatedMasterPassException::INFO); } } @@ -160,6 +160,6 @@ class AccountHistoryHelper extends HelperBase $this->acl = $this->dic->get(Acl::class); $this->accountHistoryService = $this->dic->get(AccountHistoryService::class);; - $this->view->assign('sk', $this->session->generateSecurityKey()); + $this->view->assign('sk', $this->context->generateSecurityKey()); } } \ No newline at end of file diff --git a/app/modules/web/Controllers/Helpers/Account/AccountPasswordHelper.php b/app/modules/web/Controllers/Helpers/Account/AccountPasswordHelper.php index d7a352ea..0e1300af 100644 --- a/app/modules/web/Controllers/Helpers/Account/AccountPasswordHelper.php +++ b/app/modules/web/Controllers/Helpers/Account/AccountPasswordHelper.php @@ -89,11 +89,11 @@ class AccountPasswordHelper extends HelperBase throw new HelperException(__u('No tiene permisos para acceder a esta cuenta')); } - if (!$this->dic->get(MasterPassService::class)->checkUserUpdateMPass($this->session->getUserData()->getLastUpdateMPass())) { + if (!$this->dic->get(MasterPassService::class)->checkUserUpdateMPass($this->context->getUserData()->getLastUpdateMPass())) { throw new HelperException(__('Clave maestra actualizada') . '
' . __('Reinicie la sesión para cambiarla')); } - $key = CryptSession::getSessionKey(); + $key = CryptSession::getSessionKey($this->context); $securedKey = Crypt::unlockSecuredKey($accountData->getKey(), $key); return trim(Crypt::decrypt($accountData->getPass(), $securedKey, $key)); @@ -123,6 +123,6 @@ class AccountPasswordHelper extends HelperBase } $this->view->assign('isLinked', $accountData->getParentId() > 0); - $this->view->assign('sk', $this->session->generateSecurityKey()); + $this->view->assign('sk', $this->context->generateSecurityKey()); } } \ No newline at end of file diff --git a/app/modules/web/Controllers/Helpers/Account/AccountSearchHelper.php b/app/modules/web/Controllers/Helpers/Account/AccountSearchHelper.php index af62d8c6..3b305819 100644 --- a/app/modules/web/Controllers/Helpers/Account/AccountSearchHelper.php +++ b/app/modules/web/Controllers/Helpers/Account/AccountSearchHelper.php @@ -114,7 +114,7 @@ class AccountSearchHelper extends HelperBase || $this->accountSearchFilter->isSearchFavorites() || $this->accountSearchFilter->isSortViews()); - $userPreferences = $this->session->getUserData()->getPreferences(); + $userPreferences = $this->context->getUserData()->getPreferences(); AccountSearchItem::$accountLink = $userPreferences->isAccountLink(); AccountSearchItem::$topNavbar = $userPreferences->isTopNavbar(); @@ -141,7 +141,7 @@ class AccountSearchHelper extends HelperBase // Establecer el filtro de búsqueda en la sesión como un objeto - $this->session->setSearchFilters($this->accountSearchFilter); + $this->context->setSearchFilters($this->accountSearchFilter); $this->view->assign('data', $Grid); } @@ -176,7 +176,7 @@ class AccountSearchHelper extends HelperBase $GridPager->setFilterOn($this->filterOn); $GridPager->setSourceAction(new DataGridActionSearch(ActionsInterface::ACCOUNT_SEARCH)); - $userPreferences = $this->session->getUserData()->getPreferences(); + $userPreferences = $this->context->getUserData()->getPreferences(); $showOptionalActions = $userPreferences->isOptionalActions() || $userPreferences->isResultsAsCards() || ($userPreferences->getUserId() === 0 && $this->configData->isResultsAsCards()); $actions = $this->dic->get(AccountActionsHelper::class); @@ -262,7 +262,7 @@ class AccountSearchHelper extends HelperBase protected function initialize() { $this->queryTimeStart = microtime(); - $this->sk = $this->session->generateSecurityKey(); + $this->sk = $this->context->generateSecurityKey(); $this->view->assign('sk', $this->sk); $this->setVars(); } @@ -272,10 +272,10 @@ class AccountSearchHelper extends HelperBase */ private function setVars() { - $userData = $this->session->getUserData(); + $userData = $this->context->getUserData(); $this->view->assign('isAdmin', $userData->getIsAdminApp() || $userData->getIsAdminAcc()); - $this->view->assign('showGlobalSearch', $this->configData->isGlobalSearch() && $this->session->getUserProfile()->isAccGlobalSearch()); + $this->view->assign('showGlobalSearch', $this->configData->isGlobalSearch() && $this->context->getUserProfile()->isAccGlobalSearch()); // Obtener el filtro de búsqueda desde la sesión $this->accountSearchFilter = $this->getFilters(); @@ -299,14 +299,14 @@ class AccountSearchHelper extends HelperBase */ private function getFilters() { - $accountSearchFilter = $this->session->getSearchFilters(); + $accountSearchFilter = $this->context->getSearchFilters(); if ($accountSearchFilter !== null && empty(Request::analyzeString('sk'))) { // Obtener el filtro de búsqueda desde la sesión return $accountSearchFilter; } - $userPreferences = $this->session->getUserData()->getPreferences(); + $userPreferences = $this->context->getUserData()->getPreferences(); $limitCount = ($userPreferences->getResultsPerPage() > 0) ? $userPreferences->getResultsPerPage() : $this->configData->getAccountCount(); $accountSearchFilter = new AccountSearchFilter(); diff --git a/app/modules/web/Controllers/Helpers/HelperBase.php b/app/modules/web/Controllers/Helpers/HelperBase.php index 7b811cae..a717f181 100644 --- a/app/modules/web/Controllers/Helpers/HelperBase.php +++ b/app/modules/web/Controllers/Helpers/HelperBase.php @@ -28,6 +28,7 @@ use DI\Container; use Psr\Container\ContainerInterface; use SP\Config\Config; use SP\Config\ConfigData; +use SP\Core\Context\ContextInterface; use SP\Core\Context\SessionContext; use SP\Core\Events\EventDispatcher; use SP\Mvc\View\Template; @@ -50,7 +51,7 @@ abstract class HelperBase /** * @var SessionContext */ - protected $session; + protected $context; /** * @var EventDispatcher */ @@ -69,17 +70,17 @@ abstract class HelperBase * * @param \SP\Mvc\View\Template $template * @param Config $config - * @param SessionContext $session + * @param ContextInterface $context * @param EventDispatcher $eventDispatcher * @param Container $container */ - final public function __construct(Template $template, Config $config, SessionContext $session, EventDispatcher $eventDispatcher, Container $container) + final public function __construct(Template $template, Config $config, ContextInterface $context, EventDispatcher $eventDispatcher, Container $container) { $this->dic = $container; $this->view = $template; $this->config = $config; $this->configData = $config->getConfigData(); - $this->session = $session; + $this->context = $context; $this->eventDispatcher = $eventDispatcher; if (method_exists($this, 'initialize')) { diff --git a/app/modules/web/Controllers/Helpers/ItemsGridHelper.php b/app/modules/web/Controllers/Helpers/ItemsGridHelper.php index 295864e4..760bbd36 100644 --- a/app/modules/web/Controllers/Helpers/ItemsGridHelper.php +++ b/app/modules/web/Controllers/Helpers/ItemsGridHelper.php @@ -851,7 +851,7 @@ class ItemsGridHelper extends HelperBase * @param array $data * @return DataGridTab */ - public function getApiTokensGrid(array $data) + public function getAuthTokensGrid(array $data) { // Grid Header $GridHeaders = new DataGridHeader(); @@ -877,59 +877,59 @@ class ItemsGridHelper extends HelperBase // Grid Actions $GridActionSearch = new DataGridActionSearch(); - $GridActionSearch->setId(ActionsInterface::APITOKEN_SEARCH); + $GridActionSearch->setId(ActionsInterface::AUTHTOKEN_SEARCH); $GridActionSearch->setType(DataGridActionType::SEARCH_ITEM); $GridActionSearch->setName('frmSearchToken'); $GridActionSearch->setTitle(__('Buscar Token')); $GridActionSearch->setOnSubmitFunction('appMgmt/search'); - $GridActionSearch->addData('action-route', Acl::getActionRoute(ActionsInterface::APITOKEN_SEARCH)); + $GridActionSearch->addData('action-route', Acl::getActionRoute(ActionsInterface::AUTHTOKEN_SEARCH)); $Grid->setDataActions($GridActionSearch); $Grid->setPager($this->getPager($GridActionSearch)); // Grid item's actions $GridActionNew = new DataGridAction(); - $GridActionNew->setId(ActionsInterface::APITOKEN_CREATE); + $GridActionNew->setId(ActionsInterface::AUTHTOKEN_CREATE); $GridActionNew->setType(DataGridActionType::MENUBAR_ITEM); $GridActionNew->setName(__('Nueva Autorización')); $GridActionNew->setTitle(__('Nueva Autorización')); $GridActionNew->setIcon($this->icons->getIconAdd()); $GridActionNew->setSkip(true); $GridActionNew->setOnClickFunction('appMgmt/show'); - $GridActionNew->addData('action-route', Acl::getActionRoute(ActionsInterface::APITOKEN_CREATE)); + $GridActionNew->addData('action-route', Acl::getActionRoute(ActionsInterface::AUTHTOKEN_CREATE)); $Grid->setDataActions($GridActionNew); $GridActionView = new DataGridAction(); - $GridActionView->setId(ActionsInterface::APITOKEN_VIEW); + $GridActionView->setId(ActionsInterface::AUTHTOKEN_VIEW); $GridActionView->setType(DataGridActionType::VIEW_ITEM); $GridActionView->setName(__('Ver token de Autorización')); $GridActionView->setTitle(__('Ver token de Autorización')); $GridActionView->setIcon($this->icons->getIconView()); $GridActionView->setOnClickFunction('appMgmt/show'); - $GridActionView->addData('action-route', Acl::getActionRoute(ActionsInterface::APITOKEN_VIEW)); + $GridActionView->addData('action-route', Acl::getActionRoute(ActionsInterface::AUTHTOKEN_VIEW)); $Grid->setDataActions($GridActionView); $GridActionEdit = new DataGridAction(); - $GridActionEdit->setId(ActionsInterface::APITOKEN_EDIT); + $GridActionEdit->setId(ActionsInterface::AUTHTOKEN_EDIT); $GridActionEdit->setType(DataGridActionType::EDIT_ITEM); $GridActionEdit->setName(__('Editar Autorización')); $GridActionEdit->setTitle(__('Editar Autorización')); $GridActionEdit->setIcon($this->icons->getIconEdit()); $GridActionEdit->setOnClickFunction('appMgmt/show'); - $GridActionEdit->addData('action-route', Acl::getActionRoute(ActionsInterface::APITOKEN_EDIT)); + $GridActionEdit->addData('action-route', Acl::getActionRoute(ActionsInterface::AUTHTOKEN_EDIT)); $Grid->setDataActions($GridActionEdit); $GridActionDel = new DataGridAction(); - $GridActionDel->setId(ActionsInterface::APITOKEN_DELETE); + $GridActionDel->setId(ActionsInterface::AUTHTOKEN_DELETE); $GridActionDel->setType(DataGridActionType::DELETE_ITEM); $GridActionDel->setName(__('Eliminar Autorización')); $GridActionDel->setTitle(__('Eliminar Autorización')); $GridActionDel->setIcon($this->icons->getIconDelete()); $GridActionDel->setOnClickFunction('appMgmt/delete'); - $GridActionDel->addData('action-route', Acl::getActionRoute(ActionsInterface::APITOKEN_DELETE)); + $GridActionDel->addData('action-route', Acl::getActionRoute(ActionsInterface::AUTHTOKEN_DELETE)); $Grid->setDataActions($GridActionDel); $Grid->setDataActions($GridActionDel, true); @@ -1255,9 +1255,9 @@ class ItemsGridHelper extends HelperBase $text); } - if (strlen($text) >= 150) { - $text = wordwrap($text, 150, PHP_EOL, true); - } +// if (strlen($text) >= 100) { +// $text = wordwrap($text, 100, PHP_EOL, true); +// } return str_replace(PHP_EOL, '
', $text); }); @@ -1322,7 +1322,7 @@ class ItemsGridHelper extends HelperBase */ public function getNotificationsGrid(array $data) { - $isAdminApp = $this->session->getUserData()->getIsAdminApp(); + $isAdminApp = $this->context->getUserData()->getIsAdminApp(); // Grid Header $GridHeaders = new DataGridHeader(); diff --git a/app/modules/web/Controllers/Helpers/LayoutHelper.php b/app/modules/web/Controllers/Helpers/LayoutHelper.php index e20da22c..d57b7b36 100644 --- a/app/modules/web/Controllers/Helpers/LayoutHelper.php +++ b/app/modules/web/Controllers/Helpers/LayoutHelper.php @@ -27,11 +27,11 @@ namespace SP\Modules\Web\Controllers\Helpers; use SP\Bootstrap; use SP\Core\Acl\Acl; use SP\Core\Acl\ActionsInterface; +use SP\Core\Crypt\CryptPKI; use SP\Core\Dic\ContainerException; use SP\Core\Exceptions\SPException; use SP\Core\Language; use SP\Core\Plugin\PluginUtil; -use SP\Core\SessionUtil; use SP\Core\UI\Theme; use SP\Core\UI\ThemeInterface; use SP\Html\DataGrid\DataGridAction; @@ -93,15 +93,13 @@ class LayoutHelper extends HelperBase /** * Inicializar las variables para la vista principal de la aplicación - * - * @throws ContainerException */ public function initBody() { $this->view->assign('startTime', microtime()); $this->view->assign('isInstalled', $this->configData->isInstalled()); - $this->view->assign('sk', $this->loggedIn ? $this->session->generateSecurityKey() : ''); + $this->view->assign('sk', $this->loggedIn ? $this->context->generateSecurityKey() : ''); $this->view->assign('appInfo', Util::getAppInfo()); $this->view->assign('appVersion', Util::getVersionString()); $this->view->assign('isDemoMode', $this->configData->isDemoEnabled()); @@ -112,16 +110,16 @@ class LayoutHelper extends HelperBase $this->view->assign('logonobg', Bootstrap::$WEBURI . '/public/images/logo_full_nobg.png'); $this->view->assign('httpsEnabled', Checks::httpsEnabled()); - $this->loggedIn = $this->session->isLoggedIn(); + $this->loggedIn = $this->context->isLoggedIn(); $this->view->assign('loggedIn', $this->loggedIn); $this->view->assign('lang', $this->loggedIn ? Language::$userLang : Language::$globalLang); - $this->view->assign('loadApp', $this->session->getAuthCompleted()); + $this->view->assign('loadApp', $this->context->getAuthCompleted()); try { // Cargar la clave pública en la sesión - SessionUtil::loadPublicKey(); + $this->context->setPublicKey($this->dic->get(CryptPKI::class)->getPublicKey()); } catch (SPException $e) { processException($e); } @@ -151,7 +149,7 @@ class LayoutHelper extends HelperBase $this->view->append('jsLinks', $jsUri . '&f=' . $themeJsFiles . '&b=' . $themeJsBase . '&v=' . $jsVersionHash); } - $userPreferences = $this->session->getUserData()->getPreferences(); + $userPreferences = $this->context->getUserData()->getPreferences(); if ($this->loggedIn && $userPreferences->getUserId() > 0) { $resultsAsCards = $userPreferences->isResultsAsCards(); @@ -212,7 +210,7 @@ class LayoutHelper extends HelperBase { $userType = null; - $userData = $this->session->getUserData(); + $userData = $this->context->getUserData(); $icons = $this->theme->getIcons(); if ($userData->getIsAdminApp()) { @@ -371,7 +369,7 @@ class LayoutHelper extends HelperBase { $this->theme = $this->dic->get(Theme::class); - $this->loggedIn = $this->session->isLoggedIn(); + $this->loggedIn = $this->context->isLoggedIn(); $this->view->assign('loggedIn', $this->loggedIn); } diff --git a/app/modules/web/Controllers/MainController.php b/app/modules/web/Controllers/MainController.php index e725c02a..8ec6ec6f 100644 --- a/app/modules/web/Controllers/MainController.php +++ b/app/modules/web/Controllers/MainController.php @@ -29,9 +29,9 @@ defined('APP_ROOT') || die(); use SP\Account\AccountUtil; use SP\Core\DiFactory; use SP\Core\Exceptions\SPException; -use SP\Core\Task; use SP\Core\Upgrade\Check; use SP\Http\Request; +use SP\Services\Task\Task; use SP\Util\Util; /** diff --git a/app/modules/web/Controllers/SimpleControllerBase.php b/app/modules/web/Controllers/SimpleControllerBase.php index 2b7180e1..6de24828 100644 --- a/app/modules/web/Controllers/SimpleControllerBase.php +++ b/app/modules/web/Controllers/SimpleControllerBase.php @@ -31,6 +31,7 @@ use SP\Config\Config; use SP\Config\ConfigData; use SP\Core\Acl\Acl; use SP\Core\Acl\UnauthorizedPageException; +use SP\Core\Context\ContextInterface; use SP\Core\Context\SessionContext; use SP\Core\Events\EventDispatcher; use SP\Core\UI\Theme; @@ -103,7 +104,7 @@ abstract class SimpleControllerBase $this->config = $this->dic->get(Config::class); $this->configData = $this->config->getConfigData(); - $this->session = $this->dic->get(SessionContext::class); + $this->session = $this->dic->get(ContextInterface::class); $this->theme = $this->dic->get(Theme::class); $this->eventDispatcher = $this->dic->get(EventDispatcher::class); $this->router = $this->dic->get(Klein::class); diff --git a/app/modules/web/Controllers/TaskController.php b/app/modules/web/Controllers/TaskController.php index 5cbbe1f8..e1f514ce 100644 --- a/app/modules/web/Controllers/TaskController.php +++ b/app/modules/web/Controllers/TaskController.php @@ -27,9 +27,9 @@ namespace SP\Modules\Web\Controllers; use DI\Container; use Klein\Klein; use SP\Core\Context\SessionContext; -use SP\Core\Task; -use SP\Core\TaskFactory; use SP\Services\ServiceException; +use SP\Services\Task\Task; +use SP\Services\Task\TaskFactory; use SP\Services\Task\TaskService; /** diff --git a/app/modules/web/Controllers/Traits/ItemTrait.php b/app/modules/web/Controllers/Traits/ItemTrait.php index 5b924e5b..84222e5d 100644 --- a/app/modules/web/Controllers/Traits/ItemTrait.php +++ b/app/modules/web/Controllers/Traits/ItemTrait.php @@ -77,7 +77,7 @@ trait ItemTrait $customField->typeName = $item->typeName; $customField->moduleId = (int)$item->moduleId; $customField->formId = CustomFieldService::getFormIdForName($item->definitionName); - $customField->value = $item->data !== null ? CustomFieldService::decryptData($item->data) : ''; + $customField->value = $item->data !== null ? CustomFieldService::decryptData($item->data, $this->session) : ''; $customFields[] = $customField; } catch (CryptoException $e) { diff --git a/app/modules/web/Controllers/UserPassResetController.php b/app/modules/web/Controllers/UserPassResetController.php index 30dbe3e8..68c35cec 100644 --- a/app/modules/web/Controllers/UserPassResetController.php +++ b/app/modules/web/Controllers/UserPassResetController.php @@ -85,17 +85,17 @@ class UserPassResetController extends ControllerBase $login = Request::analyzeString('login'); $email = Request::analyzeEmail('email'); - $userLoginResponse = $this->dic->get(UserService::class)->getByLogin($login); + $userData = $this->dic->get(UserService::class)->getByLogin($login); - if ($userLoginResponse->getEmail() !== $email) { + if ($userData->getEmail() !== $email) { throw new SPException(__u('Datos incorrectos'), SPException::WARNING); } - if ($userLoginResponse->getIsDisabled() || $userLoginResponse->getIsLdap()) { + if ($userData->isDisabled() || $userData->isLdap()) { throw new SPException(__u('No es posible recuperar la clave'), SPException::WARNING, __u('Consulte con el administrador')); } - $hash = $this->dic->get(UserPassRecoverService::class)->requestForUserId($userLoginResponse->getId()); + $hash = $this->dic->get(UserPassRecoverService::class)->requestForUserId($userData->getId()); $this->eventDispatcher->notifyEvent('request.user.passReset', new Event($this, EventMessage::factory() diff --git a/app/modules/web/Forms/AccountForm.php b/app/modules/web/Forms/AccountForm.php index a55964db..349623e8 100644 --- a/app/modules/web/Forms/AccountForm.php +++ b/app/modules/web/Forms/AccountForm.php @@ -85,7 +85,7 @@ class AccountForm extends FormBase implements FormInterface $this->accountRequest->login = Request::analyzeString('login'); $this->accountRequest->url = Request::analyzeString('url'); $this->accountRequest->notes = Request::analyzeString('notes'); - $this->accountRequest->userEditId = $this->session->getUserData()->getId(); + $this->accountRequest->userEditId = $this->context->getUserData()->getId(); $this->accountRequest->otherUserEdit = (int)Request::analyzeBool('otherUserEditEnabled', false); $this->accountRequest->otherUserGroupEdit = (int)Request::analyzeBool('otherUserGroupEditEnabled', false); $this->accountRequest->pass = Request::analyzeEncrypted('pass'); diff --git a/app/modules/web/Forms/AuthTokenForm.php b/app/modules/web/Forms/AuthTokenForm.php index 6b869fbe..e6679e6c 100644 --- a/app/modules/web/Forms/AuthTokenForm.php +++ b/app/modules/web/Forms/AuthTokenForm.php @@ -55,8 +55,8 @@ class AuthTokenForm extends FormBase implements FormInterface public function validate($action) { switch ($action) { - case ActionsInterface::APITOKEN_CREATE: - case ActionsInterface::APITOKEN_EDIT: + case ActionsInterface::AUTHTOKEN_CREATE: + case ActionsInterface::AUTHTOKEN_EDIT: $this->analyzeRequestData(); $this->checkCommon(); break; diff --git a/app/modules/web/Forms/FormBase.php b/app/modules/web/Forms/FormBase.php index ad12c32c..ebd4e1e2 100644 --- a/app/modules/web/Forms/FormBase.php +++ b/app/modules/web/Forms/FormBase.php @@ -26,8 +26,9 @@ namespace SP\Modules\Web\Forms; use SP\Config\Config; use SP\Config\ConfigData; +use SP\Core\Context\ContextInterface; use SP\Core\Context\SessionContext; -use SP\Core\Traits\InjectableTrait; +use SP\Core\Dic\InjectableTrait; /** * Class FormBase @@ -53,7 +54,7 @@ abstract class FormBase /** * @var SessionContext */ - protected $session; + protected $context; /** * FormBase constructor. @@ -69,14 +70,14 @@ abstract class FormBase } /** - * @param Config $config - * @param SessionContext $session + * @param Config $config + * @param ContextInterface $session */ - public function inject(Config $config, SessionContext $session) + public function inject(Config $config, ContextInterface $session) { $this->config = $config; $this->configData = $config->getConfigData(); - $this->session = $session; + $this->context = $session; } /** diff --git a/app/modules/web/Forms/NotificationForm.php b/app/modules/web/Forms/NotificationForm.php index 76415f7b..cbb8fe58 100644 --- a/app/modules/web/Forms/NotificationForm.php +++ b/app/modules/web/Forms/NotificationForm.php @@ -77,7 +77,7 @@ class NotificationForm extends FormBase implements FormInterface $this->notificationData->setUserId(Request::analyzeInt('notification_user')); $this->notificationData->setChecked(Request::analyzeBool('notification_checkout', false)); - if ($this->session->getUserData()->getIsAdminApp() && $this->notificationData->getUserId() === 0) { + if ($this->context->getUserData()->getIsAdminApp() && $this->notificationData->getUserId() === 0) { $this->notificationData->setOnlyAdmin(Request::analyzeBool('notification_onlyadmin', false)); $this->notificationData->setSticky(Request::analyzeBool('notification_sticky', false)); } diff --git a/app/modules/web/Forms/UserForm.php b/app/modules/web/Forms/UserForm.php index aae75547..520bc078 100644 --- a/app/modules/web/Forms/UserForm.php +++ b/app/modules/web/Forms/UserForm.php @@ -161,7 +161,7 @@ class UserForm extends FormBase implements FormInterface throw new ValidationException(__u('Ey, esto es una DEMO!!')); } - $userData = $this->session->getUserData(); + $userData = $this->context->getUserData(); if ((is_array($this->itemId) && in_array($userData->getId(), $this->itemId)) || $this->itemId === $userData->getId() diff --git a/app/modules/web/Init.php b/app/modules/web/Init.php index 5fb0383f..8dce8767 100644 --- a/app/modules/web/Init.php +++ b/app/modules/web/Init.php @@ -27,6 +27,8 @@ namespace SP\Modules\Web; use Defuse\Crypto\Exception\CryptoException; use DI\Container; use SP\Bootstrap; +use SP\Core\Context\ContextException; +use SP\Core\Context\ContextInterface; use SP\Core\Context\SessionContext; use SP\Core\Crypt\CryptSessionHandler; use SP\Core\Crypt\SecureKeyCookie; @@ -36,7 +38,6 @@ use SP\Core\Language; use SP\Core\ModuleBase; use SP\Core\Plugin\PluginUtil; use SP\Core\UI\Theme; -use SP\Core\Upgrade\Upgrade; use SP\Http\Request; use SP\Services\UserProfile\UserProfileService; use SP\Storage\Database; @@ -45,6 +46,7 @@ use SP\Util\HttpUtil; /** * Class Init + * * @package SP\Modules\Web */ class Init extends ModuleBase @@ -63,13 +65,10 @@ class Init extends ModuleBase * @var Language */ protected $language; - /** - * @var Upgrade - */ - protected $upgrade; /** * Init constructor. + * * @param Container $container * @throws \DI\DependencyException * @throws \DI\NotFoundException @@ -78,10 +77,9 @@ class Init extends ModuleBase { parent::__construct($container); - $this->context = $container->get(SessionContext::class); + $this->context = $container->get(ContextInterface::class); $this->theme = $container->get(Theme::class); $this->language = $container->get(Language::class); - $this->upgrade = $container->get(Upgrade::class); } /** @@ -95,11 +93,13 @@ class Init extends ModuleBase */ public function initialize($controller) { - debugLog(__FUNCTION__); + debugLog(__METHOD__); // Iniciar la sesión de PHP $this->initSession($this->configData->isEncryptSession()); + $this->theme->initialize(); + // Volver a cargar la configuración si se recarga la página if (Request::checkReload($this->router) === false) { // Cargar la configuración @@ -107,6 +107,9 @@ class Init extends ModuleBase // Cargar el lenguaje $this->language->setLanguage(); + + // Initialize theme + $this->theme->initialize(); } else { debugLog('Browser reload'); @@ -115,9 +118,11 @@ class Init extends ModuleBase // Cargar la configuración $this->config->loadConfig($this->context, true); - // Restablecer el idioma y el tema visual + // Restablecer el idioma $this->language->setLanguage(true); - $this->theme->initTheme(true); + + // Re-Initialize theme + $this->theme->initialize(true); } // Comprobar si es necesario cambiar a HTTPS @@ -175,7 +180,7 @@ class Init extends ModuleBase * Iniciar la sesión PHP * * @param bool $encrypt Encriptar la sesión de PHP - * @throws InitializationException + * @throws ContextException */ private function initSession($encrypt = false) { @@ -185,9 +190,10 @@ class Init extends ModuleBase session_set_save_handler(new CryptSessionHandler($key), true); } + try { $this->context->initialize(); - } catch (InitializationException $e) { + } catch (ContextException $e) { $this->router->response()->header('HTTP/1.1', '500 Internal Server Error'); throw $e; @@ -271,14 +277,12 @@ class Init extends ModuleBase /** * Comprobar si es necesario actualizar componentes - * - * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException */ private function checkUpgrade() { - if (Bootstrap::$SUBURI === '/index.php') { - $this->upgrade->checkDbVersion(); - $this->upgrade->checkAppVersion(); - } +// if (Bootstrap::$SUBURI === '/index.php') { +// $this->upgrade->checkDbVersion(); +// $this->upgrade->checkAppVersion(); +// } } } \ No newline at end of file diff --git a/app/modules/web/themes/material-blue/views/account/account-editpass.inc b/app/modules/web/themes/material-blue/views/account/account-editpass.inc index 158722a5..67cb2b07 100644 --- a/app/modules/web/themes/material-blue/views/account/account-editpass.inc +++ b/app/modules/web/themes/material-blue/views/account/account-editpass.inc @@ -1,6 +1,6 @@ diff --git a/app/modules/web/themes/material-blue/views/account/account-request.inc b/app/modules/web/themes/material-blue/views/account/account-request.inc index 28627372..19a525a5 100644 --- a/app/modules/web/themes/material-blue/views/account/account-request.inc +++ b/app/modules/web/themes/material-blue/views/account/account-request.inc @@ -1,6 +1,6 @@ diff --git a/app/modules/web/themes/material-blue/views/account/actions.inc b/app/modules/web/themes/material-blue/views/account/actions.inc index ca0ff377..61babfd0 100644 --- a/app/modules/web/themes/material-blue/views/account/actions.inc +++ b/app/modules/web/themes/material-blue/views/account/actions.inc @@ -1,5 +1,5 @@
    diff --git a/app/modules/web/themes/material-blue/views/account/files-list.inc b/app/modules/web/themes/material-blue/views/account/files-list.inc index 58bc61ad..7f1355ef 100644 --- a/app/modules/web/themes/material-blue/views/account/files-list.inc +++ b/app/modules/web/themes/material-blue/views/account/files-list.inc @@ -1,5 +1,5 @@ diff --git a/app/modules/web/themes/material-blue/views/common/aux-customfields.inc b/app/modules/web/themes/material-blue/views/common/aux-customfields.inc index e42b91e0..cca3fdaf 100644 --- a/app/modules/web/themes/material-blue/views/common/aux-customfields.inc +++ b/app/modules/web/themes/material-blue/views/common/aux-customfields.inc @@ -2,7 +2,7 @@ use SP\Mgmt\CustomFields\CustomFieldTypes; -/** @var $icons \Theme\Icons */ +/** @var $icons \SP\Core\UI\ThemeIcons */ foreach ($customFields as $index => $field):?> diff --git a/app/modules/web/themes/material-blue/views/config/accounts.inc b/app/modules/web/themes/material-blue/views/config/accounts.inc index 1281b3a8..27a8a573 100644 --- a/app/modules/web/themes/material-blue/views/config/accounts.inc +++ b/app/modules/web/themes/material-blue/views/config/accounts.inc @@ -1,4 +1,4 @@ - +
    +
    diff --git a/app/modules/web/themes/material-blue/views/config/encryption.inc b/app/modules/web/themes/material-blue/views/config/encryption.inc index 6532ac74..38d95fb0 100644 --- a/app/modules/web/themes/material-blue/views/config/encryption.inc +++ b/app/modules/web/themes/material-blue/views/config/encryption.inc @@ -1,6 +1,6 @@ diff --git a/app/modules/web/themes/material-blue/views/config/general-events.inc b/app/modules/web/themes/material-blue/views/config/general-events.inc index 1447cbbc..3d1132ad 100644 --- a/app/modules/web/themes/material-blue/views/config/general-events.inc +++ b/app/modules/web/themes/material-blue/views/config/general-events.inc @@ -1,4 +1,9 @@ - +
    @@ -7,7 +12,8 @@ + + + +
    -
    getIconHelp()->getIcon(); ?>
    +
    getIconHelp()->getIcon(); ?>

    @@ -16,7 +22,8 @@

    @@ -27,7 +34,8 @@ @@ -38,7 +46,8 @@ @@ -72,4 +81,21 @@
    + + +
    + + +
    \ No newline at end of file diff --git a/app/modules/web/themes/material-blue/views/config/general-site.inc b/app/modules/web/themes/material-blue/views/config/general-site.inc index 541207b3..edaa36cd 100644 --- a/app/modules/web/themes/material-blue/views/config/general-site.inc +++ b/app/modules/web/themes/material-blue/views/config/general-site.inc @@ -1,4 +1,4 @@ - +
    diff --git a/app/modules/web/themes/material-blue/views/config/general.inc b/app/modules/web/themes/material-blue/views/config/general.inc index 5f3a41f5..831565a6 100644 --- a/app/modules/web/themes/material-blue/views/config/general.inc +++ b/app/modules/web/themes/material-blue/views/config/general.inc @@ -1,5 +1,5 @@ diff --git a/app/modules/web/themes/material-blue/views/config/ldap.inc b/app/modules/web/themes/material-blue/views/config/ldap.inc index 968eff24..e4133435 100644 --- a/app/modules/web/themes/material-blue/views/config/ldap.inc +++ b/app/modules/web/themes/material-blue/views/config/ldap.inc @@ -1,4 +1,4 @@ - +
    diff --git a/app/modules/web/themes/material-blue/views/config/mail.inc b/app/modules/web/themes/material-blue/views/config/mail.inc index fd329fe4..49cb8826 100644 --- a/app/modules/web/themes/material-blue/views/config/mail.inc +++ b/app/modules/web/themes/material-blue/views/config/mail.inc @@ -1,7 +1,7 @@ @@ -148,10 +148,26 @@ value="getMailRecipients()); ?>"/> + + + + + +
    + + + + -
    diff --git a/app/modules/web/themes/material-blue/views/config/wiki.inc b/app/modules/web/themes/material-blue/views/config/wiki.inc index ef7f2bcb..3726edd3 100644 --- a/app/modules/web/themes/material-blue/views/config/wiki.inc +++ b/app/modules/web/themes/material-blue/views/config/wiki.inc @@ -1,4 +1,4 @@ - +
    diff --git a/app/modules/web/themes/material-blue/views/itemshow/customfield.inc b/app/modules/web/themes/material-blue/views/itemshow/customfield.inc index e4894f74..1645a6ae 100644 --- a/app/modules/web/themes/material-blue/views/itemshow/customfield.inc +++ b/app/modules/web/themes/material-blue/views/itemshow/customfield.inc @@ -1,6 +1,6 @@ diff --git a/app/modules/web/themes/material-blue/views/itemshow/usergroup.inc b/app/modules/web/themes/material-blue/views/itemshow/usergroup.inc index cb099463..0da4c47a 100644 --- a/app/modules/web/themes/material-blue/views/itemshow/usergroup.inc +++ b/app/modules/web/themes/material-blue/views/itemshow/usergroup.inc @@ -1,6 +1,6 @@ diff --git a/app/modules/web/themes/material-blue/views/itemshow/userpass.inc b/app/modules/web/themes/material-blue/views/itemshow/userpass.inc index 2f368ca5..9cff1f06 100644 --- a/app/modules/web/themes/material-blue/views/itemshow/userpass.inc +++ b/app/modules/web/themes/material-blue/views/itemshow/userpass.inc @@ -1,5 +1,5 @@ diff --git a/app/modules/web/themes/material-blue/views/itemshow/userprofile.inc b/app/modules/web/themes/material-blue/views/itemshow/userprofile.inc index 69b42751..e0564e39 100644 --- a/app/modules/web/themes/material-blue/views/itemshow/userprofile.inc +++ b/app/modules/web/themes/material-blue/views/itemshow/userprofile.inc @@ -1,6 +1,6 @@ +
    +
    +
    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('#(?Pweb|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='

    '+b.config().LANG[59]+"

    ";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='

    '+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='

    '+b.config().LANG[20]+"

    ";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='

    '+b.config().LANG[57]+"

    ";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='

    '+b.config().LANG[20]+"

    ";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")),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='

    '+b.config().LANG[57]+"

    ";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