Skip to content
This repository was archived by the owner on Jul 14, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions plugin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,18 @@ def response(env)
# 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

# After authentication, we'll use this to confirm that the registered json paths are fulfilled, or display an error.
# This requires SiteSetting.oauth2_fetch_user_details? to be true, and can be used with
# DiscoursePluginRegistry.oauth2_basic_additional_json_paths.
#
# Example usage:
# DiscoursePluginRegistry.register_oauth2_basic_required_json_path({
# path: "extra:data.is_allowed_user",
# required_value: true,
# error_message: I18n.t("auth.user_not_allowed")
# }, self)
DiscoursePluginRegistry.define_filtered_register :oauth2_basic_required_json_paths

class ::OAuth2BasicAuthenticator < Auth::ManagedAuthenticator
def name
"oauth2_basic"
Expand Down Expand Up @@ -312,6 +324,15 @@ def after_authenticate(auth, existing_account: nil)
DiscoursePluginRegistry.oauth2_basic_additional_json_paths.each do |detail|
auth["extra"][detail] = fetched_user_details["extra:#{detail}"]
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
result = Auth::Result.new
result.failed = true
Expand Down
48 changes: 48 additions & 0 deletions spec/plugin_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,54 @@
expect(associated_account.extra[custom_path]).to eq("received")
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

describe "avatar downloading" do
Expand Down