29th / personnel-v3

Personnel management system version 3
https://www.29th.org
2 stars 6 forks source link

Allow non-members to sign in on 29th.org #231

Closed wilson29thid closed 6 months ago

wilson29thid commented 7 months ago

Currently 29th.org has a 'Sign In' link that directs users over to the discourse forum to sign in, then it returns them back to the 29th.org page they were on. 29th.org looks at their forum session, tries to find a matching member record in our personnel database, and, if a match is found, the user is "signed in" on 29th.org as that personnel member. If no match is found in the personnel database, e.g. because they've never enlisted or it's a new forum account, they'll remain signed in on the forums, but they won't be signed in on 29th.org.

Here's the code that handles that

This has worked fine because the things you need to be signed in for on 29th.org are for members only anyway. But it will pose a problem now that we're migrating the enlistment functionality: new applicants won't have an existing member record in the personnel database. So we need to somehow have 29th.org keep hold of their forum session so that they can use it to enlist. At that point, a member record will be created, but it needs to be linked to their forum account.

The nice thing is that Discourse's SSO is clever enough to redirect the user back to the place they initiated the process, it seems. So if we have a login button on 29th.org/enlist, and they use it to register, even though they actually end up clicking an activation link in their email, which opens a new tab, they should still be redirected back to 29th.org/enlist, which will be a much nicer flow than the current one.

The SSO plugin, omniauth-discourse, makes the following pieces of discourse user data available

      uid do
        user_info[:external_id]
      end

      info do
        {
          "name" => user_info[:name],
          "email" => user_info[:email],
          "nickname" => user_info[:username]
        }
      end

      extra do
        {
          "admin" => user_info[:admin] == "true",
          "moderator" => user_info[:moderator] == "true"
        }
      end