-
-
Notifications
You must be signed in to change notification settings - Fork 827
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#314 Event self-service Transfer picks up the deleted contact ID basically transferring to the wrong contact #12639
Conversation
(Standard links)
|
@davejenx @monishdeb @jitendrapurohit I never let a good deed go unpunished & you 3 seem to be the only semi-recent contributors to this code so I'm hoping one of you might review this |
@eileenmcnaughton Looks like it was Dave G, not me but I've commented anyway. :-) |
@davejenx any Dave will do |
@davejenx I don't see your comment |
Hmm necessary improvement to find the valid contact but additional improvement would be: - $query = "select contact_id from civicrm_email left join civicrm_contact on civicrm_contact.id=civicrm_email.contact_id where email='" . $params['email'] . "' and is_deleted=0";
- $dao = CRM_Core_DAO::executeQuery($query);
- while ($dao->fetch()) {
- $contact_id = $dao->contact_id;
- }
+ $contactID = CRM_Core_DAO::singleValueQuery("select contact_id from civicrm_email left join civicrm_contact on civicrm_contact.id=civicrm_email.contact_id where email='" . $params['email'] . "' and is_deleted=0 LIMIT 1 ");
+ if (!$contactID) {
+ CRM_Core_Error::statusBounce(ts('Contact does not exist.'));
+ } |
CRM/Event/Form/SelfSvcTransfer.php
Outdated
@@ -337,7 +337,7 @@ public function postProcess() { | |||
} | |||
else { | |||
//cancel 'from' participant row | |||
$query = "select contact_id from civicrm_email where email = '" . $params['email'] . "'"; | |||
$query = "select contact_id from civicrm_email left join civicrm_contact on civicrm_contact.id=civicrm_email.contact_id where email='" . $params['email'] . "' and is_deleted=0"; |
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.
Why left join here? Looks like the WHERE clause will ensure only civicrm_email records with a matching civicrm_contact record having is_deleted = 0 will be retrieved. And foreign key constraints should ensure you can't have a civicrm_email.contact_id that doesn't match a civicrm_contact.id . So INNER JOIN seems appropriate to me.
Also there looks to be an existing issue in the code: it's putting a parameter in a SQL query by concatenation rather than passing a parameters array to CRM_Core_DAO::executeQuery(). Would be good to fix that if altering this code, in my opinion.
@eileenmcnaughton Oops, hadn't hit the button a second time to submit review comment. |
@davejenx that's so funny because I've had to face down allegations of 'Jackism' this week. Apparently a key symptom of Jackism is people named 'Jack' get asked to empty the dishwasher |
Thanks Guys for the review, I have made the changes suggested with the exception of the variable name from contactID to contact_id as it is been used in the script below |
Can we use api? So that one can alter the result using hook. Thoughts? |
actually I have had a case where due to some special chars, API not only fails to respond, but basically sends a very non standard response, I want to catch and fix that one first before using API in regards to email anywhere else. Please correct me if I am wrong |
@aniesshsethh We do have some tests on the api with special characters - there are some cases where on some server configs on some fields some characters are ignored. I would still go with the api as we use it by choice in general & this doesn't seem like the corner of the code to reject it over a really edge case bug |
okay so done @eileenmcnaughton |
e448893
to
d02a27a
Compare
You can also do it as :
The reason why i sued email api is because Contact api searches for primary emails but in your case i believe its not mandatory to be a primary email.
HTH Pradeep |
bf2abd9
to
2ddf0fc
Compare
Hi @pradpnayak I tried implementing this, but it is failing some of the tests. But regardless, I do not think this is required since the bug I am mentioning does not result in Exception, but a unstandard response, so a try catch in this scope would actually not fix this |
@pradpnayak @davejenx What's the status with this PR? |
@aniesshsethh What is the current state of this PR? |
@mattwire I am fine with the current patch if others are |
@davejenx @pradpnayak Could you please confirm if you are happy with this PR now? So we can merge. @lcdservices @alifrumin Do either of you have capacity to give this a quick test and confirm if it is ok to merge? |
To test this I tried:
On a site with this pr the result was that a new Bob gets created and the event registration is assigned to him, no "Contact does not exist." error was thrown. Perhaps I am missing a step in how to replicate this bug. |
Hi @alifrumin Sorry for the late response. This bug can be reproduced like this. Create a contact A in the system, delete it, again create that contact A so that it has a new contact id, but the old contact id should still be in the system. Now Register as contact B, and Try to transfer the ticket to contact A, it will assign that ticket to the deleted contact A instead of the valid contact A
The basic issue was this query is returning even the deleted contact_id, When we are calling it through the API, only the valid contact ID is returned I will check your steps though to reproduce the error you said, because as you said, the contact didn't already existed in the system so I guess that is why it threw the error, I will add code to handle that |
@alifrumin @aniesshsethh what is the status here? |
Hey @eileenmcnaughton thanks for following up on this. I just tested on a site with this pr and a site without the pr by:
RESULT: @aniesshsethh, perhaps I am misinterpreting "Create a contact A in the system, delete it, again create that contact A so that it has a new contact id, but the old contact id should still be in the system." thoughts? |
na you are right , Did you create contact A again with the exact same primary email as the original contact? |
I took a look through this & it's a shame this code is in core rather than an extension - it doesn't seem to have much love & less tests. However, on balance I'm going to merge this change - logically reading the code it should work, reading @alifrumin's comments it doesn't but it doesn't make it worse. However, it does make the code more consistent and readable & removes some sql interpolation - which is a bad security practice even though it may not be exploitable. |
Overview
When transferring a event registration, it picks up the first email id in the email table and get the corresponding contact id, which in some cases can be the deleted contact.
Before
It's picking up the wrong contact to attach the registration to.
After
It's now picking up the correct contact to attach the registration to.
Technical Details
Just a simple Join and checking for deleted records.
Comments
https://lab.civicrm.org/dev/core/issues/314