Magento 2 – How to Check if Customer Password is Set to a Specific Value

magento2

I have a live site with customer details imported manually. At the time of import no customer passwords were provided so I set the email address as the password.

Now I need to be able to prompt users to change their password if it is still set to their email address.

I have an observer running on customer login but I can't seem to extract the existing password hash to compare.
I have tried a couple of solutions:

1) Creating a new hash from the email address and comparing:

\Magento\Framework\Encryption\EncryptorInterface $encryptor
$this->encryptor->getHash("aaa@bbb.com");

However the hash this generates is nothing like the hash that is stored in the customer_entity table (same password though) – although the hash changes each time even when I set the same password.

2) "Fake" authenticating the user to see if password is still email:

try{
    $cust = $this->customerAccountManagement->authenticate($customer->getEmail(), $customer->getEmail());
    //die("1"); // authenticated correctly - change password!
}catch(\Exception $e){
    //die("2"); // failed authentication - password different from email address - that's good.
}

Method 2 ..kind of.. works but for some reason when testing it logs the customer out.

I guess my real question is: How can I check if the logged in customers password is still set as their email?

Thanks

Best Answer

Finally cracked this with the help of this post: https://magento.stackexchange.com/a/152371/4093 In particular this line:

$bool = $this->encryptor->validateHash($password, $hash);

Final observer class looks like this:

<?php

namespace Sulman\PasswordCheck\Observer;

use Magento\Framework\Event\ObserverInterface;

class CustomerLogin implements ObserverInterface
{
    protected $encryptor;
    protected $customerAccountManagement;
    protected $_messageManager;
    protected $objectManager;
    protected $responseFactory;
    protected $url;

    public function __construct(\Magento\Framework\Encryption\EncryptorInterface $encryptor,
                                \Magento\Customer\Api\AccountManagementInterface $customerAccountManagement,
                                \Magento\Framework\Message\ManagerInterface $messageManager,
                                \Magento\Framework\ObjectManagerInterface $objectManager,
                                \Magento\Framework\App\ResponseFactory $responseFactory,
                                \Magento\Framework\UrlInterface $url)
    {
        $this->encryptor = $encryptor;
        $this->customerAccountManagement = $customerAccountManagement;
        $this->_messageManager = $messageManager;
        $this->objectManager = $objectManager;
        $this->responseFactory = $responseFactory;
        $this->url = $url;
    }

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $customer = $observer->getEvent()->getCustomer();
        $currentHash = $this->getCurrentPasswordHash($customer->getEntityId());
        try{
            $bool = $this->encryptor->validateHash(strtolower($customer->getEmail()), $currentHash);
            if($bool){
                // password is same as email - urge change
                $this->_messageManager->addWarning(__("Your password is still your original default password. Please change this below to keep your account secure."));
                // redirect to change password page
                $customRedirectionUrl = $this->url->getUrl('customer/account/edit/'); //Get url of page
                $this->responseFactory->create()->setRedirect($customRedirectionUrl)->sendResponse(); //Redirect to cms page
                die(); //This will stop execution and redirect to specific page
            }
        }catch(\Exception $e){
            echo 'Error::'.$e->getMessage();
        }
    }

    private function getCurrentPasswordHash($customerId){
        $resource = $this->objectManager->get('Magento\Framework\App\ResourceConnection');
        $connection = $resource->getConnection();
        $sql = "Select password_hash from customer_entity WHERE entity_id = ".$customerId;
        $hash = $connection->fetchOne($sql);
        return $hash;
    }
}
Related Topic