Problem/Motivation
The validator runs a query to find existing entities with the given unique field, but does not include ->accessCheck(FALSE). If you use this with an entity that relies on query alters, for example through entity.module's default implementation, existing entities might not be found.
Steps to reproduce
Proposed resolution
Exclude the query from access checks and add test coverage.
Remaining tasks
None.
User interface changes
None.
API changes
UniqueFieldValueValidator will no longer depend on the current user's access.
Data model changes
None.
Release notes snippet
Previously, the UniqueFieldConstraint was validated based on the current user's access, which could create critical data integrity problems if the same field value already existed on an entity the current user could not acccess. To resolve this data integrity problem, validation of the UniqueFieldConstraint will no longer depend on the current user's access.
In rare cases, this can cause entities that were already saved with corrupt data to become impossible to edit through the user interface. In such a case, developer intervention will be required to set the field to a valid value programatically using the Entity Field API.
| Comment | File | Size | Author |
|---|
Issue fork drupal-3171047
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
- 3171047-entity-query-in
changes, plain diff MR !3127
Comments
Comment #2
larowlanwe're likely to need some sort of integrity check / hook_requirements message here to warn that 'field x has integrity issue, required unique values, but has duplicates for {} in entities {}'
Comment #3
berdirI fear so, but that's going to be pretty slow to calculate, well need to find all field definitions with a unique field constraint and then run an aggregate query on those entity types to find duplicates. Not sure if that's something that should run by default and every time you visit the status page. Maybe that could be done in a small contrib module instead and explain it in a change notice? This very likely only affects site with special entity types.
Comment #4
larowlanThere was talk in an update critical about adding a data-integrity checker to core. I think the example was a comment with a missing comment-type field or similar that was causing updates to fail. I guess this would fit in that.
But you're right, too slow for hook_requirements
Comment #5
catchFor critical upgrade path issues we've added those to hook_requirements('update') - but those would only run for schemas below a certain version, not every time you run updates.
#3056543: taxonomy_post_update_make_taxonomy_term_revisionable() and the menu link content equivalent fail when entities have no default translation and similar issues are where this sort of thing came up.
I could see putting this in hook_requirements('update'), showing a warning (not an error), and setting a state key so it doesn't run again, but to me feels like it could be a spin-off issue - existing sites will already have the problem, whereas the patch here fixes it for sites that don't have it yet too.
Comment #6
hchonovThen does it really make sense to add code only to warn existing sites? What about an update that will search for such cases and just write a log message?
Comment #8
jonathanshawThis is getting fixed in #3202125: EntityQuery accessCheck: unique value validation should not be access sensitive. Let's repurpose this issue to be a follow-up discussing how to warn existing sites that suffered from the bug.
Comment #9
berdirCan we do that? By fixing the bug, we might break the ability to save these then on existing sites, and depending on how it is used, it might or might not be easy to fix it. Unique-ness might be validated on a field that can't be changed afterwards?
Comment #10
jonathanshawWe decided in #3202125: EntityQuery accessCheck: unique value validation should not be access sensitive to make the bug explicit there in order to unblock that issue's parent, but not to actually fix it. And @catch asked for the fix - this issue - to be critical (as it's a data integrity issue).
Comment #13
stephencamilo commentedComment #14
larowlanComment #15
mradcliffeI added the Portland2022 tag. I also added the Needs issue summary update to maybe bring in some of the info in the issue linked in comment #10 (if necessary).
Comment #17
catchHere's a patch that brings back the bugfix + test coverage from #3202125: EntityQuery accessCheck: unique value validation should not be access sensitive.
@Berdir:
This feels like the same as any other validation tightening, we had it with email validator too, and I don't think it should stop us fixing the bug - although we should do so only a minor release for this reason.
Comment #18
jonathanshaw@catch what's your position on warning existing sites as discussed #2 - #9 ?
Comment #19
catch@jonathanshaw as discussed it's going to be too expensive for hook_requirements(), and we don't really have anywhere else to put it, so I'm not sure it's worth the effort for what is quite a specific situation. It's not the update that will fail, but only validation in cases that should have failed validation anyway.
Comment #21
mxr576How about doing an iterative approach, like...
Iteration 1:
1. On newly created instances that are not installed from config, use a different validator behind
UniqueFieldConstraintthan on the others2. Create a new _real_
\Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldValidator3. Mark
\Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldValueValidatoras deprecated and remove it in Drupal 11Iteration 2 (Drupal 11)
1. Provide a tool (script?) for analyzing the database before the Drupal 11 upgrade for non-unique values.
2. Suggest ways to fix none unique values before Drupal 11 upgrade. At worst suggest, suggest using the original "unique-ish" validator from Drupal 10 as custom code on a project.
Comment #22
jonathanshawPer #17 we have a release manager saying the fix in #17 here is good as is. I agree that it's better to fix this critical issue now than let it persist forever because a better but slightly complex solution is possible.
The patch is good, so RTBC.
Comment #24
jonathanshawThis needs to be 'Name' to fix the test failure.
Comment #27
rpayanmComment #28
jonathanshawThanks @rpayanm.
Added change record, updated IS.
RTBC for reasons gived in #22.
Comment #29
xjmJust confirmed that the MR opened in #26 fixes #24, thanks @rpayanm.
Comment #30
xjmHiding the failing patch.
Comment #31
xjmMaking a few changes to the release note:
Adding credit for the helpful reviews and discussion on the issue. I read all of them to understand the implications of this change, why we weren't providing some sort of update hook, etc. Even #21, which turned out not to be the direction we took, presented a good alternate course of action to compare it to.
Comment #32
xjmI read over #3200985: [meta] Fix undesirable access checking on entity query usages and #3202125: EntityQuery accessCheck: unique value validation should not be access sensitive as well as this issue, and agree with going forward with this solution.
There are a couple small fixes I think we should make for the test. I left suggestions on the MR.
Comment #33
jonathanshawThanks Rolando for the fix, and @xjm for the careful review. The changes to the release note seems great.
Comment #35
xjmThanks everyone! I had to fix a couple of small whitespace errors (not sure why it didn't get retested when the suggestions were applied.) Other than that it was fine, though.
On account of the potential editing bug for users, we'll keep this bugfix limited to 10.1.x only. I considered backporting it because of the data integrity aspects, but the fact is that it's been broken for a long time whereas the corrupt entities not being editable would be a new problem, so let's keep this minor-only as a disruptive bugfix.
Tagged for the 10.1.0 release notes, and published the change record. Thanks!
Comment #37
mondrakeThis seems to have broken 10.1.x on both PHPStan and PHPCS - can’t understand how checks failed.
Comment #39
xjmCrosspost.