mirror of
https://github.com/discourse/discourse.git
synced 2026-03-03 23:54:20 +08:00
606 lines
20 KiB
Ruby
606 lines
20 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
shared_context "with omniauth setup" do
|
|
include OmniauthHelpers
|
|
|
|
let(:login_page) { PageObjects::Pages::Login.new }
|
|
let(:signup_page) { PageObjects::Pages::Signup.new }
|
|
|
|
before { OmniAuth.config.test_mode = true }
|
|
end
|
|
|
|
shared_examples "social authentication scenarios" do
|
|
include_context "with omniauth setup"
|
|
|
|
context "when user does not exist" do
|
|
context "with Facebook" do
|
|
before { SiteSetting.enable_facebook_logins = true }
|
|
after { reset_omniauth_config(:facebook) }
|
|
|
|
it "fills the signup form" do
|
|
mock_facebook_auth
|
|
visit("/")
|
|
|
|
signup_page.open.click_social_button("facebook")
|
|
expect(signup_page).to be_open
|
|
expect(signup_page).to have_no_password_input
|
|
expect(signup_page).to have_valid_username
|
|
expect(signup_page).to have_valid_email
|
|
expect(signup_page).to have_no_right_side_column
|
|
|
|
signup_page.click_create_account
|
|
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
|
end
|
|
end
|
|
|
|
context "with Google" do
|
|
before { SiteSetting.enable_google_oauth2_logins = true }
|
|
after { reset_omniauth_config(:google_oauth2) }
|
|
|
|
it "fills the signup form" do
|
|
mock_google_auth
|
|
visit("/")
|
|
|
|
signup_page.open.click_social_button("google_oauth2")
|
|
expect(signup_page).to be_open
|
|
expect(signup_page).to have_no_password_input
|
|
expect(signup_page).to have_valid_username
|
|
expect(signup_page).to have_valid_email
|
|
expect(signup_page).to have_no_right_side_column
|
|
|
|
signup_page.click_create_account
|
|
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
|
end
|
|
|
|
context "when the email is not verified" do
|
|
it "needs to verify email" do
|
|
mock_google_auth(verified: false)
|
|
visit("/")
|
|
|
|
signup_page.open.click_social_button("google_oauth2")
|
|
expect(signup_page).to be_open
|
|
expect(signup_page).to have_no_password_input
|
|
expect(signup_page).to have_valid_username
|
|
expect(signup_page).to have_valid_email
|
|
expect(signup_page).to have_no_right_side_column
|
|
|
|
signup_page.click_create_account
|
|
expect(page).to have_css(".account-created")
|
|
end
|
|
end
|
|
end
|
|
|
|
context "with Github" do
|
|
before { SiteSetting.enable_github_logins = true }
|
|
after { reset_omniauth_config(:github) }
|
|
|
|
it "fills the signup form" do
|
|
mock_github_auth
|
|
visit("/")
|
|
|
|
signup_page.open.click_social_button("github")
|
|
expect(signup_page).to be_open
|
|
expect(signup_page).to have_no_password_input
|
|
expect(signup_page).to have_valid_username
|
|
expect(signup_page).to have_valid_email
|
|
expect(signup_page).to have_no_right_side_column
|
|
signup_page.click_create_account
|
|
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
|
end
|
|
|
|
context "when the email is not verified" do
|
|
it "needs to verify email" do
|
|
mock_github_auth(verified: false)
|
|
visit("/")
|
|
|
|
signup_page.open.click_social_button("github")
|
|
expect(signup_page).to be_open
|
|
expect(signup_page).to have_no_password_input
|
|
expect(signup_page).to have_valid_username
|
|
expect(signup_page).to have_valid_email
|
|
expect(signup_page).to have_no_right_side_column
|
|
signup_page.click_create_account
|
|
expect(page).to have_css(".account-created")
|
|
end
|
|
end
|
|
|
|
context "when Full Name is set to Required and auth overrides name" do
|
|
before do
|
|
SiteSetting.full_name_requirement = "required_at_signup"
|
|
SiteSetting.auth_overrides_name = true
|
|
end
|
|
|
|
it "lets user input Name when no name is provided" do
|
|
mock_github_auth(name: "")
|
|
visit("/")
|
|
|
|
signup_page.open.click_social_button("github")
|
|
expect(signup_page).to be_open
|
|
expect(signup_page).to have_no_password_input
|
|
expect(signup_page).to have_valid_username
|
|
expect(signup_page).to have_valid_email
|
|
expect(signup_page).to have_editable_name_input
|
|
|
|
signup_page.fill_input("#new-account-name", "Test User")
|
|
|
|
expect(signup_page).to have_no_right_side_column
|
|
signup_page.click_create_account
|
|
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
|
end
|
|
|
|
it "works with a provided name" do
|
|
mock_github_auth(name: "Some Name")
|
|
visit("/")
|
|
|
|
signup_page.open.click_social_button("github")
|
|
expect(signup_page).to be_open
|
|
expect(signup_page).to have_no_password_input
|
|
expect(signup_page).to have_valid_username
|
|
expect(signup_page).to have_valid_email
|
|
expect(signup_page).to have_disabled_name_input
|
|
|
|
signup_page.click_create_account
|
|
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
|
end
|
|
end
|
|
end
|
|
|
|
context "with Twitter" do
|
|
before { SiteSetting.enable_twitter_logins = true }
|
|
after { reset_omniauth_config(:twitter) }
|
|
|
|
it "fills the signup form" do
|
|
mock_twitter_auth
|
|
visit("/")
|
|
|
|
signup_page.open.click_social_button("twitter")
|
|
expect(signup_page).to be_open
|
|
expect(signup_page).to have_no_password_input
|
|
signup_page.fill_email(OmniauthHelpers::EMAIL)
|
|
expect(signup_page).to have_valid_username
|
|
expect(signup_page).to have_valid_email
|
|
expect(signup_page).to have_no_right_side_column
|
|
signup_page.click_create_account
|
|
expect(page).to have_css(".account-created")
|
|
end
|
|
|
|
context "when the email is not verified" do
|
|
it "needs to verify email" do
|
|
mock_twitter_auth(verified: false)
|
|
visit("/")
|
|
|
|
signup_page.open.click_social_button("twitter")
|
|
expect(signup_page).to be_open
|
|
expect(signup_page).to have_no_password_input
|
|
signup_page.fill_email(OmniauthHelpers::EMAIL)
|
|
expect(signup_page).to have_valid_username
|
|
expect(signup_page).to have_valid_email
|
|
signup_page.click_create_account
|
|
expect(page).to have_css(".account-created")
|
|
end
|
|
end
|
|
end
|
|
|
|
context "with Discord" do
|
|
before { SiteSetting.enable_discord_logins = true }
|
|
after { reset_omniauth_config(:discord) }
|
|
|
|
it "fills the signup form" do
|
|
mock_discord_auth
|
|
visit("/")
|
|
|
|
signup_page.open.click_social_button("discord")
|
|
expect(signup_page).to be_open
|
|
expect(signup_page).to have_no_password_input
|
|
expect(signup_page).to have_valid_username
|
|
expect(signup_page).to have_valid_email
|
|
expect(signup_page).to have_no_right_side_column
|
|
signup_page.click_create_account
|
|
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
|
end
|
|
end
|
|
|
|
context "with Linkedin" do
|
|
before do
|
|
SiteSetting.linkedin_oidc_client_id = "12345"
|
|
SiteSetting.linkedin_oidc_client_secret = "abcde"
|
|
SiteSetting.enable_linkedin_oidc_logins = true
|
|
end
|
|
after { reset_omniauth_config(:linkedin_oidc) }
|
|
|
|
it "fills the signup form" do
|
|
mock_linkedin_auth
|
|
visit("/")
|
|
|
|
signup_page.open.click_social_button("linkedin_oidc")
|
|
expect(signup_page).to be_open
|
|
expect(signup_page).to have_no_password_input
|
|
expect(signup_page).to have_valid_username
|
|
expect(signup_page).to have_valid_email
|
|
expect(signup_page).to have_no_right_side_column
|
|
signup_page.click_create_account
|
|
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
|
end
|
|
end
|
|
|
|
# These tests use Google, but they should be the same for all providers
|
|
context "when opening the external auth from /login" do
|
|
before { SiteSetting.enable_google_oauth2_logins = true }
|
|
after { reset_omniauth_config(:google_oauth2) }
|
|
|
|
it "fills the signup form" do
|
|
mock_google_auth
|
|
visit("/")
|
|
|
|
signup_page.open.click_social_button("google_oauth2")
|
|
expect(signup_page).to be_open
|
|
expect(signup_page).to have_no_password_input
|
|
expect(signup_page).to have_valid_username
|
|
expect(signup_page).to have_valid_email
|
|
expect(signup_page).to have_no_right_side_column
|
|
signup_page.click_create_account
|
|
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
|
end
|
|
end
|
|
|
|
context "when overriding local fields" do
|
|
before do
|
|
SiteSetting.enable_google_oauth2_logins = true
|
|
SiteSetting.auth_overrides_name = true
|
|
SiteSetting.auth_overrides_username = true
|
|
end
|
|
after { reset_omniauth_config(:google_oauth2) }
|
|
|
|
it "fills the signup form and disables the inputs" do
|
|
mock_google_auth
|
|
visit("/")
|
|
|
|
signup_page.open.click_social_button("google_oauth2")
|
|
expect(signup_page).to be_open
|
|
expect(signup_page).to have_no_password_input
|
|
expect(signup_page).to have_valid_username
|
|
expect(signup_page).to have_valid_email
|
|
expect(signup_page).to have_disabled_username
|
|
expect(signup_page).to have_disabled_email
|
|
expect(signup_page).to have_disabled_name
|
|
signup_page.click_create_account
|
|
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
|
end
|
|
end
|
|
|
|
context "when skipping the signup form" do
|
|
before do
|
|
SiteSetting.enable_google_oauth2_logins = true
|
|
SiteSetting.auth_skip_create_confirm = true
|
|
end
|
|
after { reset_omniauth_config(:google_oauth2) }
|
|
|
|
it "creates the account directly" do
|
|
mock_google_auth
|
|
visit("/")
|
|
|
|
signup_page.open.click_social_button("google_oauth2")
|
|
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
|
end
|
|
|
|
it "shows signup form when no username can be derived" do
|
|
SiteSetting.use_email_for_username_and_name_suggestions = false
|
|
mock_google_auth(name: "")
|
|
visit("/")
|
|
|
|
signup_page.open.click_social_button("google_oauth2")
|
|
expect(signup_page).to be_open
|
|
expect(signup_page).to have_no_password_input
|
|
expect(page).to have_field("new-account-username", with: "")
|
|
end
|
|
end
|
|
|
|
context "when there is only one external login method enabled" do
|
|
before do
|
|
SiteSetting.enable_google_oauth2_logins = true
|
|
SiteSetting.enable_local_logins = false
|
|
end
|
|
after { reset_omniauth_config(:google_oauth2) }
|
|
|
|
context "when login is required" do
|
|
before { SiteSetting.login_required = true }
|
|
|
|
it "automatically redirects when auth_immediately is enabled" do
|
|
SiteSetting.auth_immediately = true
|
|
mock_google_auth
|
|
|
|
visit("/login")
|
|
expect(signup_page).to be_open
|
|
expect(signup_page).to have_no_password_input
|
|
expect(signup_page).to have_valid_username
|
|
expect(signup_page).to have_valid_email
|
|
|
|
visit("/signup")
|
|
expect(signup_page).to be_open
|
|
expect(signup_page).to have_no_password_input
|
|
expect(signup_page).to have_valid_username
|
|
expect(signup_page).to have_valid_email
|
|
|
|
visit("/")
|
|
expect(signup_page).to be_open
|
|
expect(signup_page).to have_no_password_input
|
|
expect(signup_page).to have_valid_username
|
|
expect(signup_page).to have_valid_email
|
|
|
|
signup_page.click_create_account
|
|
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
|
end
|
|
|
|
it "shows the login-required page when auth_immediately is disabled" do
|
|
SiteSetting.auth_immediately = false
|
|
mock_google_auth
|
|
|
|
visit("/login")
|
|
expect(signup_page).to be_open
|
|
|
|
visit("/")
|
|
expect(page).to have_css(".login-welcome")
|
|
expect(page).to have_css(".site-logo")
|
|
|
|
find(".login-welcome .login-button").click
|
|
expect(signup_page).to be_open
|
|
|
|
visit("/")
|
|
find(".login-welcome .sign-up-button").click
|
|
expect(signup_page).to be_open
|
|
expect(signup_page).to have_no_password_input
|
|
expect(signup_page).to have_valid_username
|
|
expect(signup_page).to have_valid_email
|
|
signup_page.click_create_account
|
|
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
|
end
|
|
|
|
it "automatically redirects when going to /signup" do
|
|
SiteSetting.auth_immediately = false
|
|
mock_google_auth
|
|
|
|
visit("/signup")
|
|
expect(signup_page).to be_open
|
|
expect(signup_page).to have_no_password_input
|
|
expect(signup_page).to have_valid_username
|
|
expect(signup_page).to have_valid_email
|
|
signup_page.click_create_account
|
|
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
|
end
|
|
|
|
it "automatically redirects when skipping the signup form" do
|
|
SiteSetting.auth_skip_create_confirm = true
|
|
SiteSetting.auth_immediately = true
|
|
mock_google_auth
|
|
|
|
visit("/login")
|
|
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
|
end
|
|
end
|
|
|
|
it "automatically redirects when using the login button or the routes" do
|
|
SiteSetting.auth_immediately = false
|
|
mock_google_auth
|
|
|
|
visit("/")
|
|
find(".header-buttons .login-button").click
|
|
expect(signup_page).to be_open
|
|
expect(signup_page).to have_no_password_input
|
|
expect(signup_page).to have_valid_username
|
|
expect(signup_page).to have_valid_email
|
|
|
|
visit("/login")
|
|
expect(signup_page).to be_open
|
|
expect(signup_page).to have_no_password_input
|
|
expect(signup_page).to have_valid_username
|
|
expect(signup_page).to have_valid_email
|
|
|
|
visit("/signup")
|
|
expect(signup_page).to be_open
|
|
expect(signup_page).to have_no_password_input
|
|
expect(signup_page).to have_valid_username
|
|
expect(signup_page).to have_valid_email
|
|
|
|
signup_page.click_create_account
|
|
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
|
end
|
|
|
|
it "redirects the user back to the last page they visited" do
|
|
mock_google_auth
|
|
|
|
category = Fabricate(:category)
|
|
|
|
visit(category.url)
|
|
|
|
find(".header-buttons .login-button").click
|
|
|
|
expect(signup_page).to be_open
|
|
expect(signup_page).to have_no_password_input
|
|
expect(signup_page).to have_valid_username
|
|
expect(signup_page).to have_valid_email
|
|
|
|
signup_page.click_create_account
|
|
|
|
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
|
expect(page).to have_current_path(category.url)
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when user exists" do
|
|
fab!(:user) do
|
|
Fabricate(
|
|
:user,
|
|
email: OmniauthHelpers::EMAIL,
|
|
username: OmniauthHelpers::USERNAME,
|
|
password: "supersecurepassword",
|
|
)
|
|
end
|
|
|
|
context "with Facebook" do
|
|
before { SiteSetting.enable_facebook_logins = true }
|
|
after { reset_omniauth_config(:facebook) }
|
|
|
|
it "logs in user" do
|
|
mock_facebook_auth
|
|
visit("/")
|
|
|
|
signup_page.open.click_social_button("facebook")
|
|
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
|
end
|
|
|
|
it "removes destination_url cookie if present after setting up redirect" do
|
|
mock_facebook_auth
|
|
visit("/")
|
|
|
|
category = Fabricate(:category)
|
|
|
|
signup_page.open
|
|
|
|
# Manually set the destination_url, as if it were set by a plugin
|
|
page.driver.with_playwright_page do |pw_page|
|
|
pw_page.context.add_cookies(
|
|
[{ url: pw_page.url, name: :destination_url, value: category.url }],
|
|
)
|
|
|
|
cookie_found =
|
|
pw_page.context.cookies.any? { |cookie| cookie["name"] == "destination_url" }
|
|
expect(cookie_found).not_to be_falsey
|
|
end
|
|
|
|
signup_page.click_social_button("facebook")
|
|
expect(page).to have_current_path(category.url)
|
|
|
|
# Ensure the destination_url cookie was removed after being used
|
|
page.driver.with_playwright_page do |pw_page|
|
|
cookie_found =
|
|
pw_page.context.cookies.any? { |cookie| cookie["name"] == "destination_url" }
|
|
expect(cookie_found).to be_falsey
|
|
end
|
|
end
|
|
|
|
context "with a suspended user" do
|
|
before do
|
|
user.suspended_till = 2.years.from_now
|
|
user.suspended_at = Time.now
|
|
user.save!
|
|
end
|
|
|
|
it "shows suspended message" do
|
|
mock_facebook_auth
|
|
visit("/")
|
|
|
|
signup_page.open.click_social_button("facebook")
|
|
|
|
expect(page).to have_css(
|
|
".alert-error",
|
|
text: I18n.t("login.suspended", date: I18n.l(user.suspended_till, format: :date_only)),
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
context "with Google" do
|
|
before { SiteSetting.enable_google_oauth2_logins = true }
|
|
after { reset_omniauth_config(:google_oauth2) }
|
|
|
|
it "logs in user" do
|
|
mock_google_auth
|
|
visit("/")
|
|
|
|
signup_page.open.click_social_button("google_oauth2")
|
|
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
|
end
|
|
end
|
|
|
|
context "with Github" do
|
|
before { SiteSetting.enable_github_logins = true }
|
|
after { reset_omniauth_config(:github) }
|
|
|
|
it "logs in user" do
|
|
mock_github_auth
|
|
visit("/")
|
|
|
|
signup_page.open.click_social_button("github")
|
|
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
|
end
|
|
end
|
|
|
|
context "with Twitter" do
|
|
before { SiteSetting.enable_twitter_logins = true }
|
|
after { reset_omniauth_config(:twitter) }
|
|
|
|
it "logs in user" do
|
|
UserAssociatedAccount.create!(
|
|
provider_name: "twitter",
|
|
user_id: user.id,
|
|
provider_uid: OmniauthHelpers::UID,
|
|
)
|
|
|
|
mock_twitter_auth
|
|
visit("/")
|
|
|
|
signup_page.open.click_social_button("twitter")
|
|
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
|
end
|
|
end
|
|
|
|
context "with Discord" do
|
|
before { SiteSetting.enable_discord_logins = true }
|
|
after { reset_omniauth_config(:discord) }
|
|
|
|
it "logs in user" do
|
|
mock_discord_auth
|
|
visit("/")
|
|
|
|
signup_page.open.click_social_button("discord")
|
|
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
|
end
|
|
end
|
|
|
|
context "with Linkedin" do
|
|
before do
|
|
SiteSetting.linkedin_oidc_client_id = "12345"
|
|
SiteSetting.linkedin_oidc_client_secret = "abcde"
|
|
SiteSetting.enable_linkedin_oidc_logins = true
|
|
end
|
|
after { reset_omniauth_config(:linkedin_oidc) }
|
|
|
|
it "logs in user" do
|
|
mock_linkedin_auth
|
|
visit("/")
|
|
|
|
signup_page.open.click_social_button("linkedin_oidc")
|
|
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when the provider returns an error" do
|
|
before { SiteSetting.enable_google_oauth2_logins = true }
|
|
|
|
it "shows the unauthorized error message" do
|
|
visit("/auth/failure?message=unauthorized")
|
|
|
|
expect(page).to have_css(".alert-error", text: I18n.t("login.omniauth_error.unauthorized"))
|
|
end
|
|
|
|
it "shows the request_error message" do
|
|
visit("/auth/failure?message=request_error")
|
|
|
|
expect(page).to have_css(".alert-error", text: I18n.t("login.omniauth_error.request_error"))
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "Social authentication", type: :system do
|
|
before { SiteSetting.full_name_requirement = "optional_at_signup" }
|
|
|
|
context "when desktop" do
|
|
include_examples "social authentication scenarios"
|
|
end
|
|
|
|
context "when mobile", mobile: true do
|
|
include_examples "social authentication scenarios"
|
|
end
|
|
end
|