UserAuthToken error when trying to create new User in AuthProvider


(Kevin Robinson) #1

(Spun out of Reports of user logged out twice today - related to recent auth tokens changes?)

On v1.8.0.beta4 +116, users are seeing errors trying to sign in using an auth_provider we wrote.

Here’s the trace:

/var/www/discourse/app/models/user_auth_token.rb:16:in `generate!'
/var/www/discourse/lib/auth/default_current_user_provider.rb:133:in `log_on_user'
/var/www/discourse/lib/current_user.rb:18:in `log_on_user'
/var/www/discourse/app/controllers/users/omniauth_callbacks_controller.rb:125:in `user_found'
/var/www/discourse/app/controllers/users/omniauth_callbacks_controller.rb:104:in `complete_response_data'
/var/www/discourse/app/controllers/users/omniauth_callbacks_controller.rb:63:in `complete'

The auth_provider is supporting authenticating through LTI from EdX (our code here: discourse-edx-lti/lti_authenticator.rb at master · mit-teaching-systems-lab/discourse-edx-lti · GitHub). This is a bit different than an OAuth provider flow. In our case:

  1. EdX sends a POST to /auth/:provider/callback with a bunch of params
  2. Our auth_provider validates those params, and then grabs an email address out of them
  3. Our auth_provide finds or creates a User by that email address. This enables there being no “sign up” flow for users (that’s the whole point of LTI).

This works great for existing users, but is trickier for first-time users. The omniauth_callback_controller has assumptions about the sign up/log in flows, and expects a User to be set on the auth_result. So for first-time users we pass it a new User record that hasn’t been saved yet, and it saves it. I suspect something about the UserAuthToken change is problematic, or maybe that the user.save line is failing for some reason.

The most obvious thing seems to directly create the new User record in the auth_provider, and work around this, since I suspect my use of auth_provider is not what the OmniAuth controller code expects. Also, apologies if this is the wrong place to ask about this and if it’s too close to a question about developing a new feature than it is to a proper bug report. Thanks!


Reports of user logged out twice today - related to recent auth tokens changes?
(Matt Palmer) #2

Yeeeeeah, I suspect you’re going to have to save the user you’re creating before asking for a token for them. I’m honestly quite surprised it ever worked as you’ve currently implemented it, but you’re definitely going to have to change it now.


(Kevin Robinson) #3

@mpalmer Thanks!

Yeah, it worked great two weeks ago, but there was no UserAuthToken class then :slight_smile:

For now, I’m essentially just moving the code in omniauth_callbacks_controller into the AuthProvider:

# Lookup or create a new User record.
user = User.find_or_initialize_by({
  email: auth_result.email,
  username: auth_result.username
})
if user.new_record
  user.staged = false
  user.active = true
  user.password = SecureRandom.hex(32)
  user.password_required!
  user.save!
  user.reload
end

(Create user in auth_provider#after_authenticate by kevinrobinson · Pull Request #7 · mit-teaching-systems-lab/discourse-edx-lti · GitHub for anyone curious)

What’s confusing to me still is that I can’t reliably reproduce the bug on my end, and our users who experience it can sign in from EdX on the first try, but then can’t get back in on the second. I’m wondering if it’s related to expire_tokens_if_password_changed getting called, but haven’t dug into that yet.