diff --git a/README.md b/README.md index 4abaf3c1..6a6a5297 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,11 @@ ## sysPass - Systems Password Manager -[![Build Status](https://travis-ci.org/nuxsmin/sysPass.svg?branch=devel-3.0)](https://travis-ci.org/nuxsmin/sysPass) [![Join the chat at https://gitter.im/sysPass/Lobby](https://badges.gitter.im/sysPass/Lobby.svg)](https://gitter.im/sysPass/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Build Status](https://travis-ci.org/nuxsmin/sysPass.svg?branch=devel-3.0)](https://travis-ci.org/nuxsmin/sysPass) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/nuxsmin/sysPass/badges/quality-score.png?b=devel-3.0)](https://scrutinizer-ci.com/g/nuxsmin/sysPass/?branch=devel-3.0) + +[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/nuxsmin/sysPass.svg)](http://isitmaintained.com/project/nuxsmin/sysPass "Average time to resolve an issue") [![Percentage of issues still open](http://isitmaintained.com/badge/open/nuxsmin/sysPass.svg)](http://isitmaintained.com/project/nuxsmin/sysPass "Percentage of issues still open") + +Join us in the Gitter chat room: [![Join the chat at https://gitter.im/sysPass/Lobby](https://badges.gitter.im/sysPass/Lobby.svg)](https://gitter.im/sysPass/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) ---------------- diff --git a/app/modules/web/Controllers/AuthTokenController.php b/app/modules/web/Controllers/AuthTokenController.php index 328340b7..cdd39d19 100644 --- a/app/modules/web/Controllers/AuthTokenController.php +++ b/app/modules/web/Controllers/AuthTokenController.php @@ -123,6 +123,7 @@ final class AuthTokenController extends ControllerBase implements CrudController * * @throws \SP\Core\Exceptions\ConstraintException * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Services\ServiceException */ protected function setViewData($authTokenId = null) { @@ -146,7 +147,7 @@ final class AuthTokenController extends ControllerBase implements CrudController $this->view->assign('readonly'); } - $this->view->assign('customFields', $this->getCustomFieldsForItem(Acl::AUTHTOKEN, $authTokenId, $this->session)); + $this->view->assign('customFields', $this->getCustomFieldsForItem(Acl::AUTHTOKEN, $authTokenId)); } /** diff --git a/app/modules/web/Controllers/CategoryController.php b/app/modules/web/Controllers/CategoryController.php index 145aba9e..a4cbc380 100644 --- a/app/modules/web/Controllers/CategoryController.php +++ b/app/modules/web/Controllers/CategoryController.php @@ -121,6 +121,7 @@ final class CategoryController extends ControllerBase implements CrudControllerI * * @throws \SP\Core\Exceptions\ConstraintException * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Services\ServiceException */ protected function setViewData($categoryId = null) { @@ -142,7 +143,7 @@ final class CategoryController extends ControllerBase implements CrudControllerI } $this->view->assign('showViewCustomPass', $this->acl->checkUserAccess(Acl::CUSTOMFIELD_VIEW_PASS)); - $this->view->assign('customFields', $this->getCustomFieldsForItem(Acl::CATEGORY, $categoryId, $this->session)); + $this->view->assign('customFields', $this->getCustomFieldsForItem(Acl::CATEGORY, $categoryId)); } /** diff --git a/app/modules/web/Controllers/ClientController.php b/app/modules/web/Controllers/ClientController.php index ae67dfd6..ba085982 100644 --- a/app/modules/web/Controllers/ClientController.php +++ b/app/modules/web/Controllers/ClientController.php @@ -122,6 +122,7 @@ final class ClientController extends ControllerBase implements CrudControllerInt * * @throws \SP\Core\Exceptions\ConstraintException * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Services\ServiceException */ protected function setViewData($clientId = null) { @@ -143,7 +144,7 @@ final class ClientController extends ControllerBase implements CrudControllerInt } $this->view->assign('showViewCustomPass', $this->acl->checkUserAccess(Acl::CUSTOMFIELD_VIEW_PASS)); - $this->view->assign('customFields', $this->getCustomFieldsForItem(Acl::CLIENT, $clientId, $this->session)); + $this->view->assign('customFields', $this->getCustomFieldsForItem(Acl::CLIENT, $clientId)); } /** diff --git a/app/modules/web/Controllers/Helpers/Account/AccountHelper.php b/app/modules/web/Controllers/Helpers/Account/AccountHelper.php index 5c5b28e4..af88c560 100644 --- a/app/modules/web/Controllers/Helpers/Account/AccountHelper.php +++ b/app/modules/web/Controllers/Helpers/Account/AccountHelper.php @@ -233,6 +233,7 @@ final class AccountHelper extends HelperBase * * @throws \SP\Core\Exceptions\ConstraintException * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Services\ServiceException */ protected function setViewCommon() { @@ -241,7 +242,7 @@ final class AccountHelper extends HelperBase $this->view->assign('accountIsHistory', false); - $this->view->assign('customFields', $this->getCustomFieldsForItem(ActionsInterface::ACCOUNT, $this->accountId, $this->context)); + $this->view->assign('customFields', $this->getCustomFieldsForItem(ActionsInterface::ACCOUNT, $this->accountId)); $this->view->assign('categories', SelectItemAdapter::factory($this->dic->get(CategoryService::class)->getAllBasic())->getItemsFromModel()); $this->view->assign('clients', SelectItemAdapter::factory($this->dic->get(ClientService::class)->getAllForUser())->getItemsFromModel()); diff --git a/app/modules/web/Controllers/Helpers/LayoutHelper.php b/app/modules/web/Controllers/Helpers/LayoutHelper.php index 25c97805..360fc804 100644 --- a/app/modules/web/Controllers/Helpers/LayoutHelper.php +++ b/app/modules/web/Controllers/Helpers/LayoutHelper.php @@ -43,7 +43,7 @@ use SP\Util\Util; * * @package SP\Modules\Web\Controllers\Helpers */ -class LayoutHelper extends HelperBase +final class LayoutHelper extends HelperBase { /** * @var bool diff --git a/app/modules/web/Controllers/UserController.php b/app/modules/web/Controllers/UserController.php index 4b366376..6791c968 100644 --- a/app/modules/web/Controllers/UserController.php +++ b/app/modules/web/Controllers/UserController.php @@ -171,7 +171,7 @@ final class UserController extends ControllerBase implements CrudControllerInter } $this->view->assign('showViewCustomPass', $this->acl->checkUserAccess(Acl::CUSTOMFIELD_VIEW_PASS)); - $this->view->assign('customFields', $this->getCustomFieldsForItem(Acl::USER, $userId, $this->session)); + $this->view->assign('customFields', $this->getCustomFieldsForItem(Acl::USER, $userId)); } /** diff --git a/app/modules/web/Controllers/UserGroupController.php b/app/modules/web/Controllers/UserGroupController.php index eb47887a..718d2767 100644 --- a/app/modules/web/Controllers/UserGroupController.php +++ b/app/modules/web/Controllers/UserGroupController.php @@ -128,6 +128,7 @@ final class UserGroupController extends ControllerBase implements CrudController * * @throws \SP\Core\Exceptions\ConstraintException * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Services\ServiceException */ protected function setViewData($userGroupId = null) { @@ -151,7 +152,7 @@ final class UserGroupController extends ControllerBase implements CrudController } $this->view->assign('showViewCustomPass', $this->acl->checkUserAccess(Acl::CUSTOMFIELD_VIEW_PASS)); - $this->view->assign('customFields', $this->getCustomFieldsForItem(Acl::GROUP, $userGroupId, $this->session)); + $this->view->assign('customFields', $this->getCustomFieldsForItem(Acl::GROUP, $userGroupId)); } /** diff --git a/app/modules/web/Controllers/UserProfileController.php b/app/modules/web/Controllers/UserProfileController.php index 8fa64746..0fed39a9 100644 --- a/app/modules/web/Controllers/UserProfileController.php +++ b/app/modules/web/Controllers/UserProfileController.php @@ -122,6 +122,7 @@ final class UserProfileController extends ControllerBase implements CrudControll * * @throws \SP\Core\Exceptions\ConstraintException * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Services\ServiceException */ protected function setViewData($profileId = null) { @@ -146,7 +147,7 @@ final class UserProfileController extends ControllerBase implements CrudControll } $this->view->assign('showViewCustomPass', $this->acl->checkUserAccess(Acl::CUSTOMFIELD_VIEW_PASS)); - $this->view->assign('customFields', $this->getCustomFieldsForItem(Acl::PROFILE, $profileId, $this->session)); + $this->view->assign('customFields', $this->getCustomFieldsForItem(Acl::PROFILE, $profileId)); } /** diff --git a/composer.json b/composer.json index 3399ab21..b7f7301b 100644 --- a/composer.json +++ b/composer.json @@ -19,23 +19,24 @@ }, "require": { "roave/security-advisories": "dev-master", - "php": "7.0.* || 7.1.* || 7.2.*", - "defuse/php-encryption": "~2.1", - "phpmailer/phpmailer": "~6.0", + "php": "~7.0 || ~7.1 || ~7.2", + "defuse/php-encryption": "^2.1", + "phpmailer/phpmailer": "^6.0", "ademarre/binary-to-text-php": "dev-master", - "phpseclib/phpseclib": "~2.0", - "klein/klein": "v2.1.*", - "php-di/php-di": "6.0.*", - "doctrine/common": "v2.7.*", - "guzzlehttp/guzzle": "6.3.0", - "monolog/monolog": "1.23.0" + "phpseclib/phpseclib": "^2.0", + "klein/klein": "~2.1", + "php-di/php-di": "^6.0", + "doctrine/common": "~v2.7", + "guzzlehttp/guzzle": "~6.3", + "monolog/monolog": "^1.23" }, "require-dev": { "squizlabs/php_codesniffer": "3.*", "phpunit/phpunit": "^6", "phpunit/dbunit": "^3", "pdepend/pdepend" : "@stable", - "phpmd/phpmd" : "@stable" + "phpmd/phpmd" : "@stable", + "symfony/debug" : "~v3.4" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index a7bf2499..a7f3e09a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ffae607a40bea5311055c32daf891dd6", + "content-hash": "3c5fb049f0800c80b32afa323e535fd2", "packages": [ { "name": "ademarre/binary-to-text-php", @@ -515,16 +515,16 @@ }, { "name": "guzzlehttp/guzzle", - "version": "6.3.0", + "version": "6.3.3", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699" + "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f4db5a78a5ea468d4831de7f0bf9d9415e348699", - "reference": "f4db5a78a5ea468d4831de7f0bf9d9415e348699", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba", + "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba", "shasum": "" }, "require": { @@ -534,7 +534,7 @@ }, "require-dev": { "ext-curl": "*", - "phpunit/phpunit": "^4.0 || ^5.0", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", "psr/log": "^1.0" }, "suggest": { @@ -543,7 +543,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "6.2-dev" + "dev-master": "6.3-dev" } }, "autoload": { @@ -576,7 +576,7 @@ "rest", "web service" ], - "time": "2017-06-22T18:50:49+00:00" + "time": "2018-04-22T15:46:56+00:00" }, { "name": "guzzlehttp/promises", @@ -3349,6 +3349,62 @@ "homepage": "https://symfony.com", "time": "2018-06-19T14:02:58+00:00" }, + { + "name": "symfony/debug", + "version": "v3.4.13", + "source": { + "type": "git", + "url": "https://github.com/symfony/debug.git", + "reference": "0e3ca9cbde90fffec8038f4d4e16fd4046bbd018" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/debug/zipball/0e3ca9cbde90fffec8038f4d4e16fd4046bbd018", + "reference": "0e3ca9cbde90fffec8038f4d4e16fd4046bbd018", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "psr/log": "~1.0" + }, + "conflict": { + "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" + }, + "require-dev": { + "symfony/http-kernel": "~2.8|~3.0|~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Debug\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Debug Component", + "homepage": "https://symfony.com", + "time": "2018-06-26T08:45:54+00:00" + }, { "name": "symfony/dependency-injection", "version": "v3.4.13", @@ -3686,7 +3742,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "7.0.* || 7.1.* || 7.2.*" + "php": "~7.0 || ~7.1 || ~7.2" }, "platform-dev": [] } diff --git a/lib/BaseFunctions.php b/lib/BaseFunctions.php index f67be42a..1ae4e21f 100644 --- a/lib/BaseFunctions.php +++ b/lib/BaseFunctions.php @@ -242,39 +242,6 @@ function nDirname($dir, $levels) return dirname($dir, $levels); } -/** - * @param Exception $exception - * - * @throws ReflectionException - */ -function flattenExceptionBacktrace(\Exception $exception) -{ - $traceProperty = (new \ReflectionClass('Exception'))->getProperty('trace'); - $traceProperty->setAccessible(true); - $flatten = function (&$value, $key) { - if ($value instanceof \Closure) { - $closureReflection = new \ReflectionFunction($value); - $value = sprintf( - '(Closure at %s:%s)', - $closureReflection->getFileName(), - $closureReflection->getStartLine() - ); - } elseif (is_object($value)) { - $value = sprintf('object(%s)', get_class($value)); - } elseif (is_resource($value)) { - $value = sprintf('resource(%s)', get_resource_type($value)); - } - }; - do { - $trace = $traceProperty->getValue($exception); - foreach ($trace as &$call) { - array_walk_recursive($call['args'], $flatten); - } - $traceProperty->setValue($exception, $trace); - } while ($exception = $exception->getPrevious()); - $traceProperty->setAccessible(false); -} - /** * Prints a fancy trace info using Xdebug extension */ @@ -284,5 +251,3 @@ function printTraceInfo() xdebug_print_function_stack(); } } - -//set_exception_handler('\flattenExceptionBacktrace'); \ No newline at end of file diff --git a/lib/SP/Bootstrap.php b/lib/SP/Bootstrap.php index 338b7c16..755967e7 100644 --- a/lib/SP/Bootstrap.php +++ b/lib/SP/Bootstrap.php @@ -25,10 +25,10 @@ namespace SP; use DI\Container; -use Interop\Container\ContainerInterface; use Klein\Klein; use Klein\Response; use PHPMailer\PHPMailer\Exception; +use Psr\Container\ContainerInterface; use RuntimeException; use SP\Config\Config; use SP\Config\ConfigData; @@ -36,6 +36,7 @@ use SP\Config\ConfigUtil; use SP\Core\Exceptions\ConfigException; use SP\Core\Exceptions\InitializationException; use SP\Core\Language; +use SP\Core\PhpExtensionChecker; use SP\Http\Request; use SP\Modules\Api\Init as InitApi; use SP\Modules\Web\Init as InitWeb; @@ -46,6 +47,7 @@ use SP\Services\Upgrade\UpgradeUtil; use SP\Util\Checks; use SP\Util\Filter; use SP\Util\Util; +use Symfony\Component\Debug\Debug; defined('APP_ROOT') || die(); @@ -77,7 +79,7 @@ final class Bootstrap */ public static $checkPhpVersion; /** - * @var ContainerInterface|Container + * @var ContainerInterface */ private static $container; /** @@ -231,6 +233,7 @@ final class Bootstrap /** * @throws ConfigException + * @throws Core\Exceptions\CheckException * @throws InitializationException * @throws Services\Upgrade\UpgradeException */ @@ -249,6 +252,8 @@ final class Bootstrap // Establecer las rutas de la aplicación $this->initPaths(); + self::$container->get(PhpExtensionChecker::class)->checkMandatory(); + // Establecer el lenguaje por defecto $this->language->setLocales('en_US'); @@ -303,8 +308,7 @@ final class Bootstrap } if (defined('DEBUG') && DEBUG) { - error_reporting(E_ALL); - ini_set('display_errors', 'On'); + Debug::enable(); } else { error_reporting(E_ALL & ~(E_DEPRECATED | E_STRICT | E_NOTICE)); ini_set('display_errors', 'Off'); diff --git a/lib/SP/Core/Acl/Actions.php b/lib/SP/Core/Acl/Actions.php index 4b6c1f32..b26ec102 100644 --- a/lib/SP/Core/Acl/Actions.php +++ b/lib/SP/Core/Acl/Actions.php @@ -45,7 +45,7 @@ final class Actions */ const CACHE_EXPIRE = 86400; /** - * @var int + * @var int */ protected $lastLoadTime; /** @@ -91,7 +91,7 @@ final class Actions try { $this->actions = $this->fileStorage->load(self::ACTIONS_CACHE_FILE); - logger('Loaded actions cache'); + logger('Loaded actions cache', 'INFO'); } catch (FileException $e) { processException($e); @@ -105,7 +105,7 @@ final class Actions */ protected function mapAndSave() { - logger('ACTION CACHE MISS'); + logger('ACTION CACHE MISS', 'INFO'); $this->map(); $this->saveCache(); @@ -154,7 +154,7 @@ final class Actions try { $this->fileStorage->save(self::ACTIONS_CACHE_FILE, $this->actions); - logger('Saved actions cache'); + logger('Saved actions cache', 'INFO'); } catch (FileException $e) { processException($e); } diff --git a/lib/SP/Core/Language.php b/lib/SP/Core/Language.php index bb9ddb69..4b385f07 100644 --- a/lib/SP/Core/Language.php +++ b/lib/SP/Core/Language.php @@ -212,7 +212,7 @@ final class Language putenv('LANG=' . $lang); putenv('LANGUAGE=' . $lang); - if (!($result = setlocale(LC_ALL, $locales))) { + if (!setlocale(LC_ALL, $locales)) { logger('Could not set locales'); logger('Domain path: ' . LOCALES_PATH); } diff --git a/lib/SP/Core/PhpExtensionChecker.php b/lib/SP/Core/PhpExtensionChecker.php new file mode 100644 index 00000000..dcd2904d --- /dev/null +++ b/lib/SP/Core/PhpExtensionChecker.php @@ -0,0 +1,247 @@ +. + */ + +namespace SP\Core; + +use SP\Core\Exceptions\CheckException; + +/** + * Class PhpExtensionChecker + * + * @package SP\Core + */ +class PhpExtensionChecker +{ + /** + * Array of extensions needed by sysPass. + * + * true -> required + * false -> not required + */ + const EXTENSIONS = [ + 'ldap' => false, + 'curl' => false, + 'simplexml' => false, + 'libxml' => true, + 'phar' => false, + 'json' => true, + 'xml' => true, + 'pdo' => true, + 'zlib' => false, + 'gettext' => true, + 'openssl' => true, + 'pcre' => true, + 'session' => true, + 'mcrypt' => false, + 'gd' => false, + 'mbstring' => true, + 'pdo_mysql' => true, + 'fileinfo' => true + ]; + + const MSG_NOT_AVAILABLE = 'Oops, it seems that some extensions are not available: \'%s\''; + + /** + * Available extensions + * + * @var array + */ + private $available; + + /** + * PhpExtensionChecker constructor. + */ + public function __construct() + { + $this->checkExtensions(); + } + + /** + * Check for available extensions + */ + public function checkExtensions() + { + $this->available = array_intersect(array_keys(self::EXTENSIONS), array_map('strtolower', get_loaded_extensions())); + } + + /** + * Checks if the extension is installed + * + * @throws CheckException + */ + public function checkCurlAvailable() + { + if (!$this->checkIsAvailable('curl')) { + throw new CheckException(sprintf(self::MSG_NOT_AVAILABLE, 'curl')); + } + } + + /** + * Checks if the extension is installed + * + * @param $extension + * + * @return bool + */ + public function checkIsAvailable(string $extension) + { + return in_array(strtolower($extension), $this->available); + } + + /** + * Checks if the extension is installed + * + * @throws CheckException + */ + public function checkLdapAvailable() + { + if (!$this->checkIsAvailable('ldap')) { + throw new CheckException(sprintf(self::MSG_NOT_AVAILABLE, 'ldap')); + } + } + + /** + * Checks if the extension is installed + * + * @throws CheckException + */ + public function checkSimpleXmlAvailable() + { + if (!$this->checkIsAvailable('simplexml')) { + throw new CheckException(sprintf(self::MSG_NOT_AVAILABLE, 'simplexml')); + } + } + + /** + * Checks if the extension is installed + * + * @throws CheckException + */ + public function checkXmlAvailable() + { + if (!$this->checkIsAvailable('xml')) { + throw new CheckException(sprintf(self::MSG_NOT_AVAILABLE, 'xml')); + } + } + + /** + * Checks if the extension is installed + * + * @throws CheckException + */ + public function checkPharAvailable() + { + if (!$this->checkIsAvailable('phar')) { + throw new CheckException(sprintf(self::MSG_NOT_AVAILABLE, 'phar')); + } + } + + /** + * Checks if the extension is installed + * + * @throws CheckException + */ + public function checkJsonAvailable() + { + if (!$this->checkIsAvailable('json')) { + throw new CheckException(sprintf(self::MSG_NOT_AVAILABLE, 'json')); + } + } + + /** + * Checks if the extension is installed + * + * @throws CheckException + */ + public function checkPdoAvailable() + { + if (!$this->checkIsAvailable('pdo')) { + throw new CheckException(sprintf(self::MSG_NOT_AVAILABLE, 'pdo')); + } + } + + /** + * Checks if the extension is installed + * + * @throws CheckException + */ + public function checkGettextAvailable() + { + if (!$this->checkIsAvailable('gettext')) { + throw new CheckException(sprintf(self::MSG_NOT_AVAILABLE, 'gettext')); + } + } + + /** + * Checks if the extension is installed + * + * @throws CheckException + */ + public function checkOpenSslAvailable() + { + if (!$this->checkIsAvailable('openssl')) { + throw new CheckException(sprintf(self::MSG_NOT_AVAILABLE, 'openssl')); + } + } + + /** + * Checks if the extension is installed + * + * @throws CheckException + */ + public function checkGdAvailable() + { + if (!$this->checkIsAvailable('gd')) { + throw new CheckException(sprintf(self::MSG_NOT_AVAILABLE, 'gd')); + } + } + + /** + * Checks if the extension is installed + * + * @throws CheckException + */ + public function checkMbstringAvailable() + { + if (!$this->checkIsAvailable('mbstring')) { + throw new CheckException(sprintf(self::MSG_NOT_AVAILABLE, 'mbstring')); + } + } + + /** + * @throws CheckException + */ + public function checkMandatory() + { + $missing = array_filter(self::EXTENSIONS, function ($v, $k) { + return $v === true && !in_array($k, $this->available); + }, ARRAY_FILTER_USE_BOTH); + + if (count($missing) > 0) { + throw new CheckException(sprintf(self::MSG_NOT_AVAILABLE, implode(',', array_keys($missing)))); + } + + logger('Extensions checked', 'INFO'); + } +} \ No newline at end of file diff --git a/lib/SP/Core/PhpModuleChecker.php b/lib/SP/Core/PhpModuleChecker.php deleted file mode 100644 index aee7271f..00000000 --- a/lib/SP/Core/PhpModuleChecker.php +++ /dev/null @@ -1,210 +0,0 @@ -. - */ - -namespace SP\Core; - -use SP\Core\Exceptions\CheckException; - -/** - * Class PhpModuleChecker - * @package SP\Core - */ -class PhpModuleChecker -{ - const MODULES = [ - 'ldap', - 'curl', - 'simplexml', - 'phar', - 'json', - 'xml', - 'pdo', - 'zlib', - 'gettext', - 'openssl', - 'pcre', - 'session', - 'mcrypt', - 'gd', - 'mbstring' - ]; - - /** - * Available modules - * - * @var array - */ - protected $available; - - /** - * PhpModuleChecker constructor. - */ - public function __construct() - { - $this->checkModules(); - } - - /** - * Check for missing modules - */ - public function checkModules() - { - $loaded = get_loaded_extensions(); - - $this->available = array_filter(self::MODULES, function ($module) use ($loaded) { - return in_array($module, $loaded); - }); - } - - /** - * Comprobar si el módulo está instalado. - * - * @throws CheckException - */ - public function checkCurlAvailable() - { - if (!$this->checkIsAvailable('curl')) { - throw new CheckException(sprintf(__('Módulo \'%s\' no disponible'), 'curl')); - } - } - - /** - * Comprobar si el módulo está instalado. - * - * @param $module - * @return bool - */ - public function checkIsAvailable(string $module) - { - return in_array(strtolower($module), $this->available); - } - - /** - * Comprobar si el módulo está instalado. - * - * @throws CheckException - */ - public function checkLdapAvailable() - { - if (!$this->checkIsAvailable('ldap')) { - throw new CheckException(sprintf(__('Módulo \'%s\' no disponible'), 'ldap')); - } - } - - /** - * Comprobar si el módulo está instalado. - * - * @throws CheckException - */ - public function checkSimpleXmlAvailable() - { - if (!$this->checkIsAvailable('simplexml')) { - throw new CheckException(sprintf(__('Módulo \'%s\' no disponible'), 'simplexml')); - } - } - - /** - * Comprobar si el módulo está instalado. - * - * @throws CheckException - */ - public function checkPharAvailable() - { - if (!$this->checkIsAvailable('phar')) { - throw new CheckException(sprintf(__('Módulo \'%s\' no disponible'), 'phar')); - } - } - - /** - * Comprobar si el módulo está instalado. - * - * @throws CheckException - */ - public function checkJsonAvailable() - { - if (!$this->checkIsAvailable('json')) { - throw new CheckException(sprintf(__('Módulo \'%s\' no disponible'), 'json')); - } - } - - /** - * Comprobar si el módulo está instalado. - * - * @throws CheckException - */ - public function checkPdoAvailable() - { - if (!$this->checkIsAvailable('pdo')) { - throw new CheckException(sprintf(__('Módulo \'%s\' no disponible'), 'pdo')); - } - } - - /** - * Comprobar si el módulo está instalado. - * - * @throws CheckException - */ - public function checkGettextAvailable() - { - if (!$this->checkIsAvailable('gettext')) { - throw new CheckException(sprintf(__('Módulo \'%s\' no disponible'), 'gettext')); - } - } - - /** - * Comprobar si el módulo está instalado. - * - * @throws CheckException - */ - public function checkOpenSslAvailable() - { - if (!$this->checkIsAvailable('openssl')) { - throw new CheckException(sprintf(__('Módulo \'%s\' no disponible'), 'openssl')); - } - } - - /** - * Comprobar si el módulo está instalado. - * - * @throws CheckException - */ - public function checkGdAvailable() - { - if (!$this->checkIsAvailable('gd')) { - throw new CheckException(sprintf(__('Módulo \'%s\' no disponible'), 'gd')); - } - } - - /** - * Comprobar si el módulo está instalado. - * - * @throws CheckException - */ - public function checkMbstringAvailable() - { - if (!$this->checkIsAvailable('mbstring')) { - throw new CheckException(sprintf(__('Módulo \'%s\' no disponible'), 'mbstring')); - } - } -} \ No newline at end of file diff --git a/lib/SP/Core/UI/Theme.php b/lib/SP/Core/UI/Theme.php index d9e146e3..2180b484 100644 --- a/lib/SP/Core/UI/Theme.php +++ b/lib/SP/Core/UI/Theme.php @@ -101,6 +101,7 @@ final class Theme implements ThemeInterface $this->configData = $config->getConfigData(); $this->context = $context; $this->fileCache = $fileCache; + $this->module = $module; } /** @@ -165,7 +166,7 @@ final class Theme implements ThemeInterface try { $this->icons = $this->fileCache->load(self::ICONS_CACHE_FILE); - logger('Loaded icons cache'); + logger('Loaded icons cache', 'INFO'); return $this->icons; } catch (FileException $e) { @@ -183,7 +184,7 @@ final class Theme implements ThemeInterface try { $this->fileCache->save(self::ICONS_CACHE_FILE, $this->icons); - logger('Saved icons cache'); + logger('Saved icons cache', 'INFO'); } catch (FileException $e) { processException($e); } diff --git a/lib/SP/Http/Request.php b/lib/SP/Http/Request.php index 3421341a..94692ec4 100644 --- a/lib/SP/Http/Request.php +++ b/lib/SP/Http/Request.php @@ -202,8 +202,7 @@ final class Request * @param string $param * @param string $default * - * @return string - * @deprecated + * @return string|null */ public function analyzeEmail(string $param, string $default = null) { @@ -253,7 +252,7 @@ final class Request * @param $param * @param $default * - * @return string + * @return string|null */ public function analyzeString(string $param, string $default = null) { @@ -269,7 +268,7 @@ final class Request * @param callable|null $mapper * @param mixed $default * - * @return mixed + * @return array|null */ public function analyzeArray(string $param, callable $mapper = null, $default = null) { diff --git a/lib/SP/Providers/Mail/MailProvider.php b/lib/SP/Providers/Mail/MailProvider.php index d100683d..ac20a273 100644 --- a/lib/SP/Providers/Mail/MailProvider.php +++ b/lib/SP/Providers/Mail/MailProvider.php @@ -75,7 +75,7 @@ final class MailProvider extends Provider if ($this->debug) { $this->mailer->SMTPDebug = 2; $this->mailer->Debugoutput = function ($str, $level) { - logger($str); + logger($str, strtoupper($level)); }; } diff --git a/lib/SP/Services/Api/ApiService.php b/lib/SP/Services/Api/ApiService.php index 54f62a6b..111f7059 100644 --- a/lib/SP/Services/Api/ApiService.php +++ b/lib/SP/Services/Api/ApiService.php @@ -36,6 +36,7 @@ use SP\Services\ServiceException; use SP\Services\Track\TrackService; use SP\Services\User\UserService; use SP\Services\UserProfile\UserProfileService; +use SP\Util\Filter; /** * Class ApiService @@ -343,12 +344,12 @@ final class ApiService extends Service * @param bool $required * @param null $default * - * @return int|string + * @return int * @throws ServiceException */ public function getParamInt($param, $required = false, $default = null) { - return filter_var($this->getParam($param, $required, $default), FILTER_VALIDATE_INT); + return Filter::getInt($this->getParam($param, $required, $default)); } /** @@ -356,12 +357,12 @@ final class ApiService extends Service * @param bool $required * @param null $default * - * @return int|string + * @return string * @throws ServiceException */ public function getParamString($param, $required = false, $default = null) { - return filter_var($this->getParam($param, $required, $default), FILTER_SANITIZE_FULL_SPECIAL_CHARS); + return Filter::getString($this->getParam($param, $required, $default)); } /** @@ -374,7 +375,7 @@ final class ApiService extends Service */ public function getParamEmail($param, $required = false, $default = null) { - return filter_var($this->getParam($param, $required, $default), FILTER_SANITIZE_EMAIL); + return Filter::getEmail($this->getParam($param, $required, $default)); } /** @@ -382,12 +383,12 @@ final class ApiService extends Service * @param bool $required * @param null $default * - * @return int|string + * @return string * @throws ServiceException */ public function getParamRaw($param, $required = false, $default = null) { - return filter_var($this->getParam($param, $required, $default), FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW); + return Filter::getRaw($this->getParam($param, $required, $default)); } /** diff --git a/lib/SP/Services/Import/ImportService.php b/lib/SP/Services/Import/ImportService.php index f6668a22..8523aec2 100644 --- a/lib/SP/Services/Import/ImportService.php +++ b/lib/SP/Services/Import/ImportService.php @@ -80,10 +80,8 @@ final class ImportService extends Service switch ($fileType) { case 'text/plain': return new CsvImport($this->dic, $this->fileImport, $this->importParams); - break; case 'text/xml': return new XmlImport($this->dic, new XmlFileImport($this->fileImport), $this->importParams); - break; } throw new ImportException( diff --git a/lib/SP/Util/Filter.php b/lib/SP/Util/Filter.php index 8851ad5d..46260842 100644 --- a/lib/SP/Util/Filter.php +++ b/lib/SP/Util/Filter.php @@ -94,4 +94,14 @@ final class Filter { return filter_var(trim($value), FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES); } + + /** + * @param $value + * + * @return string + */ + public static function getRaw($value): string + { + return filter_var(trim($value), FILTER_UNSAFE_RAW); + } } \ No newline at end of file diff --git a/test/SP/Services/Api/ApiServiceTest.php b/test/SP/Services/Api/ApiServiceTest.php index 80fb50e1..50e8e75c 100644 --- a/test/SP/Services/Api/ApiServiceTest.php +++ b/test/SP/Services/Api/ApiServiceTest.php @@ -161,7 +161,8 @@ class ApiServiceTest extends DatabaseTestCase self::$service->setup(ActionsInterface::ACCOUNT_SEARCH); - $this->assertEquals("bla bla bla\nbla bla~!?|.$%&/()=¿ªº", self::$service->getParamString('notes')); + $this->assertEquals("bla bla bla\nbla bla~!?|.$%&/()=¿ªº€\"'", self::$service->getParamString('notes')); + $this->assertEmpty(self::$service->getParamString('test')); } @@ -175,7 +176,7 @@ class ApiServiceTest extends DatabaseTestCase self::$service->setup(ActionsInterface::ACCOUNT_SEARCH); - $this->assertEquals("bla bla blabla bla~!?|.$%&/()=¿ªº", self::$service->getParamRaw('notes')); + $this->assertEquals("bla bla bla\nbla bla~!?|.$%&/()=¿ªº€\"'", self::$service->getParamRaw('notes')); } /** diff --git a/test/res/config/config.xml b/test/res/config/config.xml index 9fbecc1b..76289881 100644 --- a/test/res/config/config.xml +++ b/test/res/config/config.xml @@ -9,11 +9,11 @@ 1 1 - f0b0e9e02a1ac6501ae935eecdcc1af9c9153a63 + 46dacd46279cb15e1712dc8bf3430e9e326164d0 0 0 - 1532986834 - 3e7c18ac5fe200f3b34d3007529d9bc25e1b6bd3 + 1533075231 + c7d4a323f7208fe105cc90545d9eb3e104fa93ea @@ -32,7 +32,7 @@ 0 - 52bb2bf6176d57b7be7fd4e66dee89669b3ba7a2 + e7e56309b3c6ddaab8d6e85c27b471e14dc3ec0c PDF JPG diff --git a/test/res/json/account_add.json b/test/res/json/account_add.json index db973d96..5840be4d 100644 --- a/test/res/json/account_add.json +++ b/test/res/json/account_add.json @@ -12,7 +12,7 @@ "categoryId": "4", "login": "toor", "url": "http://www.google.com", - "notes": "bla bla bla\nbla bla~!?|.$%&/()=¿ªº", + "notes": "bla bla bla\nbla bla~!?|.$%&/()=¿ªº€\"'", "private": "0", "privateGroup": "0", "expireDate": "0",