Summary
Previously, once a user had entered a password (entity, bundle or global password), the access was kept even after the password had been changed. Changing a password did not lock out the users who knew the old one.
The access storage backends now store a fingerprint of the password which granted the access, and compare it with the current password when checking access. When the password changes, the access is no more valid and the user has to enter the new password.
- The fingerprint is a HMAC of the password hash, the password hashes are not copied in the access storages.
- When an entity has several password fields, changing any of their passwords invalidates the accesses of this level (entity or bundle), as the storages do not know which field granted the access.
- Saving an entity or a field without entering a new password does not invalidate the accesses. Entering the same password again does, as it is hashed again.
Session backend
Accesses stored in the session are always invalidated when the password changes.
Accesses stored in the session before the update are not linked to a password, so they are no more valid after the update: users have to enter the passwords again once.
User data backend
Invalidation is configurable on the new settings page: Configuration > Content authoring > Entity Access Password > User data > Settings (/admin/config/content/entity_access_password/user_data/settings), with the "Invalidate accesses when the password changes" option.
- New installs: the invalidation is enabled.
- Existing sites: an update sets it to disabled, to keep the previous behavior. Nothing changes until the option is enabled.
- Accesses granted manually by administrators, with the user data forms, are never invalidated by a password change, whatever the option.
Before enabling the option on an existing site: the accesses stored before this version, including the ones granted manually by administrators, are not linked to the password which granted them. Once the option is enabled, they are no more valid: users have to enter the passwords again and administrators have to grant the manual accesses again. Disabling the option makes them valid again, as they are not deleted.
For developers
A new service is available to compute password fingerprints: \Drupal\entity_access_password\Service\PasswordFingerprintInterface.
$fingerprint_service = \Drupal::service(\Drupal\entity_access_password\Service\PasswordFingerprintInterface::class);
// When storing an access.
$fingerprint = $fingerprint_service->getEntityFingerprint($entity);
// When checking an access.
$has_access = $fingerprint_service->matches($stored_fingerprint, $fingerprint_service->getEntityFingerprint($entity));
It also provides getBundleFingerprint() and getGlobalFingerprint().
AccessStorageInterface and AccessCheckerInterface are unchanged, so custom access storage backends keep working. They do not invalidate accesses on password change unless they use this service.
The user data backend stores the password fingerprint instead of TRUE, and UserDataBackendInterface::MANUAL_GRANT for manually granted accesses. Code reading or writing the entity_access_password_user_data_backend user data directly should use these values.
AI Disclosure
Generated with the help of an LLM.