-
Notifications
You must be signed in to change notification settings - Fork 121
Move to ManagedAuthenticator #21
Move to ManagedAuthenticator #21
Conversation
There was a problem hiding this 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| |
There was a problem hiding this comment.
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
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).
There was a problem hiding this comment.
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']) || |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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(), |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 👍
spec/plugin_spec.rb
Outdated
|
||
let(:auth) do | ||
{ 'credentials' => { 'token': 'token' }, | ||
{ 'provider' => 'oauth2_basic', |
There was a problem hiding this comment.
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
{ 'provider' => 'oauth2_basic', | |
OmniAuth::AuthHash.new { 'provider' => 'oauth2_basic', |
Then the tests will match production behaviour
There was a problem hiding this comment.
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.
spec/plugin_spec.rb
Outdated
@@ -170,7 +178,7 @@ def register_css(arg) | |||
expect { | |||
auth_result = authenticator.after_authenticate(auth) | |||
}.to change { job_klass.jobs.count }.by(0) | |||
|
|||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whitespace
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed!
@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. |
This PR follows up on the discussion here. It does two things:
Turns the
OAuth2BasicAuthenticator
class into an extension ofAuth::ManagedAuthenticator
instead ofAuth::OAuth2Authenticator
. Mostly this involves moving the after_authenticate result and user handling to the standardisedAuth::ManagedAuthenticator
after_authenticate method.Migrates the existing storage of associated user details from
PluginStore
toUserAssoicatedAccount
.The existing tests are all passing and existing implementations should not be affected.