`run_second_factor!` failing when trying to promote admin

Following on Can't upgrade user to admin - unhandled server error

(Hey @Discoursenaut.) I spent all afternoon on this. I still can’t track down what the problem actually is, but if I add a rescue around line 1099 (`manager.run!') the mysterious “An unhandled server error has occurred.” Error. I can’t find that string anywhere in the source.

Catching the error doesn’t help since result isn’t defined, so it fails later.

I’ve tried this will all perrmutations of having the user with 2fa enabled/not enabled, enforce_second_factor off/staff. Strangely, when I added my user today and tried to make it an admin from another admin account, it worked as expected, but no other admins can make any other users admins. They say this has been a problem for a year. Could there be some database issue?

It’s a recent build (at least one today). Only standard plugins and even with safe-mode.

@Osama , you have a comment a couple lines later, maybe you have an idea?

Not seeing how result can be undefined given:

Are you absolutely sure you are on absolute latest?

1 Like

I ran a rebuild today.

Is there somewhere else I can put a debug log?

If you can get us a minimal reproduction (like list of site settings and their values) that would help a lot.

Can you rescue the entire method and log the error?

def run_second_factor!(action_class, action_data: nil, target_user: current_user)
  if current_user && target_user != current_user
    # Anon can run 2fa against another target, but logged-in users should not.
    # This should be validated at the `run_second_factor!` call site.
    raise "running 2fa against another user is not allowed"
  end

  action = action_class.new(guardian, request, opts: action_data, target_user: target_user)
  manager = SecondFactor::AuthManager.new(guardian, action, target_user: target_user)
  yield(manager) if block_given?
  result = manager.run!(request, params, secure_session)

  if !result.no_second_factors_enabled? && !result.second_factor_auth_completed? &&
       !result.second_factor_auth_skipped?
    # should never happen, but I want to know if somehow it does! (osama)
    raise "2fa process ended up in a bad state!"
  end

  result
+rescue => err
+  Rails.logger.error(err.full_message)
+  raise
end

Something should show up in /logs once you make this change (and reload Unicorn workers) and that should help us figure out what the problem is.

2 Likes

Sigh. It looks like the error in run_second_factor! was from my debugging statements; causing bugs when looking for them is one of my favorite pastimes.

Started PUT "/admin/users/30591/grant_admin" for 174.50.213.142 at 2024-07-02 14:14:38 +0000
Processing by Admin::UsersController#grant_admin as */*
  Parameters: {"user_id"=>"30591"}
Completed 403 Forbidden in 6ms (Views: 0.1ms | ActiveRecord: 0.0ms | Allocations: 2263)

I guess that the guardian is not allowing me to make the user an admin for some reason.

But I still don’t understand why it’s failing and why it’s got An unhandled server error has occurred. as the error, when I can’t find that error anywhere in the Discourse code.

Ah. And this is interesting. I have been able to change from jay@example.com to myaddress@gmail.com, but trying to confirm an address of myaddress+123@gmail.com is also getting “An unhandled server error has occurred.” message. normalize_emails is not set.

I think that something is wrong with run_second_factor!, but I can’t quite figure out what. I’m adding some Rails.logger.warn with some xxx.inspects, so maybe I’ll find something.

Best I can figure something is wrong with the auth_manager. It seems like maybe it’s trying to redirect for some reason? Normal users aren’t required to have 2fa, so I don’t know why a regular user wouldn’t be able to change their email address. But I’ve tried with a user with no 2fa, backup codes, logged in before clicking the confirm new email link and after logged in and all fail with “An unhandled server error has occurred.”

This seems related:

The 403 error is normal and expected — the frontend app catches the 403 response and interprets it as “can’t grant admin because 2FA is required, let’s navigate to the 2FA page”.

What is not normal is:

Can you tell me where you’re seeing this error? Is it a popup in the frontend? Error in logs? As you mention, I cannot find this error message anywhere in the entire history of the codebase, so it’s very weird.

So maybe the back end isn’t rendering the stuff that has the 2FA URL in it? But the error happens regardless of whether the user has 2fa turned on and regardless of whether the force-2fa sitesetting is enabled. And regardless of whether the user is logged in with 2fa already set.

image

Right. I’ve tried safe-mode, but these are the plugins:

          - git clone https://github.com/discourse/docker_manager.git
          - git clone https://github.com/discourse/discourse-topic-voting.git
          - git clone https://github.com/discourse/discourse-chat-integration.git
          - git clone https://github.com/discourse/discourse-solved.git
          - git clone https://github.com/discourse/discourse-reactions.git
          - git clone https://github.com/discourse/discourse-docs.git
          - git clone https://github.com/discourse/discourse-user-notes.git

The only clue that I’ve found is that it implies that the message is coming from Rails itself. Still, I’ve been unable to catch how that could be happening.

So maybe something is at play that’s triggering “we need 2fa” when, in fact, 2fa isn’t needed. It certainly makes sense that an error would get triggered to do 2fa login when none exists. I guess that’s in guardian? I can’t figure out where to put debugging Rails.logger stuff to debug that.

1 Like

This is a very long shot so my apologies when I am saying something totally ridiculous… but googling for " An unhandled server error has occurred" refers only to Bitwarden code which leads me to believe that there might be something on your local system that is intercepting / messing with your request. Is this something you can reproduce from another computer?

2 Likes

Can you check the networks tab in the dev tools of your browser and see what the response looks like for the request to the grant_admin endpoint?

Please also show the Payload tab.

2 Likes

image

This seems to be coming from the server. I can’t find that string in the database (say in customized text) or grepping all of /var/www/discourse

There is no Payload tab:

image

Wait!!! I restored the database to another server and it properly redirects to the second factor page, which, after getting the second factor key, immediately changes the user’s admin status (no email required! which I didn’t know!).

So it’s something with . . . something, but a clean mostly-standard install resolves the problem. In any case, not (obviously?) a :discourse: :bug: . I changed the category.

The other potential explanation, which also seems far-fetched, is that there is something somehow wrong with the UserSecondFactor model, as I did a UserSecondFactor.all.destroy_all;UserSecurityKey.all.destroy_all; on my test server since it had a different domain name. I also used Google authenticator instead of my Yubi key.

1 Like