-
-
Notifications
You must be signed in to change notification settings - Fork 48
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/drupal#54 Remove hook_user_login, fixes the masquerade module #31
Conversation
cfb30dd
to
67f628e
Compare
civicrm.user.inc
Outdated
// Also, there is a isMasquerading() function, but it does not seem to be | ||
// initialized at this point (it always returns false). | ||
$session = \CRM_Core_Session::singleton(); | ||
$session->reset(FALSE); |
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.
On the first (normal) login, the CiviCRM session stores the userID and ufID, but when the user masquerades and synchronizeUser
gets called again, the old session ufID doesn't match anymore and so it does a hard reset of the session (causing a logout).
Using $session->reset(FALSE)
does a soft reset of the CiviCRM-specific session bits, so that the call to synchronize
then re-updates the ufID and whatever is required.
Finally, I tried to reduce the scope of this fix, in case it causes regressions (my first attempt had broken the dashlets). I would have use \Drupal::service('masquerade')->isMasquerading()
, but for some reason it did not work and I could not figure out why.
@@ -11,6 +11,18 @@ use Drupal\Core\Session\AccountInterface; | |||
* Implements hook_user_login(). | |||
*/ | |||
function civicrm_user_login(AccountInterface $account) { | |||
$civicrm = \Drupal::service('civicrm'); | |||
$civicrm->initialize(); |
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.
This might not be necessary, but the other functions do it, so I figured it was safer. I didn't want to create a new wrapper function in src/Civicrm.php
just for getSession
or equivalent (as was done for the synchronize function)
$session = \CRM_Core_Session::singleton(); | ||
$session->reset(FALSE); | ||
} | ||
|
||
\Drupal::service('civicrm')->synchronizeUser($account); | ||
} |
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.
just to reduce LOC
function civicrm_user_login(AccountInterface $account) {
$civicrm = \Drupal::service('civicrm');
$civicrm->initialize();
if (\Drupal::hasService('masquerade')) {
// In theory this is harmless whether we masquerade or not, but for now narrowing
// the scope, in case it causes regressions.
// Also, there is a isMasquerading() function, but it does not seem to be
// initialized at this point (it always returns false).
\CRM_Core_Session::singleton()->reset(FALSE);
}
$civicrm->synchronizeUser($account);
}
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.
👍 fixed
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.
thanks :)
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.
It works!
c9bf234
to
d6c474f
Compare
I did another force-push to address another odd behaviour encountered with the Dashboard dashlets. |
Is there some reason that the behaviour: " logged out when attempting to masquerade" would not be observed? I've just being testing this on a pretty vanilla d8 site 8.7.6 civicrm 5.16.2, masquerade 8.x-2.0-beta2 with and without this PR - I can masquerade through to another user - but am unable to unmasquerade (clicking the link results in a log out). Am I missing something basic here? |
@stesi561 Maybe relevant: in most of my test-cases, the Drupal frontpage is the CiviCRM dashboard ( Just to double-check: when testing, were you accessing CiviCRM before & after masquerading? I suppose the bug might not trigger if you masquerade immediately after the initial login (since the CiviCRM session will not have been initialized yet). |
Hmm. Yes okay - I can replicate the problem behaviour consistently now. However applying the above patch doesn't seem to resolve? Steps to reproduce: I've upgraded the site I was using to test on to civicrm 5.17.4, and drupal 8.7.7 and tested again. This is on a drupal site installed using roundearth composer |
Any suggestions on further debugging that I can do to investigate this further? |
civicrm.user.inc
Outdated
$ufID = $session->get('ufID'); | ||
|
||
$userSystem = CRM_Core_Config::singleton()->userSystem; | ||
$userSystemID = $userSystem->getBestUFID($user); |
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.
looks like $user
variable is not defined in this function?
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.
👍 yikes, indeed. Although it produced a notice, but it was still giving the correct behaviour because getBestUFID
accepts null.
I fixed the code nonetheless and tested to make sure that fixing it did not introduce a regression.
d6c474f
to
887b28f
Compare
I tried re-testing this issue after: civicrm/civicrm-core#16177 - thinking it would fix the issue, but I'm still encountering it. |
I tested civicrm/civicrm-core#16177 in combination with this change : function civicrm_user_login(AccountInterface $account) {
$civicrm = \Drupal::service('civicrm');
$civicrm->initialize();
if (\Drupal::hasService('masquerade')) {
// In theory this is harmless whether we masquerade or not, but for now narrowing
// the scope, in case it causes regressions.
// Also, there is a isMasquerading() function, but it does not seem to be
// initialized at this point (it always returns false).
\CRM_Core_Session::singleton()->reset(FALSE);
}
$civicrm->synchronizeUser($account);
} and that seems to fix the issue on my side without regression (ie dashboard ...). |
Although I prefer to patch the CRM_Core_Session::reset() function as follows: public function reset($all = 1) {
$this->initialize();
// to make certain we clear it, first initialize it to empty
$this->_session[$this->_key] = [];
unset($this->_session[$this->_key]);
if ($all) {
unset($this->_session);
}
} But yes, it must be fully tested with other CMS... |
887b28f
to
a6a5014
Compare
@GValFr35 Thanks for your input. I updated my PR using your code. Cleaner and works well. Since this has been open for a while, and I'm not the only one running into this problem, I would be tempted to merge if @GValFr35 validates the latest edit. (I only patches in the |
I can also say that @GValFr35's patch also works for me too, using Drupal 8.9.x and CiviCRM 5.39.0. Is there any news on when this could get merged? |
Since two people have confirmed recently it works for masquerade, I think I'm ok to merge this since the first thing synchronizeUser does is call initialize, so there should be no change if masquerade is not installed. And just doing a quick test like that nothing obvious comes up. |
I've been using the last patch via composer in production since it was posted. We rely on it. |
The hook_user_login implementation was added by Torrance during the initial port to Drupal8. The Drupal7 implementation does not implement this hook.
It causes problems with the Drupal 'masquerade' module, causing the user to be logged out when attempting to masquerade. This is because the synchronizeUser() function resets the PHP session.
More details here:
https://lab.civicrm.org/dev/drupal/issues/54#note_23652
I tested the following use-cases:
Looking on the initial commit (29b7571), there doesn't seem to be a reason for the hook, so it feels safe to remove.