Skip to content

fix selection of mode on login #8

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

immerda
Copy link

@immerda immerda commented Apr 1, 2020

When the User selects a mode on the login form (ie. setting horde_select_view),
it gets always overwritten by 'auto'. The reason is that during login there is
a cycle that leads to authentication being triggered twice.

The culprit is the call to setAuth at
https://github.com/horde/Core/blob/master/lib/Horde/Core/Auth/Application.php#L669
which ends up triggering a second authentication through

$this->loadPrefs($this->getApp());

which in turn does not have access to the original $credentials array and then
sets the view to the default value.

This patch breaks the cycle, by preventing the second auth when the first one
did not finish.

When the User selects a mode on the login form (ie. setting horde_select_view),
it gets always overwritten by 'auto'. The reason is that during login there is
a cycle that leads to authentication being triggered twice.

The culprit is the call to setAuth at
https://github.com/horde/Core/blob/master/lib/Horde/Core/Auth/Application.php#L669
which ends up triggering a second authentication through

    $this->loadPrefs($this->getApp());

which in turn does not have access to the original $credentials array and then
sets the view to the default value.

The fix is to set the view first.
@immerda immerda force-pushed the fixModeSelectionOnLogin branch from a34eec7 to b2139cf Compare July 20, 2020 22:33
@mrubinsk
Copy link
Member

I can't reproduce this. When selecting a specific view from the login screen, it's always honored. I.e., I always see the mobile view, or desktop view as expected. I'm not following what you mean by the original $credentials array is not available in loadPrefs...

@immerda
Copy link
Author

immerda commented Jul 27, 2020

it is been a while since I debugged this, so it is hard to remember all the details. but I can confirm that with the newest released version of horde we still have this issue, when we disable the patch from this PR.

the problem is probably related to the authentication method. we are using

$conf['auth']['params']['app'] = 'imp';
$conf['auth']['driver'] = 'application';

the problem as I understand it is:
0.

public function authenticate($userId, $credentials, $login = true)
authenticate is called

  1. at
    if (!empty($credentials['mode'])) {
    the view is remembered from the $credentials array
  2. at
    $registry->setAuth($userId, $credentials, array(
    setAuth is called
  3. at
    $this->loadPrefs($this->getApp());
    loadPrefs is called

now here i am not fully sure anymore, but I believe it was as follows:

  1. $this->pushApp($app);
    pushApp
  2. if ($this->isAuthenticated(array('app' => $app))) {
    isAuthenticated
  3. $res = $injector->getInstance('Horde_Core_Factory_Auth')->create($app)->transparent();
    a new instance of Horde_Core_Auth_Application is created. this instance has no access to the original $credentials array. transparent() is called
  4. return $result && $this->_setAuth();
    setAuth_ is called on that new instance
  5. $this->_setView();
    view is set to 'auto' by the new instance

at this point $GLOBALS['session']->exists('horde', 'view') is set to 'auto' and the first instance of the authentication object does not set it the the user supplied value, that was passed in the $credentials

@immerda
Copy link
Author

immerda commented Aug 25, 2020

@mrubinsk is there anything we could provide on our end here? I can confirm that the issue is related to the application auth driver.

@mrubinsk
Copy link
Member

Not really. I need to digest your code path. I'm using the exact same authentication driver(s) and am unable to reproduce.

@yunosh
Copy link
Member

yunosh commented Feb 28, 2021

Looking at _setView(), the $mode is only overwritten if either force_view is true, or select_view is false. Otherwise $this->_view is used which is set earlier in authenticate().

@immerda
Copy link
Author

immerda commented Feb 28, 2021

I'll try to understand your comment tomorrow. But I just want to note again that we have since this ticket was opened the patch in this PR applied to our deployment and the mode selection really does not work without it!

@immerda
Copy link
Author

immerda commented Mar 1, 2021

@yunosh

Looking at _setView(), the $mode is only overwritten if either force_view is true, or select_view is false. Otherwise $this->_view is used which is set earlier in authenticate().

The problem is that authenticate stores the view to _view (2) on the initial Horde_Core_Auth_Application.

But then the call to setAuth internally creates a second Horde_Core_Auth_Application instance (6), on which authenticate is not called, and thus has _view unset.

This secondary instance beats the first one to call setView(). This in turn means that !$GLOBALS['session']->exists('horde', 'view') is false and the actual view is never set.

@immerda
Copy link
Author

immerda commented Mar 1, 2021

And just to tripple confirm again, that this is really what is going on, I logged in with the following patch applied:

-        if (!$GLOBALS['session']->exists('horde', 'view')) {
+            $GLOBALS['notification']->push($this->_view);
             $this->_setView();
-        }

i.e. I disable the check if the view is already set and instead always set it. And I log every time it is set.

Then I see first 8 'auto' notifications (for each horde app being initialized as described in my initial diagnosis of the issue). And then the final notification is 'dynamic', which correctly sets the view and I am logged in with the correct view.

I really don't know what else I can do to convince you the bug is real...

@immerda
Copy link
Author

immerda commented Mar 1, 2021

I have a theory why you can't reproduce it: In our case the normal horde login form is bypassed by a custom SSO mechanism. Thus, normally the horde session is created when the user loads the login form. In our case the horde session is created in the same request as the post to /login.php. And that is probably why apps are initialized during authentication, which triggers this issue.

@yunosh
Copy link
Member

yunosh commented Mar 2, 2021

That's an important piece of information. Though, ff you use a SSO authentication, how are users selecting the view from the login screen?

@immerda
Copy link
Author

immerda commented Mar 2, 2021

Indeed, I did not realize that it plays a role here.

They select the view on a custom form and the SSO then logs them into horde, by relying them to horde's login.php, doing the exact same post request that the horde login form would do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants