Skip to content
This repository was archived by the owner on Jul 14, 2025. It is now read-only.

Conversation

angusmcleod
Copy link
Contributor

This PR follows up on the discussion here. It does two things:

  1. Turns the OAuth2BasicAuthenticator class into an extension of Auth::ManagedAuthenticator instead of Auth::OAuth2Authenticator. Mostly this involves moving the after_authenticate result and user handling to the standardised Auth::ManagedAuthenticator after_authenticate method.

  2. Migrates the existing storage of associated user details from PluginStore to UserAssoicatedAccount.

The existing tests are all passing and existing implementations should not be affected.

@angusmcleod angusmcleod changed the title Move plugin methods && migrate old data Move to ManagedAuthenticator Jul 24, 2019
Copy link
Member

@davidtaylorhq davidtaylorhq left a comment

Choose a reason for hiding this comment

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

This is looking good - thanks @angusmcleod!

I've added a few small comments. The main thing is that we would like to keep database migrations as pure SQL, rather than using ActiveRecord.

@@ -0,0 +1,24 @@
class MoveToManagedAuthenticator < ActiveRecord::Migration[5.2]
def change
::PluginStoreRow.where(plugin_name: 'oauth2_basic').each do |record|
Copy link
Member

Choose a reason for hiding this comment

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

We like to keep migrations clear of any specific ruby code - that way they won't break if anything changes with PluginStoreRow or UserAssociatedAccount in future. It should be possible to do the migration in pure SQL, like

https://github.com/discourse/discourse-steam-login/blob/master/db/migrate/20190510055357_migrate_steam_auth_data.rb

You can even do the JSON parsing using something like

plugin_store_row.value::json->'user_id'

For now, let's just migrate the data to UserAssociatedAccount, and leave the old data in PluginStoreRows. Then later we can add a post deploy migration to delete the old data (needs to be post deploy so that authentication doesn't break for the few minutes during deployment).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah cool. I've made this change 👍

plugin.rb Outdated
@@ -135,63 +139,36 @@ def fetch_user_details(token, id)
nil
end
end

def primary_email_verified?(auth)
ActiveModel::Type::Boolean.new.cast(auth['info']['email_verified']) ||
Copy link
Member

Choose a reason for hiding this comment

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

I'm curious why this was required. Do you have an authentication system which was returning "true" as a string, rather than a native boolean?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

tbh I can't recall, but yes, that was what this would have been guarding against. We could take it out, but do you feel it poses a risk leaving it in?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've taken out the cast 👍

plugin.rb Outdated
override_gravatar: SiteSetting.sso_overrides_avatar
) if user && avatar_url.present?

super(auth.with_indifferent_access)
Copy link
Member

Choose a reason for hiding this comment

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

This should not be required. The auth object should be an instance of OmniAuth::AuthHash, which already supports indifferent access, and has also access via . syntax

[2] pry(main)> hash = OmniAuth::AuthHash.new({info: {name: "test"}})
=> {"info"=>{"name"=>"test"}}
[3] pry(main)> hash[:info]
=> {"name"=>"test"}
[4] pry(main)> hash["info"]
=> {"name"=>"test"}
[5] pry(main)> hash.info
=> {"name"=>"test"}

I suspect the problem here is that the tests are using normal hashes, rather than OmniAuth::AuthHash instances

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, right on the money. I've moved the with_indifferent_access to the auth hashes in the tests

plugin.rb Outdated
@@ -200,7 +177,7 @@ def enabled?
end

auth_provider title_setting: "oauth2_button_title",
authenticator: OAuth2BasicAuthenticator.new('oauth2_basic'),
authenticator: OAuth2BasicAuthenticator.new(),
Copy link
Member

Choose a reason for hiding this comment

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

Nitpick: the brackets are not required if there are no arguments. Ditto in a few other places

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fair. I've removed these 👍


let(:auth) do
{ 'credentials' => { 'token': 'token' },
{ 'provider' => 'oauth2_basic',
Copy link
Member

Choose a reason for hiding this comment

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

As mentioned above, this should be changed to

Suggested change
{ 'provider' => 'oauth2_basic',
OmniAuth::AuthHash.new { 'provider' => 'oauth2_basic',

Then the tests will match production behaviour

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup also fair. I've made that change.

@@ -170,7 +178,7 @@ def register_css(arg)
expect {
auth_result = authenticator.after_authenticate(auth)
}.to change { job_klass.jobs.count }.by(0)

Copy link
Member

Choose a reason for hiding this comment

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

Whitespace

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed!

@angusmcleod
Copy link
Contributor Author

@davidtaylorhq Thanks for the detailed review! I've followed up on each piece of feedback. Let me know if there's anything else you'd like me to change.

@davidtaylorhq davidtaylorhq merged commit 5ae9f35 into discourse:master Jul 27, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants