Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Conversation

acran
Copy link

@acran acran commented Feb 12, 2024

What type of PR?

Feature

What does this PR do?

This adds a button to the user list for admins to open the webmailer as another user.

Related issue(s)

Prerequisites

Before we can consider review and merge, please make sure the following list is done and checked.
If an entry in not applicable, you can check it or remove it from the list.

  • In case of feature or enhancement: documentation updated accordingly
  • Unless it's docs or a minor change: add changelog entry file.

Copy link
Contributor

mergify bot commented Feb 12, 2024

Thanks for submitting this pull request.
Bors-ng will now build test images. When it succeeds, we will continue to review and test your PR.

bors try

Note: if this build fails, read this.

bors-mailu bot added a commit that referenced this pull request Feb 12, 2024
@bors-mailu
Copy link
Contributor

bors-mailu bot commented Feb 12, 2024

try

Build succeeded:

@nextgens nextgens added type/security Related to security type/feature Introduces a new feature review/need2 This will block Mergify untill 2 reviews are done labels Feb 12, 2024
Diman0
Diman0 previously requested changes Apr 2, 2024
Copy link
Member

@Diman0 Diman0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR looks interesting. I can imagine that many people find this an interesting feature.

The functionality appears to work fine. When trying to visit the webmail/ url when logged in with a non-admin user, you receive a 403 error (As expected).

Since new elements are added to the UI (extra buttons for a user on the user list), it must be added to the documentation.
webadminstration.rst. More specifically here:

This page is also accessible for domain managers. On the users page new users can be added via the Add user button (top right of page). For existing users the following options are available via the columns Actions and User settings (from left to right)

When using roundcube a banner is displayed in top with the information that you are impersonating an user. However this is missing for snappymaill.
If you don't know how to add a banner for SnappyMail, then I recommend creating a discussion here asking how to do this:
https://github.com/the-djmaze/snappymail/discussions

@acran acran force-pushed the feature/impersonation branch from bdb7128 to b6b668c Compare April 3, 2024 13:47
@mergify mergify bot dismissed Diman0’s stale review April 3, 2024 13:48

Pull request has been modified.

@acran
Copy link
Author

acran commented Apr 3, 2024

Since new elements are added to the UI (extra buttons for a user on the user list), it must be added to the documentation.
webadminstration.rst.

Thank you for the suggestion. I know added the information on the new buttons to the documentation there.
(I also amended the a previous commit to only show the webmail button only if webmail is actually enabled)

When using roundcube a banner is displayed in top with the information that you are impersonating an user. However this is missing for snappymaill.

