Magento – How to Force Admin User to Change Password

adminadmin-panelconfigurationmagento-enterpriseSecurity

On Magento EE if you go to System > Configuration > Advanced > Admin > Security their is an option to set Password Change to Forced.

enter image description here

If we do this and someone has an expired password will it lock them out – or will it allow them login but force them to update their password?

I've tried looking through the Magento User Guide & Wiki but could find no answer 🙁

Best Answer

I went into one of our Enterprise installs to check this.

In app/code/core/Enterprise/Pci/Model/Observer.php there is a function called adminAuthenticate in the Observer.

public function adminAuthenticate($observer)
{

First, it updates the locking information:

    // update locking information regardless whether user locked or not
    if ((!$authResult) && ($user->getId())) {
        $now = time();
        $lockThreshold = $this->getAdminLockThreshold();
        $maxFailures = (int)Mage::getStoreConfig('admin/security/lockout_failures');
        if (!($lockThreshold && $maxFailures)) {
            return;
        }
        $failuresNum = (int)$user->getFailuresNum() + 1;
        if ($firstFailureDate = $user->getFirstFailure()) {
            $firstFailureDate = new Zend_Date($firstFailureDate, Varien_Date::DATETIME_INTERNAL_FORMAT);
            $firstFailureDate = $firstFailureDate->toValue();
        }

Then it determines if the admin account is locked out by checking the lockExpires field from admin_user against the current time.

    // check whether user is locked
    if ($lockExpires = $user->getLockExpires()) {
        $lockExpires = new Zend_Date($lockExpires, Varien_Date::DATETIME_INTERNAL_FORMAT);
        $lockExpires = $lockExpires->toValue();
        if ($lockExpires > time()) {
            throw new Mage_Core_Exception(
                Mage::helper('enterprise_pci')->__('This account is locked.'),
                self::ADMIN_USER_LOCKED
            );
        }
    }

Then it pulls the latest password and checks to see if the admin has to complete a forced password change.

$latestPassword = Mage::getResourceSingleton('enterprise_pci/admin_user')->getLatestPassword($user->getId());
    if ($latestPassword) {
        if ($this->_isLatestPasswordExpired($latestPassword)) {
            if ($this->isPasswordChangeForced()) {
                $message = Mage::helper('enterprise_pci')->__('Your password has expired, you must change it now.');
            } else {
                $myAccountUrl = Mage::getSingleton('adminhtml/url')->getUrl('adminhtml/system_account/');
                $message = Mage::helper('enterprise_pci')->__('Your password has expired, please <a href="%s">change it</a>.', $myAccountUrl);
            }
            Mage::getSingleton('adminhtml/session')->addNotice($message);
            if ($message = Mage::getSingleton('adminhtml/session')->getMessages()->getLastAddedMessage()) {
                $message->setIdentifier('enterprise_pci_password_expired')->setIsSticky(true);
                Mage::getSingleton('admin/session')->setPciAdminUserIsPasswordExpired(true);
            }
        }
    }

If the getPciAdminUserIsPasswordExpired session variable is set, then it is caught in the forceAdminPasswordChange function in controller_action_predispatch.

public function forceAdminPasswordChange($observer)
{
    if (!$this->isPasswordChangeForced()) {
        return;
    }
    $session = Mage::getSingleton('admin/session');
    if (!$session->isLoggedIn()) {
        return;
    }
    $actionList = array('adminhtml_system_account_index', 'adminhtml_system_account_save',
        'adminhtml_index_logout');
    $controller = $observer->getEvent()->getControllerAction();
    if (Mage::getSingleton('admin/session')->getPciAdminUserIsPasswordExpired()) {
        if (!in_array($controller->getFullActionName(), $actionList)) {
            if (Mage::getSingleton('admin/session')->isAllowed('admin/system/myaccount')) {
                $controller->getResponse()->setRedirect(Mage::getSingleton('adminhtml/url')
                        ->getUrl('adminhtml/system_account/'));
                $controller->setFlag('', Mage_Core_Controller_Varien_Action::FLAG_NO_DISPATCH, true);
                $controller->setFlag('', Mage_Core_Controller_Varien_Action::FLAG_NO_POST_DISPATCH, true);
            } else {
                /*
                 * if admin password is expired and access to 'My Account' page is denied
                 * than we need to do force logout with error message
                 */
                Mage::getSingleton('admin/session')->unsetAll();
                Mage::getSingleton('adminhtml/session')->unsetAll();
                Mage::getSingleton('adminhtml/session')->addError(
                    Mage::helper('enterprise_pci')->__('Your password has expired, please contact administrator.')
                );
                $controller->getRequest()->setDispatched(false);
            }
        }
    }

If the Admin user has a forced password flag set and is allowed to access My Account then they'll be able to update their password themselves. If not, then they'll be logged out with the message Your password has expired, please contact administrator.

Related Topic