Commit 39e52710 authored by Douwe Maan's avatar Douwe Maan

Merge branch 'ee-38822-oauth-search-case-insensitive' into 'master'

Port from CE to EE: Changing OAuth lookup to be case insensitive

See merge request gitlab-org/gitlab-ee!3427
parents c8391221 5e28a1fc
...@@ -45,7 +45,7 @@ module KerberosSpnegoHelper ...@@ -45,7 +45,7 @@ module KerberosSpnegoHelper
krb_principal = spnego_credentials!(spnego_token) krb_principal = spnego_credentials!(spnego_token)
return unless krb_principal return unless krb_principal
identity = ::Identity.find_by(provider: :kerberos, extern_uid: krb_principal) identity = ::Identity.with_extern_uid(:kerberos, krb_principal).take
identity&.user identity&.user
end end
......
class Identity < ActiveRecord::Base class Identity < ActiveRecord::Base
prepend EE::Identity
include Sortable include Sortable
include CaseSensitivity include CaseSensitivity
belongs_to :user belongs_to :user
validates :provider, presence: true validates :provider, presence: true
validates :extern_uid, allow_blank: true, uniqueness: { scope: :provider } validates :extern_uid, allow_blank: true, uniqueness: { scope: :provider, case_sensitive: false }
validates :user_id, uniqueness: { scope: :provider } validates :user_id, uniqueness: { scope: :provider }
scope :with_provider, ->(provider) { where(provider: provider) } scope :with_provider, ->(provider) { where(provider: provider) }
scope :with_extern_uid, ->(provider, extern_uid) do scope :with_extern_uid, ->(provider, extern_uid) do
extern_uid = Gitlab::LDAP::Person.normalize_dn(extern_uid) if provider.starts_with?('ldap') iwhere(extern_uid: normalize_uid(provider, extern_uid)).with_provider(provider)
where(extern_uid: extern_uid, provider: provider)
end end
def ldap? def ldap?
provider.starts_with?('ldap') provider.starts_with?('ldap')
end end
def self.normalize_uid(provider, uid)
if provider.to_s.starts_with?('ldap')
Gitlab::LDAP::Person.normalize_dn(uid)
else
uid.to_s
end
end
end end
...@@ -278,8 +278,7 @@ class User < ActiveRecord::Base ...@@ -278,8 +278,7 @@ class User < ActiveRecord::Base
end end
def for_github_id(id) def for_github_id(id)
joins(:identities) joins(:identities).merge(Identity.with_extern_uid(:github, id))
.where(identities: { provider: :github, extern_uid: id.to_s })
end end
# Find a User by their primary email or any associated secondary email # Find a User by their primary email or any associated secondary email
......
---
title: OAuth identity lookups case-insensitive
merge_request: 15312
author:
type: fixed
module EE
module Identity
extend ActiveSupport::Concern
prepended do
validates :secondary_extern_uid, allow_blank: true, uniqueness: { scope: :provider, case_sensitive: false }
scope :with_secondary_extern_uid, ->(provider, secondary_extern_uid) do
iwhere(secondary_extern_uid: normalize_uid(provider, secondary_extern_uid)).with_provider(provider)
end
end
end
end
...@@ -108,7 +108,7 @@ module EE ...@@ -108,7 +108,7 @@ module EE
end end
def member_uid_to_dn(uid) def member_uid_to_dn(uid)
identity = Identity.find_by(provider: provider, secondary_extern_uid: uid) identity = ::Identity.with_secondary_extern_uid(provider, uid).take
if identity.present? if identity.present?
# Use the DN on record in GitLab when it's available # Use the DN on record in GitLab when it's available
...@@ -127,8 +127,7 @@ module EE ...@@ -127,8 +127,7 @@ module EE
end end
def update_identity(dn, uid) def update_identity(dn, uid)
identity = identity = ::Identity.with_extern_uid(provider, dn).take
Identity.find_by(provider: provider, extern_uid: dn)
# User may not exist in GitLab yet. Skip. # User may not exist in GitLab yet. Skip.
return unless identity.present? return unless identity.present?
......
...@@ -44,7 +44,7 @@ module Gitlab ...@@ -44,7 +44,7 @@ module Gitlab
private private
def find_by_login(login) def find_by_login(login)
identity = ::Identity.find_by(provider: :kerberos, extern_uid: login) identity = ::Identity.with_extern_uid(:kerberos, login).take
identity && identity.user identity && identity.user
end end
end end
......
...@@ -11,11 +11,8 @@ module Gitlab ...@@ -11,11 +11,8 @@ module Gitlab
class << self class << self
def find_by_uid_and_provider(uid, provider) def find_by_uid_and_provider(uid, provider)
uid = Gitlab::LDAP::Person.normalize_dn(uid) identity = ::Identity.with_extern_uid(provider, uid).take
identity = ::Identity
.where(provider: provider)
.where(extern_uid: uid).last
identity && identity.user identity && identity.user
end end
end end
......
...@@ -159,7 +159,7 @@ module Gitlab ...@@ -159,7 +159,7 @@ module Gitlab
end end
def find_by_uid_and_provider def find_by_uid_and_provider
identity = Identity.find_by(provider: auth_hash.provider, extern_uid: auth_hash.uid) identity = Identity.with_extern_uid(auth_hash.provider, auth_hash.uid).take
identity && identity.user identity && identity.user
end end
......
...@@ -182,11 +182,9 @@ describe EE::Gitlab::LDAP::Sync::Proxy do ...@@ -182,11 +182,9 @@ describe EE::Gitlab::LDAP::Sync::Proxy do
it 'retrieves the DN from the identity' do it 'retrieves the DN from the identity' do
expect(Identity) expect(Identity)
.to receive(:find_by) .to receive(:with_secondary_extern_uid)
.with( .with(sync_proxy.provider, user.username)
provider: sync_proxy.provider, .once.and_call_original
secondary_extern_uid: user.username
).once.and_call_original
end end
end end
end end
......
...@@ -662,4 +662,13 @@ describe Gitlab::OAuth::User do ...@@ -662,4 +662,13 @@ describe Gitlab::OAuth::User do
end end
end end
end end
describe '.find_by_uid_and_provider' do
let!(:existing_user) { create(:omniauth_user, extern_uid: 'my-uid', provider: 'my-provider') }
it 'normalizes extern_uid' do
allow(oauth_user.auth_hash).to receive(:uid).and_return('MY-UID')
expect(oauth_user.find_user).to eql gl_user
end
end
end end
...@@ -33,5 +33,15 @@ describe Identity do ...@@ -33,5 +33,15 @@ describe Identity do
expect(identity).to eq(ldap_identity) expect(identity).to eq(ldap_identity)
end end
end end
context 'any other provider' do
let!(:test_entity) { create(:identity, provider: 'test_provider', extern_uid: 'test_uid') }
it 'the extern_uid lookup is case insensitive' do
identity = described_class.with_extern_uid('test_provider', 'TEST_UID').first
expect(identity).to eq(test_entity)
end
end
end end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment