diff --git a/libraries/cms/application/administrator.php b/libraries/cms/application/administrator.php index dd1d5479159fc..603770210e1e5 100644 --- a/libraries/cms/application/administrator.php +++ b/libraries/cms/application/administrator.php @@ -130,22 +130,6 @@ protected function doExecute() } } - // Check if the user is required to reset their password - $user = JFactory::getUser(); - - if ($user->get('requireReset', 0) === '1') - { - if ($this->input->getCmd('option') != 'com_admin' && $this->input->getCmd('view') != 'profile' && $this->input->getCmd('layout') != 'edit') - { - if ($this->input->getCmd('task') != 'profile.save') - { - // Redirect to the profile edit page - $this->enqueueMessage(JText::_('JGLOBAL_PASSWORD_RESET_REQUIRED'), 'notice'); - $this->redirect(JRoute::_('index.php?option=com_admin&task=profile.edit&id=' . $user->id, false)); - } - } - } - // Mark afterInitialise in the profiler. JDEBUG ? $this->profiler->mark('afterInitialise') : null; @@ -155,6 +139,15 @@ protected function doExecute() // Mark afterRoute in the profiler. JDEBUG ? $this->profiler->mark('afterRoute') : null; + /* + * Check if the user is required to reset their password + * + * Before $this->route(); "option" and "view" can't be safely read using: + * $this->input->getCmd('option'); or $this->input->getCmd('view'); + * ex: due of the sef urls + */ + $this->checkUserRequireReset('com_admin', 'profile', 'edit', 'profile.save,profile.apply'); + // Dispatch the application $this->dispatch(); diff --git a/libraries/cms/application/cms.php b/libraries/cms/application/cms.php index 440c6f801a4bf..f2aa26c7243fb 100644 --- a/libraries/cms/application/cms.php +++ b/libraries/cms/application/cms.php @@ -267,6 +267,64 @@ public function execute() $this->triggerEvent('onAfterRespond'); } + /** + * Check if the user is required to reset their password. + * + * If the user is required to reset their password will be redirected to the page that manage the password reset. + * + * @param string $option The option that manage the password reset + * @param string $view The view that manage the password reset + * @param string $layout The layout of the view that manage the password reset + * @param string $tasks Permitted tasks + */ + protected function checkUserRequireReset($option, $view, $layout, $tasks) + { + if (JFactory::getUser()->get('requireReset', 0)) + { + $redirect = false; + + /* + * By default user profile edit page is used. + * That page allows you to change more than just the password and might not be the desired behavior. + * This allows a developer to override the page that manage the password reset. + * (can be configured using the file: configuration.php, or if extended, through the global configuration form) + */ + $name = $this->getName(); + + if ($this->get($name . '_reset_password_override', 0)) + { + $option = $this->get($name . '_reset_password_option', ''); + $view = $this->get($name . '_reset_password_view', ''); + $layout = $this->get($name . '_reset_password_layout', ''); + $tasks = explode(',', $this->get($name . '_reset_password_tasks', '')); + } + + if ($this->input->getCmd('option', '') != $option || $this->input->getCmd('view', '') != $view || $this->input->getCmd('layout', '') != $layout) + { + // Requested a different page + $redirect = true; + } + else + { + $task = $this->input->getCmd('task', ''); + + // Empty task are always permitted + if (!empty($task) && array_search($task, $tasks) === false) + { + // Not permitted task + $redirect = true; + } + } + + if ($redirect) + { + // Redirect to the profile edit page + $this->enqueueMessage(JText::_('JGLOBAL_PASSWORD_RESET_REQUIRED'), 'notice'); + $this->redirect(JRoute::_('index.php?option=' . $option . '&view=' . $view . '&layout=' . $layout, false)); + } + } + } + /** * Gets a configuration value. * diff --git a/libraries/cms/application/site.php b/libraries/cms/application/site.php index 19d39be501c15..df82b1c5c3230 100644 --- a/libraries/cms/application/site.php +++ b/libraries/cms/application/site.php @@ -195,22 +195,6 @@ protected function doExecute() // Initialise the application $this->initialiseApp(); - // Check if the user is required to reset their password - $user = JFactory::getUser(); - - if ($user->get('requireReset', 0) === '1') - { - if ($this->input->getCmd('option') != 'com_users' && $this->input->getCmd('view') != 'profile' && $this->input->getCmd('layout') != 'edit') - { - if ($this->input->getCmd('task') != 'profile.save') - { - // Redirect to the profile edit page - $this->enqueueMessage(JText::_('JGLOBAL_PASSWORD_RESET_REQUIRED'), 'notice'); - $this->redirect(JRoute::_('index.php?option=com_users&view=profile&layout=edit')); - } - } - } - // Mark afterInitialise in the profiler. JDEBUG ? $this->profiler->mark('afterInitialise') : null; @@ -220,6 +204,15 @@ protected function doExecute() // Mark afterRoute in the profiler. JDEBUG ? $this->profiler->mark('afterRoute') : null; + /* + * Check if the user is required to reset their password + * + * Before $this->route(); "option" and "view" can't be safely read using: + * $this->input->getCmd('option'); or $this->input->getCmd('view'); + * ex: due of the sef urls + */ + $this->checkUserRequireReset('com_users', 'profile', 'edit', 'profile.save,profile.apply'); + // Dispatch the application $this->dispatch();