Transparancy to understand functioning of function [patchEntity & hashed password]

If the Cookbook instructions do not result in met expectations, a beginner needs to go beyond assuming and start understanding.

However, the power of the pre-written code also obstructs the transparency of what is going on. In the tutorial example project I created an email + password before configuring the hashing. From the following I expected that resetting this password (by its exact self) would lead to a hashed password, which did not happen.

“Note bcrypt will generate a different hash even for the same password saved twice.”

// in src/Model/Entity/User.php
use Authentication\PasswordHasher\DefaultPasswordHasher;

class User extends Entity
{
    // ... other methods

    // **Automatically hash passwords when they are changed.**
    protected function _setPassword(string $password)
    {
        $hasher = new DefaultPasswordHasher();
        return $hasher->hash($password);
    }
}

add() and edit() in UsersController.php use newEntity() and patchEntity(), which should thus both use _setPassword in a certain way.
After searching through the complete project directories I found out that newEntity() patchEntity() are both empty functions in RepositoryInterface.php. So I couldn’t figure out the mechanism and troubleshoot by myself based on the code. Are there other ways to understand the code or shouldn’t I even bother to try?

(This is a trivial example, I found out that the re-hashing of the same password only works for already hashed passwords. I assume that without hashing, the edited password is not really _set if it is identical to the initial password. It would be nice to be able to confirm this by the code though, especially for future encounters. )

The newEntity and patchEntity functions are prototyped in Datasource\RepositoryInterface, but actually implemented in ORM\Table.

Sorry I overlooked. Would you be able to explain the non-changing of the non-hashed password by this:?

public function patchEntity(EntityInterface $entity, array $data, array $options = []): EntityInterface
{
if (!isset($options[‘associated’])) {
$options[‘associated’] = $this->_associations->keys();
}
$marshaller = $this->marshaller();

    return $marshaller->merge($entity, $data, $options);
}

I guess that $options are set, so the if statement is not executed. But again, how to validate this without looking up all the origins of the variables?

I would think that not changing a non-hashed password would be happening at some other level, like application logic confirming that the old password matches what the user input, or rules are only allowing it to be changed if there’s a confirm field that matches the new password. Output the contents of your entity before patching, after patching, and after trying to save, to narrow down where the problem is happening.

I have little evidence to prove it, but I thought the hashing happened when the record saves.

The bcrypt passwords stored in the db have more than just the password hash in them. They have the slow-down value (whatever that’s called), and the salt that played a role in hashing.

So, until the db is queried to retrieve this information, no hashing can be done (I think).

https://www.php.net/manual/en/function.password-hash.php