Adding SSO after many users already signed up -- how to migrate them?

Hi all.

What is the proper way to import all existing Discourse users to from Discourse? Is there some sort of REST endpoint that returns all users with their hashed passwords and salts, among other things? What is the link to the hash algorithm on github? I will have to code on our side, to use the same hash algorithm with the entered password and salt, if our own doesn’t work, in order to let those guys log in. I think #2 is relevant whenever a Discourse user turns on SSO later (like we are) so solving it would help other Discourse users too.

1 Like

Interesting approach.

In user.rb

  def confirm_password?(password)
    return false unless password_hash && salt
    self.password_hash == hash_password(password, salt)

  def hash_password(password, salt)
    raise"password is too long") if password.size > User.max_password_length
    Pbkdf2.hash_password(password, salt, Rails.configuration.pbkdf2_iterations, Rails.configuration.pbkdf2_algorithm)

and then Pbkdf2 code is here: discourse/pbkdf2.rb at 201228162c277b9833bb2988388553fdbfb39521 · discourse/discourse · GitHub

1 Like

Excellent! Now what is the HTTP endpoint that I call in order to get all the user info, including password hash and salt?

I imagine that there isn’t one to serve up to the public at large (why make it easier to hack people?) So what can I do? Connect to the MySQL database? Write a Discourse plugin?

Those are basically your options, yes.

Is the database schema documented anywhere?

How to connect to the postgres database in the docker? Sorry if it’s a silly question.

I just spoke to our team, and they agree, I’m prepared to pay someone to build a small Discourse plugin that would expose via an endpoint some JSON info about a user, given their email address.

I found discourse/user.rb at main · discourse/discourse · GitHub has “password_hash” salt and name, username. But it doesn’t have email. For that, I see user_email discourse/user_email.rb at main · discourse/discourse · GitHub

So given an email the plugin will just search user_email table by the mail, then find user_id and grab the user row, and send all the “safe” fields, including the salt.

For extra security, the requests can be signed via HMAC using a shared secret that can be provided to the plugin.

Does anyone want to make this one? Message me or reply here and let me know how to contact you. Hopefully it’s straightforward (a couple SELECTs and a check for HMAC if the secret was set). We’ll read the JSON.

I would just use the existing admin/users/list/active.json and extend the response with the hashed passwords.

Also, stick to the existing API authentication mechanism, don’t reinvent another wheel.

So you’re saying have a one-time thing that imports all users joined with all their salts and passwords?

Fine but that still needs to be a plugin, does it not? So it would be great if someone with Discourse can create that.

I would probably use the data explorer plugin to export the info you want. It’ll be much easier than writing a new plugin.

1 Like