mirror of
https://gh.wpcy.net/https://github.com/discourse/discourse.git
synced 2026-05-01 10:14:34 +08:00
- Rename SSO -> DiscourseConnect. SSO is the general term for all external login methods. DiscourseConnect is the name for this protocol - Allocate different IP for each parallel spec environment, so they don't clash. This will resolve some flaky specs we're seeing - Only bind to localhost. No need to make this available from other machines
65 lines
2.3 KiB
Ruby
65 lines
2.3 KiB
Ruby
# frozen_string_literal: true
|
|
require "rotp"
|
|
|
|
describe "Discourse Connect Provider", type: :system do
|
|
include DiscourseConnectHelpers
|
|
|
|
let(:sso_secret) { SecureRandom.alphanumeric(32) }
|
|
let(:sso_port) { setup_test_discourse_connect_server(user:, sso_secret:) }
|
|
let(:sso_url) { "http://localhost:#{sso_port}/sso" }
|
|
|
|
fab!(:user) { Fabricate(:user, username: "john", password: "supersecurepassword") }
|
|
let(:login_form) { PageObjects::Pages::Login.new }
|
|
let!(:return_url) { "http://localhost:#{sso_port}/test/url" }
|
|
before do
|
|
SiteSetting.enable_discourse_connect_provider = true
|
|
SiteSetting.discourse_connect_provider_secrets = "localhost|Test"
|
|
SiteSetting.enable_discourse_connect = false
|
|
Jobs.run_immediately!
|
|
end
|
|
|
|
it "redirects back to the return_sso_url after successful login" do
|
|
sso, sig = build_discourse_connect_payload(return_url)
|
|
EmailToken.confirm(Fabricate(:email_token, user: user).token)
|
|
|
|
visit "/"
|
|
visit "/session/sso_provider?sso=#{CGI.escape(sso)}&sig=#{sig}"
|
|
expect(page).to have_current_path("/login")
|
|
|
|
login_form.fill(username: "john", password: "supersecurepassword").click_login
|
|
|
|
expect(page).to have_current_path(
|
|
/#{Regexp.escape(return_url)}\?sso=.*&sig=[0-9a-f]+/,
|
|
url: true,
|
|
ignore_query: false,
|
|
)
|
|
end
|
|
context "with two-factor authentication" do
|
|
let!(:user_second_factor) { Fabricate(:user_second_factor_totp, user: user) }
|
|
let!(:user_second_factor_backup) { Fabricate(:user_second_factor_backup, user: user) }
|
|
fab!(:other_user) { Fabricate(:user, username: "jane", password: "supersecurepassword") }
|
|
|
|
it "redirects back to the return_sso_url" do
|
|
sso, sig = build_discourse_connect_payload(return_url)
|
|
EmailToken.confirm(Fabricate(:email_token, user: user).token)
|
|
|
|
visit "/"
|
|
visit "/session/sso_provider?sso=#{CGI.escape(sso)}&sig=#{sig}"
|
|
expect(page).to have_current_path("/login")
|
|
|
|
login_form.fill(username: "john", password: "supersecurepassword").click_login
|
|
|
|
expect(page).to have_css(".second-factor")
|
|
|
|
totp = ROTP::TOTP.new(user_second_factor.data).now
|
|
find("#login-second-factor").fill_in(with: totp)
|
|
login_form.click_login
|
|
|
|
expect(page).to have_current_path(
|
|
/#{Regexp.escape(return_url)}\?sso=.*&sig=[0-9a-f]+/,
|
|
url: true,
|
|
ignore_query: false,
|
|
)
|
|
end
|
|
end
|
|
end
|