From: eileen Date: Mon, 17 Aug 2020 09:17:09 +0000 (+1200) Subject: dev/core#1945 Fix recur access regression X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=3f4728dd2964516d90994935386b054e66dbfc2d;p=civicrm-core.git dev/core#1945 Fix recur access regression --- diff --git a/CRM/Contribute/Form/ContributionRecur.php b/CRM/Contribute/Form/ContributionRecur.php index 8378d60599..ef6a633f45 100644 --- a/CRM/Contribute/Form/ContributionRecur.php +++ b/CRM/Contribute/Form/ContributionRecur.php @@ -192,21 +192,22 @@ class CRM_Contribute_Form_ContributionRecur extends CRM_Core_Form { */ protected function getSubscriptionContactID() { $sub = $this->getSubscriptionDetails(); - return $sub->contact_id ?? FALSE; + return $sub->contact_id ? (int) $sub->contact_id : FALSE; } /** * Is this being used by a front end user to update their own recurring. * * @return bool + * @throws \CRM_Core_Exception */ protected function isSelfService() { - if (!is_null($this->selfService)) { + if ($this->selfService !== NULL) { return $this->selfService; } $this->selfService = FALSE; if (!CRM_Core_Permission::check('edit contributions')) { - if ($this->_subscriptionDetails->contact_id != $this->getContactID()) { + if ($this->getSubscriptionContactID() !== $this->getContactIDIfAccessingOwnRecord()) { CRM_Core_Error::statusBounce(ts('You do not have permission to cancel this recurring contribution.')); } $this->selfService = TRUE; diff --git a/CRM/Contribute/Page/Tab.php b/CRM/Contribute/Page/Tab.php index 0a5a4f67e5..fac5a250bc 100644 --- a/CRM/Contribute/Page/Tab.php +++ b/CRM/Contribute/Page/Tab.php @@ -86,7 +86,11 @@ class CRM_Contribute_Page_Tab extends CRM_Core_Page { ]; } - if (!$paymentProcessorObj->supports('ChangeSubscriptionAmount') && !$paymentProcessorObj->supports('EditRecurringContribution')) { + if ( + (!CRM_Core_Permission::check('edit contributions') && $context === 'contribution') || + (!$paymentProcessorObj->supports('ChangeSubscriptionAmount') + && !$paymentProcessorObj->supports('EditRecurringContribution') + )) { unset($links[CRM_Core_Action::UPDATE]); } } diff --git a/CRM/Core/Form.php b/CRM/Core/Form.php index 158a6eedbb..fe06bb9915 100644 --- a/CRM/Core/Form.php +++ b/CRM/Core/Form.php @@ -2235,11 +2235,13 @@ class CRM_Core_Form extends HTML_QuickForm_Page { /** * Get the contact id of the logged in user. + * + * @return int|false */ public function getLoggedInUserContactID() { // check if the user is logged in and has a contact ID $session = CRM_Core_Session::singleton(); - return $session->get('userID'); + return $session->get('userID') ? (int) $session->get('userID') : FALSE; } /** @@ -2263,6 +2265,7 @@ class CRM_Core_Form extends HTML_QuickForm_Page { * - id_field * - url (for ajax lookup) * + * @throws \CRM_Core_Exception * @todo add data attributes so we can deal with multiple instances on a form */ public function addAutoSelector($profiles = [], $autoCompleteField = []) { @@ -2656,4 +2659,26 @@ class CRM_Core_Form extends HTML_QuickForm_Page { } } + /** + * Get the contact if from the url, using the checksum or the cid if it is the logged in user. + * + * This function returns the user being validated. It is not intended to get another user + * they have permission to (setContactID does do that) and can be used to check if the user is + * accessing their own record. + * + * @return int|false + * @throws \CRM_Core_Exception + */ + protected function getContactIDIfAccessingOwnRecord() { + $contactID = (int) CRM_Utils_Request::retrieve('cid', 'Positive', $this); + if (!$contactID) { + return FALSE; + } + if ($contactID === $this->getLoggedInUserContactID()) { + return $contactID; + } + $userChecksum = CRM_Utils_Request::retrieve('cs', 'String', $this); + return CRM_Contact_BAO_Contact_Utils::validChecksum($contactID, $userChecksum) ? $contactID : FALSE; + } + }