Auth Hash provider config method uses ivar rather than method
This bug was discovered when troubleshooting a customer issue with gitlab_username_claim
configuration for an OmniAuth identity provider.
Given an IdP configuration such as the following:
- {
name: "saml",
args: {
assertion_consumer_service_url: "https://gdk.test:3443/users/auth/saml/callback",
idp_cert_fingerprint: "BB:9B:AA:66:50:91:AA:FC:AC:BE:D8:2F:BB:D6:F9:E5:84:77:0D:B7",
idp_sso_target_url: "https://foo.example.com",
issuer: "https://gdk.test:3443",
name_identifier_format: "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent",
attribute_statements: { nickname: ['firstname'] },
gitlab_username_claim: 'uid'
}
And generating an OmniAuth Auth Hash as follows:
omni_authhash = OmniAuth::AuthHash.new(credentials: OmniAuth::AuthHash.new, extra: OmniAuth::AuthHash.new(raw_info: OmniAuth::AuthHash.new), info: OmniAuth::AuthHash::InfoHash.new(email: 'DREW@EXAMPLE.COM', name: 'Drew Blessing'), provider: 'saml', uid: 'dblessing')
Current Behavior
pry(main)> auth_hash = Gitlab::Auth::OAuth::AuthHash.new(omni_authhash)
=> #<Gitlab::Auth::OAuth::AuthHash:0x000000014010e938 @auth_hash={"credentials"=>{}, "extra"=>{"raw_info"=>{}}, "info"=>{"email"=>"DREW@EXAMPLE.COM", "name"=>"Drew Blessing"}, "provider"=>"saml", "uid"=>"dblessing"}>
pry(main)> auth_hash.username
=> "DREW"
Expected Behavior
pry(main)> auth_hash = Gitlab::Auth::OAuth::AuthHash.new(omni_authhash)
=> #<Gitlab::Auth::OAuth::AuthHash:0x000000014010e938 @auth_hash={"credentials"=>{}, "extra"=>{"raw_info"=>{}}, "info"=>{"email"=>"DREW@EXAMPLE.COM", "name"=>"Drew Blessing"}, "provider"=>"saml", "uid"=>"dblessing"}>
pry(main)> auth_hash.username
=> "dblessing"
Cause
Username claim relies on looking up the provider config, which is done by calling AuthHash#provider_config
which has the code Gitlab::Auth::OAuth::Provider.config_for(@provider) || {}
. Unless something previously called the AuthHash#provider
method, @provider
ivar is not initialized.
Fix
Replace the ivar usage with the method call instead.
def provider_config
Gitlab::Auth::OAuth::Provider.config_for(provider) || {}
end