diff --git a/lib/discourse_login_client_authenticator.rb b/lib/discourse_login_client_authenticator.rb index 19cbf93..14be1d8 100644 --- a/lib/discourse_login_client_authenticator.rb +++ b/lib/discourse_login_client_authenticator.rb @@ -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 diff --git a/lib/discourse_login_client_strategy.rb b/lib/discourse_login_client_strategy.rb new file mode 100644 index 0000000..d5e05e7 --- /dev/null +++ b/lib/discourse_login_client_strategy.rb @@ -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 diff --git a/plugin.rb b/plugin.rb index 609ddec..0c2d020 100644 --- a/plugin.rb +++ b/plugin.rb @@ -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 diff --git a/spec/lib/discourse_login_client_authenticator_spec.rb b/spec/lib/discourse_login_client_authenticator_spec.rb index 804bb04..b4fb47c 100644 --- a/spec/lib/discourse_login_client_authenticator_spec.rb +++ b/spec/lib/discourse_login_client_authenticator_spec.rb @@ -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