diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb index 54f4c63a1ba..a0dfaced60b 100644 --- a/app/controllers/invites_controller.rb +++ b/app/controllers/invites_controller.rb @@ -324,6 +324,8 @@ class InvitesController < ApplicationController }, ) + raise Discourse::NotFound if SiteSetting.enable_discourse_connect + invite = Invite.find_by(invite_key: params[:id]) redeeming_user = current_user diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb index 90d18a388ce..985a97cd37e 100644 --- a/app/controllers/users/omniauth_callbacks_controller.rb +++ b/app/controllers/users/omniauth_callbacks_controller.rb @@ -110,6 +110,9 @@ class Users::OmniauthCallbacksController < ApplicationController end def self.find_authenticator(name) + if SiteSetting.enable_discourse_connect + raise Discourse::InvalidAccess.new(I18n.t("authenticator_not_found")) + end Discourse.enabled_authenticators.each do |authenticator| return authenticator if authenticator.name == name end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 9978c11d3a5..a6825127f5b 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -664,6 +664,9 @@ class UsersController < ApplicationController params.permit(:user_fields) params.permit(:external_ids) + if SiteSetting.enable_discourse_connect && !is_api? + return fail_with("login.new_registrations_disabled_discourse_connect") + end return fail_with("login.new_registrations_disabled") unless SiteSetting.allow_new_registrations if params[:password] && params[:password].length > User.max_password_length diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index e9a5ff90b40..dbd64fa4769 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -2975,6 +2975,7 @@ en: omniauth_confirm_button: "Continue" authenticator_error_no_valid_email: "No email addresses associated with %{account} are allowed. You may need to configure your account with a different email address." new_registrations_disabled: "New account registrations are not allowed at this time." + new_registrations_disabled_discourse_connect: "New account registrations are only allowed through Discourse Connect." password_too_long: "Passwords are limited to 200 characters." email_too_long: "The email you provided is too long. Mailbox names must be no more than 254 characters, and domain names must be no more than 253 characters." wrong_invite_code: "The invite code you entered was incorrect." diff --git a/spec/integration/github_omniauth_spec.rb b/spec/integration/github_omniauth_spec.rb index 05cbcdddc48..4a8d468930f 100644 --- a/spec/integration/github_omniauth_spec.rb +++ b/spec/integration/github_omniauth_spec.rb @@ -183,4 +183,23 @@ describe "GitHub Oauth2" do expect(response.location).to eq("http://test.localhost/") expect(session[:current_user_id]).to eq(user1.id) end + + it "doesn't log in the user if discourse connect is enabled" do + SiteSetting.discourse_connect_url = "https://example.com/sso" + SiteSetting.enable_discourse_connect = true + post "/auth/github" + expect(response.status).to eq(302) + expect(response.location).to start_with("https://github.com/login/oauth/authorize?") + + setup_github_emails_stub( + [ + { email: user1.email, primary: true, verified: true, visibility: "private" }, + { email: user2.email, primary: false, verified: true, visibility: "private" }, + ], + ) + + post "/auth/github/callback", params: { state: session["omniauth.state"], code: temp_code } + expect(response.status).to eq(403) + expect(session[:current_user_id]).to be_blank + end end diff --git a/spec/integration/twitter_omniauth_spec.rb b/spec/integration/twitter_omniauth_spec.rb index f64960c6e97..cd3eea08406 100644 --- a/spec/integration/twitter_omniauth_spec.rb +++ b/spec/integration/twitter_omniauth_spec.rb @@ -106,6 +106,21 @@ describe "Twitter OAuth 1.0a" do expect(session[:current_user_id]).to eq(user1.id) end + it "doesn't sign in the user discourse connect is enabled" do + SiteSetting.discourse_connect_url = "https://example.com/sso" + SiteSetting.enable_discourse_connect = true + post "/auth/twitter" + expect(response.status).to eq(302) + expect(response.location).to start_with("https://api.twitter.com/oauth/authenticate") + + setup_twitter_email_stub(email: user1.email) + + post "/auth/twitter/callback", params: { state: session["omniauth.state"] } + + expect(response.status).to eq(403) + expect(session[:current_user_id]).to be_blank + end + it "doesn't sign in anyone if the API response from twitter doesn't include an email (implying the user's email on twitter isn't verified)" do post "/auth/twitter" expect(response.status).to eq(302) diff --git a/spec/requests/invites_controller_spec.rb b/spec/requests/invites_controller_spec.rb index ed779e44fe9..3f33c1694e9 100644 --- a/spec/requests/invites_controller_spec.rb +++ b/spec/requests/invites_controller_spec.rb @@ -966,6 +966,14 @@ RSpec.describe InvitesController do expect(response.status).to eq(404) end + it "fails when discourse connect is enabled" do + SiteSetting.discourse_connect_url = "https://example.com/sso" + SiteSetting.enable_discourse_connect = true + + put "/invites/show/#{invite.invite_key}.json" + expect(response.status).to eq(404) + end + context "with OmniAuth provider" do fab!(:authenticated_email) { "test@example.com" } diff --git a/spec/requests/session_controller_spec.rb b/spec/requests/session_controller_spec.rb index cb7d0f9f9c6..8b5f61961c6 100644 --- a/spec/requests/session_controller_spec.rb +++ b/spec/requests/session_controller_spec.rb @@ -3230,6 +3230,22 @@ RSpec.describe SessionController do expect(session[:current_user_id]).to eq(nil) end + it "fails when discourse connect is enabled" do + SiteSetting.discourse_connect_url = "https://www.example.com/sso" + SiteSetting.enable_discourse_connect = true + simulate_localhost_passkey_challenge + user.activate + user.create_or_fetch_secure_identifier + post "/session/passkey/auth.json", + params: { + publicKeyCredential: + valid_passkey_auth_data.merge( + { userHandle: Base64.strict_encode64(user.secure_identifier) }, + ), + } + expect(response.status).to eq(403) + end + it "logs the user in" do simulate_localhost_passkey_challenge user.activate diff --git a/spec/requests/users_controller_spec.rb b/spec/requests/users_controller_spec.rb index 45b2109b2dc..80e5afa3983 100644 --- a/spec/requests/users_controller_spec.rb +++ b/spec/requests/users_controller_spec.rb @@ -785,6 +785,23 @@ RSpec.describe UsersController do end end + context "with discourse connect enabled" do + before do + SiteSetting.discourse_connect_url = "http://example.com/sso" + SiteSetting.enable_discourse_connect = true + end + + it "blocks registration for local logins" do + SiteSetting.enable_local_logins = true + post_user + + response_body = response.parsed_body + expect(response_body["message"]).to eq( + "New account registrations are only allowed through Discourse Connect.", + ) + end + end + context "with local logins disabled" do before do SiteSetting.enable_local_logins = false