chore: remove redundant files
This commit is contained in:
@@ -1,229 +0,0 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe DeviseOverrides::OmniauthCallbacksController, type: :controller do
|
||||
let(:account) { create(:account) }
|
||||
let(:email) { 'saml.user@example.com' }
|
||||
|
||||
before do
|
||||
# Set up OmniAuth test mode
|
||||
OmniAuth.config.test_mode = true
|
||||
request.env['devise.mapping'] = Devise.mappings[:user]
|
||||
end
|
||||
|
||||
after do
|
||||
OmniAuth.config.test_mode = false
|
||||
end
|
||||
|
||||
describe 'POST #saml' do
|
||||
let(:auth_hash) do
|
||||
OmniAuth::AuthHash.new(
|
||||
provider: 'saml',
|
||||
uid: 'saml-uid-123',
|
||||
info: {
|
||||
email: email,
|
||||
name: 'SAML User',
|
||||
first_name: 'SAML',
|
||||
last_name: 'User'
|
||||
},
|
||||
extra: {
|
||||
raw_info: {
|
||||
groups: ['Administrators']
|
||||
}
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
context 'with successful SAML authentication' do
|
||||
before do
|
||||
# Set up session with auth data as DeviseTokenAuth would
|
||||
session['dta.omniauth.auth'] = auth_hash.to_hash
|
||||
session[:saml_account_id] = account.id
|
||||
|
||||
# Enable SAML for the account
|
||||
create(:account_saml_settings, account: account, enabled: true)
|
||||
end
|
||||
|
||||
context 'when user does not exist' do
|
||||
it 'creates a new user' do
|
||||
expect do
|
||||
post :saml
|
||||
end.to change(User, :count).by(1)
|
||||
end
|
||||
|
||||
it 'redirects to login with SSO token' do
|
||||
post :saml
|
||||
|
||||
User.from_email(email)
|
||||
expect(response).to redirect_to(%r{/app/login\?email=.*&sso_auth_token=})
|
||||
end
|
||||
|
||||
it 'associates user with account' do
|
||||
post :saml
|
||||
|
||||
user = User.from_email(email)
|
||||
expect(user.accounts).to include(account)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user already exists' do
|
||||
let!(:existing_user) { create(:user, email: email) }
|
||||
|
||||
it 'does not create a new user' do
|
||||
expect do
|
||||
post :saml
|
||||
end.not_to change(User, :count)
|
||||
end
|
||||
|
||||
it 'redirects to login with SSO token' do
|
||||
post :saml
|
||||
|
||||
expect(response).to redirect_to(%r{/app/login\?email=.*&sso_auth_token=})
|
||||
end
|
||||
|
||||
it 'adds user to account if not already added' do
|
||||
expect(existing_user.accounts).not_to include(account)
|
||||
|
||||
post :saml
|
||||
|
||||
expect(existing_user.reload.accounts).to include(account)
|
||||
end
|
||||
end
|
||||
|
||||
context 'without account_id' do
|
||||
before do
|
||||
session.delete(:saml_account_id)
|
||||
end
|
||||
|
||||
it 'still processes the authentication' do
|
||||
post :saml
|
||||
|
||||
expect(response).to redirect_to(%r{/app/login})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when SAML is not enabled for account' do
|
||||
before do
|
||||
session['dta.omniauth.auth'] = auth_hash.to_hash
|
||||
session[:saml_account_id] = account.id
|
||||
|
||||
# SAML is disabled for the account
|
||||
create(:account_saml_settings, account: account, enabled: false)
|
||||
end
|
||||
|
||||
it 'redirects with error' do
|
||||
post :saml
|
||||
|
||||
expect(response).to redirect_to(%r{/app/login\?error=saml-not-enabled})
|
||||
end
|
||||
|
||||
it 'does not create a user' do
|
||||
expect do
|
||||
post :saml
|
||||
end.not_to change(User, :count)
|
||||
end
|
||||
end
|
||||
|
||||
context 'without auth hash' do
|
||||
before do
|
||||
session.delete('dta.omniauth.auth')
|
||||
end
|
||||
|
||||
it 'redirects to login' do
|
||||
post :saml
|
||||
|
||||
expect(response).to redirect_to(%r{/app/login})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #redirect_callbacks' do
|
||||
let(:auth_hash) do
|
||||
OmniAuth::AuthHash.new(
|
||||
provider: 'saml',
|
||||
uid: 'saml-uid-123',
|
||||
info: {
|
||||
email: email,
|
||||
name: 'SAML User'
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
before do
|
||||
request.env['omniauth.auth'] = auth_hash
|
||||
request.env['omniauth.params'] = {
|
||||
'resource_class' => 'User',
|
||||
'account_id' => account.id.to_s
|
||||
}
|
||||
end
|
||||
|
||||
context 'with SAML provider' do
|
||||
it 'stores auth data in session' do
|
||||
get :redirect_callbacks, params: { provider: 'saml' }
|
||||
|
||||
expect(session['dta.omniauth.auth']).to eq(auth_hash.except('extra'))
|
||||
expect(session['dta.omniauth.params']).to include('account_id' => account.id.to_s)
|
||||
end
|
||||
|
||||
it 'redirects with 303 status for SAML' do
|
||||
get :redirect_callbacks, params: { provider: 'saml' }
|
||||
|
||||
expect(response).to have_http_status(303)
|
||||
expect(response).to redirect_to(%r{/auth/saml/callback})
|
||||
end
|
||||
end
|
||||
|
||||
context 'with non-SAML provider' do
|
||||
it 'redirects with 307 status' do
|
||||
get :redirect_callbacks, params: { provider: 'google_oauth2' }
|
||||
|
||||
expect(response).to have_http_status(307)
|
||||
expect(response).to redirect_to(%r{/auth/google_oauth2/callback})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#get_resource_from_auth_hash' do
|
||||
let(:auth_hash) do
|
||||
{
|
||||
'provider' => 'saml',
|
||||
'info' => {
|
||||
'email' => email
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:auth_hash).and_return(auth_hash)
|
||||
end
|
||||
|
||||
context 'with SAML provider' do
|
||||
it 'uses from_email to find user' do
|
||||
existing_user = create(:user, email: email.upcase) # Test case insensitivity
|
||||
|
||||
controller.send(:get_resource_from_auth_hash)
|
||||
|
||||
expect(controller.instance_variable_get(:@resource)).to eq(existing_user)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with non-SAML provider' do
|
||||
let(:auth_hash) do
|
||||
{
|
||||
'provider' => 'google_oauth2',
|
||||
'info' => {
|
||||
'email' => email
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
it 'uses where query to find user' do
|
||||
existing_user = create(:user, email: email)
|
||||
|
||||
controller.send(:get_resource_from_auth_hash)
|
||||
|
||||
expect(controller.instance_variable_get(:@resource)).to eq(existing_user)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,86 +0,0 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'SAML Authentication API', type: :request do
|
||||
let(:account) { create(:account) }
|
||||
let!(:saml_settings) do
|
||||
create(:account_saml_settings,
|
||||
:enabled,
|
||||
account: account,
|
||||
sso_url: 'https://mocksaml.com/sso')
|
||||
end
|
||||
let(:existing_user) do
|
||||
create(:user, email: 'john.doe@example.com', name: 'John Doe')
|
||||
end
|
||||
|
||||
describe 'POST /auth/saml/:account_id/callback' do
|
||||
context 'with existing user' do
|
||||
let(:auth_hash) do
|
||||
{
|
||||
'provider' => 'saml',
|
||||
'uid' => 'john.doe@example.com',
|
||||
'info' => {
|
||||
'email' => 'john.doe@example.com',
|
||||
'name' => 'John Doe'
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
existing_user
|
||||
end
|
||||
|
||||
it 'redirects to frontend login with SSO token' do
|
||||
post "/auth/saml/#{account.id}/callback",
|
||||
env: { 'omniauth.auth' => auth_hash },
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:found) # 302 redirect
|
||||
expect(response.location).to include('/app/login')
|
||||
expect(response.location).to include('email=john.doe%40example.com')
|
||||
expect(response.location).to include('sso_auth_token=')
|
||||
end
|
||||
|
||||
it 'generates SSO auth token for the user' do
|
||||
expect(existing_user).to receive(:generate_sso_auth_token).and_call_original
|
||||
|
||||
post "/auth/saml/#{account.id}/callback",
|
||||
env: { 'omniauth.auth' => auth_hash },
|
||||
as: :json
|
||||
|
||||
# Verify token was created in Redis
|
||||
expect(response).to have_http_status(:found)
|
||||
end
|
||||
|
||||
it 'does not update sign in tracking directly' do
|
||||
# Sign in tracking should happen when user completes login via frontend
|
||||
expect do
|
||||
post "/auth/saml/#{account.id}/callback",
|
||||
env: { 'omniauth.auth' => auth_hash },
|
||||
as: :json
|
||||
end.not_to change { existing_user.reload.sign_in_count }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user does not exist' do
|
||||
let(:auth_hash) do
|
||||
{
|
||||
'provider' => 'saml',
|
||||
'uid' => 'nonexistent@example.com',
|
||||
'info' => {
|
||||
'email' => 'nonexistent@example.com'
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
it 'returns user not found error' do
|
||||
post "/auth/saml/#{account.id}/callback",
|
||||
env: { 'omniauth.auth' => auth_hash },
|
||||
as: :json
|
||||
|
||||
expect(response).to have_http_status(:not_found)
|
||||
json_response = JSON.parse(response.body)
|
||||
expect(json_response['error']).to eq('User not found')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,124 +0,0 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe OmniauthController, type: :controller do
|
||||
let(:account) { create(:account) }
|
||||
let!(:saml_settings) do
|
||||
create(:account_saml_settings,
|
||||
:enabled,
|
||||
account: account,
|
||||
sso_url: 'https://mocksaml.com/sso')
|
||||
end
|
||||
let(:existing_user) do
|
||||
create(:user, email: 'john.doe@example.com', name: 'John Doe')
|
||||
end
|
||||
|
||||
describe 'GET #callback' do
|
||||
context 'with existing user' do
|
||||
let(:auth_hash) do
|
||||
OmniAuth::AuthHash.new({
|
||||
provider: 'saml',
|
||||
uid: 'john.doe@example.com',
|
||||
info: {
|
||||
email: 'john.doe@example.com',
|
||||
name: 'John Doe',
|
||||
first_name: 'John',
|
||||
last_name: 'Doe'
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
before do
|
||||
existing_user
|
||||
# Mock the OmniAuth auth hash in the request environment
|
||||
request.env['omniauth.auth'] = auth_hash
|
||||
end
|
||||
|
||||
it 'redirects to frontend login with SSO token' do
|
||||
get :callback, params: { account_id: account.id }
|
||||
|
||||
expect(response).to have_http_status(:found)
|
||||
expect(response.location).to include('/app/login')
|
||||
expect(response.location).to include('email=john.doe%40example.com')
|
||||
expect(response.location).to include('sso_auth_token=')
|
||||
end
|
||||
|
||||
it 'generates a valid SSO auth token' do
|
||||
allow(SecureRandom).to receive(:hex).and_return('test_token_12345')
|
||||
|
||||
get :callback, params: { account_id: account.id }
|
||||
|
||||
# Verify token was stored in Redis
|
||||
token_key = "chatwoot:user:#{existing_user.id}:sso_auth_token:test_token_12345"
|
||||
expect(::Redis::Alfred.get(token_key)).to eq('true')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user does not exist' do
|
||||
let(:auth_hash) do
|
||||
OmniAuth::AuthHash.new({
|
||||
provider: 'saml',
|
||||
uid: 'newuser@example.com',
|
||||
info: {
|
||||
email: 'newuser@example.com',
|
||||
name: 'New User'
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
before do
|
||||
request.env['omniauth.auth'] = auth_hash
|
||||
end
|
||||
|
||||
it 'returns user not found error' do
|
||||
get :callback, params: { account_id: account.id }
|
||||
|
||||
expect(response).to have_http_status(:not_found)
|
||||
json_response = JSON.parse(response.body)
|
||||
expect(json_response['error']).to eq('User not found')
|
||||
expect(json_response['message']).to include('newuser@example.com')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when SAML is not enabled for account' do
|
||||
before do
|
||||
saml_settings.update!(enabled: false)
|
||||
request.env['omniauth.auth'] = { info: { email: 'test@example.com' } }
|
||||
end
|
||||
|
||||
it 'returns unauthorized error' do
|
||||
get :callback, params: { account_id: account.id }
|
||||
|
||||
expect(response).to have_http_status(:unauthorized)
|
||||
json_response = JSON.parse(response.body)
|
||||
expect(json_response['error']).to eq('SAML not enabled for this account')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when authentication fails' do
|
||||
before do
|
||||
request.env['omniauth.auth'] = nil
|
||||
request.env['omniauth.error'] = 'Invalid SAML Response'
|
||||
end
|
||||
|
||||
it 'returns authentication failed error' do
|
||||
get :callback, params: { account_id: account.id }
|
||||
|
||||
expect(response).to have_http_status(:unauthorized)
|
||||
json_response = JSON.parse(response.body)
|
||||
expect(json_response['error']).to eq('SAML authentication failed')
|
||||
expect(json_response['message']).to eq('Invalid SAML Response')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #failure' do
|
||||
it 'returns authentication failure message' do
|
||||
get :failure, params: { message: 'SAML IdP error occurred' }
|
||||
|
||||
expect(response).to have_http_status(:unauthorized)
|
||||
json_response = JSON.parse(response.body)
|
||||
expect(json_response['error']).to eq('SAML authentication failed')
|
||||
expect(json_response['message']).to eq('SAML IdP error occurred')
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user