-
-
Notifications
You must be signed in to change notification settings - Fork 817
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(dev/core#660) Address regression whereby Anonymous users can no longer register for an event if they have ACLs to see a contact #13451
Conversation
(Standard links)
|
Note the huge amount of failures here https://test.civicrm.org/job/CiviCRM-Core-PR/24030/#showFailuresLink - come from data cleanup failing on the new test - which is fixed by removing the index |
7579395
to
194e36f
Compare
…at are cached using the acl_cache. This has arisen during investigation of a possible regression - it turns out that if you give the 'everyone' group access to a contact using ACLs (or hooks I believe) they get a fatal error on any attempt at event or other registration. The issue is that when attempting to check for duplicates the call is made using check_permission. This in itself is a possible regression as the CRM_Dedupe_Finder::dupesByParams function now drops the check_permission key when it is equal to 0 from civicrm@4f33e78 So we have an issue that 1) we are now applying check_permission when doing a dupe_check from front end forms - this probably is resulting in 5.9 sites getting too many duplicates are they would always be null for anon users 2) if we DO do a permissions check when an acl or hook has been used to give anon users permission to access contacts then they will get a fatal error. This is because it sets contact_id to 0 and attempts to insert it into the acl_contact_cache. I think we need to either remove the array_filter line that we think we may not need per code comments or add specific handling for the check_permission flag AND drop the foreign key constraint on the civicm_acl_contact_cache table. This means they will no longer be removed when a contact is deleted but this is a clean up issue rather than one with functionaly implications & we *should* have some form of cleanup in play on that table. In addition, removing the constraint will reduce write contention
This won't actually remove it from installs - we need to address that separately via ensuring people can and do run the System.updateIndices api call but it removes it from new installs and from tests, hence the test should pass
194e36f
to
dbb4e4f
Compare
Thanks for this PR, @eileenmcnaughton . I tested it against this issue: |
test this please |
unrelated fail - CRM_Contact_Page_View_UserDashBoardTest.testDashboardContentContributionsWithInvoicingEnabled (there is some clean up issue affecting that test) |
@@ -25,13 +25,6 @@ | |||
<comment>FK to civicrm_contact (could be null for anon user)</comment> | |||
<add>3.1</add> | |||
</field> | |||
<foreignKey> | |||
<name>user_id</name> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@eileenmcnaughton, I think I follow why check_permission
is relevant to this bug/problem. I'm having trouble seeing why the schema change is relevant.
Relatedly... when grepping for user_id
in civicrm_acl_contact_cache
, it seems like CRM/Contact/BAO/Contact/Permission.php
(at a minimum) has several references to it:
[nix-shell:~/bknix/build/dmaster/sites/all/modules/civicrm]$ svngrep user_id CRM/ Civi api/ bin/
CRM/Contact/BAO/Contact/Permission.php: AND user_id = {$contactID}
CRM/Contact/BAO/Contact/Permission.php:WHERE user_id = %1
CRM/Contact/BAO/Contact/Permission.php:INSERT INTO civicrm_acl_contact_cache ( user_id, contact_id, operation )
CRM/Contact/BAO/Contact/Permission.php:SELECT DISTINCT $userID as user_id, contact_a.id as contact_id, '{$operation}' as operation
CRM/Contact/BAO/Contact/Permission.php: LEFT JOIN civicrm_acl_contact_cache ac ON ac.user_id = $userID AND ac.contact_id = contact_a.id AND ac.operation = '{$operation}'
CRM/Contact/BAO/Contact/Permission.php:AND ac.user_id IS NULL
CRM/Contact/BAO/Contact/Permission.php: SELECT count(*) FROM civicrm_acl_contact_cache WHERE user_id = %1 AND contact_id = %1 AND operation = '{$operation}' LIMIT 1", $queryParams)) {
CRM/Contact/BAO/Contact/Permission.php: CRM_Core_DAO::executeQuery("INSERT INTO civicrm_acl_contact_cache ( user_id, contact_id, operation ) VALUES(%1, %1, '{$operation}')", $queryParams);
CRM/Contact/BAO/Contact/Permission.php: $clauses[] = " INNER JOIN civicrm_acl_contact_cache aclContactCache_{$k} ON {$alias}.id = aclContactCache_{$k}.contact_id AND aclContactCache_{$k}.user_id = $contactID ";
CRM/Contact/BAO/Contact/Permission.php: $whereClase = " aclContactCache.user_id = $contactID AND $contactAlias.is_deleted = 0";
CRM/Contact/BAO/Contact/Permission.php: return "IN (SELECT contact_id FROM civicrm_acl_contact_cache WHERE user_id = $contactID)";
CRM/Contact/BAO/Contact/Permission.php: $user_id_column = "contact_id_{$direction['from']}";
CRM/Contact/BAO/Contact/Permission.php: WHERE civicrm_relationship.{$user_id_column} = {$contactID}
CRM/Contact/BAO/Contact/Permission.php: CRM_Core_DAO::executeQuery('SET @civicrm_user_id = %1',
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@totten yeah the field is used& even without the fk it is still indexed - but it stops fatal errors under some configs (at least on new installs or ones that run the system.update_indexes api
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doh, I misread in haste. This is only dropping the <foreignKey>
; I misread it as dropping the column. Haven't fully got my head around this, but just want to note that the grep
may be less important than I originally thought.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right & it really only affects new installs at this point & crucially the test suite runs on new installs so we can start testing acls with no logged in user.
If people want to benefit from this on their own pre-existing sites there is still an extra step for them at this point
In favor of merging:
The one drawback -- part of the patch+explanation (re:dropping the FK-constraint for |
@totten also - we actually clear the cache on each contact edit I believe - without the opt out permitted on group contact cache |
This patch solves the same issue when creating new contributions and memberships (described here), thanks. |
Overview
A brief description of the pull request. Try to keep it non-technical.
Before
After
Check is done with permissions set to FALSE, this prevents the fatals.
In addition the foreign_key on civicrm_acl_contact_cache.user_id is removed from the schema. At this stage this means it's not added to new installs or test installs but will not be removed from existing installs as yet (that is a follow on task and we will do some testing on the System.update_indexes job for that). Removing it fixes a bug that preceeds the regression but which was exposed by the regression.
Technical Details
Add test to demonstrate fatal error when accessing permitted users that are cached using the acl_cache.
This has arisen during investigation of a possible regression - it turns out that if you give the 'everyone' group
access to a contact using ACLs (or hooks I believe) they get a fatal error on any attempt at event or other registration.
The issue is that when attempting to check for duplicates the call is made using check_permission. This in itself is a possible
regression as the CRM_Dedupe_Finder::dupesByParams function now drops the check_permission key when it is equal to 0 from
4f33e78
So we have an issue that
sites getting too many duplicates are they would always be null for anon users
contacts then they will get a fatal error. This is because it sets contact_id to 0 and attempts to insert it into the
acl_contact_cache.
I think we need to either remove the array_filter line that we think we may not need per code comments
or add specific handling for the check_permission flag
AND drop the foreign key constraint on the civicm_acl_contact_cache table. This means they will
no longer be removed when a contact is deleted but this is a clean up issue rather than one with
functionaly implications & we should have some form of cleanup in play on that table. In addition,
removing the constraint will reduce write contention
Comments
This needs to go in 5.9