Yes, I had skipped snappymail since I was unable to correctly configure it for local testing (see #3162).

Having had a look again now into snappymail, it seems to me that snappymail does not provide a straight-forward API to easily add a simple banner when logged in as another user the same way as with roundcibe. So I'm a bit skeptical whether the effort required to implement this analogously to roundcube is really worth it...

@nextgens is adding the same banner to snappymail a hard requirement for this PR? Would there be maybe another way than a banner to notify the user which may be easier to implement in snappymail?

And besides this: is there anything else blocking this PR from being merged?

@nextgens
Copy link
Contributor

Can't we just frame the webmails when impersonation is in use?

@acran acran force-pushed the feature/impersonation branch from b6b668c to a8dbc5c Compare May 8, 2024 12:46
@acran
Copy link
Author

acran commented May 8, 2024

@nextgens I (rebased and) added a PoC for a framed webmail with impersonation in a8dbc5c.

But in my opinion framing does not provide the best user experience and can be confusing. Because the webmailer will use the same session cookie with and without framing. So having an open tab with the admin user's normal mailbox while opening another user's mailbox with impersonation will also switch the session in the open tab to the other user's mailbox - but without the alert.

Also, having the impersonated mailbox opened in a frame (especially when keeping the mailu admin navigation as in this PoC, but that can easily be removed, though) could imply to the user that impersonation is only active in that window...

So, I'd rather let the webmailer itself handle everything instead.

But let me know which route you want to go here, and I can update the PR accordingly.

@acran
Copy link
Author

acran commented Aug 12, 2024

@nextgens anything I can do to move this PR forward?

@nextgens
Copy link
Contributor

bors try

bors-mailu bot added a commit that referenced this pull request Aug 12, 2024
@bors-mailu
Copy link
Contributor

bors-mailu bot commented Aug 12, 2024

try

Build succeeded:

@nextgens
Copy link
Contributor

nextgens commented Aug 12, 2024

But in my opinion framing does not provide the best user experience and can be confusing. Because the webmailer will use the same session cookie with and without framing. So having an open tab with the admin user's normal mailbox while opening another user's mailbox with impersonation will also switch the session in the open tab to the other user's mailbox - but without the alert.

Also, having the impersonated mailbox opened in a frame (especially when keeping the mailu admin navigation as in this PoC, but that can easily be removed, though) could imply to the user that impersonation is only active in that window...

Those are good points; We do not want that.

Would it be doable/better to have a separate 'virtual' path for each webmail instance? So that one could open several tabs with different inboxes at the same time without having things breaking.

Say redirect to /webmail-as/test@example.com/ and have nginx proxy that too? If the path is different we may have different cookies too (so completely different parallel webmail sessions).

So, I'd rather let the webmailer itself handle everything instead.

I wanted to try out framing as that is what would be maintenance free; I am not opposed to doing it differently. If the visual indication is in the URL maybe we don't need the UX to change at all.

But let me know which route you want to go here, and I can update the PR accordingly.

As is snappymail is broken (it sets some anti-framing headers).

I'd love if you could try to make the parallel webmail session thing to work. In the future we would/could even offer all webmails by default (/webmail would redirect to either /roundcube or /snappymail)

acran added 10 commits August 23, 2024 11:58
This allows admins to login to webmail as another user.
The impersonating user is also passed to the webmail container in the
X-Remote-Original-User header.

see discussion in Mailu#3106
action=login has no effect without task=login so the authenticate hook
was never actually called in these situations
Now the currently logged-in user might change when an admin user is
impersonating another user. In that case roundcube must go trigger its
internal login again.
see Mailu#3163 (comment)

But this commit needs some more work and/or refactoring to be merged!
@acran acran force-pushed the feature/impersonation branch from a8dbc5c to 2eea2a4 Compare August 23, 2024 14:18
@acran acran marked this pull request as draft August 23, 2024 14:18
@acran
Copy link
Author

acran commented Aug 23, 2024

Would it be doable/better to have a separate 'virtual' path for each webmail instance? So that one could open several tabs with different inboxes at the same time without having things breaking.

Say redirect to /webmail-as/test@example.com/ and have nginx proxy that too?

I implemented this with 2eea2a4. It is working but I'm not sure if it really is worth it because it requires a lot of additional complexity for the integration:

First, for the webmail to be available under multiple URLs we not only need to make it available with different base URLs but even under dynamic base URLs to include the e-mail address.
Since the front nginx rewrites the request URI the original/dynamic URL gets lost. I "solved" this by passing the correct base URL as an additional X-Remote-Base-Url header to the webmail nginx:

proxy_set_header X-Remote-Base-Url {{ WEB_WEBMAIL }};

proxy_set_header X-Remote-Base-Url {{ WEB_ADMIN }}/webmail-as/$user_email;

This then has to be handled by nginx as well as the PHP code:

fastcgi_param SCRIPT_NAME $http_x_remote_base_url$fastcgi_script_name;

$config['request_path'] = $_SERVER['HTTP_X_REMOTE_BASE_URL'];

If the path is different we may have different cookies too (so completely different parallel webmail sessions).

Yes, having different path for each mailbox this is possible by using proxy_cookie_path to limit the cookies set by the webmail to the proxied path in front.
But this may cause unexpected issues if the path overlap, e.g., with WEB_WEBMAIL=/.

Another problem was that auth_request does not allow to use variables in the auth URL. So to pass the impersonated user e-mail from the request I again had to add an additional X-User-Email header:

location ~ ^{{ WEB_ADMIN }}/webmail-as/([^/]+)/sso.php$ {
set $user_email $1;

if ($user_email = false) {
set $user_email '';
}
proxy_set_header X-User-Email $user_email;

email = flask.request.headers.get('X-User-Email', original_email)

All of this already adds much complexity. Additionally it probably also still requires some refactoring on how the valid webmail token(s) are stored in the session. Because up until now there is always only one valid token in the session and previously we differentiated the user (original user or impersonated user) by storing the e-mail in the session as well. But now there could be multiple valid e-mail/token combinations.
Should we re-use the same token in the session for all e-mails? Or should we rather use a new token when impersonating? I guess, both would work...

If this solution should be used, I can try to polish up the commits again, so what do you think?

@acran
Copy link
Author

acran commented Oct 5, 2024

@nextgens after thinking about it a bit more: having a dedicated proxied path for impersonated webmail is actually quite neat and provides the best UX be even allowing to have two different mailboxes open side by side in the same browser session.
Implementing that cleanly though still requires some refactoring of the admin service in how the tokens are stored in the session. I can take a shot at it if wanted.

The issue with conflicting cookies in case when WEB_WEBMAIL overlaps with the impersonating path can not really be resolved though (it would probably required some kind of cookie-rewriting middleware, which would blow up complexity...).

So it stand to reason whether the added complexity is really worth the result since it'll probably still be a rarely used feature...

How best to proceed here?

@nextgens
Copy link
Contributor

nextgens commented Oct 5, 2024

@nextgens after thinking about it a bit more: having a dedicated proxied path for impersonated webmail is actually quite neat and provides the best UX be even allowing to have two different mailboxes open side by side in the same browser session. Implementing that cleanly though still requires some refactoring of the admin service in how the tokens are stored in the session. I can take a shot at it if wanted.

The issue with conflicting cookies in case when WEB_WEBMAIL overlaps with the impersonating path can not really be resolved though (it would probably required some kind of cookie-rewriting middleware, which would blow up complexity...).

I am not sure I am following regarding overlapping paths; We could use proxy_cookie_path to ensure we maintain independent cookies with the same names but different paths, no?

So it stand to reason whether the added complexity is really worth the result since it'll probably still be a rarely used feature...

How best to proceed here?

I am not sure either

@acran
Copy link
Author

acran commented Oct 5, 2024

I am not sure I am following regarding overlapping paths; We could use proxy_cookie_path to ensure we maintain independent cookies with the same names but different paths, no?

Yes, this works and is utilized by this PR, see e.g.

proxy_set_header X-Remote-Base-Url {{ WEB_ADMIN }}/webmail-as/$user_email;
proxy_cookie_path / {{ WEB_ADMIN }}/webmail-as/$user_email;

But there is an edge case with WEB_WEBMAIL=/ and e.g. WEB_ADMIN=/admin. With that the regular webmail will be available at path / while an impersonated webmail is at path /admin/webmail-as/$user_email. Since the latter is a subpath of the former the browser can mix up the session cookies for the normal and the impersonated webmails.

With something like WEB_WEBMAIL=/webmail and WEB_ADMIN=/admin this works without issues, though.

@nextgens
Copy link
Contributor

nextgens commented Oct 6, 2024

I don't see that as a problem: we won't be backporting the feature and personally I am okay with removing WEB_* variables in the name of simplicity for next release.

We are already instructing those that do run reverse proxies to forward everything for Mailu's FQDNs to Mailu.

@acran
Copy link
Author

acran commented Oct 6, 2024

personally I am okay with removing WEB_* variables in the name of simplicity for next release.

Is this already on the roadmap? Because I see these config options as a valuable feature and would want to see them gone - especially not for this 😅

I don't see that as a problem

Aside from this single edge case me neither. Even keeping the WEB_* variables this could be "fixed" by adding a warning to the documentation or maybe a sanity check into the admin scripts...

So anyway, should I then proceed with the necessary changes to cleanup the storage of tokens in the session so we can bring this PR to a merge?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review/need2 This will block Mergify untill 2 reviews are done type/feature Introduces a new feature type/security Related to security

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.