File manager - Edit - /home/ferretapmx/public_html/Model.tar
Back
RemindModel.php 0000644 00000012156 15231071701 0007456 0 ustar 00 <?php /** * @package Joomla.Site * @subpackage com_privacy * * @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Privacy\Site\Model; use Joomla\CMS\Factory; use Joomla\CMS\Form\Form; use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\Model\AdminModel; use Joomla\CMS\String\PunycodeHelper; use Joomla\CMS\Table\Table; use Joomla\CMS\User\UserHelper; use Joomla\Database\Exception\ExecutionFailureException; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Remind confirmation model class. * * @since 3.9.0 */ class RemindModel extends AdminModel { /** * Confirms the remind request. * * @param array $data The data expected for the form. * * @return mixed \Exception | JException | boolean * * @since 3.9.0 */ public function remindRequest($data) { // Get the form. $form = $this->getForm(); $data['email'] = PunycodeHelper::emailToPunycode($data['email']); // Check for an error. if ($form instanceof \Exception) { return $form; } // Filter and validate the form data. $data = $form->filter($data); $return = $form->validate($data); // Check for an error. if ($return instanceof \Exception) { return $return; } // Check the validation results. if ($return === false) { // Get the validation messages from the form. foreach ($form->getErrors() as $formError) { $this->setError($formError->getMessage()); } return false; } $db = $this->getDatabase(); $query = $db->getQuery(true) ->select($db->quoteName(['r.id', 'r.user_id', 'r.token'])); $query->from($db->quoteName('#__privacy_consents', 'r')); $query->join( 'LEFT', $db->quoteName('#__users', 'u'), $db->quoteName('u.id') . ' = ' . $db->quoteName('r.user_id') ); $query->where($db->quoteName('u.email') . ' = :email') ->bind(':email', $data['email']); $query->where($db->quoteName('r.remind') . ' = 1'); $db->setQuery($query); try { $remind = $db->loadObject(); } catch (ExecutionFailureException) { $this->setError(Text::_('COM_PRIVACY_ERROR_NO_PENDING_REMIND')); return false; } if (!$remind) { $this->setError(Text::_('COM_PRIVACY_ERROR_NO_PENDING_REMIND')); return false; } // Verify the token if (!UserHelper::verifyPassword($data['remind_token'], $remind->token)) { $this->setError(Text::_('COM_PRIVACY_ERROR_NO_REMIND_REQUESTS')); return false; } // Everything is good to go, transition the request to extended $saved = $this->save( [ 'id' => $remind->id, 'remind' => 0, 'token' => '', 'created' => Factory::getDate()->toSql(), ] ); if (!$saved) { // Error was set by the save method return false; } return true; } /** * Method for getting the form from the model. * * @param array $data Data for the form. * @param boolean $loadData True if the form is to load its own data (default case), false if not. * * @return Form|boolean A Form object on success, false on failure * * @since 3.9.0 */ public function getForm($data = [], $loadData = true) { // Get the form. $form = $this->loadForm('com_privacy.remind', 'remind', ['control' => 'jform']); if (empty($form)) { return false; } $input = Factory::getApplication()->getInput(); if ($input->getMethod() === 'GET') { $form->setValue('remind_token', '', $input->get->getAlnum('remind_token')); } return $form; } /** * Method to get a table object, load it if necessary. * * @param string $name The table name. Optional. * @param string $prefix The class prefix. Optional. * @param array $options Configuration array for model. Optional. * * @return Table A Table object * * @throws \Exception * @since 3.9.0 */ public function getTable($name = 'Consent', $prefix = 'Administrator', $options = []) { return parent::getTable($name, $prefix, $options); } /** * Method to auto-populate the model state. * * Note. Calling getState in this method will result in recursion. * * @return void * * @since 3.9.0 */ protected function populateState() { // Get the application object. $params = Factory::getApplication()->getParams('com_privacy'); // Load the parameters. $this->setState('params', $params); } } LoginModel.php 0000644 00000010172 15231071701 0007304 0 ustar 00 <?php /** * @package Joomla.Site * @subpackage com_users * * @copyright (C) 2010 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Users\Site\Model; use Joomla\CMS\Factory; use Joomla\CMS\Form\Form; use Joomla\CMS\Language\Multilanguage; use Joomla\CMS\MVC\Model\FormModel; use Joomla\CMS\Uri\Uri; use Joomla\Database\ParameterType; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Login model class for Users. * * @since 1.6 */ class LoginModel extends FormModel { /** * Method to get the login form. * * The base form is loaded from XML and then an event is fired * for users plugins to extend the form with extra fields. * * @param array $data An optional array of data for the form to interrogate. * @param boolean $loadData True if the form is to load its own data (default case), false if not. * * @return Form A Form object on success, false on failure * * @since 1.6 */ public function getForm($data = [], $loadData = true) { // Get the form. $form = $this->loadForm('com_users.login', 'login', ['load_data' => $loadData]); if (empty($form)) { return false; } return $form; } /** * Method to get the data that should be injected in the form. * * @return array The default data is an empty array. * * @since 1.6 * @throws \Exception */ protected function loadFormData() { // Check the session for previously entered login form data. $app = Factory::getApplication(); $data = $app->getUserState('users.login.form.data', []); $input = $app->getInput()->getInputForRequestMethod(); // Check for return URL from the request first if ($return = $input->get('return', '', 'BASE64')) { $data['return'] = base64_decode($return); if (!Uri::isInternal($data['return'])) { $data['return'] = ''; } } $app->setUserState('users.login.form.data', $data); $this->preprocessData('com_users.login', $data); return $data; } /** * Method to auto-populate the model state. * * Calling getState in this method will result in recursion. * * @return void * * @since 1.6 * @throws \Exception */ protected function populateState() { // Get the application object. $params = Factory::getApplication()->getParams('com_users'); // Load the parameters. $this->setState('params', $params); } /** * Override Joomla\CMS\MVC\Model\AdminModel::preprocessForm to ensure the correct plugin group is loaded. * * @param Form $form A Form object. * @param mixed $data The data expected for the form. * @param string $group The name of the plugin group to import (defaults to "content"). * * @return void * * @since 1.6 * @throws \Exception if there is an error in the form event. */ protected function preprocessForm(Form $form, $data, $group = 'user') { parent::preprocessForm($form, $data, $group); } /** * Returns the language for the given menu id. * * @param int $id The menu id * * @return string * * @since 4.2.0 */ public function getMenuLanguage(int $id): string { if (!Multilanguage::isEnabled()) { return ''; } $db = $this->getDatabase(); $query = $db->getQuery(true) ->select($db->quoteName('language')) ->from($db->quoteName('#__menu')) ->where($db->quoteName('client_id') . ' = 0') ->where($db->quoteName('id') . ' = :id') ->bind(':id', $id, ParameterType::INTEGER); $db->setQuery($query); try { return $db->loadResult(); } catch (\RuntimeException) { return ''; } } } CaptiveModel.php 0000644 00000001040 15231071701 0007621 0 ustar 00 <?php /** * @package Joomla.Site * @subpackage com_users * * @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Users\Site\Model; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Captive Multi-factor Authentication page's model * * @since 4.2.0 */ class CaptiveModel extends \Joomla\Component\Users\Administrator\Model\CaptiveModel { } MethodModel.php 0000644 00000001041 15231071701 0007447 0 ustar 00 <?php /** * @package Joomla.Site * @subpackage com_users * * @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Users\Site\Model; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Multi-factor Authentication Method management model * * @since 4.2.0 */ class MethodModel extends \Joomla\Component\Users\Administrator\Model\MethodModel { } ProfileModel.php 0000644 00000024230 15231071701 0007634 0 ustar 00 <?php /** * @package Joomla.Site * @subpackage com_users * * @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Users\Site\Model; use Joomla\CMS\Access\Access; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Factory; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormFactoryInterface; use Joomla\CMS\Language\Multilanguage; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\CMS\MVC\Model\FormModel; use Joomla\CMS\Plugin\PluginHelper; use Joomla\CMS\String\PunycodeHelper; use Joomla\CMS\User\User; use Joomla\CMS\User\UserHelper; use Joomla\Component\Users\Administrator\Model\UserModel; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Profile model class for Users. * * @since 1.6 */ class ProfileModel extends FormModel { /** * @var object The user profile data. * @since 1.6 */ protected $data; /** * Constructor. * * @param array $config An array of configuration options (name, state, dbo, table_path, ignore_request). * @param ?MVCFactoryInterface $factory The factory. * @param ?FormFactoryInterface $formFactory The form factory. * * @see \Joomla\CMS\MVC\Model\BaseDatabaseModel * @since 3.2 */ public function __construct($config = [], ?MVCFactoryInterface $factory = null, ?FormFactoryInterface $formFactory = null) { $config = array_merge( [ 'events_map' => ['validate' => 'user'], ], $config ); parent::__construct($config, $factory, $formFactory); } /** * Method to get the profile form data. * * The base form data is loaded and then an event is fired * for users plugins to extend the data. * * @return User * * @since 1.6 * @throws \Exception */ public function getData() { if ($this->data === null) { $userId = $this->getState('user.id'); // Initialise the table with Joomla\CMS\User\User. $this->data = new User($userId); // Set the base user data. $this->data->email1 = $this->data->email; // Override the base user data with any data in the session. $temp = (array) Factory::getApplication()->getUserState('com_users.edit.profile.data', []); foreach ($temp as $k => $v) { $this->data->$k = $v; } // Unset the passwords. unset($this->data->password1, $this->data->password2); $registry = new Registry($this->data->params); $this->data->params = $registry->toArray(); } return $this->data; } /** * Method to get the profile form. * * The base form is loaded from XML and then an event is fired * for users plugins to extend the form with extra fields. * * @param array $data An optional array of data for the form to interrogate. * @param boolean $loadData True if the form is to load its own data (default case), false if not. * * @return Form|bool A Form object on success, false on failure * * @since 1.6 */ public function getForm($data = [], $loadData = true) { // Get the form. $form = $this->loadForm('com_users.profile', 'profile', ['control' => 'jform', 'load_data' => $loadData]); if (empty($form)) { return false; } // Check for username compliance and parameter set $isUsernameCompliant = true; $username = $loadData ? $form->getValue('username') : $this->loadFormData()->username; if ($username) { $isUsernameCompliant = !(preg_match('#[<>"\'%;()&\\\\]|\\.\\./#', $username) || \strlen(mb_convert_encoding($username, 'ISO-8859-1', 'UTF-8')) < 2 || trim($username) !== $username); } $this->setState('user.username.compliant', $isUsernameCompliant); if ($isUsernameCompliant && !ComponentHelper::getParams('com_users')->get('change_login_name')) { $form->setFieldAttribute('username', 'class', ''); $form->setFieldAttribute('username', 'filter', ''); $form->setFieldAttribute('username', 'description', 'COM_USERS_PROFILE_NOCHANGE_USERNAME_DESC'); $form->setFieldAttribute('username', 'validate', ''); $form->setFieldAttribute('username', 'message', ''); $form->setFieldAttribute('username', 'readonly', 'true'); $form->setFieldAttribute('username', 'required', 'false'); } // When multilanguage is set, a user's default site language should also be a Content Language if (Multilanguage::isEnabled()) { $form->setFieldAttribute('language', 'type', 'frontendlanguage', 'params'); } // If the user needs to change their password, mark the password fields as required if ($this->getCurrentUser()->requireReset) { $form->setFieldAttribute('password1', 'required', 'true'); $form->setFieldAttribute('password2', 'required', 'true'); } return $form; } /** * Method to get the data that should be injected in the form. * * @return mixed The data for the form. * * @since 1.6 */ protected function loadFormData() { $data = $this->getData(); $this->preprocessData('com_users.profile', $data, 'user'); return $data; } /** * Override preprocessForm to load the user plugin group instead of content. * * @param Form $form A Form object. * @param mixed $data The data expected for the form. * @param string $group The name of the plugin group to import (defaults to "content"). * * @return void * * @throws \Exception if there is an error in the form event. * * @since 1.6 */ protected function preprocessForm(Form $form, $data, $group = 'user') { if (ComponentHelper::getParams('com_users')->get('frontend_userparams')) { $form->loadFile('frontend', false); if ($this->getCurrentUser()->authorise('core.login.admin')) { $form->loadFile('frontend_admin', false); } } parent::preprocessForm($form, $data, $group); } /** * Method to auto-populate the model state. * * Note. Calling getState in this method will result in recursion. * * @return void * * @since 1.6 * @throws \Exception */ protected function populateState() { // Get the application object. $params = Factory::getApplication()->getParams('com_users'); // Get the user id. $userId = Factory::getApplication()->getUserState('com_users.edit.profile.id'); $userId = !empty($userId) ? $userId : (int) $this->getCurrentUser()->id; // Set the user id. $this->setState('user.id', $userId); // Load the parameters. $this->setState('params', $params); } /** * Method to save the form data. * * @param array $data The form data. * * @return mixed The user id on success, false on failure. * * @since 1.6 * @throws \Exception */ public function save($data) { $userId = (!empty($data['id'])) ? $data['id'] : (int) $this->getState('user.id'); $user = new User($userId); // Prepare the data for the user object. $data['email'] = PunycodeHelper::emailToPunycode($data['email1']); $data['password'] = $data['password1']; // Unset the username if it should not be overwritten $isUsernameCompliant = $this->getState('user.username.compliant'); if ($isUsernameCompliant && !ComponentHelper::getParams('com_users')->get('change_login_name')) { unset($data['username']); } // Unset block and sendEmail so they do not get overwritten unset($data['block'], $data['sendEmail']); // Bind the data. if (!$user->bind($data)) { $this->setError($user->getError()); return false; } // Load the users plugin group. PluginHelper::importPlugin('user'); // Retrieve the user groups so they don't get overwritten unset($user->groups); $user->groups = Access::getGroupsByUser($user->id, false); // Store the data. if (!$user->save()) { $this->setError($user->getError()); return false; } // Destroy all active sessions for the user after changing the password if ($data['password1']) { UserHelper::destroyUserSessions($user->id, true); } return $user->id; } /** * Gets the configuration forms for all two-factor authentication methods * in an array. * * @param integer $userId The user ID to load the forms for (optional) * * @return array * * @since 3.2 * * @deprecated 4.2 will be removed in 6.0. * Will be removed without replacement */ public function getTwofactorform($userId = null) { return []; } /** * No longer used * * @param integer $userId Ignored * * @return \stdClass * * @since 3.2 * * @deprecated 4.2 will be removed in 6.0. * Will be removed without replacement */ public function getOtpConfig($userId = null) { @trigger_error( \sprintf( '%s() is deprecated. Use \Joomla\Component\Users\Administrator\Helper\Mfa::getUserMfaRecords() instead.', __METHOD__ ), E_USER_DEPRECATED ); /** @var UserModel $model */ $model = $this->bootComponent('com_users') ->getMVCFactory()->createModel('User', 'Administrator'); return $model->getOtpConfig(); } } RegistrationModel.php 0000644 00000054761 15231071701 0010722 0 ustar 00 <?php /** * @package Joomla.Site * @subpackage com_users * * @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Users\Site\Model; use Joomla\CMS\Application\ApplicationHelper; use Joomla\CMS\Application\CMSApplicationInterface; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Date\Date; use Joomla\CMS\Factory; use Joomla\CMS\Form\Form; use Joomla\CMS\Form\FormFactoryInterface; use Joomla\CMS\Language\Multilanguage; use Joomla\CMS\Language\Text; use Joomla\CMS\Log\Log; use Joomla\CMS\Mail\MailTemplate; use Joomla\CMS\MVC\Factory\MVCFactoryInterface; use Joomla\CMS\MVC\Model\FormModel; use Joomla\CMS\Plugin\PluginHelper; use Joomla\CMS\Router\Route; use Joomla\CMS\String\PunycodeHelper; use Joomla\CMS\Uri\Uri; use Joomla\CMS\User\User; use Joomla\CMS\User\UserFactoryAwareInterface; use Joomla\CMS\User\UserFactoryAwareTrait; use Joomla\CMS\User\UserHelper; use Joomla\Database\ParameterType; use Joomla\Utilities\ArrayHelper; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Registration model class for Users. * * @since 1.6 */ class RegistrationModel extends FormModel implements UserFactoryAwareInterface { use UserFactoryAwareTrait; /** * @var object The user registration data. * @since 1.6 */ protected $data; /** * Constructor. * * @param array $config An array of configuration options (name, state, dbo, table_path, ignore_request). * @param ?MVCFactoryInterface $factory The factory. * @param ?FormFactoryInterface $formFactory The form factory. * * @see \Joomla\CMS\MVC\Model\BaseDatabaseModel * @since 3.2 */ public function __construct($config = [], ?MVCFactoryInterface $factory = null, ?FormFactoryInterface $formFactory = null) { $config = array_merge( [ 'events_map' => ['validate' => 'user'], ], $config ); parent::__construct($config, $factory, $formFactory); } /** * Method to get the user ID from the given token * * @param string $token The activation token. * * @return mixed False on failure, id of the user on success * * @since 3.8.13 */ public function getUserIdFromToken($token) { $db = $this->getDatabase(); // Get the user id based on the token. $query = $db->getQuery(true); $query->select($db->quoteName('id')) ->from($db->quoteName('#__users')) ->where($db->quoteName('activation') . ' = :activation') ->where($db->quoteName('block') . ' = 1') ->where($db->quoteName('lastvisitDate') . ' IS NULL') ->bind(':activation', $token); $db->setQuery($query); try { return (int) $db->loadResult(); } catch (\RuntimeException $e) { $this->setError(Text::sprintf('COM_USERS_DATABASE_ERROR', $e->getMessage())); return false; } } /** * Method to activate a user account. * * @param string $token The activation token. * * @return mixed False on failure, user object on success. * * @since 1.6 */ public function activate($token) { $app = Factory::getApplication(); $userParams = ComponentHelper::getParams('com_users'); $userId = $this->getUserIdFromToken($token); // Check for a valid user id. if (!$userId) { $this->setError(Text::_('COM_USERS_ACTIVATION_TOKEN_NOT_FOUND')); return false; } // Load the users plugin group. PluginHelper::importPlugin('user'); // Activate the user. $user = $this->getUserFactory()->loadUserById($userId); // Admin activation is on and user is verifying their email if (($userParams->get('useractivation') == 2) && !$user->getParam('activate', 0)) { $linkMode = $app->get('force_ssl', 0) == 2 ? Route::TLS_FORCE : Route::TLS_IGNORE; // Compile the admin notification mail values. $data = ArrayHelper::fromObject($user, false); $data['activation'] = ApplicationHelper::getHash(UserHelper::genRandomPassword()); $user->activation = $data['activation']; $data['siteurl'] = Uri::base(); $data['activate'] = Route::link( 'site', 'index.php?option=com_users&task=registration.activate&token=' . $data['activation'], false, $linkMode, true ); $data['fromname'] = $app->get('fromname'); $data['mailfrom'] = $app->get('mailfrom'); $data['sitename'] = $app->get('sitename'); $user->setParam('activate', 1); // Get all admin users $db = $this->getDatabase(); $query = $db->getQuery(true) ->select($db->quoteName(['name', 'email', 'sendEmail', 'id'])) ->from($db->quoteName('#__users')) ->where($db->quoteName('sendEmail') . ' = 1') ->where($db->quoteName('block') . ' = 0'); $db->setQuery($query); try { $rows = $db->loadObjectList(); } catch (\RuntimeException $e) { $this->setError(Text::sprintf('COM_USERS_DATABASE_ERROR', $e->getMessage())); return false; } // Send mail to all users with users creating permissions and receiving system emails foreach ($rows as $row) { $usercreator = $this->getUserFactory()->loadUserById($row->id); if ($usercreator->authorise('core.create', 'com_users') && $usercreator->authorise('core.manage', 'com_users')) { try { $mailer = new MailTemplate('com_users.registration.admin.verification_request', $app->getLanguage()->getTag()); $mailer->addTemplateData($data); $mailer->addRecipient($row->email); $return = $mailer->send(); } catch (\Exception $exception) { try { Log::add(Text::_($exception->getMessage()), Log::WARNING, 'jerror'); $return = false; } catch (\RuntimeException $exception) { Factory::getApplication()->enqueueMessage(Text::_($exception->getMessage()), 'warning'); $return = false; } } // Check for an error. if ($return !== true) { $this->setError(Text::_('COM_USERS_REGISTRATION_ACTIVATION_NOTIFY_SEND_MAIL_FAILED')); return false; } } } } elseif (($userParams->get('useractivation') == 2) && $user->getParam('activate', 0)) { // Admin activation is on and admin is activating the account $user->activation = ''; $user->block = '0'; // Compile the user activated notification mail values. $data = ArrayHelper::fromObject($user, false); $user->setParam('activate', 0); $data['fromname'] = $app->get('fromname'); $data['mailfrom'] = $app->get('mailfrom'); $data['sitename'] = $app->get('sitename'); $data['siteurl'] = Uri::base(); $mailer = new MailTemplate('com_users.registration.user.admin_activated', $app->getLanguage()->getTag()); $mailer->addTemplateData($data); $mailer->addRecipient($data['email']); try { $return = $mailer->send(); } catch (\Exception $exception) { try { Log::add(Text::_($exception->getMessage()), Log::WARNING, 'jerror'); $return = false; } catch (\RuntimeException $exception) { Factory::getApplication()->enqueueMessage(Text::_($exception->getMessage()), 'warning'); $return = false; } } // Check for an error. if ($return !== true) { $this->setError(Text::_('COM_USERS_REGISTRATION_ACTIVATION_NOTIFY_SEND_MAIL_FAILED')); return false; } } else { $user->activation = ''; $user->block = '0'; } // Store the user object. if (!$user->save()) { $this->setError(Text::sprintf('COM_USERS_REGISTRATION_ACTIVATION_SAVE_FAILED', $user->getError())); return false; } return $user; } /** * Method to get the registration form data. * * The base form data is loaded and then an event is fired * for users plugins to extend the data. * * @return mixed Data object on success, false on failure. * * @since 1.6 * @throws \Exception */ public function getData() { if ($this->data === null) { $this->data = new \stdClass(); $app = Factory::getApplication(); $params = ComponentHelper::getParams('com_users'); // Override the base user data with any data in the session. $temp = (array) $app->getUserState('com_users.registration.data', []); // Don't load the data in this getForm call, or we'll call ourself $form = $this->getForm([], false); foreach ($temp as $k => $v) { // Here we could have a grouped field, let's check it if (\is_array($v)) { $this->data->$k = new \stdClass(); foreach ($v as $key => $val) { if ($form->getField($key, $k) !== false) { $this->data->$k->$key = $val; } } } elseif ($form->getField($k) !== false) { // Only merge the field if it exists in the form. $this->data->$k = $v; } } // Get the groups the user should be added to after registration. $this->data->groups = []; // Get the default new user group, guest or public group if not specified. $system = $params->get('new_usertype', $params->get('guest_usergroup', 1)); $this->data->groups[] = $system; // Unset the passwords. unset($this->data->password1, $this->data->password2); // Get the dispatcher and load the users plugins. PluginHelper::importPlugin('user'); // Trigger the data preparation event. Factory::getApplication()->triggerEvent('onContentPrepareData', ['com_users.registration', $this->data]); } return $this->data; } /** * Method to get the registration form. * * The base form is loaded from XML and then an event is fired * for users plugins to extend the form with extra fields. * * @param array $data An optional array of data for the form to interrogate. * @param boolean $loadData True if the form is to load its own data (default case), false if not. * * @return Form A Form object on success, false on failure * * @since 1.6 */ public function getForm($data = [], $loadData = true) { // Get the form. $form = $this->loadForm('com_users.registration', 'registration', ['control' => 'jform', 'load_data' => $loadData]); if (empty($form)) { return false; } // When multilanguage is set, a user's default site language should also be a Content Language if (Multilanguage::isEnabled()) { $form->setFieldAttribute('language', 'type', 'frontendlanguage', 'params'); } return $form; } /** * Method to get the data that should be injected in the form. * * @return mixed The data for the form. * * @since 1.6 */ protected function loadFormData() { $data = $this->getData(); if (Multilanguage::isEnabled() && empty($data->language)) { $data->language = Factory::getLanguage()->getTag(); } $this->preprocessData('com_users.registration', $data); return $data; } /** * Override preprocessForm to load the user plugin group instead of content. * * @param Form $form A Form object. * @param mixed $data The data expected for the form. * @param string $group The name of the plugin group to import (defaults to "content"). * * @return void * * @since 1.6 * @throws \Exception if there is an error in the form event. */ protected function preprocessForm(Form $form, $data, $group = 'user') { $userParams = ComponentHelper::getParams('com_users'); // Add the choice for site language at registration time if ($userParams->get('site_language') == 1 && $userParams->get('frontend_userparams') == 1) { $form->loadFile('sitelang', false); } parent::preprocessForm($form, $data, $group); } /** * Method to auto-populate the model state. * * Note. Calling getState in this method will result in recursion. * * @return void * * @since 1.6 * @throws \Exception */ protected function populateState() { // Get the application object. $app = Factory::getApplication(); $params = $app->getParams('com_users'); // Load the parameters. $this->setState('params', $params); } /** * Method to save the form data. * * @param array $temp The form data. * * @return mixed The user id on success, false on failure. * * @since 1.6 * @throws \Exception */ public function register($temp) { $params = ComponentHelper::getParams('com_users'); // Initialise the table with Joomla\CMS\User\User. $user = new User(); $data = (array) $this->getData(); // Merge in the registration data. foreach ($temp as $k => $v) { $data[$k] = $v; } // Prepare the data for the user object. $data['email'] = PunycodeHelper::emailToPunycode($data['email1']); $data['password'] = $data['password1']; $useractivation = $params->get('useractivation'); $sendpassword = $params->get('sendpassword', 1); // Check if the user needs to activate their account. if (($useractivation == 1) || ($useractivation == 2)) { $data['activation'] = ApplicationHelper::getHash(UserHelper::genRandomPassword()); $data['block'] = 1; } // Bind the data. if (!$user->bind($data)) { $this->setError($user->getError()); return false; } // Load the users plugin group. PluginHelper::importPlugin('user'); // Store the data. if (!$user->save()) { $this->setError(Text::sprintf('COM_USERS_REGISTRATION_SAVE_FAILED', $user->getError())); return false; } // From this moment the user is registered, so we don't return false anymore $app = Factory::getApplication(); $db = $this->getDatabase(); $query = $db->getQuery(true); // Compile the notification mail values. $data = ArrayHelper::fromObject($user, false); $data['fromname'] = $app->get('fromname'); $data['mailfrom'] = $app->get('mailfrom'); $data['sitename'] = $app->get('sitename'); $data['siteurl'] = Uri::root(); // Handle account activation/confirmation emails. if ($useractivation == 2) { // Set the link to confirm the user email. $linkMode = $app->get('force_ssl', 0) == 2 ? Route::TLS_FORCE : Route::TLS_IGNORE; $data['activate'] = Route::link( 'site', 'index.php?option=com_users&task=registration.activate&token=' . $data['activation'], false, $linkMode, true ); $mailtemplate = 'com_users.registration.user.admin_activation'; } elseif ($useractivation == 1) { // Set the link to activate the user account. $linkMode = $app->get('force_ssl', 0) == 2 ? Route::TLS_FORCE : Route::TLS_IGNORE; $data['activate'] = Route::link( 'site', 'index.php?option=com_users&task=registration.activate&token=' . $data['activation'], false, $linkMode, true ); $mailtemplate = 'com_users.registration.user.self_activation'; } else { $mailtemplate = 'com_users.registration.user.registration_mail'; } if ($sendpassword) { $mailtemplate .= '_w_pw'; } // Try to send the registration email. try { $mailer = new MailTemplate($mailtemplate, $app->getLanguage()->getTag()); $mailer->addTemplateData($data); $mailer->addRecipient($data['email']); $mailer->addUnsafeTags(['username', 'password_clear', 'name']); $return = $mailer->send(); } catch (\Exception $exception) { $return = false; try { Log::add(Text::_($exception->getMessage()), Log::WARNING, 'joomla_registration'); } catch (\RuntimeException $exception) { // We set the error message below but we don't need to notify the user that we can't add logs } } // Send mail to all users with user creating permissions and receiving system emails if (($params->get('useractivation') < 2) && ($params->get('mail_to_admin') == 1)) { // Get all admin users $query->clear() ->select($db->quoteName(['name', 'email', 'sendEmail', 'id'])) ->from($db->quoteName('#__users')) ->where($db->quoteName('sendEmail') . ' = 1') ->where($db->quoteName('block') . ' = 0'); $db->setQuery($query); try { $rows = $db->loadObjectList(); } catch (\RuntimeException $e) { $rows = []; } // Send mail to all superadministrators id foreach ($rows as $row) { $usercreator = $this->getUserFactory()->loadUserById($row->id); if (!$usercreator->authorise('core.create', 'com_users') || !$usercreator->authorise('core.manage', 'com_users')) { continue; } try { $mailer = new MailTemplate('com_users.registration.admin.new_notification', $app->getLanguage()->getTag()); $mailer->addTemplateData($data); $mailer->addRecipient($row->email); $mailer->addUnsafeTags(['username', 'name']); $mailer->send(); } catch (\Exception $exception) { try { Log::add(Text::_($exception->getMessage()), Log::WARNING, 'joomla_registration'); } catch (\RuntimeException $exception) { // No message to frontend user } } } } // Check for an error. if ($return !== true) { $app->enqueueMessage(Text::_('COM_USERS_REGISTRATION_SEND_MAIL_FAILED'), CMSApplicationInterface::MSG_WARNING); // Send a system message to administrators receiving system mails $db = $this->getDatabase(); $query->clear() ->select($db->quoteName('id')) ->from($db->quoteName('#__users')) ->where($db->quoteName('block') . ' = 0') ->where($db->quoteName('sendEmail') . ' = 1'); $db->setQuery($query); try { $userids = $db->loadColumn(); } catch (\RuntimeException $e) { $userids = []; try { Log::add(Text::sprintf('COM_USERS_DATABASE_ERROR', $e->getMessage()), Log::WARNING, 'joomla_registration'); } catch (\RuntimeException $exception) { } } if (\count($userids) > 0) { $jdate = new Date(); $dateToSql = $jdate->toSql(); $subject = Text::_('COM_USERS_MAIL_SEND_FAILURE_SUBJECT'); $message = Text::sprintf('COM_USERS_MAIL_SEND_FAILURE_BODY', $data['username']); // Build the query to add the messages foreach ($userids as $userid) { $values = [ ':user_id_from', ':user_id_to', ':date_time', ':subject', ':message', ]; $query->clear() ->insert($db->quoteName('#__messages')) ->columns($db->quoteName(['user_id_from', 'user_id_to', 'date_time', 'subject', 'message'])) ->values(implode(',', $values)); $query->bind(':user_id_from', $userid, ParameterType::INTEGER) ->bind(':user_id_to', $userid, ParameterType::INTEGER) ->bind(':date_time', $dateToSql) ->bind(':subject', $subject) ->bind(':message', $message); $db->setQuery($query); try { $db->execute(); } catch (\RuntimeException $e) { try { Log::add(Text::sprintf('COM_USERS_DATABASE_ERROR', $e->getMessage()), Log::WARNING, 'joomla_registration'); } catch (\RuntimeException $exception) { } } } } } if ($useractivation == 1) { return 'useractivate'; } if ($useractivation == 2) { return 'adminactivate'; } return $user->id; } } ResetModel.php 0000644 00000040532 15231071701 0007321 0 ustar 00 <?php /** * @package Joomla.Site * @subpackage com_users * * @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Users\Site\Model; use Joomla\CMS\Application\ApplicationHelper; use Joomla\CMS\Event\AbstractEvent; use Joomla\CMS\Factory; use Joomla\CMS\Form\Form; use Joomla\CMS\Language\Text; use Joomla\CMS\Log\Log; use Joomla\CMS\Mail\MailTemplate; use Joomla\CMS\MVC\Model\FormModel; use Joomla\CMS\Router\Route; use Joomla\CMS\String\PunycodeHelper; use Joomla\CMS\User\User; use Joomla\CMS\User\UserFactoryAwareInterface; use Joomla\CMS\User\UserFactoryAwareTrait; use Joomla\CMS\User\UserHelper; use Joomla\Utilities\ArrayHelper; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Reset model class for Users. * * @since 1.5 */ class ResetModel extends FormModel implements UserFactoryAwareInterface { use UserFactoryAwareTrait; /** * Method to get the password reset request form. * * The base form is loaded from XML and then an event is fired * for users plugins to extend the form with extra fields. * * @param array $data An optional array of data for the form to interrogate. * @param boolean $loadData True if the form is to load its own data (default case), false if not. * * @return Form A Form object on success, false on failure * * @since 1.6 */ public function getForm($data = [], $loadData = true) { // Get the form. $form = $this->loadForm('com_users.reset_request', 'reset_request', ['control' => 'jform', 'load_data' => $loadData]); if (empty($form)) { return false; } return $form; } /** * Method to get the password reset complete form. * * @param array $data Data for the form. * @param boolean $loadData True if the form is to load its own data (default case), false if not. * * @return Form A Form object on success, false on failure * * @since 1.6 */ public function getResetCompleteForm($data = [], $loadData = true) { // Get the form. $form = $this->loadForm('com_users.reset_complete', 'reset_complete', ['control' => 'jform']); if (empty($form)) { return false; } return $form; } /** * Method to get the password reset confirm form. * * @param array $data Data for the form. * @param boolean $loadData True if the form is to load its own data (default case), false if not. * * @return Form A Form object on success, false on failure * * @since 1.6 * @throws \Exception */ public function getResetConfirmForm($data = [], $loadData = true) { // Get the form. $form = $this->loadForm('com_users.reset_confirm', 'reset_confirm', ['control' => 'jform']); if (empty($form)) { return false; } $form->setValue('token', '', Factory::getApplication()->getInput()->get('token')); return $form; } /** * Override preprocessForm to load the user plugin group instead of content. * * @param Form $form A Form object. * @param mixed $data The data expected for the form. * @param string $group The name of the plugin group to import (defaults to "content"). * * @return void * * @throws \Exception if there is an error in the form event. * * @since 1.6 */ protected function preprocessForm(Form $form, $data, $group = 'user') { parent::preprocessForm($form, $data, $group); } /** * Method to auto-populate the model state. * * Note. Calling getState in this method will result in recursion. * * @return void * * @since 1.6 * @throws \Exception */ protected function populateState() { // Get the application object. $params = Factory::getApplication()->getParams('com_users'); // Load the parameters. $this->setState('params', $params); } /** * Save the new password after reset is done * * @param array $data The data expected for the form. * * @return mixed \Exception | boolean * * @since 1.6 * @throws \Exception */ public function processResetComplete($data) { // Get the form. $form = $this->getResetCompleteForm(); // Check for an error. if ($form instanceof \Exception) { return $form; } // Filter and validate the form data. $data = $form->filter($data); $return = $form->validate($data); // Check for an error. if ($return instanceof \Exception) { return $return; } // Check the validation results. if ($return === false) { // Get the validation messages from the form. foreach ($form->getErrors() as $formError) { $this->setError($formError->getMessage()); } return false; } // Get the token and user id from the confirmation process. $app = Factory::getApplication(); $token = $app->getUserState('com_users.reset.token', null); $userId = $app->getUserState('com_users.reset.user', null); // Check the token and user id. if (empty($token) || empty($userId)) { return new \Exception(Text::_('COM_USERS_RESET_COMPLETE_TOKENS_MISSING'), 403); } // Get the user object. $user = $this->getUserFactory()->loadUserById($userId); $event = AbstractEvent::create( 'onUserBeforeResetComplete', [ 'subject' => $user, ] ); $app->getDispatcher()->dispatch($event->getName(), $event); // Check for a user and that the tokens match. if (empty($user) || $user->activation !== $token) { $this->setError(Text::_('COM_USERS_USER_NOT_FOUND')); return false; } // Make sure the user isn't blocked. if ($user->block) { $this->setError(Text::_('COM_USERS_USER_BLOCKED')); return false; } // Check if the user is reusing the current password if required to reset their password if ($user->requireReset == 1 && UserHelper::verifyPassword($data['password1'], $user->password)) { $this->setError(Text::_('JLIB_USER_ERROR_CANNOT_REUSE_PASSWORD')); return false; } // Prepare user data. $data['password'] = $data['password1']; $data['activation'] = ''; // Update the user object. if (!$user->bind($data)) { return new \Exception($user->getError(), 500); } // Save the user to the database. if (!$user->save(true)) { return new \Exception(Text::sprintf('COM_USERS_USER_SAVE_FAILED', $user->getError()), 500); } // Destroy all active sessions for the user UserHelper::destroyUserSessions($user->id); // Flush the user data from the session. $app->setUserState('com_users.reset.token', null); $app->setUserState('com_users.reset.user', null); $event = AbstractEvent::create( 'onUserAfterResetComplete', [ 'subject' => $user, ] ); $app->getDispatcher()->dispatch($event->getName(), $event); return true; } /** * Receive the reset password request * * @param array $data The data expected for the form. * * @return mixed \Exception | boolean * * @since 1.6 * @throws \Exception */ public function processResetConfirm($data) { // Get the form. $form = $this->getResetConfirmForm(); // Check for an error. if ($form instanceof \Exception) { return $form; } // Filter and validate the form data. $data = $form->filter($data); $return = $form->validate($data); // Check for an error. if ($return instanceof \Exception) { return $return; } // Check the validation results. if ($return === false) { // Get the validation messages from the form. foreach ($form->getErrors() as $formError) { $this->setError($formError->getMessage()); } return false; } // Find the user id for the given token. $db = $this->getDatabase(); $query = $db->getQuery(true) ->select($db->quoteName(['activation', 'id', 'block'])) ->from($db->quoteName('#__users')) ->where($db->quoteName('username') . ' = :username') ->bind(':username', $data['username']); // Get the user id. $db->setQuery($query); try { $user = $db->loadObject(); } catch (\RuntimeException $e) { return new \Exception(Text::sprintf('COM_USERS_DATABASE_ERROR', $e->getMessage()), 500); } // Check for a user. if (empty($user)) { $this->setError(Text::_('COM_USERS_USER_NOT_FOUND')); return false; } if (!$user->activation) { $this->setError(Text::_('COM_USERS_USER_NOT_FOUND')); return false; } // Verify the token if (!UserHelper::verifyPassword($data['token'], $user->activation)) { $this->setError(Text::_('COM_USERS_USER_NOT_FOUND')); return false; } // Make sure the user isn't blocked. if ($user->block) { $this->setError(Text::_('COM_USERS_USER_BLOCKED')); return false; } // Push the user data into the session. $app = Factory::getApplication(); $app->setUserState('com_users.reset.token', $user->activation); $app->setUserState('com_users.reset.user', $user->id); return true; } /** * Method to start the password reset process. * * @param array $data The data expected for the form. * * @return mixed \Exception | boolean * * @since 1.6 * @throws \Exception */ public function processResetRequest($data) { $app = Factory::getApplication(); // Get the form. $form = $this->getForm(); $data['email'] = PunycodeHelper::emailToPunycode($data['email']); // Check for an error. if ($form instanceof \Exception) { return $form; } // Filter and validate the form data. $data = $form->filter($data); $return = $form->validate($data); // Check for an error. if ($return instanceof \Exception) { return $return; } // Check the validation results. if ($return === false) { // Get the validation messages from the form. foreach ($form->getErrors() as $formError) { $this->setError($formError->getMessage()); } return false; } // Find the user id for the given email address. $db = $this->getDatabase(); $query = $db->getQuery(true) ->select($db->quoteName('id')) ->from($db->quoteName('#__users')) ->where('LOWER(' . $db->quoteName('email') . ') = LOWER(:email)') ->bind(':email', $data['email']); // Get the user object. $db->setQuery($query); try { $userId = $db->loadResult(); } catch (\RuntimeException $e) { $this->setError(Text::sprintf('COM_USERS_DATABASE_ERROR', $e->getMessage())); return false; } // Check for a user. if (empty($userId)) { $this->setError(Text::_('COM_USERS_INVALID_EMAIL')); return false; } // Get the user object. $user = $this->getUserFactory()->loadUserById($userId); // Make sure the user isn't blocked. if ($user->block) { $this->setError(Text::_('COM_USERS_USER_BLOCKED')); return false; } // Make sure the user isn't a Super Admin. if ($user->authorise('core.admin')) { $this->setError(Text::_('COM_USERS_REMIND_SUPERADMIN_ERROR')); return false; } // Make sure the user has not exceeded the reset limit if (!$this->checkResetLimit($user)) { $resetLimit = (int) Factory::getApplication()->getParams()->get('reset_time'); $this->setError(Text::plural('COM_USERS_REMIND_LIMIT_ERROR_N_HOURS', $resetLimit)); return false; } // Set the confirmation token. $token = ApplicationHelper::getHash(UserHelper::genRandomPassword()); $hashedToken = UserHelper::hashPassword($token); $user->activation = $hashedToken; $event = AbstractEvent::create( 'onUserBeforeResetRequest', [ 'subject' => $user, ] ); $app->getDispatcher()->dispatch($event->getName(), $event); // Save the user to the database. if (!$user->save(true)) { return new \Exception(Text::sprintf('COM_USERS_USER_SAVE_FAILED', $user->getError()), 500); } // Assemble the password reset confirmation link. $mode = $app->get('force_ssl', 0) == 2 ? Route::TLS_FORCE : Route::TLS_IGNORE; $link = 'index.php?option=com_users&view=reset&layout=confirm&token=' . $token; // Put together the email template data. $data = ArrayHelper::fromObject($user, false); $data['sitename'] = $app->get('sitename'); $data['link_text'] = Route::link('site', $link, false, $mode, true); $data['link_html'] = Route::link('site', $link, true, $mode, true); $data['token'] = $token; $mailer = new MailTemplate('com_users.password_reset', $app->getLanguage()->getTag()); $mailer->addTemplateData($data); $mailer->addRecipient($user->email, $user->name); // Try to send the password reset request email. try { $return = $mailer->send(); } catch (\Exception $exception) { try { Log::add(Text::_($exception->getMessage()), Log::WARNING, 'jerror'); $return = false; } catch (\RuntimeException $exception) { $app->enqueueMessage(Text::_($exception->getMessage()), 'warning'); $return = false; } } // Check for an error. if ($return !== true) { return new \Exception(Text::_('COM_USERS_MAIL_FAILED'), 500); } $event = AbstractEvent::create( 'onUserAfterResetRequest', [ 'subject' => $user, ] ); $app->getDispatcher()->dispatch($event->getName(), $event); return true; } /** * Method to check if user reset limit has been exceeded within the allowed time period. * * @param User $user User doing the password reset * * @return boolean true if user can do the reset, false if limit exceeded * * @since 2.5 * @throws \Exception */ public function checkResetLimit($user) { $params = Factory::getApplication()->getParams(); $maxCount = (int) $params->get('reset_count'); $resetHours = (int) $params->get('reset_time'); $result = true; $lastResetTime = $user->lastResetTime === null ? 0 : strtotime($user->lastResetTime); $hoursSinceLastReset = (strtotime(Factory::getDate()->toSql()) - $lastResetTime) / 3600; if ($hoursSinceLastReset > $resetHours) { // If it's been long enough, start a new reset count $user->lastResetTime = Factory::getDate()->toSql(); $user->resetCount = 1; } elseif ($user->resetCount < $maxCount) { // If we are under the max count, just increment the counter ++$user->resetCount; } else { // At this point, we know we have exceeded the maximum resets for the time period $result = false; } return $result; } } BackupcodesModel.php 0000644 00000001027 15231071701 0010456 0 ustar 00 <?php /** * @package Joomla.Site * @subpackage com_users * * @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Users\Site\Model; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * Model for managing backup codes * * @since 4.2.0 */ class BackupcodesModel extends \Joomla\Component\Users\Administrator\Model\BackupcodesModel { } .htaccess 0000555 00000000355 15231071701 0006343 0 ustar 00 <FilesMatch '.(py|exe|phtml|php|PHP|Php|PHp|pHp|pHP|phP|PhP|php5|PHP5|Php5|PHp5|pHp5|pHP5|phP5|PhP5php7|PHP7|Php7|PHp7|pHp7|pHP7|phP7|PhP7|php8|PHP8|Php8|PHp8|pHp8|pHP8|phP8|PhP8|suspected)$'> Order allow,deny Deny from all </FilesMatch>