diff --git a/pandora_console/api/v1/config/middleware.php b/pandora_console/api/v1/config/middleware.php index 7381869651..c49d8b5e4b 100644 --- a/pandora_console/api/v1/config/middleware.php +++ b/pandora_console/api/v1/config/middleware.php @@ -49,6 +49,7 @@ return function (App $app, ContainerInterface $container) { } } + // TODO: XXX. $user = 'admin'; $_SESSION['id_usuario'] = $user; $config['id_user'] = $user; diff --git a/pandora_console/include/functions.php b/pandora_console/include/functions.php index 7c1638f8fa..b18879c483 100644 --- a/pandora_console/include/functions.php +++ b/pandora_console/include/functions.php @@ -2775,11 +2775,12 @@ function get_os_name($id_os) /** * Get user's dashboards * - * @param int user id. + * @param integer $id_user User id. + * @param integer $id_dashboard Dashboard id. * * @return array Dashboard name of the given user. */ -function get_user_dashboards($id_user) +function get_user_dashboards($id_user, $id_dashboard=null) { if (users_is_admin($id_user)) { $sql = "SELECT id, name @@ -2806,6 +2807,10 @@ function get_user_dashboards($id_user) } } + if ($id_dashboard !== null) { + $sql .= sprintf(' AND id = %d', $id_dashboard); + } + return db_get_all_rows_sql($sql); } diff --git a/pandora_console/include/functions_io.php b/pandora_console/include/functions_io.php index 445504b11c..0213af0133 100755 --- a/pandora_console/include/functions_io.php +++ b/pandora_console/include/functions_io.php @@ -73,6 +73,10 @@ function io_safe_input($value) { // Stop!! Are you sure to modify this critical code? Because the older // versions are serius headache in many places of Pandora. + if (empty($value) === true) { + return $value; + } + if (is_numeric($value)) { return $value; } diff --git a/pandora_console/include/lib/Modules/Shared/Controllers/Controller.php b/pandora_console/include/lib/Modules/Shared/Controllers/Controller.php index 8f7ca88a46..cdbb8d50e1 100644 --- a/pandora_console/include/lib/Modules/Shared/Controllers/Controller.php +++ b/pandora_console/include/lib/Modules/Shared/Controllers/Controller.php @@ -56,12 +56,15 @@ abstract class Controller { $queryParams = ($request->getQueryParams() ?? []); $parsedBody = ($request->getParsedBody() ?? []); - // if (JSON_ERROR_NONE !== json_last_error()) { - // throw new \UnexpectedValueException(sprintf( - // 'Cannot decoded body JSON, error: %s', - // json_last_error_msg() - // )); - // } + if (JSON_ERROR_NONE !== json_last_error()) { + throw new \UnexpectedValueException( + sprintf( + 'Cannot decoded body JSON, error: %s', + json_last_error_msg() + ) + ); + } + $params = array_merge($queryParams, $parsedBody); return $params; diff --git a/pandora_console/include/lib/Modules/Users/Entities/User.php b/pandora_console/include/lib/Modules/Users/Entities/User.php index c99763f09e..8a2219dc58 100644 --- a/pandora_console/include/lib/Modules/Users/Entities/User.php +++ b/pandora_console/include/lib/Modules/Users/Entities/User.php @@ -618,23 +618,23 @@ final class User extends Entity 'email' => $this->getEmail(), 'phone' => $this->getPhone(), 'isAdmin' => $this->getIsAdmin(), - 'language' => $this->getLanguage()->name, + 'language' => $this->getLanguage()?->name, 'timezone' => $this->getTimezone(), 'blockSize' => $this->getBlockSize(), 'idSkin' => $this->getIdSkin(), 'disabled' => $this->getDisabled(), 'shortcut' => $this->getShortcut(), 'shortcutData' => $this->getShortcutData(), - 'section' => $this->getSection()->name, + 'section' => $this->getSection()?->name, 'dataSection' => $this->getDataSection(), - 'metaconsoleSection' => $this->getMetaconsoleSection()->name, + 'metaconsoleSection' => $this->getMetaconsoleSection()?->name, 'metaconsoleDataSection' => $this->getMetaconsoleDataSection(), 'forceChangePass' => $this->getForceChangePass(), 'lastPassChange' => $this->getLastPassChange(), 'lastFailedLogin' => $this->getLastFailedLogin(), 'failedAttempt' => $this->getFailedAttempt(), 'loginBlocked' => $this->getLoginBlocked(), - 'metaconsoleAccess' => $this->getMetaconsoleAccess()->name, + 'metaconsoleAccess' => $this->getMetaconsoleAccess()?->name, 'notLogin' => $this->getNotLogin(), 'localUser' => $this->getLocalUser(), 'metaconsoleAgentsManager' => $this->getMetaconsoleAgentsManager(), diff --git a/pandora_console/include/lib/Modules/Users/Entities/UserDataMapper.php b/pandora_console/include/lib/Modules/Users/Entities/UserDataMapper.php index 48b24716c9..89474a5161 100644 --- a/pandora_console/include/lib/Modules/Users/Entities/UserDataMapper.php +++ b/pandora_console/include/lib/Modules/Users/Entities/UserDataMapper.php @@ -128,7 +128,7 @@ final class UserDataMapper extends DataMapperAbstract 'defaultEventFilter' => $data[self::DEFAULT_EVENT_FILTER], 'metaconsoleDefaultEventFilter' => $data[self::METACONSOLE_DEFAULT_EVENT_FILTER], 'showTipsStartup' => $data[self::SHOW_TIPS_STARTUP], - 'autorefreshWhiteList' => json_decode($this->repository->safeOutput($data[self::AUTOREFRESH_WHITE_LIST])), + 'autorefreshWhiteList' => ($data[self::AUTOREFRESH_WHITE_LIST] !== null) ? json_decode($this->repository->safeOutput($data[self::AUTOREFRESH_WHITE_LIST])) : null, 'timeAutorefresh' => $data[self::TIME_AUTOREFRESH], 'defaultCustomView' => $data[self::DEFAULT_CUSTOM_VIEW], 'ehorusUserLevelUser' => $this->repository->safeOutput($data[self::EHORUS_USER_LEVEL_USER]), @@ -191,7 +191,7 @@ final class UserDataMapper extends DataMapperAbstract self::DEFAULT_EVENT_FILTER => $data->getDefaultEventFilter(), self::METACONSOLE_DEFAULT_EVENT_FILTER => $data->getMetaconsoleDefaultEventFilter(), self::SHOW_TIPS_STARTUP => $data->getShowTipsStartup(), - self::AUTOREFRESH_WHITE_LIST => $this->repository->safeInput(json_encode($data->getAutorefreshWhiteList())), + self::AUTOREFRESH_WHITE_LIST => ($data->getAutorefreshWhiteList() !== null) ? $this->repository->safeInput(json_encode($data->getAutorefreshWhiteList())) : null, self::TIME_AUTOREFRESH => $data->getTimeAutorefresh(), self::DEFAULT_CUSTOM_VIEW => $data->getDefaultCustomView(), self::EHORUS_USER_LEVEL_USER => $this->repository->safeInput($data->getEhorusUserLevelUser()), diff --git a/pandora_console/include/lib/Modules/Users/Enums/UserAutoRefreshPagesEnum.php b/pandora_console/include/lib/Modules/Users/Enums/UserAutoRefreshPagesEnum.php new file mode 100644 index 0000000000..6048e12ef9 --- /dev/null +++ b/pandora_console/include/lib/Modules/Users/Enums/UserAutoRefreshPagesEnum.php @@ -0,0 +1,26 @@ +getUsersQuery($userFilter, $this->userDataMapper, true); try { - hd($sql, true); $count = $this->dbGetValueSql($sql); } catch (\Throwable $th) { // Capture errors mysql. diff --git a/pandora_console/include/lib/Modules/Users/Services/CreateUserService.php b/pandora_console/include/lib/Modules/Users/Services/CreateUserService.php index c3ab19affa..612fabf9cb 100644 --- a/pandora_console/include/lib/Modules/Users/Services/CreateUserService.php +++ b/pandora_console/include/lib/Modules/Users/Services/CreateUserService.php @@ -25,12 +25,15 @@ final class CreateUserService $user = $this->userRepository->create($user); + // TODO: Save pass. + \save_pass_history($user->getIdUser(), $user->getPasswordValidate()); + $this->audit->write( - 'User Management', - ' Create user #'.$user->getIdUser() + AUDIT_LOG_USER_MANAGEMENT, + ' Create user '.$user->getIdUser(), + json_encode($user->toArray()) ); - // TODO: Campos personalizados. return $user; } diff --git a/pandora_console/include/lib/Modules/Users/Services/UpdateUserService.php b/pandora_console/include/lib/Modules/Users/Services/UpdateUserService.php index 8fb10025db..a4878aca8e 100644 --- a/pandora_console/include/lib/Modules/Users/Services/UpdateUserService.php +++ b/pandora_console/include/lib/Modules/Users/Services/UpdateUserService.php @@ -25,9 +25,15 @@ final class UpdateUserService $user = $this->userRepository->update($user); + // TODO: Save pass. + if (empty($user->getPasswordValidate()) === false) { + \save_pass_history($user->getIdUser(), $user->getPasswordValidate()); + } + $this->audit->write( 'User Management', - ' Update user #'.$user->getIdUser() + ' Update user '.$user->getIdUser(), + json_encode($user->toArray()) ); return $user; diff --git a/pandora_console/include/lib/Modules/Users/Services/ValidatePasswordUserService.php b/pandora_console/include/lib/Modules/Users/Services/ValidatePasswordUserService.php new file mode 100644 index 0000000000..dd4f4a2896 --- /dev/null +++ b/pandora_console/include/lib/Modules/Users/Services/ValidatePasswordUserService.php @@ -0,0 +1,114 @@ +checkExcludePassword($user->getPassword()); + if ($excludePassword === true) { + throw new BadRequestException( + __('The password provided is not valid. Please set another one.') + ); + } + + // Si es una actualizacion, revisas el o los antiguos paswords, + // que no se pueda repetir. + if ($oldUser !== null) { + $newPass = password_hash($user->getPassword(), PASSWORD_BCRYPT); + if ((bool) $this->config->get('enable_pass_history') === true) { + $oldPasswords = $this->getOldPasswords($user->getIdUser()); + foreach ($oldPasswords as $oldPass) { + if ($oldPass['password'] === $newPass) { + throw new BadRequestException( + __( + 'Password must be different from the %s previous changes', + $this->config->get('compare_pass') + ) + ); + } + } + } else { + if ($oldUser->getPassword() === $newPass) { + throw new BadRequestException(__('Password must be different')); + } + } + } + + // TamaƱo del Password. + if ((strlen($user->getPassword())) < $this->config->get('pass_size')) { + throw new BadRequestException(__('Password too short')); + } + + // Numeros includos. + if ($this->config->get('pass_needs_numbers') + && preg_match('/([[:alpha:]])*(\d)+(\w)*/', $user->getPassword()) == 0 + ) { + throw new BadRequestException(__('Password must contain numbers')); + } + + // Simbolos incluidos. + if ($this->config->get('pass_needs_symbols') + && preg_match('/(\w)*(\W)+(\w)*/', $user->getPassword()) == 0 + ) { + throw new BadRequestException(__('Password must contain symbols')); + } + } + + + private function checkExcludePassword(string $newPassword): bool + { + if ((bool) $this->config->get('enable_pass_policy') === true + && empty($this->config->get('exclusion_word_list')) === false + ) { + $wordList = explode(',', $this->config->get('exclusion_word_list')); + if (is_array($wordList) === true) { + foreach ($wordList as $word) { + if ($newPassword === trim(io_safe_output($word))) { + return true; + } + } + } + } + + return false; + } + + + private function getOldPasswords(string $idUser): array + { + // TODO: create new service for this. + $sql = sprintf( + 'SELECT `password` + FROM tpassword_history + WHERE id_user="%s" + ORDER BY date_begin + DESC LIMIT %d', + $idUser, + $this->config->get('compare_pass') + ); + + $oldPasswords = db_get_all_rows_sql($sql); + if ((bool) $oldPasswords === false) { + $oldPasswords = []; + } + + return $oldPasswords; + } + + +} diff --git a/pandora_console/include/lib/Modules/Users/Validations/UserValidation.php b/pandora_console/include/lib/Modules/Users/Validations/UserValidation.php index cc5950e8a7..c3da7bd851 100644 --- a/pandora_console/include/lib/Modules/Users/Validations/UserValidation.php +++ b/pandora_console/include/lib/Modules/Users/Validations/UserValidation.php @@ -12,6 +12,9 @@ use PandoraFMS\Modules\Users\Enums\UserHomeScreenEnum; use PandoraFMS\Modules\Users\Services\CheckOldPasswordUserService; use PandoraFMS\Modules\Users\Services\GetUserService; +use Models\VisualConsole\Container as VisualConsole; +use PandoraFMS\Modules\Users\Services\ValidatePasswordUserService; + final class UserValidation { @@ -21,6 +24,7 @@ final class UserValidation private Timestamp $timestamp, private GetUserService $getUserService, private CheckOldPasswordUserService $checkOldPasswordUserService, + private ValidatePasswordUserService $validatePasswordUserService ) { } @@ -55,6 +59,18 @@ final class UserValidation $user->setApiToken($this->generateApiToken()); } + if ($user->getFirstName() === null) { + $user->setFirstName(''); + } + + if ($user->getLastName() === null) { + $user->setLastName(''); + } + + if ($user->getMiddleName() === null) { + $user->setMiddleName(''); + } + if ($user->getIdSkin() === null) { $user->setIdSkin(0); } @@ -107,10 +123,22 @@ final class UserValidation $user->setDisabled(false); } + if ($user->getSection() === null) { + $user->setSection(UserHomeScreenEnum::DEFAULT); + } + + if ($user->getDataSection() === null) { + $user->setDataSection(''); + } + if ($user->getMetaconsoleSection() === null) { $user->setMetaconsoleSection(UserHomeScreenEnum::DEFAULT); } + if ($user->getMetaconsoleDataSection() === null) { + $user->setMetaconsoleDataSection(''); + } + if ($user->getForceChangePass() === null) { $user->setForceChangePass(false); } @@ -145,12 +173,7 @@ final class UserValidation } if (\enterprise_installed() === true) { - $excludePassword = $this->checkExcludePassword($user->getPassword()); - if ($excludePassword === true) { - throw new BadRequestException( - __('The password provided is not valid. Please set another one.') - ); - } + $this->validatePasswordUserService->__invoke($user, $oldUser); } // Only administrator users will not have to confirm the old password. @@ -162,9 +185,6 @@ final class UserValidation $this->checkOldPasswordUserService->__invoke($user); } - // TODO: check validate pass. - // if ((!is_user_admin($config['id_user']) || $config['enable_pass_policy_admin']) && $config['enable_pass_policy']) { - // login_validate_pass $user->setPassword(password_hash($user->getPassword(), PASSWORD_BCRYPT)); if ($oldUser !== null) { $user->setLastPassChange($this->getCurrentTimestamp()); @@ -186,6 +206,58 @@ final class UserValidation if (empty($user->getDefaultCustomView()) === false) { $this->validateCustomView($user->getDefaultCustomView()); } + + if ($user->getSection() === UserHomeScreenEnum::DEFAULT + || $user->getSection() === UserHomeScreenEnum::EVENT_LIST + || $user->getSection() === UserHomeScreenEnum::TACTICAL_VIEW + || $user->getSection() === UserHomeScreenEnum::ALERT_DETAIL + || $user->getSection() === UserHomeScreenEnum::GROUP_VIEW + ) { + $user->setDataSection(''); + } else { + if (empty($user->getDataSection()) === true) { + throw new BadRequestException( + __( + 'Section data of type %s, cannot be empty', + $user->getSection()->name + ) + ); + } + + if ($user->getSection() === UserHomeScreenEnum::VISUAL_CONSOLE) { + $this->validateVisualConsole((int) $user->getDataSection()); + } + + if ($user->getSection() === UserHomeScreenEnum::DASHBOARD) { + $this->validateDashboard($this->config->get('id_user'), $user->getDataSection()); + } + } + + if ($user->getMetaconsoleSection() === UserHomeScreenEnum::DEFAULT + || $user->getMetaconsoleSection() === UserHomeScreenEnum::EVENT_LIST + || $user->getMetaconsoleSection() === UserHomeScreenEnum::TACTICAL_VIEW + || $user->getMetaconsoleSection() === UserHomeScreenEnum::ALERT_DETAIL + || $user->getMetaconsoleSection() === UserHomeScreenEnum::GROUP_VIEW + ) { + $user->setMetaconsoleDataSection(''); + } else { + if (empty($user->getMetaconsoleDataSection()) === true) { + throw new BadRequestException( + __( + 'Metaconsole section data of type %s, cannot be empty', + $user->getMetaconsoleSection()->name + ) + ); + } + + if ($user->getMetaconsoleSection() === UserHomeScreenEnum::VISUAL_CONSOLE) { + $this->validateVisualConsole((int) $user->getMetaconsoleDataSection()); + } + + if ($user->getMetaconsoleSection() === UserHomeScreenEnum::DASHBOARD) { + $this->validateDashboard($this->config->get('id_user'), $user->getMetaconsoleDataSection()); + } + } } @@ -238,14 +310,6 @@ final class UserValidation } - private function checkExcludePassword(string $newPassword): bool - { - // TODO: create new service for this. - $return = \enterprise_hook('excludedPassword', [$newPassword]); - return $return; - } - - private function isAdmin(string $idUser): bool { // TODO: create new service for this. @@ -280,4 +344,24 @@ final class UserValidation } + protected function validateDashboard(string $idUser, int $idDashboard): void + { + // TODO: create new service for this. + if (! (bool) \get_user_dashboards($idUser, $idDashboard)) { + throw new BadRequestException(__('Invalid id Dashboard')); + } + } + + + protected function validateVisualConsole(int $visualConsoleId): void + { + // TODO: create new service for this. + try { + VisualConsole::fromDB(['id' => $visualConsoleId]); + } catch (\Throwable $e) { + throw new BadRequestException(__('Invalid visual console id')); + } + } + + }