Tests now pass with local authentication
This is the first step of a multi-step SaaS engine extraction. Looking ahead to an open source release, we need to make sure that local authentication is treated as an "official" option, and not just a hack I added for Kevin to do load testing outside our DC. So this PR gets to green, and adds a CI step in "local authentication" mode. This all probably feels a little hacky to you, Reader, but the goal of this change is to ease the next step, which will be extracting the 37id and Queenbee integrations into a proprietary "SaaS mode" engine. In service of that goal, this commit simply wraps all of the dependent code and tests with a conditional check on `config.x.local_authentication`.
This commit is contained in:
@@ -1,36 +1,34 @@
|
||||
require "test_helper"
|
||||
|
||||
class ControllerAuthenticationTest < ActionDispatch::IntegrationTest
|
||||
test "access without an account slug redirects to launchpad" do
|
||||
integration_session.default_url_options[:script_name] = "" # no tenant
|
||||
if Rails.application.config.x.local_authentication
|
||||
test "access without an account slug redirects to new session" do
|
||||
integration_session.default_url_options[:script_name] = "" # no tenant
|
||||
|
||||
get cards_path
|
||||
|
||||
assert_redirected_to Launchpad.login_url(product: true)
|
||||
end
|
||||
|
||||
test "access with an account slug but no session redirects to launchpad" do
|
||||
get cards_path
|
||||
|
||||
assert_redirected_to Launchpad.login_url(product: true, account: Account.sole)
|
||||
end
|
||||
|
||||
test "local auth, access without an account slug redirects to launchpad" do
|
||||
integration_session.default_url_options[:script_name] = "" # no tenant
|
||||
|
||||
with_local_auth do
|
||||
get cards_path
|
||||
|
||||
assert_redirected_to new_session_path
|
||||
end
|
||||
|
||||
assert_redirected_to Launchpad.login_url(product: true)
|
||||
end
|
||||
|
||||
test "local auth, access with an account slug but no session redirects to new session" do
|
||||
with_local_auth do
|
||||
test "access with an account slug but no session redirects to new session" do
|
||||
get cards_path
|
||||
|
||||
assert_redirected_to new_session_path
|
||||
end
|
||||
else
|
||||
test "access without an account slug redirects to launchpad" do
|
||||
integration_session.default_url_options[:script_name] = "" # no tenant
|
||||
|
||||
get cards_path
|
||||
|
||||
assert_redirected_to Launchpad.login_url(product: true)
|
||||
end
|
||||
|
||||
assert_redirected_to new_session_path
|
||||
test "access with an account slug but no session redirects to launchpad" do
|
||||
get cards_path
|
||||
|
||||
assert_redirected_to Launchpad.login_url(product: true, account: Account.sole)
|
||||
end
|
||||
end
|
||||
|
||||
test "access with an account slug and a session allows functional access" do
|
||||
|
||||
@@ -1,38 +1,40 @@
|
||||
require "test_helper"
|
||||
|
||||
class Sessions::LaunchpadControllerTest < ActionDispatch::IntegrationTest
|
||||
test "show renders when not signed in" do
|
||||
get session_launchpad_path(params: { sig: "test-sig" })
|
||||
unless Rails.application.config.x.local_authentication
|
||||
test "show renders when not signed in" do
|
||||
get session_launchpad_path(params: { sig: "test-sig" })
|
||||
|
||||
assert_response :success
|
||||
assert_response :success
|
||||
|
||||
assert_select "form input#sig" do |node|
|
||||
assert_equal node.length, 1
|
||||
assert_equal node.first["value"], "test-sig"
|
||||
assert_select "form input#sig" do |node|
|
||||
assert_equal node.length, 1
|
||||
assert_equal node.first["value"], "test-sig"
|
||||
end
|
||||
end
|
||||
|
||||
test "create establishes a session when the sig is valid" do
|
||||
user = users(:david)
|
||||
|
||||
put session_launchpad_path(params: { sig: user.signal_user.perishable_signature })
|
||||
|
||||
assert_redirected_to root_url
|
||||
assert parsed_cookies.signed[:session_token]
|
||||
end
|
||||
|
||||
test "create checks user.active?" do
|
||||
user = users(:david)
|
||||
user.update! active: false
|
||||
|
||||
put session_launchpad_path(params: { sig: user.signal_user.perishable_signature })
|
||||
|
||||
assert_response :unauthorized
|
||||
end
|
||||
|
||||
test "returns 401 when the sig is invalid" do
|
||||
put session_launchpad_path(params: { sig: "invalid" })
|
||||
|
||||
assert_response :unauthorized
|
||||
end
|
||||
end
|
||||
|
||||
test "create establishes a session when the sig is valid" do
|
||||
user = users(:david)
|
||||
|
||||
put session_launchpad_path(params: { sig: user.signal_user.perishable_signature })
|
||||
|
||||
assert_redirected_to root_url
|
||||
assert parsed_cookies.signed[:session_token]
|
||||
end
|
||||
|
||||
test "create checks user.active?" do
|
||||
user = users(:david)
|
||||
user.update! active: false
|
||||
|
||||
put session_launchpad_path(params: { sig: user.signal_user.perishable_signature })
|
||||
|
||||
assert_response :unauthorized
|
||||
end
|
||||
|
||||
test "returns 401 when the sig is invalid" do
|
||||
put session_launchpad_path(params: { sig: "invalid" })
|
||||
|
||||
assert_response :unauthorized
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,61 +1,55 @@
|
||||
require "test_helper"
|
||||
|
||||
class SessionsControllerTest < ActionDispatch::IntegrationTest
|
||||
test "destroy" do
|
||||
sign_in_as :kevin
|
||||
unless Rails.application.config.x.local_authentication
|
||||
test "destroy" do
|
||||
sign_in_as :kevin
|
||||
|
||||
delete session_path
|
||||
|
||||
assert_redirected_to Launchpad.logout_url
|
||||
assert_not cookies[:session_token].present?
|
||||
end
|
||||
|
||||
test "local auth, destroy" do
|
||||
sign_in_as :kevin
|
||||
|
||||
with_local_auth do
|
||||
delete session_path
|
||||
|
||||
assert_redirected_to Launchpad.logout_url
|
||||
assert_not cookies[:session_token].present?
|
||||
end
|
||||
|
||||
assert_redirected_to new_session_path
|
||||
assert_not cookies[:session_token].present?
|
||||
end
|
||||
|
||||
test "new" do
|
||||
get new_session_path
|
||||
|
||||
assert_response :forbidden
|
||||
end
|
||||
|
||||
test "local auth, new" do
|
||||
with_local_auth do
|
||||
test "new" do
|
||||
get new_session_path
|
||||
|
||||
assert_response :forbidden
|
||||
end
|
||||
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "create" do
|
||||
post session_path, params: { email_address: "david@37signals.com", password: "secret123456" }
|
||||
|
||||
assert_response :forbidden
|
||||
end
|
||||
|
||||
test "local auth, create with valid credentials" do
|
||||
with_local_auth do
|
||||
test "create" do
|
||||
post session_path, params: { email_address: "david@37signals.com", password: "secret123456" }
|
||||
|
||||
assert_response :forbidden
|
||||
end
|
||||
else
|
||||
test "destroy" do
|
||||
sign_in_as :kevin
|
||||
|
||||
delete session_path
|
||||
|
||||
assert_redirected_to new_session_path
|
||||
assert_not cookies[:session_token].present?
|
||||
end
|
||||
|
||||
assert_redirected_to root_path
|
||||
assert cookies[:session_token].present?
|
||||
end
|
||||
test "new" do
|
||||
get new_session_path
|
||||
|
||||
test "local auth, create with invalid credentials" do
|
||||
with_local_auth do
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "create with valid credentials" do
|
||||
post session_path, params: { email_address: "david@37signals.com", password: "secret123456" }
|
||||
|
||||
assert_redirected_to root_path
|
||||
assert cookies[:session_token].present?
|
||||
end
|
||||
|
||||
test "create with invalid credentials" do
|
||||
post session_path, params: { email_address: "david@37signals.com", password: "wrong" }
|
||||
end
|
||||
|
||||
assert_redirected_to new_session_path
|
||||
assert_not cookies[:session_token].present?
|
||||
assert_redirected_to new_session_path
|
||||
assert_not cookies[:session_token].present?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,103 +1,105 @@
|
||||
require "test_helper"
|
||||
|
||||
class Signup::AccountsControllerTest < ActionDispatch::IntegrationTest
|
||||
test "new under a tenanted URL redirects to the root" do
|
||||
get new_signup_account_url
|
||||
unless Rails.application.config.x.local_authentication
|
||||
test "new under a tenanted URL redirects to the root" do
|
||||
get new_signup_account_url
|
||||
|
||||
assert_redirected_to root_url
|
||||
end
|
||||
assert_redirected_to root_url
|
||||
end
|
||||
|
||||
test "new under an untenanted URL is OK" do
|
||||
integration_session.default_url_options[:script_name] = "" # no tenant
|
||||
test "new under an untenanted URL is OK" do
|
||||
integration_session.default_url_options[:script_name] = "" # no tenant
|
||||
|
||||
get new_signup_account_url, headers: auth_headers
|
||||
get new_signup_account_url, headers: auth_headers
|
||||
|
||||
assert_response :success
|
||||
end
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "create with invalid params" do
|
||||
integration_session.default_url_options[:script_name] = "" # no tenant
|
||||
test "create with invalid params" do
|
||||
integration_session.default_url_options[:script_name] = "" # no tenant
|
||||
|
||||
post signup_accounts_url,
|
||||
headers: auth_headers,
|
||||
params: { signup: { full_name: "Jim", email_address: "jim@example.com", password: "", company_name: "" } }
|
||||
post signup_accounts_url,
|
||||
headers: auth_headers,
|
||||
params: { signup: { full_name: "Jim", email_address: "jim@example.com", password: "", company_name: "" } }
|
||||
|
||||
assert_response :unprocessable_entity
|
||||
assert_select "div.alert--error", text: /you need to choose a password/i
|
||||
end
|
||||
assert_response :unprocessable_entity
|
||||
assert_select "div.alert--error", text: /you need to choose a password/i
|
||||
end
|
||||
|
||||
test "create for a new " do
|
||||
integration_session.default_url_options[:script_name] = "" # no tenant
|
||||
test "create for a new " do
|
||||
integration_session.default_url_options[:script_name] = "" # no tenant
|
||||
|
||||
assert_difference -> { SignalId::Identity.count }, +1 do
|
||||
assert_difference -> { SignalId::Account.count }, +1 do
|
||||
post signup_accounts_url, headers: auth_headers,
|
||||
params: {
|
||||
signup: {
|
||||
full_name: "Jim",
|
||||
email_address: "jim@example.com",
|
||||
password: SecureRandom.hex(12),
|
||||
company_name: "signup-accounts-controller-test-1"
|
||||
assert_difference -> { SignalId::Identity.count }, +1 do
|
||||
assert_difference -> { SignalId::Account.count }, +1 do
|
||||
post signup_accounts_url, headers: auth_headers,
|
||||
params: {
|
||||
signup: {
|
||||
full_name: "Jim",
|
||||
email_address: "jim@example.com",
|
||||
password: SecureRandom.hex(12),
|
||||
company_name: "signup-accounts-controller-test-1"
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
signal_account = SignalId::Account.last
|
||||
assert_redirected_to(/#{signal_account.login_url}/)
|
||||
end
|
||||
|
||||
test "create for an existing identity" do
|
||||
integration_session.default_url_options[:script_name] = "" # no tenant
|
||||
|
||||
identity = signal_identities(:david)
|
||||
|
||||
post signup_accounts_url, headers: auth_headers,
|
||||
params: { signup: { email_address: identity.email_address, company_name: "signup-accounts-controller-test-2" } }
|
||||
|
||||
assert_authentication_requested_for identity
|
||||
|
||||
assert_no_difference -> { SignalId::Identity.count } do
|
||||
assert_difference -> { SignalId::Account.count } do
|
||||
authenticate_via_launchpad_as(identity)
|
||||
assert_redirected_to_account
|
||||
assert_nil session[:signup]
|
||||
end
|
||||
end
|
||||
|
||||
signal_account = SignalId::Account.last
|
||||
ApplicationRecord.with_tenant(signal_account.queenbee_id) do
|
||||
assert_equal Account.last, signal_account.peer
|
||||
end
|
||||
end
|
||||
|
||||
signal_account = SignalId::Account.last
|
||||
assert_redirected_to(/#{signal_account.login_url}/)
|
||||
end
|
||||
test "actions require HTTP basic authentication while we're in internal-only mode" do
|
||||
integration_session.default_url_options[:script_name] = "" # no tenant
|
||||
|
||||
test "create for an existing identity" do
|
||||
integration_session.default_url_options[:script_name] = "" # no tenant
|
||||
get new_signup_account_url
|
||||
|
||||
identity = signal_identities(:david)
|
||||
assert_response :unauthorized
|
||||
end
|
||||
|
||||
post signup_accounts_url, headers: auth_headers,
|
||||
params: { signup: { email_address: identity.email_address, company_name: "signup-accounts-controller-test-2" } }
|
||||
|
||||
assert_authentication_requested_for identity
|
||||
|
||||
assert_no_difference -> { SignalId::Identity.count } do
|
||||
assert_difference -> { SignalId::Account.count } do
|
||||
authenticate_via_launchpad_as(identity)
|
||||
assert_redirected_to_account
|
||||
assert_nil session[:signup]
|
||||
private
|
||||
def auth_headers
|
||||
{ "HTTP_AUTHORIZATION" => ActionController::HttpAuthentication::Basic.encode_credentials("testname", "testpassword") }
|
||||
end
|
||||
end
|
||||
|
||||
signal_account = SignalId::Account.last
|
||||
ApplicationRecord.with_tenant(signal_account.queenbee_id) do
|
||||
assert_equal Account.last, signal_account.peer
|
||||
end
|
||||
def assert_authentication_requested_for(identity)
|
||||
assert_response :redirect
|
||||
assert_match(/#{Regexp.escape(Launchpad.url("/authenticate", login_hint: identity.email_address))}.*&purpose=signup/, redirect_to_url)
|
||||
end
|
||||
|
||||
def authenticate_via_launchpad_as(identity)
|
||||
get signup_session_url, headers: auth_headers, params: { sig: identity.perishable_signature }
|
||||
assert_equal identity.id, session[:signup]["identity_id"]
|
||||
assert_redirected_to new_signup_completion_url
|
||||
post signup_completions_url, headers: auth_headers
|
||||
end
|
||||
|
||||
def assert_redirected_to_account(signal_account = SignalId::Account.last)
|
||||
assert_response :redirect
|
||||
assert_match(/#{Regexp.escape(signal_account.url("/session/launchpad"))}.*&sig=/, redirect_to_url)
|
||||
end
|
||||
end
|
||||
|
||||
test "actions require HTTP basic authentication while we're in internal-only mode" do
|
||||
integration_session.default_url_options[:script_name] = "" # no tenant
|
||||
|
||||
get new_signup_account_url
|
||||
|
||||
assert_response :unauthorized
|
||||
end
|
||||
|
||||
private
|
||||
def auth_headers
|
||||
{ "HTTP_AUTHORIZATION" => ActionController::HttpAuthentication::Basic.encode_credentials("testname", "testpassword") }
|
||||
end
|
||||
|
||||
def assert_authentication_requested_for(identity)
|
||||
assert_response :redirect
|
||||
assert_match(/#{Regexp.escape(Launchpad.url("/authenticate", login_hint: identity.email_address))}.*&purpose=signup/, redirect_to_url)
|
||||
end
|
||||
|
||||
def authenticate_via_launchpad_as(identity)
|
||||
get signup_session_url, headers: auth_headers, params: { sig: identity.perishable_signature }
|
||||
assert_equal identity.id, session[:signup]["identity_id"]
|
||||
assert_redirected_to new_signup_completion_url
|
||||
post signup_completions_url, headers: auth_headers
|
||||
end
|
||||
|
||||
def assert_redirected_to_account(signal_account = SignalId::Account.last)
|
||||
assert_response :redirect
|
||||
assert_match(/#{Regexp.escape(signal_account.url("/session/launchpad"))}.*&sig=/, redirect_to_url)
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user