2021-06-01 12:20:20 +00:00
|
|
|
# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/
|
|
|
|
|
2019-09-05 14:02:31 +00:00
|
|
|
require 'rails_helper'
|
|
|
|
|
|
|
|
RSpec.describe 'Sessions endpoints', type: :request do
|
2019-09-30 17:34:13 +00:00
|
|
|
|
2021-07-21 12:00:13 +00:00
|
|
|
describe 'GET /' do
|
|
|
|
|
|
|
|
let(:headers) { {} }
|
|
|
|
let(:session_key) { Zammad::Application::Initializer::SessionStore::SESSION_KEY }
|
|
|
|
|
|
|
|
before do
|
|
|
|
Setting.set('http_type', http_type)
|
|
|
|
|
|
|
|
get '/', headers: headers
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when Setting 'http_type' is set to 'https'" do
|
|
|
|
|
|
|
|
let(:http_type) { 'https' }
|
|
|
|
|
|
|
|
context "when it's not an HTTPS request" do
|
|
|
|
|
|
|
|
it 'sets no Cookie' do
|
|
|
|
expect(response.header['Set-Cookie']).to be_nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when it's an HTTPS request" do
|
|
|
|
|
|
|
|
let(:headers) do
|
|
|
|
{
|
|
|
|
'X-Forwarded-Proto' => 'https'
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
it "sets Cookie with 'secure' flag" do
|
|
|
|
expect(response.header['Set-Cookie']).to include(session_key).and include('; secure;')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when Setting 'http_type' is set to 'http'" do
|
|
|
|
|
|
|
|
let(:http_type) { 'http' }
|
|
|
|
|
|
|
|
context "when it's not an HTTPS request" do
|
|
|
|
|
|
|
|
it 'sets Cookie' do
|
|
|
|
expect(response.header['Set-Cookie']).to include(session_key).and not_include('; secure;')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when it's an HTTPS request" do
|
|
|
|
|
|
|
|
let(:headers) do
|
|
|
|
{
|
|
|
|
'X-Forwarded-Proto' => 'https'
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
it "sets Cookie without 'secure' flag" do
|
|
|
|
expect(response.header['Set-Cookie']).to include(session_key).and not_include('; secure;')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-02-12 14:25:31 +00:00
|
|
|
describe 'GET /signshow' do
|
|
|
|
|
|
|
|
context 'user logged in' do
|
|
|
|
|
2020-06-19 09:17:18 +00:00
|
|
|
subject(:user) { create(:agent, password: password) }
|
2020-02-12 14:25:31 +00:00
|
|
|
|
|
|
|
let(:password) { SecureRandom.urlsafe_base64(20) }
|
|
|
|
let(:fingerprint) { SecureRandom.urlsafe_base64(40) }
|
|
|
|
|
|
|
|
before do
|
|
|
|
params = {
|
|
|
|
fingerprint: fingerprint,
|
|
|
|
username: user.login,
|
|
|
|
password: password
|
|
|
|
}
|
|
|
|
post '/api/v1/signin', params: params, as: :json
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'leaks no sensitive data' do
|
|
|
|
params = { fingerprint: fingerprint }
|
|
|
|
get '/api/v1/signshow', params: params, as: :json
|
|
|
|
|
|
|
|
expect(json_response['session']).not_to include('password')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-09-30 17:34:13 +00:00
|
|
|
describe 'GET /auth/sso (single sign-on)' do
|
2020-08-26 13:21:17 +00:00
|
|
|
|
|
|
|
before do
|
|
|
|
Setting.set('auth_sso', true)
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when SSO is disabled' do
|
|
|
|
|
|
|
|
before do
|
|
|
|
Setting.set('auth_sso', false)
|
|
|
|
end
|
|
|
|
|
|
|
|
let(:headers) { { 'X-Forwarded-User' => login } }
|
|
|
|
let(:login) { User.last.login }
|
|
|
|
|
|
|
|
it 'returns a new user-session response' do
|
|
|
|
get '/auth/sso', as: :json, headers: headers
|
|
|
|
|
2021-02-04 08:28:41 +00:00
|
|
|
expect(response).to have_http_status(:forbidden)
|
2020-08-26 13:21:17 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-09-05 14:02:31 +00:00
|
|
|
context 'with invalid user login' do
|
|
|
|
let(:login) { User.pluck(:login).max.next }
|
|
|
|
|
|
|
|
context 'in "REMOTE_USER" request env var' do
|
|
|
|
let(:env) { { 'REMOTE_USER' => login } }
|
|
|
|
|
2019-09-30 17:34:13 +00:00
|
|
|
it 'returns unauthorized response' do
|
|
|
|
get '/auth/sso', as: :json, env: env
|
2019-09-05 14:02:31 +00:00
|
|
|
|
2019-09-30 17:34:13 +00:00
|
|
|
expect(response).to have_http_status(:unauthorized)
|
2019-09-05 14:02:31 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'in "HTTP_REMOTE_USER" request env var' do
|
|
|
|
let(:env) { { 'HTTP_REMOTE_USER' => login } }
|
|
|
|
|
2019-09-30 17:34:13 +00:00
|
|
|
it 'returns unauthorized response' do
|
|
|
|
get '/auth/sso', as: :json, env: env
|
2019-09-05 14:02:31 +00:00
|
|
|
|
2019-09-30 17:34:13 +00:00
|
|
|
expect(response).to have_http_status(:unauthorized)
|
2019-09-05 14:02:31 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'in "X-Forwarded-User" request header' do
|
|
|
|
let(:headers) { { 'X-Forwarded-User' => login } }
|
|
|
|
|
2019-09-30 17:34:13 +00:00
|
|
|
it 'returns unauthorized response' do
|
|
|
|
get '/auth/sso', as: :json, headers: headers
|
2019-09-05 14:02:31 +00:00
|
|
|
|
2019-09-30 17:34:13 +00:00
|
|
|
expect(response).to have_http_status(:unauthorized)
|
2019-09-05 14:02:31 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with valid user login' do
|
2021-02-04 08:28:41 +00:00
|
|
|
let(:user) { create(:agent) }
|
2019-09-05 14:02:31 +00:00
|
|
|
let(:login) { user.login }
|
|
|
|
|
|
|
|
context 'in Maintenance Mode' do
|
|
|
|
before { Setting.set('maintenance_mode', true) }
|
|
|
|
|
|
|
|
context 'in "REMOTE_USER" request env var' do
|
|
|
|
let(:env) { { 'REMOTE_USER' => login } }
|
|
|
|
|
2021-02-04 08:28:41 +00:00
|
|
|
it 'returns 403 Forbidden' do
|
2019-09-30 17:34:13 +00:00
|
|
|
get '/auth/sso', as: :json, env: env
|
2019-09-05 14:02:31 +00:00
|
|
|
|
2021-02-04 08:28:41 +00:00
|
|
|
expect(response).to have_http_status(:forbidden)
|
2019-09-05 14:02:31 +00:00
|
|
|
expect(json_response).to include('error' => 'Maintenance mode enabled!')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'in "HTTP_REMOTE_USER" request env var' do
|
|
|
|
let(:env) { { 'HTTP_REMOTE_USER' => login } }
|
|
|
|
|
2021-02-04 08:28:41 +00:00
|
|
|
it 'returns 403 Forbidden' do
|
2019-09-30 17:34:13 +00:00
|
|
|
get '/auth/sso', as: :json, env: env
|
2019-09-05 14:02:31 +00:00
|
|
|
|
2021-02-04 08:28:41 +00:00
|
|
|
expect(response).to have_http_status(:forbidden)
|
2019-09-05 14:02:31 +00:00
|
|
|
expect(json_response).to include('error' => 'Maintenance mode enabled!')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'in "X-Forwarded-User" request header' do
|
|
|
|
let(:headers) { { 'X-Forwarded-User' => login } }
|
|
|
|
|
2021-02-04 08:28:41 +00:00
|
|
|
it 'returns 403 Forbidden' do
|
2019-09-30 17:34:13 +00:00
|
|
|
get '/auth/sso', as: :json, headers: headers
|
2019-09-05 14:02:31 +00:00
|
|
|
|
2021-02-04 08:28:41 +00:00
|
|
|
expect(response).to have_http_status(:forbidden)
|
2019-09-05 14:02:31 +00:00
|
|
|
expect(json_response).to include('error' => 'Maintenance mode enabled!')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'in "REMOTE_USER" request env var' do
|
|
|
|
let(:env) { { 'REMOTE_USER' => login } }
|
|
|
|
|
|
|
|
it 'returns a new user-session response' do
|
2019-09-30 17:34:13 +00:00
|
|
|
get '/auth/sso', as: :json, env: env
|
2019-09-05 14:02:31 +00:00
|
|
|
|
2019-09-30 17:34:13 +00:00
|
|
|
expect(response).to redirect_to('/#')
|
2019-09-05 14:02:31 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'sets the :user_id session parameter' do
|
2019-09-30 17:34:13 +00:00
|
|
|
expect { get '/auth/sso', as: :json, env: env }
|
2019-09-05 14:02:31 +00:00
|
|
|
.to change { request&.session&.fetch(:user_id) }.to(user.id)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'in "HTTP_REMOTE_USER" request env var' do
|
|
|
|
let(:env) { { 'HTTP_REMOTE_USER' => login } }
|
|
|
|
|
|
|
|
it 'returns a new user-session response' do
|
2019-09-30 17:34:13 +00:00
|
|
|
get '/auth/sso', as: :json, env: env
|
2019-09-05 14:02:31 +00:00
|
|
|
|
2019-09-30 17:34:13 +00:00
|
|
|
expect(response).to redirect_to('/#')
|
2019-09-05 14:02:31 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'sets the :user_id session parameter' do
|
2019-09-30 17:34:13 +00:00
|
|
|
expect { get '/auth/sso', as: :json, env: env }
|
2019-09-05 14:02:31 +00:00
|
|
|
.to change { request&.session&.fetch(:user_id) }.to(user.id)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'in "X-Forwarded-User" request header' do
|
|
|
|
let(:headers) { { 'X-Forwarded-User' => login } }
|
|
|
|
|
|
|
|
it 'returns a new user-session response' do
|
2019-09-30 17:34:13 +00:00
|
|
|
get '/auth/sso', as: :json, headers: headers
|
2019-09-05 14:02:31 +00:00
|
|
|
|
2019-09-30 17:34:13 +00:00
|
|
|
expect(response).to redirect_to('/#')
|
2019-09-05 14:02:31 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
it 'sets the :user_id session parameter on the client' do
|
2019-09-30 17:34:13 +00:00
|
|
|
expect { get '/auth/sso', as: :json, headers: headers }
|
2019-09-05 14:02:31 +00:00
|
|
|
.to change { request&.session&.fetch(:user_id) }.to(user.id)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|