From 94ee2fa6b44e627d01880f0be084ff52c37872ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20G=C3=BCnther?= Date: Tue, 29 Nov 2022 08:47:17 +0100 Subject: [PATCH] Allow mapping other attributes using the preferred_username claim Login claims from oidc are not respected, as we always map login to the email in the omniauth service, unless the strategy provides other mappings. OIDC standard claims have the `preferred_username` claim, which we can use to map to the login. https://community.openproject.org/wp/45064 --- .../lib/open_project/openid_connect/engine.rb | 8 +++++++ .../spec/requests/openid_connect_spec.rb | 21 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/modules/openid_connect/lib/open_project/openid_connect/engine.rb b/modules/openid_connect/lib/open_project/openid_connect/engine.rb index f52a677a03..d4e407c68f 100644 --- a/modules/openid_connect/lib/open_project/openid_connect/engine.rb +++ b/modules/openid_connect/lib/open_project/openid_connect/engine.rb @@ -54,6 +54,14 @@ module OpenProject::OpenIDConnect ::OpenProject::OpenIDConnect::SessionMapper.handle_logout(logout_token) end + # Allow username mapping from 'preferred_username' claim + h[:openproject_attribute_map] = Proc.new do |auth| + {}.tap do |additional| + preferred_username = auth.dig('extra', 'raw_info', 'preferred_username') + additional[:login] = preferred_username if preferred_username.present? + end + end + h end end diff --git a/modules/openid_connect/spec/requests/openid_connect_spec.rb b/modules/openid_connect/spec/requests/openid_connect_spec.rb index a7c61945c7..dccc65c0aa 100644 --- a/modules/openid_connect/spec/requests/openid_connect_spec.rb +++ b/modules/openid_connect/spec/requests/openid_connect_spec.rb @@ -130,6 +130,27 @@ describe 'OpenID Connect', expect(response.cookies['_open_project_session_access_token']).to eq 'foo bar baz' end end + + context 'with a preferred_username claim' do + let(:user_info) do + { + sub: '87117114115116', + name: 'Hans Wurst', + email: 'h.wurst@finn.de', + given_name: 'Hans', + family_name: 'Wurst', + preferred_username: 'h.wurst' + } + end + + it 'maps to the login' do + click_on_signin + redirect_from_provider + + user = User.find_by(login: 'h.wurst') + expect(user).to be_present + end + end end context 'provider configuration through the settings' do