diff --git a/ajax/ajax_install.php b/ajax/ajax_install.php deleted file mode 100644 index d0a97d50..00000000 --- a/ajax/ajax_install.php +++ /dev/null @@ -1,64 +0,0 @@ -. - */ - -use SP\Core\Exceptions\SPException; -use SP\Core\Installer; -use SP\DataModel\InstallData; -use SP\Http\JsonResponse; -use SP\Http\Request; -use SP\Util\Json; - -define('APP_ROOT', dirname(__DIR__)); -define('IS_INSTALLER', 1); - -require APP_ROOT . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'Base.php'; - -Request::checkReferer('POST'); - -$Json = new JsonResponse(); - -$InstallData = new InstallData(); -$InstallData->setSiteLang(Request::analyze('sitelang', 'en_US')); -$InstallData->setAdminLogin(Request::analyze('adminlogin', 'admin')); -$InstallData->setAdminPass(Request::analyzeEncrypted('adminpass')); -$InstallData->setMasterPassword(Request::analyzeEncrypted('masterpassword')); -$InstallData->setDbAdminUser(Request::analyze('dbuser', 'root')); -$InstallData->setDbAdminPass(Request::analyzeEncrypted('dbpass')); -$InstallData->setDbName(Request::analyze('dbname', 'syspass')); -$InstallData->setDbHost(Request::analyze('dbhost', 'localhost')); -$InstallData->setHostingMode(Request::analyze('hostingmode', false)); - -try { - $Installer = new Installer($InstallData); - $Installer->checkData(); - $Installer->install(); - - $Json->setStatus(0); - $Json->setDescription(__('Instalación finalizada')); -} catch (SPException $e) { - $Json->setDescription($e->getMessage()); - $Json->addMessage($e->getHint()); -} - -Json::returnJson($Json); diff --git a/app/modules/web/Controllers/ErrorController.php b/app/modules/web/Controllers/ErrorController.php new file mode 100644 index 00000000..17ccd15a --- /dev/null +++ b/app/modules/web/Controllers/ErrorController.php @@ -0,0 +1,92 @@ +. + */ + +namespace SP\Modules\Web\Controllers; + +use Klein\Klein; +use SP\Bootstrap; +use SP\Core\Traits\InjectableTrait; +use SP\Mvc\View\Template; +use SP\Util\Util; + +/** + * Class ErrorController + * + * @package SP\Modules\Web\Controllers + */ +class ErrorController +{ + use InjectableTrait; + + /** + * @var Template + */ + protected $view; + /** + * @var Klein + */ + protected $router; + + /** + * ErrorController constructor. + * + * @throws \ReflectionException + * @throws \SP\Core\Dic\ContainerException + */ + public function __construct() + { + $this->injectDependencies(); + } + + /** + * @param Template $view + * @param Klein $router + */ + public function inject(Template $view, Klein $router) + { + $this->view = $view; + $this->router = $router; + } + + /** + * @todo + */ + public function indexAction() + { + $this->view->assign('startTime', microtime()); + + $this->view->assign('appInfo', Util::getAppInfo()); + $this->view->assign('appVersion', Util::getVersionString()); + $this->view->assign('logoIcon', Bootstrap::$WEBURI . '/public/images/logo_icon.png'); + $this->view->assign('logoNoText', Bootstrap::$WEBURI . '/public/images/logo_icon.svg'); + $this->view->assign('logo', Bootstrap::$WEBURI . '/public/images/logo_full_bg.png'); + $this->view->assign('logonobg', Bootstrap::$WEBURI . '/public/images/logo_full_nobg.png'); + $this->view->assign('lang', 'en'); + $this->view->assign('error', 'Error!'); + + $this->router->response()->header('Content-Type', 'text/html; charset=UTF-8'); + $this->router->response()->header('Cache-Control', 'public, no-cache, max-age=0, must-revalidate'); + $this->router->response()->header('Pragma', 'public; max-age=0'); + } +} \ No newline at end of file diff --git a/app/modules/web/Controllers/Helpers/HelperBase.php b/app/modules/web/Controllers/Helpers/HelperBase.php index 5968058e..43730a2f 100644 --- a/app/modules/web/Controllers/Helpers/HelperBase.php +++ b/app/modules/web/Controllers/Helpers/HelperBase.php @@ -69,6 +69,7 @@ abstract class HelperBase * @param Session $session * @param EventDispatcher $eventDispatcher * @throws \SP\Core\Dic\ContainerException + * @throws \ReflectionException */ final public function __construct(Template $template, Config $config, Session $session, EventDispatcher $eventDispatcher) { diff --git a/app/modules/web/Controllers/Helpers/LayoutHelper.php b/app/modules/web/Controllers/Helpers/LayoutHelper.php index 19221d18..af812459 100644 --- a/app/modules/web/Controllers/Helpers/LayoutHelper.php +++ b/app/modules/web/Controllers/Helpers/LayoutHelper.php @@ -27,6 +27,7 @@ namespace SP\Modules\Web\Controllers\Helpers; use SP\Bootstrap; use SP\Core\Acl\Acl; use SP\Core\Acl\ActionsInterface; +use SP\Core\Dic\ContainerException; use SP\Core\Exceptions\SPException; use SP\Core\Language; use SP\Core\Plugin\PluginUtil; @@ -64,10 +65,12 @@ class LayoutHelper extends HelperBase * @param string $page Page/view name * @param Acl $acl * @return LayoutHelper + * @throws ContainerException */ public function getFullLayout($page, Acl $acl = null) { $this->view->addTemplate('main', '_layouts'); + $this->view->assign('useFixedHeader'); $this->setPage($page); $this->initBody(); @@ -95,6 +98,8 @@ class LayoutHelper extends HelperBase /** * Inicializar las variables para la vista principal de la aplicación + * + * @throws ContainerException */ public function initBody() { @@ -330,6 +335,7 @@ class LayoutHelper extends HelperBase * @param string $template * @param string $page Page/view name * @return LayoutHelper + * @throws ContainerException */ public function getPublicLayout($template, $page = '') { @@ -349,6 +355,7 @@ class LayoutHelper extends HelperBase * @param string $template * @param string $page Page/view name * @return LayoutHelper + * @throws ContainerException */ public function getCustomLayout($template, $page = '') { diff --git a/app/modules/web/Controllers/IndexController.php b/app/modules/web/Controllers/IndexController.php index 0b602de3..e6eb057c 100644 --- a/app/modules/web/Controllers/IndexController.php +++ b/app/modules/web/Controllers/IndexController.php @@ -40,6 +40,7 @@ class IndexController extends ControllerBase * Index action * * @throws \SP\Core\Dic\ContainerException + * @throws \ReflectionException */ public function indexAction() { diff --git a/app/modules/web/Controllers/InstallController.php b/app/modules/web/Controllers/InstallController.php index 7406bb4b..0c874dfa 100644 --- a/app/modules/web/Controllers/InstallController.php +++ b/app/modules/web/Controllers/InstallController.php @@ -47,6 +47,7 @@ class InstallController extends ControllerBase /** * @throws \SP\Core\Dic\ContainerException + * @throws \ReflectionException */ public function indexAction() { diff --git a/app/modules/web/Controllers/LoginController.php b/app/modules/web/Controllers/LoginController.php index 01bacb30..cb3d128b 100644 --- a/app/modules/web/Controllers/LoginController.php +++ b/app/modules/web/Controllers/LoginController.php @@ -58,6 +58,7 @@ class LoginController extends ControllerBase * Logout action * * @throws \SP\Core\Dic\ContainerException + * @throws \ReflectionException */ public function logoutAction() { @@ -77,13 +78,8 @@ class LoginController extends ControllerBase SessionFactory::setLoggedOut(true); $layoutHelper = new LayoutHelper($this->view, $this->config, $this->session, $this->eventDispatcher); - $layoutHelper->setPage('logout'); - $layoutHelper->initBody(); + $layoutHelper->getCustomLayout('logout', 'logout'); - $this->view->addTemplate('logout'); - - $this->view->addPartial('body-footer'); - $this->view->addPartial('body-end'); $this->view(); } else { Response::redirect('index.php?r=login'); @@ -94,6 +90,7 @@ class LoginController extends ControllerBase * Index action * * @throws \SP\Core\Dic\ContainerException + * @throws \ReflectionException */ public function indexAction() { diff --git a/app/modules/web/themes/material-blue/views/_layouts/error.inc b/app/modules/web/themes/material-blue/views/_layouts/error.inc new file mode 100644 index 00000000..6d953727 --- /dev/null +++ b/app/modules/web/themes/material-blue/views/_layouts/error.inc @@ -0,0 +1,43 @@ + + + + + <?php echo $appInfo['appname'], ' :: ', $appInfo['appdesc']; ?> + + + + + + +
+ + +
+
+
+
+ +
+
+
+
+ + + + +
+
+
+
+ +
+
+
+
+
+ + + diff --git a/lib/SP/Bootstrap.php b/lib/SP/Bootstrap.php index 301669ab..d57115b7 100644 --- a/lib/SP/Bootstrap.php +++ b/lib/SP/Bootstrap.php @@ -52,7 +52,6 @@ use SP\Http\JsonResponse; use SP\Http\Request; use SP\Log\Email; use SP\Log\Log; -use SP\Mgmt\Profiles\Profile; use SP\Modules\Web\Controllers\MainController; use SP\Mvc\View\Template; use SP\Providers\Auth\Browser\Browser; @@ -177,6 +176,8 @@ class Bootstrap */ protected function initRouter() { + $oops = "Oops, it looks like this content doesn't exist..."; + // Update request when we have a subdirectory // $_SERVER['REQUEST_URI'] = self::$WEBROOT; @@ -185,7 +186,7 @@ class Bootstrap // Manejar URLs con módulo indicado $this->router->respond(['GET', 'POST'], '@/(index\.php)?', - function ($request, $response, $service) use ($self) { + function ($request, $response, $service) use ($self, $oops) { $self->router->onError(function ($router, $err_msg, $type, $err) { debugLog('Routing error: ' . $err_msg); @@ -202,7 +203,7 @@ class Bootstrap $route = filter_var($request->param('r', 'index/index'), FILTER_SANITIZE_STRING); if (!preg_match_all('#(?P[a-zA-Z]+)(?:/(?P[a-zA-Z]+))?(?P(/[a-zA-Z\d]+)+)?#', $route, $components)) { - throw new RuntimeException("Oops, invalid route\n"); + throw new RuntimeException($oops); } $controller = $components['controller'][0]; @@ -221,21 +222,19 @@ class Bootstrap $controllerClass = 'SP\\Modules\\' . ucfirst(APP_MODULE) . '\\Controllers\\' . ucfirst($controller) . 'Controller'; - if (class_exists($controllerClass)) { - $callableMethod = [new $controllerClass($method), $method]; + $reflection = new \ReflectionMethod($controllerClass, $method); - if (!is_callable($callableMethod)) { - throw new RuntimeException("Oops, it looks like this content doesn't exist...\n"); - } - - $self->initialize(in_array($controller, self::PARTIAL_INIT, true)); - - debugLog('Routing call: ' . $controllerClass . '::' . $method . '::' . print_r($params, true)); - - return call_user_func_array($callableMethod, $params); + if (!$reflection->isPublic()) { + throw new RuntimeException($oops); } - throw new RuntimeException("Oops, it looks like this content doesn't exist...\n"); + $self->initialize(in_array($controller, self::PARTIAL_INIT, true)); + + debugLog('Routing call: ' . $controllerClass . '::' . $method . '::' . print_r($params, true)); + + return $reflection->invokeArgs(new $controllerClass($method), $params); + } catch (\ReflectionException $e) { + throw new RuntimeException($oops); } catch (RuntimeException $e) { debugLog($e->getMessage(), true); @@ -315,7 +314,7 @@ class Bootstrap if ($this->session->isLoggedIn()) { // Recargar los permisos del perfil de usuario - $this->session->setUserProfile(Profile::getItem()->getById($this->session->getUserData()->getUserProfileId())); +// $this->session->setUserProfile(Profile::getItem()->getById($this->session->getUserData()->getUserProfileId())); // Reset de los datos de ACL de cuentas $this->session->resetAccountAcl(); } @@ -332,8 +331,14 @@ class Bootstrap // Comprobar si el modo mantenimiento está activado $this->checkMaintenanceMode(); - // Comprobar si la Base de datos existe - DBUtil::checkDatabaseExist(self::$container->get(Database::class)->getDbHandler(), $this->configData->getDbName()); + try { + // Comprobar si la Base de datos existe + DBUtil::checkDatabaseExist(self::$container->get(Database::class)->getDbHandler(), $this->configData->getDbName()); + } catch (\Exception $e) { + if ($e->getCode() === 1049) { + $this->router->response()->redirect('index.php?r=install/index')->send(); + } + } // Comprobar si es necesario actualizar componentes // $this->checkUpgrade(); diff --git a/lib/SP/Controller/ControllerBase.php b/lib/SP/Controller/ControllerBase.php index 6eadd863..a1e90903 100644 --- a/lib/SP/Controller/ControllerBase.php +++ b/lib/SP/Controller/ControllerBase.php @@ -110,7 +110,6 @@ abstract class ControllerBase $this->controllerName = substr($class, strrpos($class, '\\') + 1, -strlen('Controller')); $this->actionName = $actionName; - $this->view = new Template(); $this->view->setBase(strtolower($this->controllerName)); $this->icons = $this->theme->getIcons(); @@ -149,8 +148,9 @@ abstract class ControllerBase * @param EventDispatcher $ev * @param Acl $acl * @param Klein $router + * @param Template $view */ - public function inject(Config $config, Session $session, Theme $theme, EventDispatcher $ev, Acl $acl, Klein $router) + public function inject(Config $config, Session $session, Theme $theme, EventDispatcher $ev, Acl $acl, Klein $router, Template $view) { $this->config = $config; $this->configData = $config->getConfigData(); @@ -159,6 +159,7 @@ abstract class ControllerBase $this->eventDispatcher = $ev; $this->acl = $acl; $this->router = $router; + $this->view = $view; } /** diff --git a/lib/SP/Core/Dic/Injector.php b/lib/SP/Core/Dic/Injector.php index 3bb8af6a..a7d7bf10 100644 --- a/lib/SP/Core/Dic/Injector.php +++ b/lib/SP/Core/Dic/Injector.php @@ -43,7 +43,6 @@ class Injector * @param $context * @return mixed * @throws ContainerException - * @throws \ReflectionException */ public static function inject(ContainerInterface $container, $context) { @@ -72,6 +71,8 @@ class Injector throw new ContainerException($e->getMessage(), $e->getCode(), $e); } catch (ContainerExceptionInterface $e) { throw new ContainerException($e->getMessage(), $e->getCode(), $e); + } catch (\ReflectionException $e) { + throw new ContainerException($e->getMessage(), $e->getCode(), $e); } } } \ No newline at end of file diff --git a/lib/SP/Core/Install/Installer.php b/lib/SP/Core/Install/Installer.php index 5c5015d1..949a01d4 100644 --- a/lib/SP/Core/Install/Installer.php +++ b/lib/SP/Core/Install/Installer.php @@ -270,19 +270,11 @@ class Installer $this->configData->setSiteLang($this->installData->getSiteLang()); } - /** - * Setup database connection for sysPass - */ - private function setupDBConnectionData() - { - // FIXME: ugly!! - $this->databaseConnectionData->refreshFromConfig($this->configData); - } - /** * @throws Dic\ContainerException * @throws SPException * @throws \ReflectionException + * @todo Select DB type */ private function setupDb() { @@ -302,6 +294,15 @@ class Installer $this->dbs->checkConnection(); } + /** + * Setup database connection for sysPass + */ + private function setupDBConnectionData() + { + // FIXME: ugly!! + $this->databaseConnectionData->refreshFromConfig($this->configData); + } + /** * Saves the master password metadata * @@ -347,11 +348,10 @@ class Installer $userData->setUserGroupId($this->userGroupService->create($userGroupData)); $userData->setUserProfileId($this->userProfileService->create($userProfileData)); $userData->setLogin($this->installData->getAdminLogin()); - $userData->setPass(Hash::hashKey($this->installData->getAdminPass())); $userData->setName('sysPass Admin'); $userData->setIsAdminApp(1); - $this->userService->createWithMasterPass($userData, $this->installData->getMasterPassword()); + $this->userService->createWithMasterPass($userData, $this->installData->getAdminPass(), $this->installData->getMasterPassword()); // __u('Error al actualizar la clave maestra del usuario "admin"'), } catch (\Exception $e) { diff --git a/lib/SP/Core/SessionUtil.php b/lib/SP/Core/SessionUtil.php index 02b50800..cca7e523 100644 --- a/lib/SP/Core/SessionUtil.php +++ b/lib/SP/Core/SessionUtil.php @@ -58,6 +58,7 @@ class SessionUtil * Establecer la clave pública RSA en la sessión * * @throws \SP\Core\Exceptions\SPException + * @throws Dic\ContainerException */ public static function loadPublicKey() { @@ -70,8 +71,6 @@ class SessionUtil * * @return string con la clave maestra * @throws \Defuse\Crypto\Exception\CryptoException - * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException - * @throws \Defuse\Crypto\Exception\BadFormatException */ public static function getSessionMPass() { diff --git a/lib/SP/Services/Auth/LoginService.php b/lib/SP/Services/Auth/LoginService.php index ff1d9c95..cdfa34e2 100644 --- a/lib/SP/Services/Auth/LoginService.php +++ b/lib/SP/Services/Auth/LoginService.php @@ -113,6 +113,10 @@ class LoginService * @var UserService */ protected $userService; + /** + * @var Language + */ + protected $language; /** * @var Session */ @@ -142,13 +146,22 @@ class LoginService $this->session = $session; $this->eventDispatcher = $eventDispatcher; - $this->userService = new UserService(); $this->jsonResponse = new JsonResponse(); $this->LogMessage = new LogMessage(); $this->userLoginData = new UserLoginData(); $this->LogMessage->setAction(__u('Inicio sesión')); } + /** + * @param UserService $userService + * @param Language $language + */ + public function inject(UserService $userService, Language $language) + { + $this->userService = $userService; + $this->language = $language; + } + /** * Ejecutar las acciones de login * @@ -156,6 +169,7 @@ class LoginService * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException * @throws \Psr\Container\ContainerExceptionInterface * @throws \Psr\Container\NotFoundExceptionInterface + * @throws \ReflectionException */ public function doLogin() { @@ -401,7 +415,7 @@ class LoginService */ protected function loadUserPreferences() { - Language::setLanguage(true); + $this->language->setLanguage(true); $this->theme->initTheme(true); diff --git a/lib/SP/Services/User/UserService.php b/lib/SP/Services/User/UserService.php index 94a9045c..67d7d8ea 100644 --- a/lib/SP/Services/User/UserService.php +++ b/lib/SP/Services/User/UserService.php @@ -210,14 +210,17 @@ class UserService * Creates an item * * @param UserData $itemData - * @param null $masterPass + * @param string $userPass + * @param string $masterPass * @return int * @throws SPException * @throws \Defuse\Crypto\Exception\CryptoException */ - public function createWithMasterPass($itemData, $masterPass) + public function createWithMasterPass($itemData, $userPass, $masterPass) { - $response = $this->userPassService->createMasterPass($masterPass, $itemData->getLogin(), $itemData->getPass()); + $response = $this->userPassService->createMasterPass($masterPass, $itemData->getLogin(), $userPass); + + $itemData->setPass(Hash::hashKey($userPass)); $itemData->setMPass($response->getCryptMasterPass()); $itemData->setMKey($response->getCryptSecuredKey()); $itemData->setLastUpdateMPass(time()); diff --git a/lib/SP/Storage/DBUtil.php b/lib/SP/Storage/DBUtil.php index 9eb6740f..c9b5a121 100644 --- a/lib/SP/Storage/DBUtil.php +++ b/lib/SP/Storage/DBUtil.php @@ -81,6 +81,7 @@ class DBUtil return $DBStorage->getConnection()->quote(trim($str)); } catch (SPException $e) { debugLog($e->getMessage()); + debugLog($e->getHint()); } return $str; @@ -91,6 +92,7 @@ class DBUtil * * @param DBStorageInterface $DBStorage * @return array + * @throws SPException */ public static function getDBinfo(DBStorageInterface $DBStorage) { @@ -109,6 +111,12 @@ class DBUtil foreach ($attributes as $val) { $dbinfo[$val] = $db->getAttribute(constant('PDO::ATTR_' . $val)); } + } catch (SPException $e) { + debugLog($e->getMessage()); + debugLog($e->getHint()); + debugLog($e->getCode()); + + throw $e; } catch (\Exception $e) { debugLog($e->getMessage()); } @@ -122,6 +130,7 @@ class DBUtil * @param DBStorageInterface $DBStorage * @param string $dbName * @return bool + * @throws SPException */ public static function checkDatabaseExist(DBStorageInterface $DBStorage, $dbName) { @@ -133,6 +142,11 @@ class DBUtil AND `table_name` IN (\'Client\', \'Category\', \'Account\', \'User\', \'Config\', \'EventLog\')'; return (int)$DBStorage->getConnection()->query($query)->fetchColumn() === 6; + } catch (SPException $e) { + debugLog($e->getMessage()); + debugLog($e->getHint()); + + throw $e; } catch (\Exception $e) { debugLog($e->getMessage()); debugLog($e->getCode()); diff --git a/lib/SP/Storage/MySQLHandler.php b/lib/SP/Storage/MySQLHandler.php index 6a140f26..f7f6f72d 100644 --- a/lib/SP/Storage/MySQLHandler.php +++ b/lib/SP/Storage/MySQLHandler.php @@ -125,7 +125,7 @@ class MySQLHandler implements DBStorageInterface */ public function getConnectionUri() { - if ('' === $this->connectionData->getDbSocket()) { + if (empty($this->connectionData->getDbSocket())) { $dsn = 'mysql:host=' . $this->connectionData->getDbHost(); if (null !== $this->connectionData->getDbPort()) { @@ -135,14 +135,13 @@ class MySQLHandler implements DBStorageInterface if (null !== $this->connectionData->getDbName()) { $dsn .= ';dbname=' . $this->connectionData->getDbName(); } - - + return $dsn . ';charset=utf8'; } $dsn = 'mysql:unix_socket=' . $this->connectionData->getDbSocket(); - if ('' !== $this->connectionData->getDbName()) { + if (!empty($this->connectionData->getDbName())) { $dsn .= ';dbname=' . $this->connectionData->getDbName(); }