Skip to content
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

redirect to admin login page when forward fails #2886

Merged
merged 2 commits into from
Dec 1, 2022

Conversation

stefan0xC
Copy link
Contributor

Currently, if the admin guard fails the user will get a 404 page instead of being forwarded to the login page.

This change addresses issues like #2880 and #2883 by implementing a default forward catcher for all admin pages so this comment is correct:

None => return Outcome::Forward(()), // If there is no cookie, redirect to login

@stefan0xC

This comment was marked as resolved.

@BlackDex
Copy link
Collaborator

I'm not sure if this will work as nicely.
Using this code, and when logged in, if i go to an invalid page lets say i go to /admin/userss/overview (note the extra s), that will also redirect me to the /admin page instead of showing me a 404.

Maybe the Request Guard should be change somehow, or we need to add extra functions which do not contain the AdminToken as a second rank which then redirects those back to the login page, which should in theory cause invalid endpoints to still show a 404 page instead of being redirected to the admin.

The "/<_..>" is to general in my opinion.
Unfortunately there is no way to have one function with multiple #[get()] attributes which would help instead of having to create specific functions for them all.

Now, I don't know if we are able to extract the registered routes, and match that within one single function, and based upon that either redirect to the admin login page, or return a 404. I haven't looked into it.

@BlackDex
Copy link
Collaborator

BlackDex commented Nov 15, 2022

Also, something that just popped up into my mind.
It would even be nicer if, in the case someone wasn't logged-in, we can redirect that person back to the page they wanted to go to. So, if i go to /admin/diagnostics, but i have to login first, redirect that person to something like /admin?redirect=/admin/diagnostics and act upon that or something, that would even be more user friendly.

Maybe, we could just show the login page on the /admin/diagnostics page, and upon login use the referrer to redirect them to the correct page?

@stefan0xC stefan0xC marked this pull request as draft November 17, 2022 10:41
@stefan0xC

This comment was marked as resolved.

src/api/admin.rs Outdated Show resolved Hide resolved
@stefan0xC

This comment was marked as resolved.

@stefan0xC stefan0xC marked this pull request as ready for review November 17, 2022 15:31
Copy link
Collaborator

@BlackDex BlackDex left a comment

Choose a reason for hiding this comment

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

I haven't tested this my self yet.
So, no clue how this is working out, and if there are other ways on handling this.

But using a _ for a variable as a parameter is not that nice i think, only because Rust will complain if you are not using it, i think there is an other way, but not from the top of my head.

src/api/admin.rs Outdated Show resolved Hide resolved
@stefan0xC stefan0xC force-pushed the forward-to-admin-login branch 3 times, most recently from fbdc849 to 24f30dc Compare November 18, 2022 06:35
@stefan0xC
Copy link
Contributor Author

stefan0xC commented Nov 24, 2022

While cleaning up my commit I noticed that the statement

/// Used for `Location` response headers, which must specify an absolute URI
/// (see https://tools.ietf.org/html/rfc2616#section-14.30).
fn admin_url(referer: Referer) -> String {
is kinda outdated. I think in practice most browsers supported relative URIs but the RFC has been obsoleted since 2014 (see RFC7231) and since June 2022 there has been a new consolidating RFC9110, which both officiall allow for URI-references and thus also relative URIs in the Location header.

As explained by this rejected errata the use of relative URIs is intended and "accurately reflects real-world usage" so I think it's fine to go back to using admin_page().

@BlackDex
Copy link
Collaborator

While cleaning up my commit I noticed that the statement

/// Used for `Location` response headers, which must specify an absolute URI
/// (see https://tools.ietf.org/html/rfc2616#section-14.30).
fn admin_url(referer: Referer) -> String {

is kinda outdated. I think in practice most browsers supported relative URIs but the RFC has been obsoleted since 2014 (see RFC7231) and since June 2022 there has been a new consolidating RFC9110, which both officiall allow for URI-references and thus also relative URIs in the Location header.

As explained by this rejected errata the use of relative URIs is intended and "accurately reflects real-world usage" so I think it's fine to go back to using admin_page().

MDN Also indicates the same: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Location

@stefan0xC
Copy link
Contributor Author

Okay, I've squashed everything into a single commit because I think I'm done.

@BlackDex
Copy link
Collaborator

BlackDex commented Nov 27, 2022

Hmm, this will break scripts which use the admin to modify users and orgs etc..
Like https://github.com/ViViDboarder/vaultwarden_ldap for example, but also custom user scripts who just POST a login to /admin.

I'm playing with it my self right now, and I think i have a nice solution. But unfortunately no time left today to continue working it out.

Basically, it kinda reverts almost everything, except the unauthorized catcher, and uses the render_admin_login with an extra Option<String> which contains the redirect value. But, for that to fully work, i also need to modify the post to of the form, and maybe some other stuff. But, that will have to wait for me at least.

currently, if the admin guard fails the user will get a 404 page.
and when the session times out after 20 minutes post methods will
give the reason "undefined" as a response while generating the support
string will fail without any user feedback.

this commit changes the error handling on admin pages

* by removing the reliance on Rockets forwarding and making the login
  page an explicit route that can be redirected to from all admin pages

* by removing the obsolete and mostly unused Referer struct we can
  redirect the user back to the requested admin page directley

* by providing an error message for json requests the
  `get_diagnostics_config` and all post methods can return a more
  comprehensible message and the user can be alerted

* the `admin_url()` function can be simplified because rfc2616 has been
  obsoleted by rfc7231 in 2014 (and also by the recently released
  rfc9110) which allows relative urls in the Location header.

  c.f. https://www.rfc-editor.org/rfc/rfc7231#section-7.1.2 and
  https://www.rfc-editor.org/rfc/rfc9110#section-10.2.2
revert some changes and also rename catcher to `admin_login` to make its
function clearer

Co-authored-by: BlackDex <black.dex@gmail.com>
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