diff --git a/plugin.rb b/plugin.rb index df9a3d9..4d8739a 100644 --- a/plugin.rb +++ b/plugin.rb @@ -71,6 +71,10 @@ class OAuth2FaradayFormatter < Faraday::Logging::Formatter end end +# You should use this register if you want to add custom paths to traverse the user details JSON. +# We'll store the value in the user associated account's extra attribute hash using the full path as the key. +DiscoursePluginRegistry.define_filtered_register :oauth2_basic_additional_json_paths + class ::OAuth2BasicAuthenticator < Auth::ManagedAuthenticator def name 'oauth2_basic' @@ -164,8 +168,8 @@ class ::OAuth2BasicAuthenticator < Auth::ManagedAuthenticator end end - def json_walk(result, user_json, prop) - path = SiteSetting.public_send("oauth2_json_#{prop}_path") + def json_walk(result, user_json, prop, custom_path: nil) + path = custom_path || SiteSetting.public_send("oauth2_json_#{prop}_path") if path.present? #this.[].that is the same as this.that, allows for both this[0].that and this.[0].that path styles path = path.gsub(".[].", ".").gsub(".[", "[") @@ -229,6 +233,11 @@ class ::OAuth2BasicAuthenticator < Auth::ManagedAuthenticator json_walk(result, user_json, :email) json_walk(result, user_json, :email_verified) json_walk(result, user_json, :avatar) + + DiscoursePluginRegistry.oauth2_basic_additional_json_paths.each do |detail| + prop = "extra:#{detail}" + json_walk(result, user_json, prop, custom_path: detail) + end end result else @@ -259,6 +268,10 @@ class ::OAuth2BasicAuthenticator < Auth::ManagedAuthenticator ['name', 'email', 'email_verified'].each do |property| auth['info'][property] = fetched_user_details[property.to_sym] if fetched_user_details[property.to_sym] end + + DiscoursePluginRegistry.oauth2_basic_additional_json_paths.each do |detail| + auth['extra'][detail] = fetched_user_details["extra:#{detail}"] + end else result = Auth::Result.new result.failed = true diff --git a/spec/plugin_spec.rb b/spec/plugin_spec.rb index 999bbc0..864d8e8 100644 --- a/spec/plugin_spec.rb +++ b/spec/plugin_spec.rb @@ -122,6 +122,31 @@ describe OAuth2BasicAuthenticator do result = authenticator.after_authenticate(auth) expect(result.failed).to eq(true) end + + describe 'fetch custom attributes' do + after { DiscoursePluginRegistry.reset! } + + let(:response) do + { + status: 200, + body: '{"account":{"email":"newemail@example.com","custom_attr":"received"}}' + } + end + + it 'stores custom attributes in the user associated account' do + custom_path = 'account.custom_attr' + DiscoursePluginRegistry.register_oauth2_basic_additional_json_path( + custom_path, + Plugin::Instance.new + ) + stub_request(:get, SiteSetting.oauth2_user_json_url).to_return(response) + + result = authenticator.after_authenticate(auth) + associated_account = UserAssociatedAccount.last + + expect(associated_account.extra[custom_path]).to eq("received") + end + end end context 'avatar downloading' do