mirror of
https://github.com/discourse/discourse.git
synced 2025-01-04 11:44:22 +08:00
SECURITY: When enabled only allow Discourse Connect logins
If Discourse Connect is enabled no other methods for account creation or authentication should be allowed.
This commit is contained in:
parent
15b43a205b
commit
17bdffc900
|
@ -324,6 +324,8 @@ class InvitesController < ApplicationController
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
raise Discourse::NotFound if SiteSetting.enable_discourse_connect
|
||||||
|
|
||||||
invite = Invite.find_by(invite_key: params[:id])
|
invite = Invite.find_by(invite_key: params[:id])
|
||||||
redeeming_user = current_user
|
redeeming_user = current_user
|
||||||
|
|
||||||
|
|
|
@ -110,6 +110,9 @@ class Users::OmniauthCallbacksController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.find_authenticator(name)
|
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|
|
Discourse.enabled_authenticators.each do |authenticator|
|
||||||
return authenticator if authenticator.name == name
|
return authenticator if authenticator.name == name
|
||||||
end
|
end
|
||||||
|
|
|
@ -664,6 +664,9 @@ class UsersController < ApplicationController
|
||||||
params.permit(:user_fields)
|
params.permit(:user_fields)
|
||||||
params.permit(:external_ids)
|
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
|
return fail_with("login.new_registrations_disabled") unless SiteSetting.allow_new_registrations
|
||||||
|
|
||||||
if params[:password] && params[:password].length > User.max_password_length
|
if params[:password] && params[:password].length > User.max_password_length
|
||||||
|
|
|
@ -2975,6 +2975,7 @@ en:
|
||||||
omniauth_confirm_button: "Continue"
|
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."
|
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: "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."
|
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."
|
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."
|
wrong_invite_code: "The invite code you entered was incorrect."
|
||||||
|
|
|
@ -183,4 +183,23 @@ describe "GitHub Oauth2" do
|
||||||
expect(response.location).to eq("http://test.localhost/")
|
expect(response.location).to eq("http://test.localhost/")
|
||||||
expect(session[:current_user_id]).to eq(user1.id)
|
expect(session[:current_user_id]).to eq(user1.id)
|
||||||
end
|
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
|
end
|
||||||
|
|
|
@ -106,6 +106,21 @@ describe "Twitter OAuth 1.0a" do
|
||||||
expect(session[:current_user_id]).to eq(user1.id)
|
expect(session[:current_user_id]).to eq(user1.id)
|
||||||
end
|
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
|
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"
|
post "/auth/twitter"
|
||||||
expect(response.status).to eq(302)
|
expect(response.status).to eq(302)
|
||||||
|
|
|
@ -966,6 +966,14 @@ RSpec.describe InvitesController do
|
||||||
expect(response.status).to eq(404)
|
expect(response.status).to eq(404)
|
||||||
end
|
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
|
context "with OmniAuth provider" do
|
||||||
fab!(:authenticated_email) { "test@example.com" }
|
fab!(:authenticated_email) { "test@example.com" }
|
||||||
|
|
||||||
|
|
|
@ -3230,6 +3230,22 @@ RSpec.describe SessionController do
|
||||||
expect(session[:current_user_id]).to eq(nil)
|
expect(session[:current_user_id]).to eq(nil)
|
||||||
end
|
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
|
it "logs the user in" do
|
||||||
simulate_localhost_passkey_challenge
|
simulate_localhost_passkey_challenge
|
||||||
user.activate
|
user.activate
|
||||||
|
|
|
@ -785,6 +785,23 @@ RSpec.describe UsersController do
|
||||||
end
|
end
|
||||||
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
|
context "with local logins disabled" do
|
||||||
before do
|
before do
|
||||||
SiteSetting.enable_local_logins = false
|
SiteSetting.enable_local_logins = false
|
||||||
|
|
Loading…
Reference in New Issue
Block a user