diff --git a/app/modules/cli/Commands/Crypt/UpdateMasterPasswordCommand.php b/app/modules/cli/Commands/Crypt/UpdateMasterPasswordCommand.php index b3dd79c6..dbade78f 100644 --- a/app/modules/cli/Commands/Crypt/UpdateMasterPasswordCommand.php +++ b/app/modules/cli/Commands/Crypt/UpdateMasterPasswordCommand.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2022, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -27,6 +27,7 @@ namespace SP\Modules\Cli\Commands\Crypt; use Exception; use Psr\Log\LoggerInterface; use RuntimeException; +use SP\Domain\Account\AccountServiceInterface; use SP\Domain\Account\Services\AccountService; use SP\Domain\Config\ConfigInterface; use SP\Domain\Config\ConfigServiceInterface; @@ -71,7 +72,7 @@ final class UpdateMasterPasswordCommand extends CommandBase public function __construct( MasterPassServiceInterface $masterPassService, - AccountService $accountService, + AccountServiceInterface $accountService, ConfigServiceInterface $configService, LoggerInterface $logger, ConfigInterface $config @@ -301,4 +302,4 @@ final class UpdateMasterPasswordCommand extends CommandBase return true; } -} \ No newline at end of file +} diff --git a/app/modules/web/Controllers/Account/AccountControllerBase.php b/app/modules/web/Controllers/Account/AccountControllerBase.php index 395abef4..ab7f5440 100644 --- a/app/modules/web/Controllers/Account/AccountControllerBase.php +++ b/app/modules/web/Controllers/Account/AccountControllerBase.php @@ -26,7 +26,6 @@ namespace SP\Modules\Web\Controllers\Account; use SP\Core\Application; use SP\Core\Context\ContextBase; -use SP\Domain\Account\Services\AccountAclService; use SP\Modules\Web\Controllers\ControllerBase; use SP\Mvc\Controller\WebControllerHelper; @@ -65,9 +64,6 @@ abstract class AccountControllerBase extends ControllerBase if (DEBUG === true && $this->session->getAppStatus() === ContextBase::APP_STATUS_RELOADED) { $this->session->resetAppStatus(); - - // Reset de los datos de ACL de cuentas - AccountAclService::clearAcl($this->session->getUserData()->getId()); } } -} \ No newline at end of file +} diff --git a/app/modules/web/Controllers/Account/IndexController.php b/app/modules/web/Controllers/Account/IndexController.php index 44eec9dd..68e0c7bb 100644 --- a/app/modules/web/Controllers/Account/IndexController.php +++ b/app/modules/web/Controllers/Account/IndexController.php @@ -27,9 +27,11 @@ namespace SP\Modules\Web\Controllers\Account; use Exception; use SP\Core\Application; +use SP\Core\Context\ContextBase; use SP\Core\Events\Event; use SP\Modules\Web\Controllers\Helpers\Account\AccountSearchHelper; use SP\Mvc\Controller\WebControllerHelper; +use SP\Providers\Acl\AclHandler; use SP\Util\ErrorUtil; /** @@ -73,4 +75,4 @@ final class IndexController extends AccountControllerBase ErrorUtil::showExceptionInView($this->view, $e); } } -} \ No newline at end of file +} diff --git a/composer.json b/composer.json index 50801e34..7431321c 100644 --- a/composer.json +++ b/composer.json @@ -1,9 +1,4 @@ { - "name": "syspass/syspass", - "description": "PHP web based Password Manager for business and personal use.", - "homepage": "https://syspass.org", - "minimum-stability": "stable", - "license": "GPL-3.0", "authors": [ { "name": "Rubén Domínguez", @@ -12,11 +7,29 @@ "homepage": "https://syspass.org/" } ], - "support": { - "issues": "https://github.com/nuxsmin/sysPass/issues", - "source": "https://github.com/nuxsmin/sysPass", - "docs": "https://doc.syspass.org" + "autoload": { + "psr-4": { + "SP\\": "lib/SP/", + "SP\\Modules\\Web\\": "app/modules/web/", + "SP\\Modules\\Api\\": "app/modules/api/", + "SP\\Modules\\Cli\\": "app/modules/cli/", + "SP\\Tests\\": "tests/SP/" + } }, + "config": { + "classmap-authoritative": false, + "platform": { + "php": "8.0" + }, + "allow-plugins": { + "ocramius/package-versions": true + } + }, + "description": "PHP web based Password Manager for business and personal use.", + "homepage": "https://syspass.org", + "license": "GPL-3.0", + "minimum-stability": "stable", + "name": "syspass/syspass", "require": { "php": "~8.0 || ~8.1", "defuse/php-encryption": "^2.1", @@ -56,32 +69,19 @@ "squizlabs/php_codesniffer": "^3", "phpstan/phpstan": "^1.9" }, + "scripts": { + "phpcs": "phpcs --standard=PSR2 lib", + "phpstan": "vendor/bin/phpstan analyse lib tests --xdebug" + }, "suggest": { "syspass/plugin-authenticator": "^v2.2", "ext-ldap": "*", "ext-curl": "*", "ext-xdebug": "*" }, - "autoload": { - "psr-4": { - "SP\\": "lib/SP/", - "SP\\Modules\\Web\\": "app/modules/web/", - "SP\\Modules\\Api\\": "app/modules/api/", - "SP\\Modules\\Cli\\": "app/modules/cli/", - "SP\\Tests\\": "tests/SP/" - } - }, - "config": { - "classmap-authoritative": false, - "platform": { - "php": "8.0" - }, - "allow-plugins": { - "ocramius/package-versions": true - } - }, - "scripts": { - "phpcs": "phpcs --standard=PSR2 lib", - "phpstan": "vendor/bin/phpstan analyse lib tests --xdebug" + "support": { + "issues": "https://github.com/nuxsmin/sysPass/issues", + "source": "https://github.com/nuxsmin/sysPass", + "docs": "https://doc.syspass.org" } } diff --git a/composer.lock b/composer.lock index 31ca5555..12cb8155 100644 --- a/composer.lock +++ b/composer.lock @@ -1394,16 +1394,16 @@ }, { "name": "laminas/laminas-code", - "version": "4.7.0", + "version": "4.7.1", "source": { "type": "git", "url": "https://github.com/laminas/laminas-code.git", - "reference": "0337d9265bc2e6376babad8c511500821620cb30" + "reference": "91aabc066d5620428120800c0eafc0411e441a62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-code/zipball/0337d9265bc2e6376babad8c511500821620cb30", - "reference": "0337d9265bc2e6376babad8c511500821620cb30", + "url": "https://api.github.com/repos/laminas/laminas-code/zipball/91aabc066d5620428120800c0eafc0411e441a62", + "reference": "91aabc066d5620428120800c0eafc0411e441a62", "shasum": "" }, "require": { @@ -1456,7 +1456,7 @@ "type": "community_bridge" } ], - "time": "2022-09-13T10:33:30+00:00" + "time": "2022-11-21T01:32:31+00:00" }, { "name": "laravel/serializable-closure", @@ -4687,12 +4687,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "ed33734832e5a87eaa4341be7ce580de54157460" + "reference": "0399700d159e09b16645945758b65b921d3491fe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/ed33734832e5a87eaa4341be7ce580de54157460", - "reference": "ed33734832e5a87eaa4341be7ce580de54157460", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/0399700d159e09b16645945758b65b921d3491fe", + "reference": "0399700d159e09b16645945758b65b921d3491fe", "shasum": "" }, "conflict": { @@ -4716,6 +4716,7 @@ "asymmetricrypt/asymmetricrypt": ">=0,<9.9.99", "awesome-support/awesome-support": "<=6.0.7", "aws/aws-sdk-php": ">=3,<3.2.1", + "backdrop/backdrop": "<=1.23", "badaso/core": "<2.6.1", "bagisto/bagisto": "<0.1.5", "barrelstrength/sprout-base-email": "<1.2.7", @@ -4749,7 +4750,7 @@ "codeigniter4/shield": "= 1.0.0-beta", "codiad/codiad": "<=2.8.4", "composer/composer": "<1.10.26|>=2-alpha.1,<2.2.12|>=2.3,<2.3.5", - "concrete5/concrete5": ">= 9.0.0RC1, < 9.1.3|<9", + "concrete5/concrete5": "<9.1.3|>= 9.0.0RC1, < 9.1.3", "concrete5/core": "<8.5.8|>=9,<9.1", "contao-components/mediaelement": ">=2.14.2,<2.21.1", "contao/contao": ">=4,<4.4.56|>=4.5,<4.9.18|>=4.10,<4.11.7|>=4.13,<4.13.3", @@ -4775,7 +4776,7 @@ "doctrine/mongodb-odm": ">=1,<1.0.2", "doctrine/mongodb-odm-bundle": ">=2,<3.0.1", "doctrine/orm": ">=2,<2.4.8|>=2.5,<2.5.1|>=2.8.3,<2.8.4", - "dolibarr/dolibarr": "<16|= 12.0.5|>= 3.3.beta1, < 13.0.2", + "dolibarr/dolibarr": "<16|>=16.0.1,<16.0.3|= 12.0.5|>= 3.3.beta1, < 13.0.2", "dompdf/dompdf": "<2.0.1", "drupal/core": ">=7,<7.91|>=8,<9.3.19|>=9.4,<9.4.3", "drupal/drupal": ">=7,<7.80|>=8,<8.9.16|>=9,<9.1.12|>=9.2,<9.2.4", @@ -4814,7 +4815,7 @@ "fenom/fenom": "<=2.12.1", "filegator/filegator": "<7.8", "firebase/php-jwt": "<2", - "flarum/core": ">=1,<=1.0.1", + "flarum/core": ">=1,<=1.0.1|>=1.5,<1.6.2", "flarum/sticky": ">=0.1-beta.14,<=0.1-beta.15", "flarum/tags": "<=0.1-beta.13", "fluidtypo3/vhs": "<5.1.1", @@ -4870,6 +4871,7 @@ "ivankristianto/phpwhois": "<=4.3", "jackalope/jackalope-doctrine-dbal": "<1.7.4", "james-heinrich/getid3": "<1.9.21", + "jasig/phpcas": "<1.3.3", "joomla/archive": "<1.1.12|>=2,<2.0.1", "joomla/filesystem": "<1.6.2|>=2,<2.0.1", "joomla/filter": "<1.4.4|>=2,<2.0.1", @@ -4897,7 +4899,7 @@ "league/commonmark": "<0.18.3", "league/flysystem": "<1.1.4|>=2,<2.1.1", "lexik/jwt-authentication-bundle": "<2.10.7|>=2.11,<2.11.3", - "librenms/librenms": "<=22.8", + "librenms/librenms": "<22.10", "limesurvey/limesurvey": "<3.27.19", "livehelperchat/livehelperchat": "<=3.91", "livewire/livewire": ">2.2.4,<2.2.6", @@ -4922,7 +4924,7 @@ "modx/revolution": "<= 2.8.3-pl|<2.8", "mojo42/jirafeau": "<4.4", "monolog/monolog": ">=1.8,<1.12", - "moodle/moodle": "<4.0.1", + "moodle/moodle": "<4.0.5", "mustache/mustache": ">=2,<2.14.1", "namshi/jose": "<2.2", "neoan3-apps/template": "<1.1.1", @@ -5022,12 +5024,12 @@ "shopware/storefront": "<=6.4.8.1", "shopxo/shopxo": "<2.2.6", "showdoc/showdoc": "<2.10.4", - "silverstripe/admin": ">=1,<1.8.1", - "silverstripe/assets": ">=1,<1.10.1", - "silverstripe/cms": "<4.3.6|>=4.4,<4.4.4", + "silverstripe/admin": ">=1,<1.11.3", + "silverstripe/assets": ">=1,<1.11.1", + "silverstripe/cms": "<4.11.3", "silverstripe/comments": ">=1.3,<1.9.99|>=2,<2.9.99|>=3,<3.1.1", "silverstripe/forum": "<=0.6.1|>=0.7,<=0.7.3", - "silverstripe/framework": "<4.10.9", + "silverstripe/framework": "<4.11.14", "silverstripe/graphql": "<3.5.2|>=4-alpha.1,<4-alpha.2|= 4.0.0-alpha1", "silverstripe/hybridsessions": ">=1,<2.4.1|>=2.5,<2.5.1", "silverstripe/registry": ">=2.1,<2.1.2|>=2.2,<2.2.1", @@ -5036,6 +5038,7 @@ "silverstripe/subsites": ">=2,<2.1.1", "silverstripe/taxonomy": ">=1.3,<1.3.1|>=2,<2.0.1", "silverstripe/userforms": "<3", + "silverstripe/versioned-admin": ">=1,<1.11.1", "simple-updates/phpwhois": "<=1", "simplesamlphp/saml2": "<1.10.6|>=2,<2.3.8|>=3,<3.1.4", "simplesamlphp/simplesamlphp": "<1.18.6", @@ -5110,7 +5113,7 @@ "topthink/framework": "<=6.0.13", "topthink/think": "<=6.0.9", "topthink/thinkphp": "<=3.2.3", - "tribalsystems/zenario": "<9.2.55826", + "tribalsystems/zenario": "<=9.3.57186", "truckersmp/phpwhois": "<=4.3.1", "twig/twig": "<1.44.7|>=2,<2.15.3|>=3,<3.4.3", "typo3/cms": ">=6.2,<6.2.30|>=7,<7.6.32|>=8,<8.7.38|>=9,<9.5.29|>=10,<10.4.32|>=11,<11.5.16", @@ -5146,7 +5149,7 @@ "yetiforce/yetiforce-crm": "<=6.4", "yidashi/yii2cmf": "<=2", "yii2mod/yii2-cms": "<1.9.2", - "yiisoft/yii": ">=1.1.14,<1.1.15", + "yiisoft/yii": "<1.1.27", "yiisoft/yii2": "<2.0.38", "yiisoft/yii2-bootstrap": "<2.0.4", "yiisoft/yii2-dev": "<2.0.43", @@ -5217,7 +5220,7 @@ "type": "tidelift" } ], - "time": "2022-11-16T22:04:17+00:00" + "time": "2022-11-23T23:04:03+00:00" }, { "name": "sebastian/cli-parser", diff --git a/lib/BaseFunctions.php b/lib/BaseFunctions.php index 583205e3..6f57eb3e 100644 --- a/lib/BaseFunctions.php +++ b/lib/BaseFunctions.php @@ -65,6 +65,7 @@ function logger(mixed $data, string $type = 'DEBUG'): void $caller ); + /** @noinspection ForgottenDebugOutputInspection */ $useOwn = (!defined('LOG_FILE') || !@error_log($line, 3, LOG_FILE) ); @@ -77,6 +78,7 @@ function logger(mixed $data, string $type = 'DEBUG'): void $caller ); + /** @noinspection ForgottenDebugOutputInspection */ @error_log($line); } } diff --git a/lib/SP/Core/Acl/Acl.php b/lib/SP/Core/Acl/Acl.php index c7d962dd..d61913d8 100644 --- a/lib/SP/Core/Acl/Acl.php +++ b/lib/SP/Core/Acl/Acl.php @@ -5,7 +5,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2022, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -29,6 +29,8 @@ use SP\Core\Context\ContextInterface; use SP\Core\Events\Event; use SP\Core\Events\EventDispatcher; use SP\Core\Events\EventMessage; +use function SP\__u; +use function SP\processException; defined('APP_ROOT') || die(); @@ -50,10 +52,9 @@ class Acl implements ActionsInterface */ public function __construct( ContextInterface $context, - EventDispatcher $eventDispatcher, + EventDispatcher $eventDispatcher, Actions $actions = null - ) - { + ) { $this->context = $context; $this->eventDispatcher = $eventDispatcher; @@ -77,8 +78,8 @@ class Acl implements ActionsInterface /** * Obtener el nombre de la acción indicada * - * @param int $actionId El id de la acción - * @param bool $translate + * @param int $actionId El id de la acción + * @param bool $translate * * @return string * @internal param bool $shortName Si se devuelve el nombre corto de la acción @@ -132,18 +133,18 @@ class Acl implements ActionsInterface return ($userData->getIsAdminAcc() || $userProfile->isAccFiles()); case self::ITEMS_MANAGE: return ($userData->getIsAdminAcc() - || $userProfile->isMgmCategories() - || $userProfile->isMgmCustomers() - || $userProfile->isMgmAccounts() - || $userProfile->isMgmFiles() - || $userProfile->isMgmTags() - || $userProfile->isMgmCustomFields() - || $userProfile->isMgmPublicLinks()); + || $userProfile->isMgmCategories() + || $userProfile->isMgmCustomers() + || $userProfile->isMgmAccounts() + || $userProfile->isMgmFiles() + || $userProfile->isMgmTags() + || $userProfile->isMgmCustomFields() + || $userProfile->isMgmPublicLinks()); case self::CONFIG: return ($userProfile->isConfigGeneral() - || $userProfile->isConfigEncryption() - || $userProfile->isConfigBackup() - || $userProfile->isConfigImport()); + || $userProfile->isConfigEncryption() + || $userProfile->isConfigBackup() + || $userProfile->isConfigImport()); case self::CONFIG_GENERAL: case self::CONFIG_ACCOUNT: case self::CONFIG_WIKI: @@ -212,12 +213,12 @@ class Acl implements ActionsInterface return $userProfile->isConfigBackup(); case self::ACCESS_MANAGE: return ($userProfile->isMgmUsers() - || $userProfile->isMgmGroups() - || $userProfile->isMgmProfiles() - || $userProfile->isMgmApiTokens()); + || $userProfile->isMgmGroups() + || $userProfile->isMgmProfiles() + || $userProfile->isMgmApiTokens()); case self::SECURITY_MANAGE: return $userProfile->isEvl() - || $userProfile->isMgmUsers(); + || $userProfile->isMgmUsers(); case self::USER: case self::USER_SEARCH: case self::USER_VIEW: @@ -280,13 +281,17 @@ class Acl implements ActionsInterface $actionName = __u('N/A'); } - $this->eventDispatcher->notifyEvent('acl.deny', - new Event($this, EventMessage::factory() - ->addDescription(__u('Access denied')) - ->addDetail(__u('Action'), $actionName) - ->addDetail(__u('User'), $userData->getLogin())) + $this->eventDispatcher->notifyEvent( + 'acl.deny', + new Event( + $this, + EventMessage::factory() + ->addDescription(__u('Access denied')) + ->addDetail(__u('Action'), $actionName) + ->addDetail(__u('User'), $userData->getLogin()) + ) ); return false; } -} \ No newline at end of file +} diff --git a/lib/SP/Core/Context/ContextBase.php b/lib/SP/Core/Context/ContextBase.php index b61f9729..709f1e10 100644 --- a/lib/SP/Core/Context/ContextBase.php +++ b/lib/SP/Core/Context/ContextBase.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2022, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -24,6 +24,8 @@ namespace SP\Core\Context; +use function SP\__u; + /** * Class ContextBase * @@ -31,13 +33,11 @@ namespace SP\Core\Context; */ abstract class ContextBase implements ContextInterface { - public const APP_STATUS_UPDATED = 'updated'; - public const APP_STATUS_RELOADED = 'reloaded'; - public const APP_STATUS_INSTALLED = 'installed'; + public const APP_STATUS_RELOADED = 'reloaded'; public const APP_STATUS_LOGGEDOUT = 'loggedout'; private ?ContextCollection $context = null; - private ContextCollection $trasient; + private ContextCollection $trasient; /** * ContextBase constructor. @@ -56,7 +56,7 @@ abstract class ContextBase implements ContextInterface public function setTrasientKey(string $key, $value) { // If the key starts with "_" it's a protected key, thus cannot be overwritten - if (strpos($key, '_') === 0 + if (str_starts_with($key, '_') && $this->trasient->exists($key) && $this->trasient->get($key) !== $value ) { @@ -101,6 +101,7 @@ abstract class ContextBase implements ContextInterface if (!isset($context['context'])) { $context['context'] = $this->context = new ContextCollection(); + return; } @@ -128,6 +129,7 @@ abstract class ContextBase implements ContextInterface { $this->checkContext(); + return is_numeric($default) ? (int)$this->context->get($key, $default) : $this->context->get($key, $default); @@ -146,12 +148,12 @@ 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 * * @throws ContextException */ - protected function setContextKey(string $key, $value) + protected function setContextKey(string $key, mixed $value): mixed { $this->checkContext(); @@ -159,4 +161,4 @@ abstract class ContextBase implements ContextInterface return $value; } -} \ No newline at end of file +} diff --git a/lib/SP/Core/Context/SessionContext.php b/lib/SP/Core/Context/SessionContext.php index 7f228ba7..65301ada 100644 --- a/lib/SP/Core/Context/SessionContext.php +++ b/lib/SP/Core/Context/SessionContext.php @@ -29,6 +29,8 @@ use SP\DataModel\Dto\AccountCache; use SP\DataModel\ProfileData; use SP\Domain\Account\Search\AccountSearchFilter; use SP\Domain\User\Services\UserLoginResponse; +use function SP\logger; +use function SP\processException; /** * Class Session @@ -39,7 +41,7 @@ class SessionContext extends ContextBase { public const MAX_SID_TIME = 120; - private static bool $isReset = false; + private static bool $isReset = false; private static bool $isLocked = false; /** @@ -79,8 +81,8 @@ class SessionContext extends ContextBase /** * Devolver una variable de sesión * - * @param string $key - * @param mixed $default + * @param string $key + * @param mixed $default * * @return mixed */ @@ -108,16 +110,16 @@ 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(string $key, $value) + protected function setContextKey(string $key, mixed $value): mixed { try { if (self::$isLocked) { - logger('Session locked; key=' . $key); + logger('Session locked; key='.$key); } else { parent::setContextKey($key, $value); } @@ -133,7 +135,7 @@ class SessionContext extends ContextBase /** * Establecer la hora de carga de la configuración * - * @param int $time + * @param int $time */ public function setConfigTime(int $time): void { @@ -153,7 +155,7 @@ class SessionContext extends ContextBase /** * Establece los datos del usuario en la sesión. * - * @param UserLoginResponse|null $userLoginResponse + * @param UserLoginResponse|null $userLoginResponse */ public function setUserData(UserLoginResponse $userLoginResponse = null): void { @@ -173,7 +175,7 @@ class SessionContext extends ContextBase /** * Establece el objeto de perfil de usuario en la sesión. * - * @param ProfileData $ProfileData + * @param ProfileData $ProfileData */ public function setUserProfile(ProfileData $ProfileData): void { @@ -189,7 +191,7 @@ class SessionContext extends ContextBase } /** - * @param \SP\Domain\Account\Search\AccountSearchFilter $searchFilters + * @param \SP\Domain\Account\Search\AccountSearchFilter $searchFilters */ public function setSearchFilters(AccountSearchFilter $searchFilters): void { @@ -209,7 +211,7 @@ class SessionContext extends ContextBase public function isLoggedIn(): bool { return self::$isReset === false && $this->getUserData()->getLogin() - && is_object($this->getUserData()->getPreferences()); + && is_object($this->getUserData()->getPreferences()); } /** @@ -253,7 +255,7 @@ class SessionContext extends ContextBase /** * Sets a temporary master password * - * @param string $password + * @param string $password */ public function setTemporaryMasterPass(string $password): void { @@ -293,7 +295,7 @@ class SessionContext extends ContextBase /** * Establecer el timeout de la sesión * - * @param int $timeout El valor en segundos + * @param int $timeout El valor en segundos * * @return int */ @@ -365,7 +367,7 @@ class SessionContext extends ContextBase /** * Establece el color asociado a una cuenta * - * @param array $color + * @param array $color */ public function setAccountColor(array $color): void { @@ -385,7 +387,7 @@ class SessionContext extends ContextBase /** * Establecer el estado de la aplicación * - * @param string $status + * @param string $status */ public function setAppStatus(string $status): void { @@ -405,7 +407,7 @@ class SessionContext extends ContextBase /** * Set the CSRF key * - * @param string $csrf + * @param string $csrf */ public function setCSRF(string $csrf): void { @@ -435,7 +437,7 @@ class SessionContext extends ContextBase /** * Establecer la clave maestra encriptada * - * @param Vault $vault + * @param Vault $vault */ public function setVault(Vault $vault): void { @@ -445,7 +447,7 @@ class SessionContext extends ContextBase /** * Establece la cache de cuentas * - * @param array $accountsCache + * @param array $accountsCache */ public function setAccountsCache(array $accountsCache): void { @@ -523,9 +525,9 @@ class SessionContext extends ContextBase } /** - * @param string $pluginName - * @param string $key - * @param mixed $value + * @param string $pluginName + * @param string $key + * @param mixed $value * * @return mixed */ @@ -540,8 +542,8 @@ class SessionContext extends ContextBase } /** - * @param string $pluginName - * @param string $key + * @param string $pluginName + * @param string $key * * @return mixed */ diff --git a/lib/SP/Core/Context/StatelessContext.php b/lib/SP/Core/Context/StatelessContext.php index 2cb250a8..8cd4542a 100644 --- a/lib/SP/Core/Context/StatelessContext.php +++ b/lib/SP/Core/Context/StatelessContext.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2022, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -26,6 +26,7 @@ namespace SP\Core\Context; use SP\DataModel\ProfileData; use SP\Domain\User\Services\UserLoginResponse; +use function SP\processException; /** * Class ApiContext @@ -37,7 +38,7 @@ class StatelessContext extends ContextBase /** * Establece los datos del usuario en la sesión. * - * @param UserLoginResponse|null $userLoginResponse + * @param UserLoginResponse|null $userLoginResponse */ public function setUserData(UserLoginResponse $userLoginResponse = null): void { @@ -47,17 +48,15 @@ class StatelessContext 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(string $key, $value) + protected function setContextKey(string $key, mixed $value): mixed { try { - parent::setContextKey($key, $value); - - return $value; + return parent::setContextKey($key, $value); } catch (ContextException $e) { processException($e); } @@ -68,7 +67,7 @@ class StatelessContext extends ContextBase /** * Obtiene el objeto de perfil de usuario de la sesión. * - * @return ProfileData + * @return \SP\DataModel\ProfileData|null */ public function getUserProfile(): ?ProfileData { @@ -78,12 +77,12 @@ class StatelessContext extends ContextBase /** * Devolver una variable de sesión * - * @param string $key - * @param mixed $default + * @param string $key + * @param mixed $default * * @return mixed */ - protected function getContextKey(string $key, $default = null) + protected function getContextKey(string $key, $default = null): mixed { try { return parent::getContextKey($key, $default); @@ -97,7 +96,7 @@ class StatelessContext extends ContextBase /** * Establece el objeto de perfil de usuario en la sesión. * - * @param ProfileData $profileData + * @param ProfileData $profileData */ public function setUserProfile(ProfileData $profileData): void { @@ -155,7 +154,7 @@ class StatelessContext extends ContextBase /** * Establecer el estado de la aplicación * - * @param string $status + * @param string $status */ public function setAppStatus(string $status): void { @@ -184,7 +183,7 @@ class StatelessContext extends ContextBase /** * Establecer la hora de carga de la configuración * - * @param int $time + * @param int $time */ public function setConfigTime(int $time): void { @@ -212,7 +211,7 @@ class StatelessContext extends ContextBase /** * Sets a temporary master password * - * @param string $password + * @param string $password * * @throws ContextException */ @@ -222,9 +221,9 @@ class StatelessContext extends ContextBase } /** - * @param string $pluginName - * @param string $key - * @param mixed $value + * @param string $pluginName + * @param string $key + * @param mixed $value * * @return mixed */ @@ -238,8 +237,8 @@ class StatelessContext extends ContextBase } /** - * @param string $pluginName - * @param string $key + * @param string $pluginName + * @param string $key * * @return mixed */ @@ -249,4 +248,4 @@ class StatelessContext extends ContextBase return $ctxKey[$pluginName][$key] ?? null; } -} \ No newline at end of file +} diff --git a/lib/SP/Core/DataCollection.php b/lib/SP/Core/DataCollection.php index a0e42df3..98f6653d 100644 --- a/lib/SP/Core/DataCollection.php +++ b/lib/SP/Core/DataCollection.php @@ -24,280 +24,32 @@ namespace SP\Core; -use ArrayAccess; -use ArrayIterator; -use Countable; -use IteratorAggregate; -use Traversable; +use ArrayObject; /** * Class DataCollection * * @package SP\Core\Context */ -abstract class DataCollection implements IteratorAggregate, ArrayAccess, Countable +abstract class DataCollection extends ArrayObject { - /** - * Collection of data attributes - */ - protected array $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(): Traversable + public function get(string $key, mixed $default = null): mixed { - return new ArrayIterator($this->attributes); + if (!property_exists($this, $key)) { + return $default; + } + + return $this->{$key}; } - /** - * 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): bool + public function set(string $key, mixed $value): void { - return $this->exists($offset); + $this->{$key} = $value; } - /** - * See if an attribute exists in the collection - * - * @param string $key The name of the parameter - * - * @return boolean - */ public function exists(string $key): bool { - // Don't use "isset", since it returns false for null values - return array_key_exists($key, $this->attributes); + return property_exists($this, $key); } - - /** - * 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): mixed - { - 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(string $key, $default_val = null) - { - return $this->attributes[$key] ?? $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): void - { - $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(string $key, $value): DataCollection - { - $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): void - { - $this->remove($offset); - } - - /** - * Remove an attribute from the collection - * - * @param string $key The name of the parameter - * - * @return void - */ - public function remove(string $key): void - { - 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(): int - { - return count($this->attributes); - } - - /** - * Clear the collection's contents - * - * Semantic alias of a no-argument `$this->replace` call - * - * @return DataCollection - */ - public function clear(): DataCollection - { - 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()): DataCollection - { - $this->attributes = $attributes; - - return $this; - } - - /** - * Check if the collection is empty - * - * @return boolean - */ - public function isEmpty(): bool - { - return count($this->attributes) === 0; - } - - /** - * Magic "__get" method - * - * Allows the ability to arbitrarily request an attribute from - * this instance while treating it as an instance property - * - * @param string $key The name of the parameter to return - * - * @return mixed - * @see get() - */ - public function __get(string $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 - * - * @param string $key The name of the parameter to set - * @param mixed $value The value of the parameter to set - * - * @return void - * @see set() - */ - public function __set(string $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 - * - * @param string $key The name of the parameter - * - * @return boolean - * @see exists() - */ - public function __isset(string $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 - * - * @param string $key The name of the parameter - * - * @return void - * @see remove() - * - */ - public function __unset(string $key) - { - $this->remove($key); - } -} \ No newline at end of file +} diff --git a/lib/SP/DataModel/AccountVData.php b/lib/SP/DataModel/AccountVData.php index ce6cbb2c..18b0ed76 100644 --- a/lib/SP/DataModel/AccountVData.php +++ b/lib/SP/DataModel/AccountVData.php @@ -24,7 +24,6 @@ namespace SP\DataModel; - use SP\Domain\Common\Out\DataModelBase; /** @@ -34,570 +33,190 @@ use SP\Domain\Common\Out\DataModelBase; */ class AccountVData extends DataModelBase { - /** - * @var int Id de la cuenta. - */ - public $id = 0; - /** - * @var int Id del usuario principal de la cuenta. - */ - public $userId = 0; - /** - * @var int Id del grupo principal de la cuenta. - */ - public $userGroupId = 0; - /** - * @var int Id del usuario que editó la cuenta. - */ - public $userEditId = 0; - /** - * @var string El nombre de la cuenta. - */ - public $name = ''; - /** - * @var int Id del cliente de la cuenta. - */ - public $clientId = 0; - /** - * @var int Id de la categoría de la cuenta. - */ - public $categoryId = 0; - /** - * @var string El nombre de usuario de la cuenta. - */ - public $login = ''; - /** - * @var string La URL de la cuenta. - */ - public $url = ''; - /** - * @var string La clave de la cuenta. - */ - public $pass = ''; - /** - * @var string La clave de encriptación de la cuenta - */ - public $key = ''; - /** - * @var string Las nosta de la cuenta. - */ - public $notes = ''; - /** - * @var int - */ - public $otherUserEdit = 0; - /** - * @var int - */ - public $otherUserGroupEdit = 0; - /** - * @var int - */ - public $dateAdd = 0; - /** - * @var int - */ - public $dateEdit = 0; - /** - * @var int - */ - public $countView = 0; - /** - * @var int - */ - public $countDecrypt = 0; - /** - * @var int - */ - public $isPrivate = 0; - /** - * @var int - */ - public $isPrivateGroup = 0; - /** - * @var int - */ - public $passDate = 0; - /** - * @var int - */ - public $passDateChange = 0; - /** - * @var int - */ - public $parentId = 0; - /** - * @var string - */ - public $categoryName = ''; - /** - * @var string - */ - public $clientName = ''; - /** - * @var string - */ - public $userGroupName = ''; - /** - * @var string - */ - public $userName = ''; - /** - * @var string - */ - public $userLogin = ''; - /** - * @var string - */ - public $userEditName = ''; - /** - * @var string - */ - public $userEditLogin = ''; - /** - * @var string - */ - public $publicLinkHash = ''; + protected ?int $id = null; + protected ?int $userId = null; + protected ?int $userGroupId = null; + protected ?int $userEditId = null; + protected ?string $name = null; + protected ?int $clientId = null; + protected ?int $categoryId = null; + protected ?string $login = null; + protected ?string $url = null; + protected ?string $pass = null; + protected ?string $key = null; + protected ?string $notes = null; + protected ?int $otherUserEdit = null; + protected ?int $otherUserGroupEdit = null; + protected ?int $dateAdd = null; + protected ?int $dateEdit = null; + protected ?int $countView = null; + protected ?int $countDecrypt = null; + protected ?int $isPrivate = null; + protected ?int $isPrivateGroup = null; + protected ?int $passDate = null; + protected ?int $passDateChange = null; + protected ?int $parentId = null; + protected ?string $categoryName = null; + protected ?string $clientName = null; + protected ?string $userGroupName = null; + protected ?string $userName = null; + protected ?string $userLogin = null; + protected ?string $userEditName = null; + protected ?string $userEditLogin = null; + protected ?string $publicLinkHash = null; - /** - * AccountData constructor. - * - * @param int $accountId - */ - public function __construct($accountId = 0) + public function getId(): ?int { - $this->id = (int)$accountId; + return $this->id; } - /** - * @return int - */ - public function getDateAdd() + public function getUserId(): ?int { - return (int)$this->dateAdd; + return $this->userId; } - /** - * @param int $dateAdd - */ - public function setDateAdd($dateAdd) + public function getUserGroupId(): ?int { - $this->dateAdd = $dateAdd; + return $this->userGroupId; } - /** - * @return int - */ - public function getDateEdit() + public function getUserEditId(): ?int { - return (int)$this->dateEdit; + return $this->userEditId; } - /** - * @param int $dateEdit - */ - public function setDateEdit($dateEdit) - { - $this->dateEdit = $dateEdit; - } - - /** - * @return int - */ - public function getUserEditId() - { - return (int)$this->userEditId; - } - - /** - * @param int $userEditId - */ - public function setUserEditId($userEditId) - { - $this->userEditId = (int)$userEditId; - } - - /** - * @return string - */ - public function getPass() - { - return $this->pass; - } - - /** - * @param string $pass - */ - public function setPass($pass) - { - $this->pass = $pass; - } - - /** - * @return string - */ - public function getKey() - { - return $this->key; - } - - /** - * @param string $key - */ - public function setKey($key) - { - $this->key = $key; - } - - /** - * @return int|null - */ - public function getId() - { - return (int)$this->id; - } - - /** - * @param int $id - */ - public function setId($id) - { - $this->id = (int)$id; - } - - /** - * @return int - */ - public function getUserId() - { - return (int)$this->userId; - } - - /** - * @param int $userId - */ - public function setUserId($userId) - { - $this->userId = (int)$userId; - } - - /** - * @return int - */ - public function getUserGroupId() - { - return (int)$this->userGroupId; - } - - /** - * @param int $userGroupId - */ - public function setUserGroupId($userGroupId) - { - $this->userGroupId = (int)$userGroupId; - } - - /** - * @return int - */ - public function getOtherUserEdit() - { - return (int)$this->otherUserEdit; - } - - /** - * @param bool $otherUserEdit - */ - public function setOtherUserEdit($otherUserEdit) - { - $this->otherUserEdit = (int)$otherUserEdit; - } - - /** - * @return int - */ - public function getOtherUserGroupEdit() - { - return (int)$this->otherUserGroupEdit; - } - - /** - * @param bool $otherUserGroupEdit - */ - public function setOtherUserGroupEdit($otherUserGroupEdit) - { - $this->otherUserGroupEdit = (int)$otherUserGroupEdit; - } - - /** - * @return string - */ - public function getName() + public function getName(): ?string { return $this->name; } - /** - * @param string $name - */ - public function setName($name) + public function getClientId(): ?int { - $this->name = $name; + return $this->clientId; } - /** - * @return int - */ - public function getCategoryId() + public function getCategoryId(): ?int { - return (int)$this->categoryId; + return $this->categoryId; } - /** - * @param int $categoryId - */ - public function setCategoryId($categoryId) - { - $this->categoryId = (int)$categoryId; - } - - /** - * @return int - */ - public function getClientId() - { - return (int)$this->clientId; - } - - /** - * @param int $clientId - */ - public function setClientId($clientId) - { - $this->clientId = (int)$clientId; - } - - /** - * @return string - */ - public function getLogin() + public function getLogin(): ?string { return $this->login; } - /** - * @param string $login - */ - public function setLogin($login) - { - $this->login = $login; - } - - /** - * @return string - */ - public function getUrl() + public function getUrl(): ?string { return $this->url; } - /** - * @param string $url - */ - public function setUrl($url) + public function getPass(): ?string { - $this->url = $url; + return $this->pass; } - /** - * @return string - */ - public function getNotes() + public function getKey(): ?string + { + return $this->key; + } + + public function getNotes(): ?string { return $this->notes; } - /** - * @param string $notes - */ - public function setNotes($notes) + public function getOtherUserEdit(): ?int { - $this->notes = $notes; + return $this->otherUserEdit; } - /** - * @return int - */ - public function getCountView() + public function getOtherUserGroupEdit(): ?int { - return (int)$this->countView; + return $this->otherUserGroupEdit; } - /** - * @param int $countView - */ - public function setCountView($countView) + public function getDateAdd(): ?int { - $this->countView = (int)$countView; + return $this->dateAdd; } - /** - * @return int - */ - public function getCountDecrypt() + public function getDateEdit(): ?int { - return (int)$this->countDecrypt; + return $this->dateEdit; } - /** - * @param int $countDecrypt - */ - public function setCountDecrypt($countDecrypt) + public function getCountView(): ?int { - $this->countDecrypt = (int)$countDecrypt; + return $this->countView; } - /** - * @return int - */ - public function getIsPrivate() + public function getCountDecrypt(): ?int { - return (int)$this->isPrivate; + return $this->countDecrypt; } - /** - * @param int $isPrivate - */ - public function setIsPrivate($isPrivate) + public function getIsPrivate(): ?int { - $this->isPrivate = (int)$isPrivate; + return $this->isPrivate; } - /** - * @return int - */ - public function getPassDate() + public function getIsPrivateGroup(): ?int { - return (int)$this->passDate; + return $this->isPrivateGroup; } - /** - * @param int $passDate - */ - public function setPassDate($passDate) + public function getPassDate(): ?int { - $this->passDate = (int)$passDate; + return $this->passDate; } - /** - * @return int - */ - public function getPassDateChange() + public function getPassDateChange(): ?int { - return (int)$this->passDateChange; + return $this->passDateChange; } - /** - * @param int $passDateChange - */ - public function setPassDateChange($passDateChange) + public function getParentId(): ?int { - $this->passDateChange = (int)$passDateChange; + return $this->parentId; } - /** - * @return int - */ - public function getParentId() - { - return (int)$this->parentId; - } - - /** - * @param int $parentId - */ - public function setParentId($parentId) - { - $this->parentId = (int)$parentId; - } - - /** - * @return int - */ - public function getIsPrivateGroup() - { - return (int)$this->isPrivateGroup; - } - - /** - * @param int $isPrivateGroup - */ - public function setIsPrivateGroup($isPrivateGroup) - { - $this->isPrivateGroup = (int)$isPrivateGroup; - } - - /** - * @return string - */ - public function getUserEditName() - { - return $this->userEditName; - } - - /** - * @return string - */ - public function getUserEditLogin() - { - return $this->userEditLogin; - } - - /** - * @return string - */ - public function getPublicLinkHash() - { - return $this->publicLinkHash; - } - - /** - * @return string - */ - public function getCategoryName() + public function getCategoryName(): ?string { return $this->categoryName; } - /** - * @return string - */ - public function getClientName() + public function getClientName(): ?string { return $this->clientName; } - /** - * @return string - */ - public function getUserGroupName() + public function getUserGroupName(): ?string { return $this->userGroupName; } - /** - * @return string - */ - public function getUserName() + public function getUserName(): ?string { return $this->userName; } - /** - * @return string - */ - public function getUserLogin() + public function getUserLogin(): ?string { return $this->userLogin; } -} \ No newline at end of file + + public function getUserEditName(): ?string + { + return $this->userEditName; + } + + public function getUserEditLogin(): ?string + { + return $this->userEditLogin; + } + + public function getPublicLinkHash(): ?string + { + return $this->publicLinkHash; + } +} diff --git a/lib/SP/DataModel/Dto/AccountAclDto.php b/lib/SP/DataModel/Dto/AccountAclDto.php index a41ba296..f16de1c1 100644 --- a/lib/SP/DataModel/Dto/AccountAclDto.php +++ b/lib/SP/DataModel/Dto/AccountAclDto.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2022, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -24,7 +24,6 @@ namespace SP\DataModel\Dto; -use SP\DataModel\AccountHistoryData; use SP\DataModel\AccountSearchVData; use SP\DataModel\ItemData; @@ -35,140 +34,127 @@ use SP\DataModel\ItemData; */ final class AccountAclDto { - /** - * @var int - */ - private $accountId; - /** - * @var int - */ - private $userId; + private int $accountId; + private int $userId; + private int $userGroupId; + private int $dateEdit; /** * @var ItemData[] */ - private $usersId; - /** - * @var int - */ - private $userGroupId; + private array $usersId; /** * @var ItemData[] */ - private $userGroupsId; - /** - * @var int - */ - private $dateEdit; + private array $userGroupsId; - private function __construct() - { + /** + * @param int $accountId + * @param int $userId + * @param array $usersId + * @param int $userGroupId + * @param array $userGroupsId + * @param int $dateEdit + */ + public function __construct( + int $accountId, + int $userId, + array $usersId, + int $userGroupId, + array $userGroupsId, + int $dateEdit + ) { + $this->accountId = $accountId; + $this->userId = $userId; + $this->usersId = self::buildFromItemData($usersId); + $this->userGroupId = $userGroupId; + $this->userGroupsId = self::buildFromItemData($userGroupsId); + $this->dateEdit = $dateEdit; } /** - * @param AccountDetailsResponse $accountDetailsResponse + * @param ItemData[] $items + * + * @return array + */ + private static function buildFromItemData(array $items): array + { + return array_filter($items, static fn($value) => $value instanceof ItemData); + } + + /** + * @param AccountDetailsResponse $accountDetailsResponse * * @return AccountAclDto */ - public static function makeFromAccount(AccountDetailsResponse $accountDetailsResponse) + public static function makeFromAccount(AccountDetailsResponse $accountDetailsResponse): AccountAclDto { - $dto = new self(); - $dto->accountId = $accountDetailsResponse->getId(); - $dto->userId = $accountDetailsResponse->getAccountVData()->getUserId(); - $dto->usersId = $accountDetailsResponse->getUsers(); - $dto->userGroupId = $accountDetailsResponse->getAccountVData()->getUserGroupId(); - $dto->userGroupsId = $accountDetailsResponse->getUserGroups(); - $dto->dateEdit = strtotime($accountDetailsResponse->getAccountVData()->getDateEdit()); - - return $dto; + return new self( + $accountDetailsResponse->getId(), + $accountDetailsResponse->getAccountVData()->getUserId(), + $accountDetailsResponse->getUsers(), + $accountDetailsResponse->getAccountVData()->getUserGroupId(), + $accountDetailsResponse->getUserGroups(), + strtotime($accountDetailsResponse->getAccountVData()->getDateEdit()) + ); } - /** - * @param AccountHistoryData $accountHistoryData - * - * @param array $users - * @param array $userGroups - * - * @return AccountAclDto - */ - public static function makeFromAccountHistory(AccountHistoryData $accountHistoryData, array $users, array $userGroups) - { - $dto = new self(); - $dto->accountId = $accountHistoryData->getId(); - $dto->userId = $accountHistoryData->getUserId(); - $dto->usersId = $users; - $dto->userGroupId = $accountHistoryData->getUserGroupId(); - $dto->userGroupsId = $userGroups; - $dto->dateEdit = strtotime($accountHistoryData->getDateEdit()); - - return $dto; - } - - /** - * @param AccountSearchVData $accountSearchVData - * - * @param array $users - * @param array $userGroups - * - * @return AccountAclDto - */ - public static function makeFromAccountSearch(AccountSearchVData $accountSearchVData, array $users, array $userGroups) - { - $dto = new self(); - $dto->accountId = $accountSearchVData->getId(); - $dto->userId = $accountSearchVData->getUserId(); - $dto->usersId = $users; - $dto->userGroupId = $accountSearchVData->getUserGroupId(); - $dto->userGroupsId = $userGroups; - $dto->dateEdit = strtotime($accountSearchVData->getDateEdit()); - - return $dto; - } - - /** - * @return int - */ - public function getUserId() + public function getUserId(): int { return $this->userId; } - /** - * @return ItemData[] - */ - public function getUsersId() - { - return $this->usersId; - } - - /** - * @return int - */ - public function getUserGroupId() + public function getUserGroupId(): int { return $this->userGroupId; } - /** - * @return ItemData[] - */ - public function getUserGroupsId() - { - return $this->userGroupsId; - } - - /** - * @return int - */ - public function getDateEdit() + public function getDateEdit(): int { return $this->dateEdit; } /** - * @return int + * @param AccountSearchVData $accountSearchVData + * + * @param array $users + * @param array $userGroups + * + * @return AccountAclDto */ - public function getAccountId() + public static function makeFromAccountSearch( + AccountSearchVData $accountSearchVData, + array $users, + array $userGroups + ): AccountAclDto { + return new self( + $accountSearchVData->getId(), + $accountSearchVData->getUserId(), + $users, + $accountSearchVData->getUserGroupId(), + $userGroups, + strtotime($accountSearchVData->getDateEdit()) + ); + } + + public function getAccountId(): int { return $this->accountId; } -} \ No newline at end of file + + /** + * @return ItemData[] + */ + public function getUsersId(): array + { + return $this->usersId; + } + + /** + * @return ItemData[] + */ + public function getUserGroupsId(): array + { + return $this->userGroupsId; + } + +} diff --git a/lib/SP/DataModel/ItemData.php b/lib/SP/DataModel/ItemData.php index bfeb6508..8c4819e7 100644 --- a/lib/SP/DataModel/ItemData.php +++ b/lib/SP/DataModel/ItemData.php @@ -34,8 +34,8 @@ use SP\Domain\Common\Out\DataModelInterface; */ class ItemData extends DataModelBase implements DataModelInterface { - private ?int $id = null; - private ?string $name = null; + protected ?int $id = null; + protected ?string $name = null; public function getId(): ?int { diff --git a/lib/SP/DataModel/ProfileData.php b/lib/SP/DataModel/ProfileData.php index be148d5f..482c9806 100644 --- a/lib/SP/DataModel/ProfileData.php +++ b/lib/SP/DataModel/ProfileData.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2022, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -33,561 +33,541 @@ defined('APP_ROOT') || die(); */ class ProfileData { - /** - * @var bool - */ - protected $accView = false; - /** - * @var bool - */ - protected $accViewPass = false; - /** - * @var bool - */ - protected $accViewHistory = false; - /** - * @var bool - */ - protected $accEdit = false; - /** - * @var bool - */ - protected $accEditPass = false; - /** - * @var bool - */ - protected $accAdd = false; - /** - * @var bool - */ - protected $accDelete = false; - /** - * @var bool - */ - protected $accFiles = false; - /** - * @var bool - */ - protected $accPrivate = false; - /** - * @var bool - */ - protected $accPrivateGroup = false; - /** - * @var bool - */ - protected $accPermission = false; - /** - * @var bool - */ - protected $accPublicLinks = false; - /** - * @var bool - */ - protected $accGlobalSearch = false; - /** - * @var bool - */ - protected $configGeneral = false; - /** - * @var bool - */ - protected $configEncryption = false; - /** - * @var bool - */ - protected $configBackup = false; - /** - * @var bool - */ - protected $configImport = false; - /** - * @var bool - */ - protected $mgmUsers = false; - /** - * @var bool - */ - protected $mgmGroups = false; - /** - * @var bool - */ - protected $mgmProfiles = false; - /** - * @var bool - */ - protected $mgmCategories = false; - /** - * @var bool - */ - protected $mgmCustomers = false; - /** - * @var bool - */ - protected $mgmApiTokens = false; - /** - * @var bool - */ - protected $mgmPublicLinks = false; - /** - * @var bool - */ - protected $mgmAccounts = false; - /** - * @var bool - */ - protected $mgmTags = false; - /** - * @var bool - */ - protected $mgmFiles = false; - /** - * @var bool - */ - protected $mgmItemsPreset = false; - /** - * @var bool - */ - protected $evl = false; - /** - * @var bool - */ - protected $mgmCustomFields = false; + protected bool $accView = false; + protected bool $accViewPass = false; + protected bool $accViewHistory = false; + protected bool $accEdit = false; + protected bool $accEditPass = false; + protected bool $accAdd = false; + protected bool $accDelete = false; + protected bool $accFiles = false; + protected bool $accPrivate = false; + protected bool $accPrivateGroup = false; + protected bool $accPermission = false; + protected bool $accPublicLinks = false; + protected bool $accGlobalSearch = false; + protected bool $configGeneral = false; + protected bool $configEncryption = false; + protected bool $configBackup = false; + protected bool $configImport = false; + protected bool $mgmUsers = false; + protected bool $mgmGroups = false; + protected bool $mgmProfiles = false; + protected bool $mgmCategories = false; + protected bool $mgmCustomers = false; + protected bool $mgmApiTokens = false; + protected bool $mgmPublicLinks = false; + protected bool $mgmAccounts = false; + protected bool $mgmTags = false; + protected bool $mgmFiles = false; + protected bool $mgmItemsPreset = false; + protected bool $evl = false; + protected bool $mgmCustomFields = false; - /** - * @return boolean - */ - public function isAccView() + public function isAccView(): bool { return $this->accView; } /** - * @param boolean $accView + * @param bool $accView * * @return ProfileData */ - public function setAccView($accView) + public function setAccView(bool $accView): ProfileData { $this->accView = $accView; return $this; } - /** - * @return boolean - */ - public function isAccViewPass() + public function isAccViewPass(): bool { return $this->accViewPass; } /** - * @param boolean $accViewPass + * @param bool $accViewPass * * @return ProfileData */ - public function setAccViewPass($accViewPass) + public function setAccViewPass(bool $accViewPass): ProfileData { $this->accViewPass = $accViewPass; return $this; } - /** - * @return boolean - */ - public function isAccViewHistory() + public function isAccViewHistory(): bool { return $this->accViewHistory; } /** - * @param boolean $accViewHistory + * @param bool $accViewHistory * * @return ProfileData */ - public function setAccViewHistory($accViewHistory) + public function setAccViewHistory(bool $accViewHistory): ProfileData { $this->accViewHistory = $accViewHistory; return $this; } - /** - * @return boolean - */ - public function isAccEdit() + public function isAccEdit(): bool { return $this->accEdit; } /** - * @param boolean $accEdit + * @param bool $accEdit * * @return ProfileData */ - public function setAccEdit($accEdit) + public function setAccEdit(bool $accEdit): ProfileData { $this->accEdit = $accEdit; return $this; } - /** - * @return boolean - */ - public function isAccEditPass() + public function isAccEditPass(): bool { return $this->accEditPass; } /** - * @param boolean $accEditPass + * @param bool $accEditPass * * @return ProfileData */ - public function setAccEditPass($accEditPass) + public function setAccEditPass(bool $accEditPass): ProfileData { $this->accEditPass = $accEditPass; return $this; } - /** - * @return boolean - */ - public function isAccAdd() + public function isAccAdd(): bool { return $this->accAdd; } /** - * @param boolean $accAdd + * @param bool $accAdd * * @return ProfileData */ - public function setAccAdd($accAdd) + public function setAccAdd(bool $accAdd): ProfileData { $this->accAdd = $accAdd; return $this; } - /** - * @return boolean - */ - public function isAccDelete() + public function isAccDelete(): bool { return $this->accDelete; } /** - * @param boolean $accDelete + * @param bool $accDelete * * @return ProfileData */ - public function setAccDelete($accDelete) + public function setAccDelete(bool $accDelete): ProfileData { $this->accDelete = $accDelete; return $this; } - /** - * @return boolean - */ - public function isAccFiles() + public function isAccFiles(): bool { return $this->accFiles; } /** - * @param boolean $accFiles + * @param bool $accFiles * * @return ProfileData */ - public function setAccFiles($accFiles) + public function setAccFiles(bool $accFiles): ProfileData { $this->accFiles = $accFiles; return $this; } + public function isAccPrivate(): bool + { + return $this->accPrivate; + } + /** - * @return boolean + * @param bool $accPrivate + * + * @return ProfileData */ - public function isAccPublicLinks() + public function setAccPrivate(bool $accPrivate): ProfileData + { + $this->accPrivate = $accPrivate; + + return $this; + } + + public function isAccPrivateGroup(): bool + { + return $this->accPrivateGroup; + } + + /** + * @param bool $accPrivateGroup + * + * @return ProfileData + */ + public function setAccPrivateGroup(bool $accPrivateGroup): ProfileData + { + $this->accPrivateGroup = $accPrivateGroup; + + return $this; + } + + public function isAccPermission(): bool + { + return $this->accPermission; + } + + /** + * @param bool $accPermission + * + * @return ProfileData + */ + public function setAccPermission(bool $accPermission): ProfileData + { + $this->accPermission = $accPermission; + + return $this; + } + + public function isAccPublicLinks(): bool { return $this->accPublicLinks; } /** - * @param boolean $accPublicLinks + * @param bool $accPublicLinks * * @return ProfileData */ - public function setAccPublicLinks($accPublicLinks) + public function setAccPublicLinks(bool $accPublicLinks): ProfileData { $this->accPublicLinks = $accPublicLinks; return $this; } + public function isAccGlobalSearch(): bool + { + return $this->accGlobalSearch; + } + /** - * @return boolean + * @param bool $accGlobalSearch + * + * @return ProfileData */ - public function isConfigGeneral() + public function setAccGlobalSearch(bool $accGlobalSearch): ProfileData + { + $this->accGlobalSearch = $accGlobalSearch; + + return $this; + } + + public function isConfigGeneral(): bool { return $this->configGeneral; } /** - * @param boolean $configGeneral + * @param bool $configGeneral * * @return ProfileData */ - public function setConfigGeneral($configGeneral) + public function setConfigGeneral(bool $configGeneral): ProfileData { $this->configGeneral = $configGeneral; return $this; } - /** - * @return boolean - */ - public function isConfigEncryption() + public function isConfigEncryption(): bool { return $this->configEncryption; } /** - * @param boolean $configEncryption + * @param bool $configEncryption * * @return ProfileData */ - public function setConfigEncryption($configEncryption) + public function setConfigEncryption(bool $configEncryption): ProfileData { $this->configEncryption = $configEncryption; return $this; } - /** - * @return boolean - */ - public function isConfigBackup() + public function isConfigBackup(): bool { return $this->configBackup; } /** - * @param boolean $configBackup + * @param bool $configBackup * * @return ProfileData */ - public function setConfigBackup($configBackup) + public function setConfigBackup(bool $configBackup): ProfileData { $this->configBackup = $configBackup; return $this; } - /** - * @return boolean - */ - public function isConfigImport() + public function isConfigImport(): bool { return $this->configImport; } /** - * @param boolean $configImport + * @param bool $configImport * * @return ProfileData */ - public function setConfigImport($configImport) + public function setConfigImport(bool $configImport): ProfileData { $this->configImport = $configImport; return $this; } - /** - * @return boolean - */ - public function isMgmUsers() + public function isMgmUsers(): bool { return $this->mgmUsers; } /** - * @param boolean $mgmUsers + * @param bool $mgmUsers * * @return ProfileData */ - public function setMgmUsers($mgmUsers) + public function setMgmUsers(bool $mgmUsers): ProfileData { $this->mgmUsers = $mgmUsers; return $this; } - /** - * @return boolean - */ - public function isMgmGroups() + public function isMgmGroups(): bool { return $this->mgmGroups; } /** - * @param boolean $mgmGroups + * @param bool $mgmGroups * * @return ProfileData */ - public function setMgmGroups($mgmGroups) + public function setMgmGroups(bool $mgmGroups): ProfileData { $this->mgmGroups = $mgmGroups; return $this; } - /** - * @return boolean - */ - public function isMgmProfiles() + public function isMgmProfiles(): bool { return $this->mgmProfiles; } /** - * @param boolean $mgmProfiles + * @param bool $mgmProfiles * * @return ProfileData */ - public function setMgmProfiles($mgmProfiles) + public function setMgmProfiles(bool $mgmProfiles): ProfileData { $this->mgmProfiles = $mgmProfiles; return $this; } - /** - * @return boolean - */ - public function isMgmCategories() + public function isMgmCategories(): bool { return $this->mgmCategories; } /** - * @param boolean $mgmCategories + * @param bool $mgmCategories * * @return ProfileData */ - public function setMgmCategories($mgmCategories) + public function setMgmCategories(bool $mgmCategories): ProfileData { $this->mgmCategories = $mgmCategories; return $this; } - /** - * @return boolean - */ - public function isMgmCustomers() + public function isMgmCustomers(): bool { return $this->mgmCustomers; } /** - * @param boolean $mgmCustomers + * @param bool $mgmCustomers * * @return ProfileData */ - public function setMgmCustomers($mgmCustomers) + public function setMgmCustomers(bool $mgmCustomers): ProfileData { $this->mgmCustomers = $mgmCustomers; return $this; } - /** - * @return boolean - */ - public function isMgmApiTokens() + public function isMgmApiTokens(): bool { return $this->mgmApiTokens; } /** - * @param boolean $mgmApiTokens + * @param bool $mgmApiTokens * * @return ProfileData */ - public function setMgmApiTokens($mgmApiTokens) + public function setMgmApiTokens(bool $mgmApiTokens): ProfileData { $this->mgmApiTokens = $mgmApiTokens; return $this; } - /** - * @return boolean - */ - public function isMgmPublicLinks() + public function isMgmPublicLinks(): bool { return $this->mgmPublicLinks; } /** - * @param boolean $mgmPublicLinks + * @param bool $mgmPublicLinks * * @return ProfileData */ - public function setMgmPublicLinks($mgmPublicLinks) + public function setMgmPublicLinks(bool $mgmPublicLinks): ProfileData { $this->mgmPublicLinks = $mgmPublicLinks; return $this; } + public function isMgmAccounts(): bool + { + return $this->mgmAccounts; + } + /** - * @return boolean + * @param bool $mgmAccounts + * + * @return ProfileData */ - public function isEvl() + public function setMgmAccounts(bool $mgmAccounts): ProfileData + { + $this->mgmAccounts = $mgmAccounts; + + return $this; + } + + public function isMgmTags(): bool + { + return $this->mgmTags; + } + + /** + * @param bool $mgmTags + * + * @return ProfileData + */ + public function setMgmTags(bool $mgmTags): ProfileData + { + $this->mgmTags = $mgmTags; + + return $this; + } + + public function isMgmFiles(): bool + { + return $this->mgmFiles; + } + + /** + * @param bool $mgmFiles + * + * @return ProfileData + */ + public function setMgmFiles(bool $mgmFiles): ProfileData + { + $this->mgmFiles = $mgmFiles; + + return $this; + } + + public function isMgmItemsPreset(): bool + { + return $this->mgmItemsPreset; + } + + /** + * @param bool $mgmItemsPreset + * + * @return ProfileData + */ + public function setMgmItemsPreset(bool $mgmItemsPreset): ProfileData + { + $this->mgmItemsPreset = $mgmItemsPreset; + + return $this; + } + + public function isEvl(): bool { return $this->evl; } /** - * @param boolean $evl + * @param bool $evl * * @return ProfileData */ - public function setEvl($evl) + public function setEvl(bool $evl): ProfileData { $this->evl = $evl; return $this; } - /** - * @return boolean - */ - public function isMgmCustomFields() + public function isMgmCustomFields(): bool { return $this->mgmCustomFields; } /** - * @param boolean $mgmCustomFields + * @param bool $mgmCustomFields * * @return ProfileData */ - public function setMgmCustomFields($mgmCustomFields) + public function setMgmCustomFields(bool $mgmCustomFields): ProfileData { $this->mgmCustomFields = $mgmCustomFields; @@ -608,181 +588,8 @@ class ProfileData // Para realizar la conversión de nombre de propiedades que empiezan por _ foreach (get_object_vars($this) as $name => $value) { if ($name[0] === '_') { - $newName = substr($name, 1); - $this->$newName = $value; + $this->{substr($name, 1)} = $value; } } } - - /** - * @return boolean - */ - public function isAccPrivate() - { - return $this->accPrivate; - } - - /** - * @param boolean $accPrivate - * - * @return ProfileData - */ - public function setAccPrivate($accPrivate) - { - $this->accPrivate = $accPrivate; - - return $this; - } - - /** - * @return boolean - */ - public function isAccPermission() - { - return $this->accPermission; - } - - /** - * @param boolean $accPermission - * - * @return ProfileData - */ - public function setAccPermission($accPermission) - { - $this->accPermission = $accPermission; - - return $this; - } - - /** - * @return boolean - */ - public function isMgmAccounts() - { - return $this->mgmAccounts; - } - - /** - * @param boolean $mgmAccounts - * - * @return ProfileData - */ - public function setMgmAccounts($mgmAccounts) - { - $this->mgmAccounts = $mgmAccounts; - - return $this; - } - - /** - * @return boolean - */ - public function isMgmTags() - { - return $this->mgmTags; - } - - /** - * @param boolean $mgmTags - * - * @return ProfileData - */ - public function setMgmTags($mgmTags) - { - $this->mgmTags = $mgmTags; - - return $this; - } - - /** - * @return boolean - */ - public function isMgmFiles() - { - return $this->mgmFiles; - } - - /** - * @param boolean $mgmFiles - * - * @return ProfileData - */ - public function setMgmFiles($mgmFiles) - { - $this->mgmFiles = $mgmFiles; - - return $this; - } - - /** - * @return boolean - */ - public function isAccGlobalSearch() - { - return $this->accGlobalSearch; - } - - /** - * @param boolean $accGlobalSearch - * - * @return ProfileData - */ - public function setAccGlobalSearch($accGlobalSearch) - { - $this->accGlobalSearch = $accGlobalSearch; - - return $this; - } - - /** - * @return bool - */ - public function isAccPrivateGroup() - { - return $this->accPrivateGroup; - } - - /** - * @param bool $accPrivateGroup - * - * @return ProfileData - */ - public function setAccPrivateGroup($accPrivateGroup) - { - $this->accPrivateGroup = $accPrivateGroup; - - return $this; - } - - /** - * @return $this - */ - public function reset() - { - foreach ($this as $property => $value) { - $this->{$property} = false; - } - - return $this; - } - - /** - * @return bool - */ - public function isMgmItemsPreset(): bool - { - return $this->mgmItemsPreset; - } - - /** - * @param bool $mgmItemsPreset - * - * @return ProfileData - */ - public function setMgmItemsPreset(bool $mgmItemsPreset) - { - $this->mgmItemsPreset = $mgmItemsPreset; - - return $this; - } -} \ No newline at end of file +} diff --git a/lib/SP/DataModel/SerializedModel.php b/lib/SP/DataModel/SerializedModel.php index 85a12a05..7beb5176 100644 --- a/lib/SP/DataModel/SerializedModel.php +++ b/lib/SP/DataModel/SerializedModel.php @@ -42,7 +42,7 @@ trait SerializedModel * @return mixed|null * @throws NoSuchPropertyException */ - public function hydrate(?string $class = null, string $property = 'data') + public function hydrate(?string $class = null, string $property = 'data'): mixed { if (property_exists($this, $property)) { if ($this->{$property} === null) { @@ -58,4 +58,4 @@ trait SerializedModel throw new NoSuchPropertyException($property); } -} \ No newline at end of file +} diff --git a/lib/SP/DataModel/UserProfileData.php b/lib/SP/DataModel/UserProfileData.php index 75d0a12d..2d5321c3 100644 --- a/lib/SP/DataModel/UserProfileData.php +++ b/lib/SP/DataModel/UserProfileData.php @@ -48,14 +48,6 @@ class UserProfileData extends DataModelBase implements DataModelInterface return $this->name; } - /** - * @param string $name - */ - public function setName($name) - { - $this->name = $name; - } - /** * @return int|null */ @@ -65,26 +57,10 @@ class UserProfileData extends DataModelBase implements DataModelInterface } /** - * @param int $id + * @return \SP\DataModel\ProfileData|null */ - public function setId($id) - { - $this->id = (int)$id; - } - - /** - * @return ProfileData - */ - public function getProfile() + public function getProfile(): ?ProfileData { return $this->profile; } - - /** - * @param ProfileData $profile - */ - public function setProfile(ProfileData $profile) - { - $this->profile = $profile; - } -} \ No newline at end of file +} diff --git a/lib/SP/Domain/Account/AccountAclServiceInterface.php b/lib/SP/Domain/Account/AccountAclServiceInterface.php index ef34a81c..46834cc6 100644 --- a/lib/SP/Domain/Account/AccountAclServiceInterface.php +++ b/lib/SP/Domain/Account/AccountAclServiceInterface.php @@ -30,7 +30,6 @@ use SP\DataModel\Dto\AccountAclDto; use SP\DataModel\ProfileData; use SP\Domain\Account\Services\AccountAcl; use SP\Domain\User\Services\UserLoginResponse; -use SP\Infrastructure\File\FileCacheInterface; /** * Class AccountAclService @@ -53,14 +52,14 @@ interface AccountAclServiceInterface * Obtener la ACL de una cuenta * * @param int $actionId - * @param AccountAclDto|null $accountAclDto + * @param AccountAclDto $accountAclDto * @param bool $isHistory * * @return AccountAcl - * @throws ConstraintException - * @throws QueryException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ - public function getAcl(int $actionId, ?AccountAclDto $accountAclDto = null, bool $isHistory = false): AccountAcl; + public function getAcl(int $actionId, AccountAclDto $accountAclDto, bool $isHistory = false): AccountAcl; /** * Resturns an stored ACL @@ -71,21 +70,4 @@ interface AccountAclServiceInterface * @return \SP\Domain\Account\Services\AccountAcl|null */ public function getAclFromCache(int $accountId, int $actionId): ?AccountAcl; - - /** - * @param int $accountId - * @param int $actionId - * - * @return string - */ - public function getCacheFileForAcl(int $accountId, int $actionId): string; - - /** - * Saves the ACL - * - * @param AccountAcl $accountAcl - * - * @return null|FileCacheInterface - */ - public function saveAclInCache(AccountAcl $accountAcl): ?FileCacheInterface; } diff --git a/lib/SP/Domain/Account/AccountServiceInterface.php b/lib/SP/Domain/Account/AccountServiceInterface.php index bd58ee94..160ac569 100644 --- a/lib/SP/Domain/Account/AccountServiceInterface.php +++ b/lib/SP/Domain/Account/AccountServiceInterface.php @@ -24,21 +24,206 @@ namespace SP\Domain\Account; +use SP\Core\Exceptions\ConstraintException; +use SP\Core\Exceptions\NoSuchPropertyException; +use SP\Core\Exceptions\QueryException; use SP\Core\Exceptions\SPException; +use SP\DataModel\AccountExtData; +use SP\DataModel\AccountHistoryData; use SP\DataModel\Dto\AccountDetailsResponse; +use SP\DataModel\ItemSearchData; +use SP\Domain\Account\Out\AccountData; +use SP\Domain\Account\Out\AccountPassData; +use SP\Domain\Account\Services\AccountBulkRequest; +use SP\Domain\Account\Services\AccountPasswordRequest; +use SP\Domain\Account\Services\AccountRequest; +use SP\Domain\Common\Services\ServiceException; +use SP\Infrastructure\Common\Repositories\NoSuchItemException; +use SP\Infrastructure\Database\QueryResult; /** - * Interface AccountServiceInterface + * Class AccountService * * @package SP\Domain\Account\Services */ interface AccountServiceInterface { /** - * @param int $id + * @throws QueryException + * @throws ConstraintException + */ + public function withUsersById(AccountDetailsResponse $accountDetailsResponse): AccountServiceInterface; + + /** + * @throws QueryException + * @throws ConstraintException + */ + public function withUserGroupsById(AccountDetailsResponse $accountDetailsResponse): AccountServiceInterface; + + /** + * @throws QueryException + * @throws ConstraintException + */ + public function withTagsById(AccountDetailsResponse $accountDetailsResponse): AccountServiceInterface; + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function incrementViewCounter(int $id): bool; + + /** + * @throws QueryException + * @throws ConstraintException + */ + public function incrementDecryptCounter(int $id): bool; + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Infrastructure\Common\Repositories\NoSuchItemException + */ + public function getPasswordForId(int $id): AccountPassData; + + /** + * @param \SP\DataModel\AccountHistoryData $data * - * @return AccountDetailsResponse + * @return int + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function createFromHistory(AccountHistoryData $data): int; + + /** + * @throws QueryException * @throws SPException + * @throws ConstraintException + * @throws NoSuchPropertyException + */ + public function create(AccountRequest $accountRequest): int; + + /** + * Devolver los datos de la clave encriptados + * + * @throws \SP\Domain\Common\Services\ServiceException + */ + public function getPasswordEncrypted(string $pass, ?string $masterPass = null): array; + + /** + * @throws QueryException + * @throws NoSuchItemException + * @throws ConstraintException */ public function getById(int $id): AccountDetailsResponse; + + /** + * Updates external items for the account + * + * @param \SP\Domain\Account\Services\AccountRequest $accountRequest + * + * @throws \SP\Domain\Common\Services\ServiceException + */ + public function update(AccountRequest $accountRequest): void; + + /** + * Update accounts in bulk mode + * + * @param \SP\Domain\Account\Services\AccountBulkRequest $request + * + * @throws \SP\Domain\Common\Services\ServiceException + */ + public function updateBulk(AccountBulkRequest $request): void; + + /** + * @param \SP\Domain\Account\Services\AccountRequest $accountRequest + * + * @throws \SP\Domain\Common\Services\ServiceException + */ + public function editPassword(AccountRequest $accountRequest): void; + + /** + * Updates an already encrypted password data from a master password changing action + * + * @throws ConstraintException + * @throws QueryException + */ + public function updatePasswordMasterPass(AccountPasswordRequest $accountRequest): bool; + + /** + * @param int $historyId + * @param int $accountId + * + * @throws \SP\Domain\Common\Services\ServiceException + * @throws \SP\Infrastructure\Common\Repositories\NoSuchItemException + */ + public function editRestore(int $historyId, int $accountId): void; + + /** + * @throws \SP\Domain\Common\Services\ServiceException + */ + public function delete(int $id): AccountServiceInterface; + + /** + * @param int[] $ids + * + * @throws SPException + * @throws ServiceException + */ + public function deleteByIdBatch(array $ids): AccountServiceInterface; + + /** + * @throws QueryException + * @throws ConstraintException + */ + public function getForUser(?int $accountId = null): array; + + /** + * @throws QueryException + * @throws ConstraintException + */ + public function getLinked(int $accountId): array; + + /** + * @throws QueryException + * @throws ConstraintException + * @throws NoSuchItemException + */ + public function getPasswordHistoryForId(int $id): AccountPassData; + + /** + * @return AccountData[] + */ + public function getAllBasic(): array; + + /** + * @param \SP\DataModel\ItemSearchData $itemSearchData + * + * @return \SP\Infrastructure\Database\QueryResult + */ + public function search(ItemSearchData $itemSearchData): QueryResult; + + /** + * Devolver el número total de cuentas + * + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function getTotalNumAccounts(): int; + + /** + * Obtener los datos de una cuenta. + * + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Infrastructure\Common\Repositories\NoSuchItemException + */ + public function getDataForLink(int $id): AccountExtData; + + /** + * Obtener los datos relativos a la clave de todas las cuentas. + * + * @throws QueryException + * @throws ConstraintException + */ + public function getAccountsPassData(): array; } diff --git a/lib/SP/Domain/Account/Services/AccountAcl.php b/lib/SP/Domain/Account/Services/AccountAcl.php index 79a23fe9..79b7b203 100644 --- a/lib/SP/Domain/Account/Services/AccountAcl.php +++ b/lib/SP/Domain/Account/Services/AccountAcl.php @@ -135,6 +135,11 @@ final class AccountAcl || $this->actionId === ActionsInterface::ACCOUNT_DELETE); } + /** + * @param bool $showDetails + * + * @return AccountAcl + */ public function setShowDetails(bool $showDetails): AccountAcl { $this->showDetails = $showDetails; @@ -148,6 +153,11 @@ final class AccountAcl || $this->actionId === ActionsInterface::ACCOUNT_COPY); } + /** + * @param bool $showPass + * + * @return AccountAcl + */ public function setShowPass(bool $showPass): AccountAcl { $this->showPass = $showPass; @@ -194,6 +204,11 @@ final class AccountAcl || $this->actionId === ActionsInterface::ACCOUNT_COPY; } + /** + * @param bool $showSave + * + * @return AccountAcl + */ public function setShowSave(bool $showSave): AccountAcl { $this->showSave = $showSave; @@ -394,18 +409,6 @@ final class AccountAcl return $this; } - public function isHistory(): bool - { - return $this->isHistory; - } - - public function setIsHistory(bool $isHistory): AccountAcl - { - $this->isHistory = $isHistory; - - return $this; - } - public function isCompiledShowAccess(): bool { return $this->compiledShowAccess; @@ -432,7 +435,7 @@ final class AccountAcl public function reset(): void { - foreach ($this as $property => $value) { + foreach (get_class_vars(__CLASS__) as $property => $value) { if (str_starts_with($property, 'show')) { $this->{$property} = false; } diff --git a/lib/SP/Domain/Account/Services/AccountAclService.php b/lib/SP/Domain/Account/Services/AccountAclService.php index 8b12777f..10882b56 100644 --- a/lib/SP/Domain/Account/Services/AccountAclService.php +++ b/lib/SP/Domain/Account/Services/AccountAclService.php @@ -27,8 +27,9 @@ namespace SP\Domain\Account\Services; use SP\Core\Acl\Acl; use SP\Core\Acl\ActionsInterface; use SP\Core\Application; +use SP\Core\Events\Event; +use SP\Core\Events\EventMessage; use SP\Core\Exceptions\ConstraintException; -use SP\Core\Exceptions\FileNotFoundException; use SP\Core\Exceptions\QueryException; use SP\DataModel\Dto\AccountAclDto; use SP\DataModel\ProfileData; @@ -36,10 +37,9 @@ use SP\Domain\Account\AccountAclServiceInterface; use SP\Domain\Common\Services\Service; use SP\Domain\User\Services\UserLoginResponse; use SP\Domain\User\UserToUserGroupServiceInterface; -use SP\Infrastructure\File\FileCache; use SP\Infrastructure\File\FileCacheInterface; use SP\Infrastructure\File\FileException; -use SP\Util\FileUtil; +use function SP\processException; /** * Class AccountAclService @@ -52,92 +52,76 @@ final class AccountAclService extends Service implements AccountAclServiceInterf * ACL's file base path */ public const ACL_PATH = CACHE_PATH.DIRECTORY_SEPARATOR.'accountAcl'.DIRECTORY_SEPARATOR; - public static bool $useCache = true; + private ?AccountAclDto $accountAclDto = null; private ?AccountAcl $accountAcl = null; private Acl $acl; + private ?FileCacheInterface $fileCache; private UserToUserGroupServiceInterface $userToUserGroupService; private UserLoginResponse $userData; - public function __construct(Application $application, Acl $acl, UserToUserGroupServiceInterface $userGroupService) - { + public function __construct( + Application $application, + Acl $acl, + UserToUserGroupServiceInterface $userGroupService, + ?FileCacheInterface $fileCache = null + ) { parent::__construct($application); $this->acl = $acl; $this->userToUserGroupService = $userGroupService; $this->userData = $this->context->getUserData(); - } - - /** - * @param $userId - * - * @return bool - */ - public static function clearAcl($userId): bool - { - logger(sprintf('Clearing ACL for user ID: %d', $userId)); - - try { - if (FileUtil::rmdir_recursive(self::ACL_PATH.$userId) === false) { - logger(sprintf('Unable to delete %s directory', self::ACL_PATH.$userId)); - - return false; - } - - return true; - } catch (FileNotFoundException $e) { - processException($e); - } - - return false; + $this->fileCache = $fileCache; } /** * Obtener la ACL de una cuenta * * @param int $actionId - * @param AccountAclDto|null $accountAclDto + * @param AccountAclDto $accountAclDto * @param bool $isHistory * * @return AccountAcl * @throws ConstraintException * @throws QueryException */ - public function getAcl(int $actionId, ?AccountAclDto $accountAclDto = null, bool $isHistory = false): AccountAcl + public function getAcl(int $actionId, AccountAclDto $accountAclDto, bool $isHistory = false): AccountAcl { $this->accountAcl = new AccountAcl($actionId, $isHistory); $this->accountAcl->setShowPermission( self::getShowPermission($this->context->getUserData(), $this->context->getUserProfile()) ); - if ($accountAclDto !== null) { - $this->accountAclDto = $accountAclDto; + $this->accountAclDto = $accountAclDto; + if (null !== $this->fileCache) { $accountAcl = $this->getAclFromCache($accountAclDto->getAccountId(), $actionId); - if (self::$useCache && null !== $accountAcl) { - $this->accountAcl->setModified( - ( - $accountAclDto->getDateEdit() > $accountAcl->getTime() - || $this->userData->getLastUpdate() > $accountAcl->getTime() - ) - ); + if (null !== $accountAcl) { + $isModified = $accountAclDto->getDateEdit() > $accountAcl->getTime() + || $this->userData->getLastUpdate() > $accountAcl->getTime(); - if (!$this->accountAcl->isModified()) { - logger('Account ACL HIT'); + if (!$isModified) { + $this->eventDispatcher->notifyEvent( + 'get.acl', + new Event($this, EventMessage::factory()->addDescription('Account ACL HIT')) + ); return $accountAcl; } + + $this->accountAcl->setModified(true); } - - logger('Account ACL MISS'); - - $this->accountAcl->setAccountId($accountAclDto->getAccountId()); - - return $this->updateAcl(); } - return $this->accountAcl; + $this->eventDispatcher->notifyEvent( + 'get.acl', + new Event($this, EventMessage::factory()->addDescription('Account ACL MISS')) + ); + + $this->accountAcl->setAccountId($accountAclDto->getAccountId()); + + return $this->buildAcl(); } /** @@ -161,18 +145,18 @@ final class AccountAclService extends Service implements AccountAclServiceInterf * @param int $accountId * @param int $actionId * - * @return AccountAcl + * @return \SP\Domain\Account\Services\AccountAcl|null */ public function getAclFromCache(int $accountId, int $actionId): ?AccountAcl { try { - $acl = FileCache::factory($this->getCacheFileForAcl($accountId, $actionId))->load(); + $acl = $this->fileCache->load($this->getCacheFileForAcl($accountId, $actionId)); if ($acl instanceof AccountAcl) { return $acl; } } catch (FileException $e) { - logger($e->getMessage()); + processException($e); } return null; @@ -184,7 +168,7 @@ final class AccountAclService extends Service implements AccountAclServiceInterf * * @return string */ - public function getCacheFileForAcl(int $accountId, int $actionId): string + private function getCacheFileForAcl(int $accountId, int $actionId): string { $userId = $this->context->getUserData()->getId(); @@ -197,41 +181,13 @@ final class AccountAclService extends Service implements AccountAclServiceInterf .'.cache'; } - /** - * Actualizar la ACL - * - * @return AccountAcl - * @throws ConstraintException - * @throws QueryException - */ - private function updateAcl(): AccountAcl - { - if ($this->checkComponents()) { - $this->makeAcl(); - } - - if (self::$useCache) { - $this->saveAclInCache($this->accountAcl); - } - - return $this->accountAcl; - } - - /** - * @return bool - */ - private function checkComponents(): bool - { - return null !== $this->accountAclDto; - } - /** * Crear la ACL de una cuenta * * @throws ConstraintException * @throws QueryException */ - private function makeAcl(): void + private function buildAcl(): AccountAcl { $this->compileAccountAccess(); $this->accountAcl->setCompiledAccountAccess(true); @@ -240,6 +196,10 @@ final class AccountAclService extends Service implements AccountAclServiceInterf $this->accountAcl->setCompiledShowAccess(true); $this->accountAcl->setTime(time()); + + $this->saveAclInCache($this->accountAcl); + + return $this->accountAcl; } /** @@ -318,7 +278,7 @@ final class AccountAclService extends Service implements AccountAclServiceInterf array_filter( $this->accountAclDto->getUsersId(), static function ($value) use ($userId) { - return (int)$value->id === $userId; + return (int)$value->getId() === $userId; } ) ); @@ -355,11 +315,11 @@ final class AccountAclService extends Service implements AccountAclServiceInterf array_filter( $this->accountAclDto->getUserGroupsId(), static function ($value) use ($userGroupId, $isAccountFullGroupAccess, $userGroups) { - return (int)$value->id === $userGroupId + return (int)$value->getId() === $userGroupId // o... permitir los grupos que no sean el principal del usuario? || ($isAccountFullGroupAccess // Comprobar si el usuario está vinculado desde los grupos secundarios de la cuenta - && in_array((int)$value->id, $userGroups, true)); + && in_array((int)$value->getId(), $userGroups, true)); } ) ); @@ -406,16 +366,21 @@ final class AccountAclService extends Service implements AccountAclServiceInterf * * @param AccountAcl $accountAcl * - * @return null|FileCacheInterface + * @return void */ - public function saveAclInCache(AccountAcl $accountAcl): ?FileCacheInterface + private function saveAclInCache(AccountAcl $accountAcl): void { + if (null === $this->fileCache) { + return; + } + try { - return FileCache::factory( + $this->fileCache->save( + $accountAcl, $this->getCacheFileForAcl($accountAcl->getAccountId(), $accountAcl->getActionId()) - )->save($accountAcl); + ); } catch (FileException $e) { - return null; + processException($e); } } -} \ No newline at end of file +} diff --git a/lib/SP/Domain/Account/Services/AccountCryptService.php b/lib/SP/Domain/Account/Services/AccountCryptService.php index dbd77a49..8f5761be 100644 --- a/lib/SP/Domain/Account/Services/AccountCryptService.php +++ b/lib/SP/Domain/Account/Services/AccountCryptService.php @@ -33,6 +33,7 @@ use SP\Core\Events\EventMessage; use SP\Core\Exceptions\SPException; use SP\Domain\Account\AccountCryptServiceInterface; use SP\Domain\Account\AccountHistoryServiceInterface; +use SP\Domain\Account\AccountServiceInterface; use SP\Domain\Common\Services\Service; use SP\Domain\Common\Services\ServiceException; use SP\Domain\Crypt\Services\UpdateMasterPassRequest; @@ -52,7 +53,7 @@ final class AccountCryptService extends Service implements AccountCryptServiceIn public function __construct( Application $application, - AccountService $accountService, + AccountServiceInterface $accountService, AccountHistoryServiceInterface $accountHistoryService ) { parent::__construct($application); @@ -274,4 +275,4 @@ final class AccountCryptService extends Service implements AccountCryptServiceIn ); } } -} \ No newline at end of file +} diff --git a/lib/SP/Domain/Account/Services/AccountSearchItem.php b/lib/SP/Domain/Account/Services/AccountSearchItem.php index 3c31ecfc..08cf4bb9 100644 --- a/lib/SP/Domain/Account/Services/AccountSearchItem.php +++ b/lib/SP/Domain/Account/Services/AccountSearchItem.php @@ -294,9 +294,6 @@ final class AccountSearchItem public function isWikiMatch(string $wikiFilter): bool { - return preg_match( - '/^'.$wikiFilter.'/i', - $this->accountSearchVData->getName() - ) === 1; + return preg_match('/^'.$wikiFilter.'/i', $this->accountSearchVData->getName()) === 1; } -} \ No newline at end of file +} diff --git a/lib/SP/Domain/Account/Services/AccountService.php b/lib/SP/Domain/Account/Services/AccountService.php index 7ad1921b..4896bb13 100644 --- a/lib/SP/Domain/Account/Services/AccountService.php +++ b/lib/SP/Domain/Account/Services/AccountService.php @@ -55,6 +55,8 @@ use SP\Domain\ItemPreset\ItemPresetInterface; use SP\Domain\ItemPreset\ItemPresetServiceInterface; use SP\Infrastructure\Common\Repositories\NoSuchItemException; use SP\Infrastructure\Database\QueryResult; +use function SP\__u; +use function SP\logger; /** * Class AccountService @@ -72,7 +74,6 @@ final class AccountService extends Service implements AccountServiceInterface private ItemPresetServiceInterface $itemPresetService; private AccountHistoryServiceInterface $accountHistoryService; private ConfigServiceInterface $configService; - private AccountFilterUserInterface $accountFilterUser; public function __construct( Application $application, @@ -83,7 +84,6 @@ final class AccountService extends Service implements AccountServiceInterface ItemPresetServiceInterface $itemPresetService, AccountHistoryServiceInterface $accountHistoryService, ConfigServiceInterface $configService, - AccountFilterUserInterface $accountFilterUser ) { $this->accountRepository = $accountRepository; $this->accountToUserGroupRepository = $accountToUserGroupRepository; @@ -92,7 +92,6 @@ final class AccountService extends Service implements AccountServiceInterface $this->itemPresetService = $itemPresetService; $this->accountHistoryService = $accountHistoryService; $this->configService = $configService; - $this->accountFilterUser = $accountFilterUser; parent::__construct($application); } @@ -101,7 +100,7 @@ final class AccountService extends Service implements AccountServiceInterface * @throws QueryException * @throws ConstraintException */ - public function withUsersById(AccountDetailsResponse $accountDetailsResponse): AccountService + public function withUsersById(AccountDetailsResponse $accountDetailsResponse): AccountServiceInterface { $accountDetailsResponse->setUsers( $this->accountToUserRepository->getUsersByAccountId($accountDetailsResponse->getId()) @@ -115,7 +114,7 @@ final class AccountService extends Service implements AccountServiceInterface * @throws QueryException * @throws ConstraintException */ - public function withUserGroupsById(AccountDetailsResponse $accountDetailsResponse): AccountService + public function withUserGroupsById(AccountDetailsResponse $accountDetailsResponse): AccountServiceInterface { $accountDetailsResponse->setUserGroups( $this->accountToUserGroupRepository->getUserGroupsByAccountId($accountDetailsResponse->getId()) @@ -129,7 +128,7 @@ final class AccountService extends Service implements AccountServiceInterface * @throws QueryException * @throws ConstraintException */ - public function withTagsById(AccountDetailsResponse $accountDetailsResponse): AccountService + public function withTagsById(AccountDetailsResponse $accountDetailsResponse): AccountServiceInterface { $accountDetailsResponse->setTags( $this->accountToTagRepository->getTagsByAccountId($accountDetailsResponse->getId()) @@ -177,6 +176,8 @@ final class AccountService extends Service implements AccountServiceInterface * @param \SP\DataModel\AccountHistoryData $data * * @return int + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ public function createFromHistory(AccountHistoryData $data): int { @@ -327,7 +328,6 @@ final class AccountService extends Service implements AccountServiceInterface private function addItems(AccountRequest $accountRequest): void { try { - if ($accountRequest->changePermissions) { if (is_array($accountRequest->userGroupsView) && count($accountRequest->userGroupsView) !== 0 @@ -380,29 +380,25 @@ final class AccountService extends Service implements AccountServiceInterface $userData = $this->context->getUserData(); $accountPermission = $itemPresetData->hydrate(AccountPermission::class); - $accountRequest = new AccountRequest(); - $accountRequest->id = $accountId; - $accountRequest->usersView = array_diff($accountPermission->getUsersView(), [$userData->getId()]); - $accountRequest->usersEdit = array_diff($accountPermission->getUsersEdit(), [$userData->getId()]); - $accountRequest->userGroupsView = - array_diff($accountPermission->getUserGroupsView(), [$userData->getUserGroupId()]); - $accountRequest->userGroupsEdit = - array_diff($accountPermission->getUserGroupsEdit(), [$userData->getUserGroupId()]); + $usersView = array_diff($accountPermission->getUsersView(), [$userData->getId()]); + $usersEdit = array_diff($accountPermission->getUsersEdit(), [$userData->getId()]); + $userGroupsView = array_diff($accountPermission->getUserGroupsView(), [$userData->getUserGroupId()]); + $userGroupsEdit = array_diff($accountPermission->getUserGroupsEdit(), [$userData->getUserGroupId()]); - if (!empty($accountRequest->usersView)) { - $this->accountToUserRepository->addByType($accountRequest, false); + if (count($usersView) !== 0) { + $this->accountToUserRepository->addByType($accountId, $usersView, false); } - if (!empty($accountRequest->usersEdit)) { - $this->accountToUserRepository->addByType($accountRequest, true); + if (count($usersEdit) !== 0) { + $this->accountToUserRepository->addByType($accountId, $usersEdit, true); } - if (!empty($accountRequest->userGroupsView)) { - $this->accountToUserGroupRepository->addByType($accountRequest, false); + if (count($userGroupsView) !== 0) { + $this->accountToUserGroupRepository->addByType($accountId, $userGroupsView, false); } - if (!empty($accountRequest->userGroupsEdit)) { - $this->accountToUserGroupRepository->addByType($accountRequest, true); + if (count($userGroupsEdit) !== 0) { + $this->accountToUserGroupRepository->addByType($accountId, $userGroupsEdit, true); } } } @@ -642,13 +638,13 @@ final class AccountService extends Service implements AccountServiceInterface /** * @throws \SP\Domain\Common\Services\ServiceException */ - public function delete(int $id): AccountService + public function delete(int $id): AccountServiceInterface { $this->accountRepository->transactionAware( function () use ($id) { $this->addHistory($id, 1); - if ($this->accountRepository->delete($id) === 0) { + if ($this->accountRepository->delete($id)) { throw new NoSuchItemException(__u('Account not found')); } } @@ -663,7 +659,7 @@ final class AccountService extends Service implements AccountServiceInterface * @throws SPException * @throws ServiceException */ - public function deleteByIdBatch(array $ids): AccountService + public function deleteByIdBatch(array $ids): AccountServiceInterface { if ($this->accountRepository->deleteByIdBatch($ids) === 0) { throw new ServiceException(__u('Error while deleting the accounts')); @@ -708,8 +704,6 @@ final class AccountService extends Service implements AccountServiceInterface /** * @return AccountData[] - * @throws QueryException - * @throws ConstraintException */ public function getAllBasic(): array { diff --git a/lib/SP/Domain/Common/Services/Service.php b/lib/SP/Domain/Common/Services/Service.php index a8ad75c3..1a37fddf 100644 --- a/lib/SP/Domain/Common/Services/Service.php +++ b/lib/SP/Domain/Common/Services/Service.php @@ -24,19 +24,16 @@ namespace SP\Domain\Common\Services; -use Closure; use Defuse\Crypto\Exception\CryptoException; -use Exception; use SP\Core\Application; use SP\Core\Context\ContextException; use SP\Core\Context\ContextInterface; use SP\Core\Context\SessionContext; use SP\Core\Crypt\Session; -use SP\Core\Events\Event; use SP\Core\Events\EventDispatcher; -use SP\Core\Events\EventMessage; use SP\Domain\Config\ConfigInterface; -use SP\Infrastructure\Database\DatabaseInterface; +use function SP\__u; +use function SP\logger; /** * Class Service @@ -58,42 +55,6 @@ abstract class Service $this->eventDispatcher = $application->getEventDispatcher(); } - /** - * Bubbles a Closure in a database transaction - * - * @param \Closure $closure - * @param \SP\Infrastructure\Database\DatabaseInterface $database - * - * @return mixed - * @throws \SP\Domain\Common\Services\ServiceException - * @throws \Exception - */ - protected function transactionAware(Closure $closure, DatabaseInterface $database) - { - if ($database->beginTransaction()) { - try { - $result = $closure->call($this); - - $database->endTransaction(); - - return $result; - } catch (Exception $e) { - $database->rollbackTransaction(); - - logger('Transaction:Rollback'); - - $this->eventDispatcher->notifyEvent( - 'database.rollback', - new Event($this, EventMessage::factory()->addDescription(__u('Rollback'))) - ); - - throw $e; - } - } else { - throw new ServiceException(__u('Unable to start a transaction')); - } - } - /** * @throws ServiceException */ @@ -135,4 +96,4 @@ abstract class Service throw new ServiceException(__u('Error while setting master password in context')); } } -} \ No newline at end of file +} diff --git a/lib/SP/Domain/Config/Adapters/ConfigData.php b/lib/SP/Domain/Config/Adapters/ConfigData.php index fc183f4e..bfadf354 100644 --- a/lib/SP/Domain/Config/Adapters/ConfigData.php +++ b/lib/SP/Domain/Config/Adapters/ConfigData.php @@ -48,7 +48,7 @@ final class ConfigData extends DataCollection implements JsonSerializable, Confi public function getAttributes(): array { - return $this->attributes; + return $this->getArrayCopy(); } public function getLogEvents(): array @@ -374,7 +374,7 @@ final class ConfigData extends DataCollection implements JsonSerializable, Confi */ public function setConfigHash(): ConfigDataInterface { - $this->set(ConfigDataInterface::CONFIG_HASH, sha1(serialize($this->attributes))); + $this->set(ConfigDataInterface::CONFIG_HASH, sha1(serialize($this->getArrayCopy()))); return $this; } @@ -910,7 +910,7 @@ final class ConfigData extends DataCollection implements JsonSerializable, Confi */ public function jsonSerialize(): array { - return $this->attributes; + return $this->getArrayCopy(); } public function getConfigSaver(): ?string diff --git a/lib/SP/Domain/Config/Services/ConfigFileService.php b/lib/SP/Domain/Config/Services/ConfigFileService.php index 97e9fd30..b3c3f740 100644 --- a/lib/SP/Domain/Config/Services/ConfigFileService.php +++ b/lib/SP/Domain/Config/Services/ConfigFileService.php @@ -39,6 +39,7 @@ use SP\Infrastructure\File\FileException; use SP\Infrastructure\File\XmlFileStorageInterface; use SP\Util\PasswordUtil; use function SP\logger; +use function SP\processException; defined('APP_ROOT') || die(); diff --git a/lib/SP/Domain/CustomField/Services/CustomFieldItem.php b/lib/SP/Domain/CustomField/Services/CustomFieldItem.php index d590f40a..92419f80 100644 --- a/lib/SP/Domain/CustomField/Services/CustomFieldItem.php +++ b/lib/SP/Domain/CustomField/Services/CustomFieldItem.php @@ -50,7 +50,7 @@ final class CustomFieldItem implements JsonSerializable /** * @inheritDoc */ - public function jsonSerialize() + public function jsonSerialize(): array { return [ 'required' => $this->required, @@ -65,4 +65,4 @@ final class CustomFieldItem implements JsonSerializable 'isValueEncrypted' => $this->isValueEncrypted, ]; } -} \ No newline at end of file +} diff --git a/lib/SP/Domain/Install/Services/InstallerService.php b/lib/SP/Domain/Install/Services/InstallerService.php index 7e0b9e23..0554f463 100644 --- a/lib/SP/Domain/Install/Services/InstallerService.php +++ b/lib/SP/Domain/Install/Services/InstallerService.php @@ -48,6 +48,8 @@ use SP\Domain\User\UserServiceInterface; use SP\Http\RequestInterface; use SP\Infrastructure\Database\DatabaseConnectionData; use SP\Util\VersionUtil; +use function SP\__u; +use function SP\processException; defined('APP_ROOT') || die(); @@ -340,9 +342,7 @@ final class InstallerService implements InstallerServiceInterface $userGroupData->setName('Admins'); $userGroupData->setDescription('sysPass Admins'); - $userProfileData = new UserProfileData(); - $userProfileData->setName('Admin'); - $userProfileData->setProfile(new ProfileData()); + $userProfileData = new UserProfileData(['name' => 'Admin', 'profile' => new ProfileData()]); $userData = new UserData(); $userData->setUserGroupId($this->userGroupService->create($userGroupData)); @@ -374,4 +374,4 @@ final class InstallerService implements InstallerServiceInterface ); } } -} \ No newline at end of file +} diff --git a/lib/SP/Domain/Install/Services/MysqlService.php b/lib/SP/Domain/Install/Services/MysqlService.php index 57a60299..436b62b9 100644 --- a/lib/SP/Domain/Install/Services/MysqlService.php +++ b/lib/SP/Domain/Install/Services/MysqlService.php @@ -33,6 +33,10 @@ use SP\Infrastructure\Database\DatabaseUtil; use SP\Infrastructure\Database\DbStorageInterface; use SP\Infrastructure\File\FileException; use SP\Util\PasswordUtil; +use function SP\__; +use function SP\__u; +use function SP\logger; +use function SP\processException; /** * Class MySQL @@ -189,7 +193,6 @@ final class MysqlService implements DatabaseSetupInterface public function createDatabase(?string $dbUser = null): void { if (!$this->installData->isHostingMode()) { - if ($this->checkDatabaseExists()) { throw new SPException( __u('The database already exists'), @@ -401,4 +404,4 @@ final class MysqlService implements DatabaseSetupInterface ); } } -} \ No newline at end of file +} diff --git a/lib/SP/Infrastructure/File/FileCache.php b/lib/SP/Infrastructure/File/FileCache.php index 0de62c45..3ac3fc55 100644 --- a/lib/SP/Infrastructure/File/FileCache.php +++ b/lib/SP/Infrastructure/File/FileCache.php @@ -29,21 +29,25 @@ namespace SP\Infrastructure\File; * * @package SP\Infrastructure\File; */ -final class FileCache extends FileCacheBase +class FileCache extends FileCacheBase { /** * @throws FileException */ - public function load() + public function load(?string $path = null): mixed { + $this->checkOrInitializePath($path); + + /** @noinspection UnserializeExploitsInspection */ return unserialize($this->path->checkIsReadable()->readToString()); } /** * @throws FileException */ - public function save($data): FileCacheInterface + public function save(mixed $data, ?string $path = null): FileCacheInterface { + $this->checkOrInitializePath($path); $this->createPath(); $this->path->checkIsWritable(); @@ -53,4 +57,4 @@ final class FileCache extends FileCacheBase return $this; } -} \ No newline at end of file +} diff --git a/lib/SP/Infrastructure/File/FileCacheBase.php b/lib/SP/Infrastructure/File/FileCacheBase.php index 10fa51ec..59f6f165 100644 --- a/lib/SP/Infrastructure/File/FileCacheBase.php +++ b/lib/SP/Infrastructure/File/FileCacheBase.php @@ -24,6 +24,7 @@ namespace SP\Infrastructure\File; +use function SP\__; /** * Class FileCacheBase @@ -32,11 +33,13 @@ namespace SP\Infrastructure\File; */ abstract class FileCacheBase implements FileCacheInterface { - protected FileHandler $path; + protected ?FileHandler $path = null; - public function __construct(string $path) + public function __construct(?string $path = null) { - $this->path = new FileHandler($path); + if (null !== $path) { + $this->path = new FileHandler($path); + } } public static function factory(string $path): FileCacheBase @@ -96,4 +99,18 @@ abstract class FileCacheBase implements FileCacheInterface { return file_exists($this->path->getFile()); } -} \ No newline at end of file + + /** + * @throws \SP\Infrastructure\File\FileException + */ + protected function checkOrInitializePath(?string $path = null): void + { + if (null === $path && null === $this->path) { + throw new FileException(__('Path is needed')); + } + + if (null === $this->path || $this->path->getFile() !== $path) { + $this->path = new FileHandler($path); + } + } +} diff --git a/lib/SP/Infrastructure/File/FileCacheInterface.php b/lib/SP/Infrastructure/File/FileCacheInterface.php index 763e7549..7f925308 100644 --- a/lib/SP/Infrastructure/File/FileCacheInterface.php +++ b/lib/SP/Infrastructure/File/FileCacheInterface.php @@ -32,15 +32,17 @@ namespace SP\Infrastructure\File; interface FileCacheInterface { /** + * @param string|null $path + * * @return mixed - * @throws FileException + * @throws \SP\Infrastructure\File\FileException */ - public function load(); + public function load(?string $path = null): mixed; /** * @throws FileException */ - public function save($data): FileCacheInterface; + public function save(mixed $data, ?string $path = null): FileCacheInterface; public function delete(): FileCacheInterface; @@ -57,4 +59,4 @@ interface FileCacheInterface public function isExpiredDate(int $date): bool; public function exists(): bool; -} \ No newline at end of file +} diff --git a/lib/SP/Infrastructure/File/FileCachePacked.php b/lib/SP/Infrastructure/File/FileCachePacked.php index 258858f9..720658aa 100644 --- a/lib/SP/Infrastructure/File/FileCachePacked.php +++ b/lib/SP/Infrastructure/File/FileCachePacked.php @@ -37,8 +37,10 @@ final class FileCachePacked extends FileCacheBase * @throws RuntimeException * @throws FileException */ - public function load() + public function load(?string $path = null): mixed { + $this->checkOrInitializePath($path); + $this->path->checkIsReadable(); $dataUnpacked = gzuncompress($this->path->readToString()); @@ -63,8 +65,9 @@ final class FileCachePacked extends FileCacheBase /** * @throws FileException */ - public function save($data): FileCacheInterface + public function save(mixed $data, ?string $path = null): FileCacheInterface { + $this->checkOrInitializePath($path); $this->createPath(); $data = gzcompress(serialize($data)); @@ -82,4 +85,4 @@ final class FileCachePacked extends FileCacheBase return $this; } -} \ No newline at end of file +} diff --git a/lib/SP/Infrastructure/File/FileHandler.php b/lib/SP/Infrastructure/File/FileHandler.php index 44e20125..a400da8b 100644 --- a/lib/SP/Infrastructure/File/FileHandler.php +++ b/lib/SP/Infrastructure/File/FileHandler.php @@ -25,6 +25,7 @@ namespace SP\Infrastructure\File; use SP\Util\Util; +use function SP\logger; /** * Class FileHandler @@ -339,4 +340,4 @@ final class FileHandler implements FileHandlerInterface return filemtime($this->file) ?: 0; } -} \ No newline at end of file +} diff --git a/lib/SP/Providers/Acl/AclHandler.php b/lib/SP/Providers/Acl/AclHandler.php index 465ed178..2f156b29 100644 --- a/lib/SP/Providers/Acl/AclHandler.php +++ b/lib/SP/Providers/Acl/AclHandler.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2022, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -28,6 +28,7 @@ use Exception; use SP\Core\Application; use SP\Core\Events\Event; use SP\Core\Events\EventReceiver; +use SP\Core\Exceptions\FileNotFoundException; use SP\Core\Exceptions\SPException; use SP\Domain\Account\Services\AccountAclService; use SP\Domain\User\Services\UserGroupService; @@ -36,7 +37,11 @@ use SP\Domain\User\UserGroupServiceInterface; use SP\Domain\User\UserProfileServiceInterface; use SP\Providers\EventsTrait; use SP\Providers\Provider; +use SP\Util\FileUtil; use SplSubject; +use function SP\__u; +use function SP\logger; +use function SP\processException; /** * Class AclHandler @@ -70,7 +75,6 @@ final class AclHandler extends Provider implements EventReceiver parent::__construct($application); } - /** * Devuelve los eventos que implementa el observador * @@ -147,7 +151,7 @@ final class AclHandler extends Provider implements EventReceiver if (isset($extra['userProfileId'])) { foreach ($this->userProfileService->getUsersForProfile($extra['userProfileId'][0]) as $user) { - AccountAclService::clearAcl($user->id); + $this->clearAcl($user->id); } } } catch (Exception $e) { @@ -155,6 +159,30 @@ final class AclHandler extends Provider implements EventReceiver } } + /** + * @param $userId + * + * @return bool + */ + private function clearAcl($userId): bool + { + logger(sprintf('Clearing ACL for user ID: %d', $userId)); + + try { + if (FileUtil::rmdirRecursive(AccountAclService::ACL_PATH.$userId) === false) { + logger(sprintf('Unable to delete %s directory', AccountAclService::ACL_PATH.$userId)); + + return false; + } + + return true; + } catch (FileNotFoundException $e) { + processException($e); + } + + return false; + } + /** * @throws \SP\Core\Exceptions\SPException */ @@ -170,7 +198,7 @@ final class AclHandler extends Provider implements EventReceiver if (isset($extra['userId'])) { foreach ($extra['userId'] as $id) { - AccountAclService::clearAcl($id); + $this->clearAcl($id); } } } @@ -188,7 +216,7 @@ final class AclHandler extends Provider implements EventReceiver if (isset($extra['userGroupId'])) { foreach ($this->userGroupService->getUsageByUsers($extra['userGroupId'][0]) as $user) { - AccountAclService::clearAcl($user->id); + $this->clearAcl($user->id); } } } catch (Exception $e) { @@ -201,4 +229,4 @@ final class AclHandler extends Provider implements EventReceiver $this->events = $this->parseEventsToRegex(self::EVENTS); $this->initialized = true; } -} \ No newline at end of file +} diff --git a/lib/SP/Util/FileUtil.php b/lib/SP/Util/FileUtil.php index 6df0aeb5..8f3f9691 100644 --- a/lib/SP/Util/FileUtil.php +++ b/lib/SP/Util/FileUtil.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2021, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2022, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -35,7 +35,7 @@ use SP\DataModel\FileData; * * @package SP\Util */ -final class FileUtil +class FileUtil { private const IMAGE_MIME = [ 'image/jpeg', @@ -50,7 +50,7 @@ final class FileUtil * @throws \SP\Core\Exceptions\FileNotFoundException * @see https://stackoverflow.com/a/7288067 */ - public static function rmdir_recursive(string $dir): bool + public static function rmdirRecursive(string $dir): bool { if (!is_dir($dir)) { throw new FileNotFoundException('Directory does not exist'); @@ -79,4 +79,4 @@ final class FileUtil { return in_array(strtolower($fileData->getType()), self::IMAGE_MIME, true); } -} \ No newline at end of file +} diff --git a/phpstan.neon b/phpstan.neon index 3624ceeb..cc7eeeac 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,3 +1,4 @@ parameters: bootstrapFiles: - - lib/BaseFunctions.php \ No newline at end of file + - lib/BaseFunctions.php + - lib/Base.php diff --git a/tests/SP/Domain/Account/Services/AccountAclServiceTest.php b/tests/SP/Domain/Account/Services/AccountAclServiceTest.php new file mode 100644 index 00000000..0b7b3fe7 --- /dev/null +++ b/tests/SP/Domain/Account/Services/AccountAclServiceTest.php @@ -0,0 +1,834 @@ +. + */ + +namespace SP\Tests\Domain\Account\Services; + +use SP\Core\Acl\Acl; +use SP\Core\Acl\ActionsInterface; +use SP\Core\Exceptions\ConstraintException; +use SP\Core\Exceptions\QueryException; +use SP\DataModel\Dto\AccountAclDto; +use SP\DataModel\Dto\AccountDetailsResponse; +use SP\DataModel\ItemData; +use SP\Domain\Account\Services\AccountAcl; +use SP\Domain\Account\Services\AccountAclService; +use SP\Domain\Common\Out\SimpleModel; +use SP\Domain\User\UserToUserGroupServiceInterface; +use SP\Infrastructure\File\FileCacheInterface; +use SP\Infrastructure\File\FileException; +use SP\Tests\UnitaryTestCase; + +/** + * Class AccountAclServiceTest + * + * @package SP\Tests\Services + */ +class AccountAclServiceTest extends UnitaryTestCase +{ + private const ACTIONS = [ + ActionsInterface::ACCOUNT_SEARCH, + ActionsInterface::ACCOUNT_VIEW, + ActionsInterface::ACCOUNT_VIEW_PASS, + ActionsInterface::ACCOUNT_HISTORY_VIEW, + ActionsInterface::ACCOUNT_CREATE, + ActionsInterface::ACCOUNT_EDIT, + ActionsInterface::ACCOUNT_EDIT_PASS, + ActionsInterface::ACCOUNT_EDIT_RESTORE, + ActionsInterface::ACCOUNT_COPY, + ActionsInterface::ACCOUNT_COPY_PASS, + ActionsInterface::ACCOUNT_DELETE, + ]; + private static array $accounts; + protected AccountDetailsResponse $account; + private AccountAclService $accountAclService; + + public static function setUpBeforeClass(): void + { + parent::setUpBeforeClass(); + + self::$accounts = [ + 1 => [ + 'userGroupId' => 1, + 'userId' => 1, + 'isPrivate' => 0, + 'isPrivateGroup' => 0, + 'otherUserGroupEdit' => 0, + 'otherUserEdit' => 0, + 'users' => [new ItemData(['id' => 3, 'isEdit' => 1])], + 'groups' => [new ItemData(['id' => 2, 'isEdit' => 1])], + + ], + 2 => [ + 'userGroupId' => 1, + 'userId' => 1, + 'isPrivate' => 0, + 'isPrivateGroup' => 0, + 'otherUserGroupEdit' => 0, + 'otherUserEdit' => 0, + 'users' => [], + 'groups' => [ + new ItemData(['id' => 2, 'isEdit' => 1]), + new ItemData(['id' => 3, 'isEdit' => 1]), + ], + ], + 3 => [ + 'userGroupId' => 3, + 'userId' => 3, + 'isPrivate' => 1, + 'isPrivateGroup' => 0, + 'otherUserGroupEdit' => 0, + 'otherUserEdit' => 0, + 'users' => [], + 'groups' => [], + ], + 4 => [ + 'userGroupId' => 3, + 'userId' => 3, + 'isPrivate' => 0, + 'isPrivateGroup' => 1, + 'otherUserGroupEdit' => 0, + 'otherUserEdit' => 0, + 'users' => [], + 'groups' => [], + ], + ]; + } + + /** + * @group acl:admin + * + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testGetAclForAdminApp(): void + { + $this->context + ->getUserProfile() + ->setAccAdd(true) + ->setAccView(true) + ->setAccViewPass(true) + ->setAccEdit(true) + ->setAccEditPass(true) + ->setAccFiles(true) + ->setAccDelete(true) + ->setAccPermission(true) + ->setAccViewHistory(true); + + $this->checkForUserByExample( + $this->setUpAccountEnvironment( + self::$faker->numberBetween(1, 4), + self::$faker->randomNumber(), + self::$faker->randomNumber(), + 1, + 0 + ), + $this->getExampleAclForAdmin() + ); + } + + /** + * @param AccountAclDto $accountAclDto The ACL dto to compile the ACL for the user + * @param AccountAcl $example An example ACL to test against the compiled ACL + * + * @throws ConstraintException + * @throws QueryException + */ + private function checkForUserByExample(AccountAclDto $accountAclDto, AccountAcl $example): void + { + foreach (self::ACTIONS as $action) { + $example->setActionId($action); + + $aclUnderTest = $this->accountAclService->getAcl($action, $accountAclDto); + + $this->assertTrue($aclUnderTest->isCompiledAccountAccess()); + $this->assertTrue($aclUnderTest->isCompiledShowAccess()); + + $this->assertEquals($example->isResultView(), $aclUnderTest->isResultView()); + $this->assertEquals($example->isResultEdit(), $aclUnderTest->isResultEdit()); + $this->assertEquals($example->isShowPermission(), $aclUnderTest->isShowPermission()); + + if ($action !== ActionsInterface::ACCOUNT_CREATE + && $action !== ActionsInterface::ACCOUNT_COPY_PASS + ) { + $this->assertEquals($example->checkAccountAccess($action), $aclUnderTest->checkAccountAccess($action)); + } + + if ($action === ActionsInterface::ACCOUNT_VIEW + || $action === ActionsInterface::ACCOUNT_HISTORY_VIEW + || $action === ActionsInterface::ACCOUNT_DELETE + ) { + $this->assertEquals($example->isShowDetails(), $aclUnderTest->isShowDetails()); + } + + if ($action === ActionsInterface::ACCOUNT_CREATE + || $action === ActionsInterface::ACCOUNT_COPY + ) { + $this->assertEquals($example->isShowPass(), $aclUnderTest->isShowPass()); + } + + if ($action === ActionsInterface::ACCOUNT_EDIT + || $action === ActionsInterface::ACCOUNT_VIEW + || $action === ActionsInterface::ACCOUNT_HISTORY_VIEW + ) { + $this->assertEquals($example->isShowFiles(), $aclUnderTest->isShowFiles()); + } + + if ($action === ActionsInterface::ACCOUNT_SEARCH + || $action === ActionsInterface::ACCOUNT_VIEW + || $action === ActionsInterface::ACCOUNT_VIEW_PASS + || $action === ActionsInterface::ACCOUNT_HISTORY_VIEW + || $action === ActionsInterface::ACCOUNT_EDIT + ) { + $this->assertEquals($example->isShowViewPass(), $aclUnderTest->isShowViewPass()); + } + + if ($action === ActionsInterface::ACCOUNT_EDIT + || $action === ActionsInterface::ACCOUNT_CREATE + || $action === ActionsInterface::ACCOUNT_COPY + ) { + $this->assertEquals($example->isShowSave(), $aclUnderTest->isShowSave()); + } + + if ($action === ActionsInterface::ACCOUNT_SEARCH + || $action === ActionsInterface::ACCOUNT_VIEW + ) { + $this->assertEquals($example->isShowEdit(), $aclUnderTest->isShowEdit()); + } + + if ($action === ActionsInterface::ACCOUNT_EDIT + || $action === ActionsInterface::ACCOUNT_VIEW + ) { + $this->assertEquals($example->isShowEditPass(), $aclUnderTest->isShowEditPass()); + } + + if ($action === ActionsInterface::ACCOUNT_SEARCH + || $action === ActionsInterface::ACCOUNT_DELETE + || $action === ActionsInterface::ACCOUNT_EDIT + ) { + $this->assertEquals($example->isShowDelete(), $aclUnderTest->isShowDelete()); + } + + if ($action === ActionsInterface::ACCOUNT_HISTORY_VIEW) { + $this->assertEquals($example->isShowRestore(), $aclUnderTest->isShowRestore()); + } + + $this->assertEquals($example->isShowLink(), $aclUnderTest->isShowLink()); + + if ($action === ActionsInterface::ACCOUNT_VIEW + || $action === ActionsInterface::ACCOUNT_HISTORY_VIEW + ) { + $this->assertEquals($example->isShowHistory(), $aclUnderTest->isShowHistory()); + } + + if ($action === ActionsInterface::ACCOUNT_SEARCH + || $action === ActionsInterface::ACCOUNT_VIEW + || $action === ActionsInterface::ACCOUNT_EDIT + ) { + $this->assertEquals($example->isShowCopy(), $aclUnderTest->isShowCopy()); + } + } + } + + /** + * @param int $accountId + * @param int $userId + * @param int $groupId + * + * @param bool $isAdminApp + * @param bool|int $isAdminAcc + * + * @return AccountAclDto + */ + private function setUpAccountEnvironment( + int $accountId, + int $userId, + int $groupId, + bool $isAdminApp = false, + bool $isAdminAcc = false + ): AccountAclDto { + $this->context + ->getUserData() + ->setId($userId) + ->setUserGroupId($groupId) + ->setIsAdminApp($isAdminApp) + ->setIsAdminAcc($isAdminAcc); + + return new AccountAclDto( + $accountId, + self::$accounts[$accountId]['userId'], + self::$accounts[$accountId]['users'], + self::$accounts[$accountId]['userGroupId'], + self::$accounts[$accountId]['groups'], + self::$faker->unixTime + ); + } + + /** + * @group acl:admin + * + * @return \SP\Domain\Account\Services\AccountAcl + */ + private function getExampleAclForAdmin(): AccountAcl + { + return (new AccountAcl(0)) + ->setCompiledAccountAccess(true) + ->setCompiledShowAccess(true) + ->setResultView(true) + ->setResultEdit(true) + ->setResultView(true) + ->setResultEdit(true) + ->setShowCopy(true) + ->setShowPermission(true) + ->setShowLink(true) + ->setShowView(true) + ->setShowViewPass(true) + ->setShowRestore(true) + ->setShowHistory(true) + ->setShowDelete(true) + ->setShowEdit(true) + ->setShowEditPass(true) + ->setShowFiles(true) + ->setShowDetails(true) + ->setShowPass(true); + } + + /** + * @group acl:admin + * + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\ConstraintException + */ + public function testGetAclForAdminAcc(): void + { + $this->context + ->getUserProfile() + ->setAccAdd(true) + ->setAccView(true) + ->setAccViewPass(true) + ->setAccEdit(true) + ->setAccEditPass(true) + ->setAccFiles(true) + ->setAccDelete(true) + ->setAccPermission(true) + ->setAccViewHistory(true); + + $exampleAcl = $this->getExampleAclForAdmin()->setShowLink(false); + + $this->checkForUserByExample( + $this->setUpAccountEnvironment( + self::$faker->numberBetween(1, 4), + self::$faker->randomNumber(), + self::$faker->randomNumber(), + 0, + 1 + ), + $exampleAcl + ); + } + + /** + * @group acl:action + * @dataProvider accountPropertiesProvider + * + * @param int $accountId + * @param int $userId + * @param int $groupId + * @param bool $shouldView + * @param bool $shouldEdit + * + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testCheckViewPass( + int $accountId, + int $userId, + int $groupId, + bool $shouldView = true, + bool $shouldEdit = true + ): void { + $shouldViewOrEdit = $shouldView || $shouldEdit; + + $this->context + ->getUserProfile() + ->setAccViewPass($shouldView); + + $example = (new AccountAcl(0)) + ->setCompiledAccountAccess(true) + ->setCompiledShowAccess(true) + ->setResultView($shouldViewOrEdit) + ->setResultEdit($shouldEdit) + ->setShowViewPass($shouldView); + + $this->checkForUserByExample($this->setUpAccountEnvironment($accountId, $userId, $groupId), $example); + } + + /** + * @group acl:action + * @dataProvider accountPropertiesProvider + * + * @param int $accountId + * @param int $userId + * @param int $groupId + * @param bool $shouldView + * @param bool $shouldEdit + * + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testCheckDelete( + int $accountId, + int $userId, + int $groupId, + bool $shouldView = true, + bool $shouldEdit = true + ): void { + $shouldViewOrEdit = $shouldView || $shouldEdit; + + $this->context + ->getUserProfile() + ->setAccDelete($shouldView); + + $example = (new AccountAcl(0)) + ->setCompiledAccountAccess(true) + ->setCompiledShowAccess(true) + ->setResultView($shouldViewOrEdit) + ->setResultEdit($shouldEdit) + ->setShowDelete($shouldEdit); + + $this->checkForUserByExample($this->setUpAccountEnvironment($accountId, $userId, $groupId), $example); + } + + /** + * @group acl:action + * @dataProvider accountPropertiesProvider + * + * @param int $accountId + * @param int $userId + * @param int $groupId + * @param bool $shouldView + * @param bool $shouldEdit + * + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testEditPass( + int $accountId, + int $userId, + int $groupId, + bool $shouldView = true, + bool $shouldEdit = true + ): void { + $shouldViewOrEdit = $shouldView || $shouldEdit; + + $this->context + ->getUserProfile() + ->setAccEditPass($shouldEdit); + + $example = (new AccountAcl(0)) + ->setCompiledAccountAccess(true) + ->setCompiledShowAccess(true) + ->setResultView($shouldViewOrEdit) + ->setResultEdit($shouldEdit) + ->setShowEditPass($shouldEdit); + + $this->checkForUserByExample($this->setUpAccountEnvironment($accountId, $userId, $groupId), $example); + } + + /** + * @group acl:action + * @dataProvider accountPropertiesProvider + * + * @param int $accountId + * @param int $userId + * @param int $groupId + * @param bool $shouldView + * @param bool $shouldEdit + * + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testEditAndRestore( + int $accountId, + int $userId, + int $groupId, + bool $shouldView = true, + bool $shouldEdit = true + ): void { + $shouldViewOrEdit = $shouldView || $shouldEdit; + + $this->context + ->getUserProfile() + ->setAccEdit($shouldEdit); + + $example = (new AccountAcl(0)) + ->setCompiledAccountAccess(true) + ->setCompiledShowAccess(true) + ->setResultView($shouldViewOrEdit) + ->setResultEdit($shouldEdit) + ->setShowEdit($shouldEdit) + ->setShowRestore($shouldEdit); + + $this->checkForUserByExample($this->setUpAccountEnvironment($accountId, $userId, $groupId), $example); + } + + /** + * @group acl:action + * @dataProvider accountPropertiesProvider + * + * @param int $accountId + * @param int $userId + * @param int $groupId + * @param bool $shouldView + * @param bool $shouldEdit + * + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testCheckPermission( + int $accountId, + int $userId, + int $groupId, + bool $shouldView = true, + bool $shouldEdit = true + ): void { + $shouldViewOrEdit = $shouldView || $shouldEdit; + + $this->context + ->getUserProfile() + ->setAccPermission($shouldEdit); + + $example = (new AccountAcl(0)) + ->setCompiledAccountAccess(true) + ->setCompiledShowAccess(true) + ->setResultView($shouldViewOrEdit) + ->setResultEdit($shouldEdit) + ->setShowPermission($shouldEdit); + + $this->checkForUserByExample($this->setUpAccountEnvironment($accountId, $userId, $groupId), $example); + } + + /** + * @group acl:action + * @dataProvider accountPropertiesProvider + * + * @param int $accountId + * @param int $userId + * @param int $groupId + * @param bool $shouldView + * @param bool $shouldEdit + * + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testViewFiles( + int $accountId, + int $userId, + int $groupId, + bool $shouldView = true, + bool $shouldEdit = true + ): void { + $shouldViewOrEdit = $shouldView || $shouldEdit; + + $this->context + ->getUserProfile() + ->setAccFiles($shouldEdit); + + $example = (new AccountAcl(0)) + ->setCompiledAccountAccess(true) + ->setCompiledShowAccess(true) + ->setResultView($shouldViewOrEdit) + ->setResultEdit($shouldEdit) + ->setShowFiles($shouldView); + + $this->checkForUserByExample($this->setUpAccountEnvironment($accountId, $userId, $groupId), $example); + } + + /** + * @group acl:action + * @dataProvider accountPropertiesProvider + * + * @param int $accountId + * @param int $userId + * @param int $groupId + * @param bool $shouldView + * @param bool $shouldEdit + * + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testCheckView( + int $accountId, + int $userId, + int $groupId, + bool $shouldView = true, + bool $shouldEdit = true + ): void { + $shouldViewOrEdit = $shouldView || $shouldEdit; + + $this->context + ->getUserProfile() + ->setAccView($shouldViewOrEdit) + ->setAccEdit($shouldEdit); + + $example = (new AccountAcl(0)) + ->setCompiledAccountAccess(true) + ->setCompiledShowAccess(true) + ->setResultView($shouldViewOrEdit) + ->setResultEdit($shouldEdit) + ->setShowView($shouldViewOrEdit) + ->setShowEdit($shouldEdit) + ->setShowRestore($shouldEdit) + ->setShowDetails($shouldViewOrEdit) + ->setShowPermission( + AccountAclService::getShowPermission($this->context->getUserData(), $this->context->getUserProfile()) + ); + + $this->checkForUserByExample($this->setUpAccountEnvironment($accountId, $userId, $groupId), $example); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testCacheIsUsedWithHit(): void + { + $dto = new AccountAclDto( + self::$faker->randomNumber(), + 1, + [], + self::$faker->randomNumber(), + [], + self::$faker->unixTime + ); + + $userToUserGroupService = $this->createMock(UserToUserGroupServiceInterface::class); + $userToUserGroupService->method('getGroupsForUser')->willReturn([]); + $fileCache = $this->createMock(FileCacheInterface::class); + + $accountAclService = new AccountAclService( + $this->application, + new Acl($this->context, $this->application->getEventDispatcher()), + $userToUserGroupService, + $fileCache + ); + + $this->context->getUserData()->setLastUpdate($dto->getDateEdit() + 10); + + $acl = new AccountAcl(self::$faker->randomNumber()); + $acl->setTime($dto->getDateEdit() + 10); + + $fileCache->expects(self::once()) + ->method('load') + ->with(self::callback((static fn($path) => is_string($path)))) + ->willReturn($acl); + + $accountAclService->getAcl(self::$faker->randomNumber(), $dto); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testCacheIsUsedWithMiss(): void + { + $dto = new AccountAclDto( + self::$faker->randomNumber(), + 1, + [], + self::$faker->randomNumber(), + [], + self::$faker->unixTime + ); + + $userToUserGroupService = $this->createMock(UserToUserGroupServiceInterface::class); + $userToUserGroupService->method('getGroupsForUser')->willReturn([]); + $fileCache = $this->createMock(FileCacheInterface::class); + + $accountAclService = new AccountAclService( + $this->application, + new Acl($this->context, $this->application->getEventDispatcher()), + $userToUserGroupService, + $fileCache + ); + + $acl = new AccountAcl(self::$faker->randomNumber()); + + $fileCache->expects(self::once()) + ->method('load') + ->with(self::callback((static fn($path) => is_string($path)))) + ->willReturn($acl); + + $fileCache->expects(self::once()) + ->method('save') + ->with( + self::callback((static fn($acl) => $acl instanceof AccountAcl)), + self::callback((static fn($path) => is_string($path))) + ); + + $accountAclService->getAcl(self::$faker->randomNumber(), $dto); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testCacheLoadThrowsExceptionAndLogged(): void + { + $dto = new AccountAclDto( + self::$faker->randomNumber(), + 1, + [], + self::$faker->randomNumber(), + [], + self::$faker->unixTime + ); + + $userToUserGroupService = $this->createMock(UserToUserGroupServiceInterface::class); + $userToUserGroupService->method('getGroupsForUser')->willReturn([]); + $fileCache = $this->createMock(FileCacheInterface::class); + + $accountAclService = new AccountAclService( + $this->application, + new Acl($this->context, $this->application->getEventDispatcher()), + $userToUserGroupService, + $fileCache + ); + + $fileCache->expects(self::once()) + ->method('load') + ->with(self::callback((static fn($path) => is_string($path)))) + ->willThrowException(new FileException('test')); + + $accountAclService->getAcl(self::$faker->randomNumber(), $dto); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testCacheSaveThrowsExceptionAndLogged(): void + { + $dto = new AccountAclDto( + self::$faker->randomNumber(), + 1, + [], + self::$faker->randomNumber(), + [], + self::$faker->unixTime + ); + + $userToUserGroupService = $this->createMock(UserToUserGroupServiceInterface::class); + $userToUserGroupService->method('getGroupsForUser')->willReturn([]); + $fileCache = $this->createMock(FileCacheInterface::class); + + $accountAclService = new AccountAclService( + $this->application, + new Acl($this->context, $this->application->getEventDispatcher()), + $userToUserGroupService, + $fileCache + ); + + $fileCache->expects(self::once()) + ->method('save') + ->with( + self::callback((static fn($acl) => $acl instanceof AccountAcl)), + self::callback((static fn($path) => is_string($path))) + ) + ->willThrowException(new FileException('test')); + + $accountAclService->getAcl(self::$faker->randomNumber(), $dto); + } + + protected function setUp(): void + { + parent::setUp(); + + $acl = new Acl($this->context, $this->application->getEventDispatcher()); + $userToUserGroupService = $this->createMock(UserToUserGroupServiceInterface::class); + $userToUserGroupService->method('getGroupsForUser') + ->willReturnMap([ + [1, [new SimpleModel(['userGroupId' => 2])]], + [2, [new SimpleModel(['userGroupId' => 1])]], + [3, [new SimpleModel(['userGroupId' => 2])]], + [4, []], + ]); + + $this->accountAclService = new AccountAclService( + $this->application, + $acl, + $userToUserGroupService + ); + } + + private function accountPropertiesProvider(): array + { + /** + * Account |View |Edit + * 1 |u=3 g=1,2 |u=3 g=1,2 + * 2 |g=1,2,3 |g=1,2,3 + * 3 |u=3 g=3 |u=3 g=3 + * 4 |u=3 |u=3 + * + * User | Group + * 1 | 2 + * 2 | 1 + * 3 | 2 + * 4 | None + * Matrix: Account | UserId | GroupId | ShouldView | ShouldEdit + */ + return [ + [1, 2, 2, true, true], + [1, 3, 0, true, true], + [1, 3, 1, true, true], + [1, 3, 2, true, true], + [1, 4, 0, false, false], + [1, 4, 3, false, false], + [1, 4, 4, false, false], + [2, 2, 1, true, true], + [2, 2, 2, true, true], + [2, 2, 3, true, true], + [2, 3, 0, false, false], + [2, 3, 3, true, true], + [2, 4, 0, false, false], + [2, 4, 1, true, true], + [2, 4, 2, true, true], + [2, 4, 3, true, true], + [2, 4, 4, false, false], + [3, 1, 1, false, false], + [3, 1, 2, false, false], + [3, 1, 3, true, true], + [3, 2, 1, false, false], + [3, 2, 2, false, false], + [3, 2, 3, true, true], + [3, 3, 0, true, true], + [3, 3, 1, true, true], + [3, 3, 2, true, true], + [3, 3, 3, true, true], + [4, 3, 0, true, true], + [4, 3, 1, true, true], + [4, 3, 2, true, true], + [4, 3, 3, true, true], + ]; + } +} diff --git a/tests/SP/Domain/Install/Services/MySQLTest.php b/tests/SP/Domain/Install/Services/MySQLTest.php index 9b1f5fdf..91dc3c9d 100644 --- a/tests/SP/Domain/Install/Services/MySQLTest.php +++ b/tests/SP/Domain/Install/Services/MySQLTest.php @@ -35,6 +35,8 @@ use SP\Infrastructure\Database\DbStorageInterface; use SP\Infrastructure\File\FileException; use SP\Tests\Stubs\Pdo; use SP\Tests\UnitaryTestCase; +use function SP\__; +use function SP\__u; /** * Class MySQLTest diff --git a/tests/SP/Services/Account/AccountAclServiceTest.php b/tests/SP/Services/Account/AccountAclServiceTest.php deleted file mode 100644 index a9188de8..00000000 --- a/tests/SP/Services/Account/AccountAclServiceTest.php +++ /dev/null @@ -1,809 +0,0 @@ -. - */ - -namespace SP\Tests\Services\Account; - -use Closure; -use DI\DependencyException; -use DI\NotFoundException; -use SP\Core\Acl\Acl; -use SP\Core\Acl\ActionsInterface; -use SP\Core\Application; -use SP\Core\Context\ContextException; -use SP\Core\Context\ContextInterface; -use SP\Core\Context\StatelessContext; -use SP\Core\Exceptions\ConstraintException; -use SP\Core\Exceptions\QueryException; -use SP\DataModel\Dto\AccountAclDto; -use SP\DataModel\Dto\AccountDetailsResponse; -use SP\Domain\Account\AccountAclServiceInterface; -use SP\Domain\Account\Services\AccountAcl; -use SP\Domain\Account\Services\AccountAclService; -use SP\Domain\Account\Services\AccountService; -use SP\Domain\User\Services\UserLoginResponse; -use SP\Infrastructure\Common\Repositories\NoSuchItemException; -use SP\Tests\DatabaseTestCase; -use function SP\Tests\setupContext; - -/** - * Class AccountAclServiceTest - * - * @package SP\Tests\Services - */ -class AccountAclServiceTest extends DatabaseTestCase -{ - private static Closure $service; - private static AccountService $accountService; - private static StatelessContext $context; - private static array $actions = [ - ActionsInterface::ACCOUNT_SEARCH, - ActionsInterface::ACCOUNT_VIEW, - ActionsInterface::ACCOUNT_VIEW_PASS, - ActionsInterface::ACCOUNT_HISTORY_VIEW, - ActionsInterface::ACCOUNT_CREATE, - ActionsInterface::ACCOUNT_EDIT, - ActionsInterface::ACCOUNT_EDIT_PASS, - ActionsInterface::ACCOUNT_EDIT_RESTORE, - ActionsInterface::ACCOUNT_COPY, - ActionsInterface::ACCOUNT_COPY_PASS, - ActionsInterface::ACCOUNT_DELETE, - ]; - protected AccountDetailsResponse $account; - - /** - * @throws NotFoundException - * @throws ContextException - * @throws DependencyException - */ - public static function setUpBeforeClass(): void - { - $dic = setupContext(); - - self::$loadFixtures = true; - - self::$context = $dic->get(ContextInterface::class); - - // Es necesario utilizar una función anónima para evitar la fijación - // de los datos del contexto - self::$service = static function () use ($dic) { - return new AccountAclService($dic, $dic->get(Application::class)); - }; - - self::$accountService = $dic->get(AccountService::class); - } - - /** - * testSaveAclInCache - */ - public function testSaveAclInCache() - { - /** @var AccountAclServiceInterface $service */ - $service = self::$service->call($this); - - $accountAcl = new AccountAcl(10); - $accountAcl->setAccountId(1); - $accountAcl->setCompiledAccountAccess(true); - $accountAcl->setCompiledShowAccess(true); - $accountAcl->setResultView(true); - $accountAcl->setResultEdit(true); - $accountAcl->setShowCopy(true); - $accountAcl->setShowPermission(true); - $accountAcl->setShowLink(false); - $accountAcl->setShowView(true); - $accountAcl->setShowViewPass(true); - $accountAcl->setShowRestore(true); - $accountAcl->setShowHistory(true); - $accountAcl->setShowDelete(true); - $accountAcl->setShowEdit(true); - $accountAcl->setShowEditPass(true); - $accountAcl->setShowFiles(true); - $accountAcl->setShowDetails(true); - $accountAcl->setShowPass(true); - - $service->saveAclInCache($accountAcl); - - $result = $service->getAclFromCache(1, 10); - - $this->assertInstanceOf(AccountAcl::class, $result); - $this->assertEquals($accountAcl, $result); - - $accountAcl->reset(); - - $this->assertNotEquals($accountAcl, $result); - } - - /** - * testClearAcl - */ - public function testClearAcl() - { - /** @var \SP\Domain\Account\AccountAclServiceInterface $service */ - $service = self::$service->call($this); - - $accountAcl = new AccountAcl(10); - $accountAcl->setAccountId(1); - - $service->saveAclInCache($accountAcl); - - $this->assertTrue(AccountAclService::clearAcl(1)); - - $this->assertFalse(AccountAclService::clearAcl(2)); - } - - /** - * @throws ConstraintException - * @throws QueryException - * @throws NoSuchItemException - */ - public function testGetAclAdmin() - { - $this->checkAllowAll($this->setUpAccountEnvironment(1, 1, 1, 1)); - $this->checkAllowAll($this->setUpAccountEnvironment(2, 1, 1, 1)); - - $accountAcl = new AccountAcl(0); - $accountAcl->setCompiledAccountAccess(true); - $accountAcl->setCompiledShowAccess(true); - $accountAcl->setResultView(true); - $accountAcl->setResultEdit(true); - $accountAcl->setShowCopy(true); - $accountAcl->setShowPermission(true); - $accountAcl->setShowLink(false); - $accountAcl->setShowView(true); - $accountAcl->setShowViewPass(true); - $accountAcl->setShowRestore(true); - $accountAcl->setShowHistory(true); - $accountAcl->setShowDelete(true); - $accountAcl->setShowEdit(true); - $accountAcl->setShowEditPass(true); - $accountAcl->setShowFiles(true); - $accountAcl->setShowDetails(true); - $accountAcl->setShowPass(true); - - $this->checkForUserByExample($this->setUpAccountEnvironment(1, 1, 1, 0, 1), $accountAcl); - $this->checkForUserByExample($this->setUpAccountEnvironment(2, 1, 1, 0, 1), $accountAcl); - } - - /** - * @param AccountAclDto $accountAclDto - * - * @param bool $should - * - * @throws ConstraintException - * @throws QueryException - */ - private function checkAllowAll(AccountAclDto $accountAclDto, $should = true) - { - self::$context - ->getUserProfile() - ->reset() - ->setAccAdd($should) - ->setAccView($should) - ->setAccViewPass($should) - ->setAccEdit($should) - ->setAccEditPass($should) - ->setAccFiles($should) - ->setAccDelete($should) - ->setAccPermission($should) - ->setAccViewHistory($should); - - $accountAcl = (new AccountAcl(0)) - ->setCompiledAccountAccess(true) - ->setCompiledShowAccess(true) - ->setResultView($should) - ->setResultEdit($should) - ->setResultView(true) - ->setResultEdit(true) - ->setShowCopy(true) - ->setShowPermission(true) - ->setShowLink(true) - ->setShowView(true) - ->setShowViewPass(true) - ->setShowRestore(true) - ->setShowHistory(true) - ->setShowDelete(true) - ->setShowEdit(true) - ->setShowEditPass(true) - ->setShowFiles(true) - ->setShowDetails(true) - ->setShowPass(true); - - $this->checkForUserByExample($accountAclDto, $accountAcl); - } - - /** - * @param AccountAclDto $accountAclDto - * - * @param AccountAcl $accountAclExample - * - * @throws ConstraintException - * @throws QueryException - */ - private function checkForUserByExample(AccountAclDto $accountAclDto, AccountAcl $accountAclExample) - { - /** @var AccountAclServiceInterface $service */ - $service = self::$service->call($this); - - foreach (self::$actions as $action) { - $accountAclExample->setActionId($action); - - $accountAcl = $service->getAcl($action, $accountAclDto); - - $this->assertInstanceOf(AccountAcl::class, $accountAcl); - $this->assertTrue($accountAcl->isCompiledAccountAccess()); - $this->assertTrue($accountAcl->isCompiledShowAccess()); - - $this->assertEquals($accountAclExample->isResultView(), $accountAcl->isResultView()); - $this->assertEquals($accountAclExample->isResultEdit(), $accountAcl->isResultEdit()); - - if ($action !== Acl::ACCOUNT_CREATE - && $action !== Acl::ACCOUNT_COPY_PASS - ) { - $this->assertEquals( - $accountAclExample->checkAccountAccess($action), - $accountAcl->checkAccountAccess($action) - ); - } - - if ($action === Acl::ACCOUNT_VIEW - || $action === Acl::ACCOUNT_HISTORY_VIEW - || $action === Acl::ACCOUNT_DELETE - ) { - $this->assertEquals($accountAclExample->isShowDetails(), $accountAcl->isShowDetails()); - } - - if ($action === Acl::ACCOUNT_CREATE - || $action === Acl::ACCOUNT_COPY - ) { - $this->assertEquals($accountAclExample->isShowPass(), $accountAcl->isShowPass()); - } - - if ($action === Acl::ACCOUNT_EDIT - || $action === Acl::ACCOUNT_VIEW - || $action === Acl::ACCOUNT_HISTORY_VIEW - ) { - $this->assertEquals($accountAclExample->isShowFiles(), $accountAcl->isShowFiles()); - } - - if ($action === Acl::ACCOUNT_SEARCH - || $action === Acl::ACCOUNT_VIEW - || $action === Acl::ACCOUNT_VIEW_PASS - || $action === Acl::ACCOUNT_HISTORY_VIEW - || $action === Acl::ACCOUNT_EDIT - ) { - $this->assertEquals($accountAclExample->isShowViewPass(), $accountAcl->isShowViewPass()); - } - - if ($action === Acl::ACCOUNT_EDIT - || $action === Acl::ACCOUNT_CREATE - || $action === Acl::ACCOUNT_COPY - ) { - $this->assertEquals($accountAclExample->isShowSave(), $accountAcl->isShowSave()); - } - - if ($action === Acl::ACCOUNT_SEARCH - || $action === Acl::ACCOUNT_VIEW - ) { - $this->assertEquals($accountAclExample->isShowEdit(), $accountAcl->isShowEdit()); - } - - if ($action === Acl::ACCOUNT_EDIT - || $action === Acl::ACCOUNT_VIEW - ) { - $this->assertEquals($accountAclExample->isShowEditPass(), $accountAcl->isShowEditPass()); - } - - if ($action === Acl::ACCOUNT_SEARCH - || $action === Acl::ACCOUNT_DELETE - || $action === Acl::ACCOUNT_EDIT - ) { - $this->assertEquals($accountAclExample->isShowDelete(), $accountAcl->isShowDelete()); - } - - if ($action === Acl::ACCOUNT_HISTORY_VIEW) { - $this->assertEquals($accountAclExample->isShowRestore(), $accountAcl->isShowRestore()); - } - - $this->assertEquals($accountAclExample->isShowLink(), $accountAcl->isShowLink()); - - if ($action === Acl::ACCOUNT_VIEW - || $action === Acl::ACCOUNT_HISTORY_VIEW - ) { - $this->assertEquals($accountAclExample->isShowHistory(), $accountAcl->isShowHistory()); - } - - if ($action === Acl::ACCOUNT_SEARCH - || $action === Acl::ACCOUNT_VIEW - || $action === Acl::ACCOUNT_EDIT - ) { - $this->assertEquals($accountAclExample->isShowCopy(), $accountAcl->isShowCopy()); - } - } - } - - /** - * @param $accountId - * @param $userId - * @param $groupId - * - * @param int $isAdminApp - * @param int $isAdminAcc - * - * @return AccountAclDto - * @throws ConstraintException - * @throws QueryException - * @throws NoSuchItemException - */ - private function setUpAccountEnvironment($accountId, $userId, $groupId, $isAdminApp = false, $isAdminAcc = false) - { - AccountAclService::$useCache = false; - - if ($this->account === null || $this->account->getId() !== $accountId) { - $this->account = self::$accountService->getById($accountId); - self::$accountService->withUsersById($this->account); - self::$accountService->withUserGroupsById($this->account); - } - - $userData = new UserLoginResponse(); - $userData->setId($userId); - $userData->setIsAdminApp($isAdminApp); - $userData->setIsAdminAcc($isAdminAcc); - $userData->setUserGroupId($groupId); - - self::$context->setUserData($userData); - - return AccountAclDto::makeFromAccount($this->account); - } - - /** - * @throws ConstraintException - * @throws QueryException - * @throws NoSuchItemException - */ - public function testGetAclUser() - { - $accountAclDto = $this->setUpAccountEnvironment(1, 2, 2); - - $this->checkView($accountAclDto); - $this->checkViewPass($accountAclDto); - $this->checkDelete($accountAclDto); - $this->checkEditPass($accountAclDto); - $this->checkEditAndRestore($accountAclDto); - $this->checkPermissions($accountAclDto); - $this->checkViewFiles($accountAclDto); - - $accountAclDto = $this->setUpAccountEnvironment(1, 3, 3); - - $this->checkView($accountAclDto); - $this->checkViewPass($accountAclDto); - $this->checkDelete($accountAclDto); - $this->checkEditPass($accountAclDto); - $this->checkEditAndRestore($accountAclDto); - $this->checkPermissions($accountAclDto); - $this->checkViewFiles($accountAclDto); - - $accountAclDto = $this->setUpAccountEnvironment(1, 4, 3); - $should = ['view' => false, 'edit' => false]; - - $this->checkView($accountAclDto, $should); - $this->checkViewPass($accountAclDto, $should); - $this->checkDelete($accountAclDto, $should); - $this->checkEditPass($accountAclDto, $should); - $this->checkEditAndRestore($accountAclDto, $should); - $this->checkPermissions($accountAclDto, $should); - $this->checkViewFiles($accountAclDto, $should); - - $accountAclDto = $this->setUpAccountEnvironment(2, 1, 1); - - $this->checkView($accountAclDto); - $this->checkViewPass($accountAclDto); - $this->checkDelete($accountAclDto); - $this->checkEditPass($accountAclDto); - $this->checkEditAndRestore($accountAclDto); - $this->checkPermissions($accountAclDto); - $this->checkViewFiles($accountAclDto); - - $accountAclDto = $this->setUpAccountEnvironment(2, 2, 2); - $should = ['view' => true, 'edit' => false]; - - $this->checkView($accountAclDto, $should); - $this->checkViewPass($accountAclDto, $should); - $this->checkDelete($accountAclDto, $should); - $this->checkEditPass($accountAclDto, $should); - $this->checkEditAndRestore($accountAclDto, $should); - $this->checkPermissions($accountAclDto, $should); - $this->checkViewFiles($accountAclDto, $should); - - $accountAclDto = $this->setUpAccountEnvironment(2, 3, 3); - $should = ['view' => true, 'edit' => false]; - - $this->checkView($accountAclDto, $should); - $this->checkViewPass($accountAclDto, $should); - $this->checkDelete($accountAclDto, $should, true, false); - $this->checkEditPass($accountAclDto, $should, true, false); - $this->checkEditAndRestore($accountAclDto, $should, true, false); - $this->checkPermissions($accountAclDto, $should); - $this->checkViewFiles($accountAclDto, $should); - - - $accountAclDto = $this->setUpAccountEnvironment(2, 4, 3); - $should = ['view' => true, 'edit' => false]; - - $this->checkView($accountAclDto, $should); - $this->checkViewPass($accountAclDto, $should); - $this->checkDelete($accountAclDto, $should, true, false); - $this->checkEditPass($accountAclDto, $should, true, false); - $this->checkEditAndRestore($accountAclDto, $should, true, false); - $this->checkPermissions($accountAclDto, $should); - $this->checkViewFiles($accountAclDto, $should); - - $accountAclDto = $this->setUpAccountEnvironment(2, 5, 4); - $should = ['view' => false, 'edit' => false]; - - $this->checkView($accountAclDto, $should); - $this->checkViewPass($accountAclDto, $should); - $this->checkDelete($accountAclDto, $should); - $this->checkEditPass($accountAclDto, $should); - $this->checkEditAndRestore($accountAclDto, $should); - $this->checkPermissions($accountAclDto, $should); - $this->checkViewFiles($accountAclDto, $should); - - $accountAclDto = $this->setUpAccountEnvironment(2, 1, 1); - - $this->checkView($accountAclDto); - $this->checkViewPass($accountAclDto); - $this->checkDelete($accountAclDto); - $this->checkEditPass($accountAclDto); - $this->checkEditAndRestore($accountAclDto); - $this->checkPermissions($accountAclDto); - $this->checkViewFiles($accountAclDto); - } - - /** - * @param AccountAclDto $accountAclDto - * - * @param array $should Sets view and edit status - * @param bool $profile Sets profile action status - * @param bool $acl Sets ACL expected result - * - * @throws ConstraintException - * @throws QueryException - */ - private function checkView( - AccountAclDto $accountAclDto, - $should = ['view' => true, 'edit' => true], - $profile = true, - $acl = true - ) { - $userProfile = self::$context - ->getUserProfile() - ->reset() - ->setAccView($profile); - - $accountAcl = (new AccountAcl(0)) - ->setCompiledAccountAccess(true) - ->setCompiledShowAccess(true) - ->setResultView($should['view']) - ->setResultEdit($should['edit']) - ->setShowDetails($acl); - - $this->checkForUserByExample($accountAclDto, $accountAcl); - - // Checks if ACL returns false when profile action is granted and account access is denied - if ($should['view'] === false && $should['edit'] === false) { - $userProfile->setAccView(true); - $accountAcl->setShowDetails(false); - - $this->checkForUserByExample($accountAclDto, $accountAcl); - } elseif ($profile === true) { // Checks ACL when profile action is denied - $userProfile->setAccView(false); - $accountAcl->setShowDetails(false); - - $this->checkForUserByExample($accountAclDto, $accountAcl); - } - } - - /** - * @param AccountAclDto $accountAclDto - * - * @param array $should - * - * @param bool $profile - * @param bool $acl - * - * @throws ConstraintException - * @throws QueryException - */ - private function checkViewPass( - AccountAclDto $accountAclDto, - $should = ['view' => true, 'edit' => true], - $profile = true, - $acl = true - ) { - $userProfile = self::$context - ->getUserProfile() - ->reset() - ->setAccViewPass($profile); - - $accountAcl = (new AccountAcl(0)) - ->setCompiledAccountAccess(true) - ->setCompiledShowAccess(true) - ->setResultView($should['view']) - ->setResultEdit($should['edit']) - ->setShowViewPass($acl); - - $this->checkForUserByExample($accountAclDto, $accountAcl); - - // Checks if ACL returns false when profile action is granted and account access is denied - if ($should['view'] === false && $should['edit'] === false) { - $userProfile->setAccViewPass(true); - $accountAcl->setShowViewPass(false); - - $this->checkForUserByExample($accountAclDto, $accountAcl); - } elseif ($profile === true && $acl === true) { // Checks ACL when profile action is denied - $userProfile->setAccViewPass(false); - $accountAcl->setShowViewPass(false); - - $this->checkForUserByExample($accountAclDto, $accountAcl); - } - } - - /** - * @param AccountAclDto $accountAclDto - * - * @param array $should - * - * @param bool $profile - * @param bool $acl - * - * @throws ConstraintException - * @throws QueryException - */ - private function checkDelete( - AccountAclDto $accountAclDto, - $should = ['view' => true, 'edit' => true], - $profile = true, - $acl = true - ) { - $userProfile = self::$context - ->getUserProfile() - ->reset() - ->setAccDelete($profile); - - $accountAcl = (new AccountAcl(0)) - ->setCompiledAccountAccess(true) - ->setCompiledShowAccess(true) - ->setResultView($should['view']) - ->setResultEdit($should['edit']) - ->setShowDelete($acl); - - $this->checkForUserByExample($accountAclDto, $accountAcl); - - // Checks if ACL returns false when profile action is granted and account access is denied - if ($should['view'] === false && $should['edit'] === false) { - $userProfile->setAccDelete(true); - $accountAcl->setShowDelete(false); - - $this->checkForUserByExample($accountAclDto, $accountAcl); - } elseif ($profile === true) { // Checks ACL when profile action is denied - $userProfile->setAccDelete(false); - $accountAcl->setShowDelete(false); - - $this->checkForUserByExample($accountAclDto, $accountAcl); - } - } - - /** - * @param AccountAclDto $accountAclDto - * - * @param array $should - * - * @param bool $profile - * @param bool $acl - * - * @throws ConstraintException - * @throws QueryException - */ - private function checkEditPass( - AccountAclDto $accountAclDto, - $should = ['view' => true, 'edit' => true], - $profile = true, - $acl = true - ) { - $userProfile = self::$context - ->getUserProfile() - ->reset() - ->setAccEditPass($profile); - - $accountAcl = (new AccountAcl(0)) - ->setCompiledAccountAccess(true) - ->setCompiledShowAccess(true) - ->setResultView($should['view']) - ->setResultEdit($should['edit']) - ->setShowEditPass($acl); - - $this->checkForUserByExample($accountAclDto, $accountAcl); - - // Checks if ACL returns false when profile action is granted and account access is denied - if ($should['view'] === false && $should['edit'] === false) { - $userProfile->setAccEditPass(true); - $accountAcl->setShowEditPass(false); - - $this->checkForUserByExample($accountAclDto, $accountAcl); - } elseif ($profile === true) { // Checks ACL when profile action is denied - $userProfile->setAccEditPass(false); - $accountAcl->setShowEditPass(false); - - $this->checkForUserByExample($accountAclDto, $accountAcl); - } - } - - /** - * @param AccountAclDto $accountAclDto - * - * @param array $should - * - * @param bool $profile - * @param bool $acl - * - * @throws ConstraintException - * @throws QueryException - */ - private function checkEditAndRestore( - AccountAclDto $accountAclDto, - $should = ['view' => true, 'edit' => true], - $profile = true, - $acl = true - ) { - $userProfile = self::$context - ->getUserProfile() - ->reset() - ->setAccEdit($profile); - - $accountAcl = (new AccountAcl(0)) - ->setCompiledAccountAccess(true) - ->setCompiledShowAccess(true) - ->setResultView($should['view']) - ->setResultEdit($should['edit']) - ->setShowEdit($acl) - ->setShowRestore($acl); - - $this->checkForUserByExample($accountAclDto, $accountAcl); - - // Checks if ACL returns false when profile action is granted and account access is denied - if ($should['view'] === false && $should['edit'] === false) { - $userProfile->setAccEdit(true); - $accountAcl->setShowEdit(false) - ->setShowRestore(false); - - $this->checkForUserByExample($accountAclDto, $accountAcl); - } elseif ($profile === true) { // Checks ACL when profile action is denied - $userProfile->setAccEdit(false); - $accountAcl->setShowEdit(false) - ->setShowRestore(false); - - $this->checkForUserByExample($accountAclDto, $accountAcl); - } - } - - /** - * @param AccountAclDto $accountAclDto - * - * @param array $should - * - * @param bool $profile - * @param bool $acl - * - * @throws ConstraintException - * @throws QueryException - */ - private function checkPermissions( - AccountAclDto $accountAclDto, - $should = ['view' => true, 'edit' => true], - $profile = true, - $acl = true - ) { - $userProfile = self::$context - ->getUserProfile() - ->reset() - ->setAccPermission($profile); - - $accountAcl = (new AccountAcl(0)) - ->setCompiledAccountAccess(true) - ->setCompiledShowAccess(true) - ->setResultView($should['view']) - ->setResultEdit($should['edit']) - ->setShowPermission($acl); - - $this->checkForUserByExample($accountAclDto, $accountAcl); - - // Checks if ACL returns false when profile action is granted and account access is denied - if ($should['view'] === false && $should['edit'] === false) { - $userProfile->setAccPermission(true); - $accountAcl->setShowPermission(false); - - $this->checkForUserByExample($accountAclDto, $accountAcl); - } elseif ($profile === true) { // Checks ACL when profile action is denied - $userProfile->setAccPermission(false); - $accountAcl->setShowPermission(false); - - $this->checkForUserByExample($accountAclDto, $accountAcl); - } - } - - /** - * @param AccountAclDto $accountAclDto - * - * @param array $should - * - * @param bool $profile - * @param bool $acl - * - * @throws ConstraintException - * @throws QueryException - */ - private function checkViewFiles( - AccountAclDto $accountAclDto, - $should = ['view' => true, 'edit' => true], - $profile = true, - $acl = true - ) { - $userProfile = self::$context - ->getUserProfile() - ->reset() - ->setAccFiles($profile); - - $accountAcl = (new AccountAcl(0)) - ->setCompiledAccountAccess(true) - ->setCompiledShowAccess(true) - ->setResultView($should['view']) - ->setResultEdit($should['edit']) - ->setShowFiles($acl); - - $this->checkForUserByExample($accountAclDto, $accountAcl); - - // Checks if ACL returns false when profile action is granted and account access is denied - if ($should['view'] === false && $should['edit'] === false) { - $userProfile->setAccFiles(true); - $accountAcl->setShowFiles(false); - - $this->checkForUserByExample($accountAclDto, $accountAcl); - } elseif ($profile === true) { // Checks ACL when profile action is denied - $userProfile->setAccFiles(false); - $accountAcl->setShowFiles(false); - - $this->checkForUserByExample($accountAclDto, $accountAcl); - } - } - - /** - * testGetAclFromCache - */ - public function testGetAclFromCache() - { - /** @var AccountAclServiceInterface $service */ - $service = self::$service->call($this); - - $this->assertNull($service->getAclFromCache(1, 10)); - } -} diff --git a/tests/SP/Services/Account/AccountCryptServiceTest.php b/tests/SP/Services/Account/AccountCryptServiceTest.php index e3864281..5b29fb0f 100644 --- a/tests/SP/Services/Account/AccountCryptServiceTest.php +++ b/tests/SP/Services/Account/AccountCryptServiceTest.php @@ -1,10 +1,10 @@ . + * along with sysPass. If not, see . */ namespace SP\Tests\Services\Account; @@ -32,6 +32,7 @@ use SP\Core\Crypt\Crypt; use SP\Core\Exceptions\ConstraintException; use SP\Core\Exceptions\QueryException; use SP\Domain\Account\AccountCryptServiceInterface; +use SP\Domain\Account\AccountServiceInterface; use SP\Domain\Account\Services\AccountCryptService; use SP\Domain\Account\Services\AccountService; use SP\Domain\Common\Services\ServiceException; @@ -51,7 +52,7 @@ class AccountCryptServiceTest extends DatabaseTestCase const NEW_MASTERPASS = '00123456789'; const CURRENT_HASH = '$2y$10$xtsuN2PUvgSH/0mrfBlsbOActVgCjYcqDqC6L3T9QraNxZC4RXGYa'; /** - * @var AccountService + * @var \SP\Domain\Account\AccountServiceInterface */ private static $accountService; /** diff --git a/tests/SP/Services/Account/AccountServiceTest.php b/tests/SP/Services/Account/AccountServiceTest.php index d2bebb31..f225cfa2 100644 --- a/tests/SP/Services/Account/AccountServiceTest.php +++ b/tests/SP/Services/Account/AccountServiceTest.php @@ -40,8 +40,9 @@ use SP\DataModel\AccountVData; use SP\DataModel\ItemSearchData; use SP\DataModel\ProfileData; use SP\Domain\Account\AccountHistoryServiceInterface; -use SP\Domain\Account\Search\AccountSearchFilter; +use SP\Domain\Account\AccountServiceInterface; use SP\Domain\Account\Out\AccountData; +use SP\Domain\Account\Search\AccountSearchFilter; use SP\Domain\Account\Services\AccountBulkRequest; use SP\Domain\Account\Services\AccountHistoryService; use SP\Domain\Account\Services\AccountPasswordRequest; @@ -72,7 +73,7 @@ class AccountServiceTest extends DatabaseTestCase */ private static $context; /** - * @var AccountService + * @var \SP\Domain\Account\AccountServiceInterface */ private static $service; diff --git a/tests/SP/Services/Crypt/MasterPassServiceTest.php b/tests/SP/Services/Crypt/MasterPassServiceTest.php index d72381fe..9aec1292 100644 --- a/tests/SP/Services/Crypt/MasterPassServiceTest.php +++ b/tests/SP/Services/Crypt/MasterPassServiceTest.php @@ -1,10 +1,10 @@ . + * along with sysPass. If not, see . */ namespace SP\Tests\Services\Crypt; @@ -32,6 +32,7 @@ use SP\Core\Context\ContextException; use SP\Core\Crypt\Crypt; use SP\Core\Exceptions\ConstraintException; use SP\Core\Exceptions\QueryException; +use SP\Domain\Account\AccountServiceInterface; use SP\Domain\Account\Services\AccountService; use SP\Domain\Crypt\Services\MasterPassService; use SP\Domain\Crypt\Services\UpdateMasterPassRequest; @@ -53,7 +54,7 @@ class MasterPassServiceTest extends DatabaseTestCase */ private static $customFieldService; /** - * @var AccountService + * @var \SP\Domain\Account\AccountServiceInterface */ private static $accountService; /** diff --git a/tests/SP/UnitaryTestCase.php b/tests/SP/UnitaryTestCase.php index 6187a29d..bd2eeef0 100644 --- a/tests/SP/UnitaryTestCase.php +++ b/tests/SP/UnitaryTestCase.php @@ -32,6 +32,7 @@ use SP\Core\Application; use SP\Core\Context\ContextInterface; use SP\Core\Context\StatelessContext; use SP\Core\Events\EventDispatcher; +use SP\DataModel\ProfileData; use SP\Domain\Config\ConfigInterface; use SP\Domain\Config\Services\ConfigBackupService; use SP\Domain\Config\Services\ConfigFileService; @@ -61,6 +62,11 @@ abstract class UnitaryTestCase extends TestCase parent::setUpBeforeClass(); } + public static function getRandomNumbers(int $count): array + { + return array_map(static fn() => self::$faker->randomNumber(), range(0, $count - 1)); + } + /** * @throws \SP\Core\Exceptions\ConfigException * @throws \SP\Core\Context\ContextException @@ -89,6 +95,7 @@ abstract class UnitaryTestCase extends TestCase $this->context = new StatelessContext(); $this->context->initialize(); $this->context->setUserData($userLogin); + $this->context->setUserProfile(new ProfileData()); $config = new ConfigFileService( $this->createStub(XmlHandler::class), @@ -99,9 +106,4 @@ abstract class UnitaryTestCase extends TestCase return new Application($config, $this->createStub(EventDispatcher::class), $this->context); } - - public static function getRandomNumbers(int $count): array - { - return array_map(static fn() => self::$faker->randomNumber(), range(0, $count - 1)); - } -} \ No newline at end of file +} diff --git a/tests/SP/bootstrap.php b/tests/SP/bootstrap.php index 18e6c46e..c3fc6590 100644 --- a/tests/SP/bootstrap.php +++ b/tests/SP/bootstrap.php @@ -49,30 +49,30 @@ const APP_DEFINITIONS_FILE = APP_ROOT.DIRECTORY_SEPARATOR.'lib'.DIRECTORY_SEPARA define('RESOURCE_PATH', TEST_ROOT.DIRECTORY_SEPARATOR.'res'); define('CONFIG_PATH', RESOURCE_PATH.DIRECTORY_SEPARATOR.'config'); -define('CONFIG_FILE', CONFIG_PATH . DIRECTORY_SEPARATOR . 'config.xml'); -define('ACTIONS_FILE', CONFIG_PATH . DIRECTORY_SEPARATOR . 'actions.xml'); -define('LOCALES_PATH', APP_ROOT . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR . 'locales'); -define('MODULES_PATH', APP_ROOT . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR . 'modules'); -define('SQL_PATH', APP_ROOT . DIRECTORY_SEPARATOR . 'schemas'); -define('CACHE_PATH', RESOURCE_PATH . DIRECTORY_SEPARATOR . 'cache'); -define('TMP_PATH', TEST_ROOT . DIRECTORY_SEPARATOR . 'tmp'); +define('CONFIG_FILE', CONFIG_PATH.DIRECTORY_SEPARATOR.'config.xml'); +define('ACTIONS_FILE', CONFIG_PATH.DIRECTORY_SEPARATOR.'actions.xml'); +define('LOCALES_PATH', APP_ROOT.DIRECTORY_SEPARATOR.'app'.DIRECTORY_SEPARATOR.'locales'); +define('MODULES_PATH', APP_ROOT.DIRECTORY_SEPARATOR.'app'.DIRECTORY_SEPARATOR.'modules'); +define('SQL_PATH', APP_ROOT.DIRECTORY_SEPARATOR.'schemas'); +define('CACHE_PATH', RESOURCE_PATH.DIRECTORY_SEPARATOR.'cache'); +define('TMP_PATH', TEST_ROOT.DIRECTORY_SEPARATOR.'tmp'); define('BACKUP_PATH', TMP_PATH); define('PLUGINS_PATH', TMP_PATH); -define('XML_SCHEMA', APP_ROOT . DIRECTORY_SEPARATOR . 'schemas' . DIRECTORY_SEPARATOR . 'syspass.xsd'); -define('LOG_FILE', TMP_PATH . DIRECTORY_SEPARATOR . 'test.log'); +define('XML_SCHEMA', APP_ROOT.DIRECTORY_SEPARATOR.'schemas'.DIRECTORY_SEPARATOR.'syspass.xsd'); +define('LOG_FILE', TMP_PATH.DIRECTORY_SEPARATOR.'test.log'); define('FIXTURE_FILES', [ - RESOURCE_PATH . DIRECTORY_SEPARATOR . 'datasets' . DIRECTORY_SEPARATOR . 'truncate.sql', - RESOURCE_PATH . DIRECTORY_SEPARATOR . 'datasets' . DIRECTORY_SEPARATOR . 'syspass.sql' + RESOURCE_PATH.DIRECTORY_SEPARATOR.'datasets'.DIRECTORY_SEPARATOR.'truncate.sql', + RESOURCE_PATH.DIRECTORY_SEPARATOR.'datasets'.DIRECTORY_SEPARATOR.'syspass.sql', ]); define('SELF_IP_ADDRESS', getRealIpAddress()); define('SELF_HOSTNAME', gethostbyaddr(SELF_IP_ADDRESS)); -require_once APP_ROOT . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; -require_once APP_ROOT . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'BaseFunctions.php'; +require_once APP_ROOT.DIRECTORY_SEPARATOR.'vendor'.DIRECTORY_SEPARATOR.'autoload.php'; +require_once APP_ROOT.DIRECTORY_SEPARATOR.'lib'.DIRECTORY_SEPARATOR.'BaseFunctions.php'; -logger('APP_ROOT=' . APP_ROOT); -logger('TEST_ROOT=' . TEST_ROOT); -logger('SELF_IP_ADDRESS=' . SELF_IP_ADDRESS); +logger('APP_ROOT='.APP_ROOT); +logger('TEST_ROOT='.TEST_ROOT); +logger('SELF_IP_ADDRESS='.SELF_IP_ADDRESS); // Setup directories try { @@ -85,7 +85,7 @@ try { if (is_dir(CONFIG_PATH) && decoct(fileperms(CONFIG_PATH) & 0777) !== '750' ) { - print 'Setting permissions for ' . CONFIG_PATH . PHP_EOL; + print 'Setting permissions for '.CONFIG_PATH.PHP_EOL; chmod(CONFIG_PATH, 0750); } @@ -156,7 +156,7 @@ function getDbHandler(?DatabaseConnectionData $connectionData = null): MysqlHand function getResource(string $dir, string $file): string { - return file_get_contents(RESOURCE_PATH . DIRECTORY_SEPARATOR . $dir . DIRECTORY_SEPARATOR . $file) ?: ''; + return file_get_contents(RESOURCE_PATH.DIRECTORY_SEPARATOR.$dir.DIRECTORY_SEPARATOR.$file) ?: ''; } function saveResource(string $dir, string $file, string $data): bool|int @@ -172,12 +172,12 @@ function recreateDir(string $dir): void if (is_dir($dir)) { logger('Deleting '.$dir); - FileUtil::rmdir_recursive($dir); + FileUtil::rmdirRecursive($dir); } - logger('Creating '.$dir.PHP_EOL); + logger('Creating '.$dir); if (!mkdir($dir) && !is_dir($dir)) { throw new RuntimeException(sprintf('Directory "%s" was not created', $dir)); } -} \ No newline at end of file +}