FEATURE: Allow specifiying required paths when retrieving userinfo

This commit is contained in:
Nat 2024-01-31 12:43:28 +08:00
parent 05cefd5ecd
commit c7e88e2086
No known key found for this signature in database
GPG Key ID: 4938B35D927EC773
2 changed files with 63 additions and 0 deletions

View File

@ -78,6 +78,12 @@ end
# We'll store the value in the user associated account's extra attribute hash using the full path as the key. # 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 DiscoursePluginRegistry.define_filtered_register :oauth2_basic_additional_json_paths
# After authentication, we'll use this to confirm that the registered json paths are fulfilled,
# or display an error message to the user.
# This requires SiteSetting.oauth2_fetch_user_details? to be true, and can be used with
# DiscoursePluginRegistry.oauth2_basic_additional_json_paths.
DiscoursePluginRegistry.define_filtered_register :oauth2_basic_required_json_paths
class ::OAuth2BasicAuthenticator < Auth::ManagedAuthenticator class ::OAuth2BasicAuthenticator < Auth::ManagedAuthenticator
def name def name
"oauth2_basic" "oauth2_basic"
@ -312,6 +318,15 @@ class ::OAuth2BasicAuthenticator < Auth::ManagedAuthenticator
DiscoursePluginRegistry.oauth2_basic_additional_json_paths.each do |detail| DiscoursePluginRegistry.oauth2_basic_additional_json_paths.each do |detail|
auth["extra"][detail] = fetched_user_details["extra:#{detail}"] auth["extra"][detail] = fetched_user_details["extra:#{detail}"]
end end
DiscoursePluginRegistry.oauth2_basic_required_json_paths.each do |x|
if fetched_user_details[x[:path]] != x[:required_value]
result = Auth::Result.new
result.failed = true
result.failed_reason = x[:error_message]
return result
end
end
else else
result = Auth::Result.new result = Auth::Result.new
result.failed = true result.failed = true

View File

@ -122,6 +122,54 @@ describe OAuth2BasicAuthenticator do
expect(associated_account.extra[custom_path]).to eq("received") expect(associated_account.extra[custom_path]).to eq("received")
end end
end end
describe "required attributes" do
after { DiscoursePluginRegistry.reset_register!(:oauth2_basic_required_json_paths) }
it "'authenticates' successfully if required json path is fulfilled" do
DiscoursePluginRegistry.register_oauth2_basic_additional_json_path(
"account.is_legit",
Plugin::Instance.new,
)
DiscoursePluginRegistry.register_oauth2_basic_required_json_path(
{ path: "extra:account.is_legit", required_value: true },
Plugin::Instance.new,
)
response = {
status: 200,
body: '{"account":{"email":"newemail@example.com","is_legit":true}}',
}
stub_request(:get, SiteSetting.oauth2_user_json_url).to_return(response)
result = authenticator.after_authenticate(auth)
expect(result.failed).to eq(false)
end
it "fails 'authentication' if required json path is unfulfilled" do
DiscoursePluginRegistry.register_oauth2_basic_additional_json_path(
"account.is_legit",
Plugin::Instance.new,
)
DiscoursePluginRegistry.register_oauth2_basic_required_json_path(
{
path: "extra:account.is_legit",
required_value: true,
error_message: "You're not legit",
},
Plugin::Instance.new,
)
response = {
status: 200,
body: '{"account":{"email":"newemail@example.com","is_legit":false}}',
}
stub_request(:get, SiteSetting.oauth2_user_json_url).to_return(response)
result = authenticator.after_authenticate(auth)
expect(result.failed).to eq(true)
expect(result.failed_reason).to eq("You're not legit")
end
end
end end
describe "avatar downloading" do describe "avatar downloading" do