Skip to content

UX: add the user's intent as a query parameter #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 20, 2025
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
63 changes: 16 additions & 47 deletions lib/discourse_login_client_authenticator.rb
Original file line number Diff line number Diff line change
@@ -1,69 +1,38 @@
# frozen_string_literal: true

class DiscourseLoginClientAuthenticator < Auth::ManagedAuthenticator
class DiscourseLoginClientStrategy < ::OmniAuth::Strategies::OAuth2
option :name, "discourse_login"

option :client_options,
authorize_url: "/oauth/authorize",
token_url: "/oauth/token",
auth_scheme: :basic_auth

option :authorize_options, [:scope]

uid { access_token.params["info"]["uuid"] }

info do
{
nickname: access_token.params["info"]["username"],
email: access_token.params["info"]["email"],
image: access_token.params["info"]["image"],
}
end

def callback_url
Discourse.base_url_no_prefix + script_name + callback_path
end
def enabled?
SiteSetting.discourse_login_client_enabled && SiteSetting.discourse_login_client_id.present? &&
SiteSetting.discourse_login_client_secret.present?
end

def name
"discourse_login"
end

def can_revoke?
true
def display_name
"Discourse ID"
end

def can_connect_existing_user?
true
end

def base_url
def site
SiteSetting.discourse_login_client_url.presence || "https://logindemo.discourse.group"
end

def register_middleware(omniauth)
omniauth.provider DiscourseLoginClientStrategy,
setup:
lambda { |env|
opts = env["omniauth.strategy"].options
opts[:client_id] = SiteSetting.discourse_login_client_id
opts[:client_secret] = SiteSetting.discourse_login_client_secret
opts[:client_options][:site] = base_url
opts[:scope] = "read"
}
scope: "read",
setup: ->(env) do
env["omniauth.strategy"].options.merge!(
client_id: SiteSetting.discourse_login_client_id,
client_secret: SiteSetting.discourse_login_client_secret,
client_options: {
site:,
},
)
end
end

def primary_email_verified?(auth_token)
true # email will be verified at source
end

def always_update_user_email?
false # not sure
end

def enabled?
SiteSetting.discourse_login_client_enabled && SiteSetting.discourse_login_client_id.present? &&
SiteSetting.discourse_login_client_secret.present?
end
end
25 changes: 25 additions & 0 deletions lib/discourse_login_client_strategy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

class DiscourseLoginClientStrategy < ::OmniAuth::Strategies::OAuth2
option :name, "discourse_login"

option :client_options, auth_scheme: :basic_auth

def authorize_params
super.tap { _1[:intent] = "signup" if request.params["signup"] == "true" }
end

def callback_url
Discourse.base_url_no_prefix + callback_path
end

uid { access_token.params["info"]["uuid"] }

info do
{
nickname: access_token.params["info"]["username"],
email: access_token.params["info"]["email"],
image: access_token.params["info"]["image"],
}
end
end
1 change: 1 addition & 0 deletions plugin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
# url: TODO
# required_version: 3.3.0

require_relative "lib/discourse_login_client_strategy"
require_relative "lib/discourse_login_client_authenticator"

enabled_site_setting :discourse_login_client_enabled
Expand Down
19 changes: 6 additions & 13 deletions spec/lib/discourse_login_client_authenticator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,35 +54,28 @@
end
end

describe "#base_url" do
describe "#site" do
it "returns default URL when setting is blank" do
SiteSetting.discourse_login_client_url = ""
expect(authenticator.base_url).to eq("https://logindemo.discourse.group")
expect(authenticator.site).to eq("https://logindemo.discourse.group")
end

it "returns configured URL when setting is present" do
SiteSetting.discourse_login_client_url = "https://custom.example.com"
expect(authenticator.base_url).to eq("https://custom.example.com")
expect(authenticator.site).to eq("https://custom.example.com")
end
end
end

describe "DiscourseLoginClientStrategy" do
let(:strategy) { DiscourseLoginClientAuthenticator::DiscourseLoginClientStrategy.new({}) }
let(:strategy) { DiscourseLoginClientStrategy.new({}) }

it "uses 'discourse_login' name" do
expect(strategy.options.name).to eq("discourse_login")
end

it "defines client_options" do
client_options = strategy.options.client_options
expect(client_options.authorize_url).to eq("/oauth/authorize")
expect(client_options.token_url).to eq("/oauth/token")
expect(client_options.auth_scheme).to eq(:basic_auth)
end

it "defines authorize_options" do
expect(strategy.options.authorize_options).to include(:scope)
it "uses basic auth as authentication scheme" do
expect(strategy.options.client_options.auth_scheme).to eq(:basic_auth)
end

it "defines callback_url" do
Expand Down
Loading