mirror of
https://github.com/opf/openproject.git
synced 2026-06-14 03:30:14 +00:00
[40240] Return the original authenticated user in case of optional sso
https://community.openproject.org/wp/40240
This commit is contained in:
@@ -14,6 +14,17 @@ module AuthSourceSSO
|
||||
# Get the header-provided login value
|
||||
login = read_sso_login
|
||||
|
||||
if login.present?
|
||||
perform_header_sso login, user
|
||||
elsif header_optional?
|
||||
user
|
||||
else
|
||||
handle_sso_failure!
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def perform_header_sso(login, user)
|
||||
# Log out the current user if the login does not match
|
||||
logged_user = match_sso_with_logged_user(login, user)
|
||||
|
||||
@@ -21,7 +32,9 @@ module AuthSourceSSO
|
||||
return logged_user if logged_user.present?
|
||||
|
||||
Rails.logger.debug { "Starting header-based auth source SSO for #{header_name}='#{op_auth_header_value}'" }
|
||||
perform_header_sso login
|
||||
|
||||
user = find_user_from_auth_source(login) || create_user_from_auth_source(login)
|
||||
handle_sso_for! user, login
|
||||
end
|
||||
|
||||
def match_sso_with_logged_user(login, user)
|
||||
@@ -34,16 +47,6 @@ module AuthSourceSSO
|
||||
nil
|
||||
end
|
||||
|
||||
def perform_header_sso(login)
|
||||
if login
|
||||
user = find_user_from_auth_source(login) || create_user_from_auth_source(login)
|
||||
|
||||
handle_sso_for! user, login
|
||||
else
|
||||
handle_sso_failure!
|
||||
end
|
||||
end
|
||||
|
||||
def read_sso_login
|
||||
get_validated_login! op_auth_header_value
|
||||
end
|
||||
@@ -162,7 +165,8 @@ module AuthSourceSSO
|
||||
def handle_sso_for!(user, login)
|
||||
if sso_login_failed?(user)
|
||||
handle_sso_failure!({ user: user, login: login })
|
||||
else # valid user
|
||||
else
|
||||
# valid user
|
||||
# If a user is invited, ensure it gets activated
|
||||
activated = user.invited?
|
||||
activate_user_if_invited! user
|
||||
@@ -191,8 +195,6 @@ module AuthSourceSSO
|
||||
end
|
||||
|
||||
def handle_sso_failure!(session_args = {})
|
||||
return if header_optional?
|
||||
|
||||
session[:auth_source_sso_failure] = session_args.merge(
|
||||
back_url: request.base_url + request.original_fullpath,
|
||||
ttl: 1
|
||||
|
||||
@@ -45,6 +45,7 @@ describe MyController, type: :controller do
|
||||
let!(:user) { FactoryBot.create :user, login: login, auth_source_id: auth_source.id, last_login_on: 5.days.ago }
|
||||
let(:login) { "h.wurst" }
|
||||
let(:header_login_value) { login }
|
||||
let(:header_value) { "#{header_login_value}#{secret ? ':' : ''}#{secret}" }
|
||||
|
||||
shared_examples 'should log in the user' do
|
||||
it "logs in given user" do
|
||||
@@ -81,8 +82,19 @@ describe MyController, type: :controller do
|
||||
}
|
||||
end
|
||||
|
||||
it "should redirect to login" do
|
||||
expect(response).to redirect_to("/login?back_url=http%3A%2F%2Ftest.host%2Fmy%2Faccount")
|
||||
context 'when no header is present' do
|
||||
let(:header_value) { nil }
|
||||
|
||||
it "redirects to login" do
|
||||
expect(response).to redirect_to("/login?back_url=http%3A%2F%2Ftest.host%2Fmy%2Faccount")
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the header is present' do
|
||||
it "shows an error" do
|
||||
expect(response).to redirect_to("/sso")
|
||||
expect(session).to have_key(:auth_source_sso_failure)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -94,8 +106,7 @@ describe MyController, type: :controller do
|
||||
.and_return(sso_config)
|
||||
end
|
||||
|
||||
separator = secret ? ':' : ''
|
||||
request.headers[header] = "#{header_login_value}#{separator}#{secret}"
|
||||
request.headers[header] = header_value
|
||||
end
|
||||
|
||||
describe 'login' do
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 the OpenProject GmbH
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License version 3.
|
||||
#
|
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
# Copyright (C) 2010-2013 the ChiliProject Team
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# See COPYRIGHT and LICENSE files for more details.
|
||||
#++
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe 'Login with auth source SSO', type: :feature, clear_cache: true do
|
||||
before do
|
||||
if sso_config
|
||||
allow(OpenProject::Configuration)
|
||||
.to receive(:auth_source_sso)
|
||||
.and_return(sso_config)
|
||||
end
|
||||
end
|
||||
|
||||
let(:sso_config) do
|
||||
{
|
||||
header: "X-Remote-User",
|
||||
optional: true
|
||||
}
|
||||
end
|
||||
|
||||
let(:user_password) { 'bob' * 4 }
|
||||
let(:user) do
|
||||
FactoryBot.create(:user,
|
||||
login: 'bob',
|
||||
password: user_password,
|
||||
password_confirmation: user_password)
|
||||
end
|
||||
|
||||
it 'can still login' do
|
||||
login_with(user.login, user_password)
|
||||
|
||||
# on the my page
|
||||
expect(page)
|
||||
.to have_current_path my_page_path
|
||||
|
||||
expect(page)
|
||||
.to have_selector("a[title='#{user.name}']")
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user