From 26af0e2d601401114a0574203a56f5f71417adf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Javier=20L=C3=B3pez?= Date: Thu, 15 Feb 2018 09:27:38 +0000 Subject: [PATCH] Fixed user synced attributes metadata after removing current provider --- app/models/identity.rb | 9 +++++ .../fj-37528-error-after-disabling-ldap.yml | 6 ++++ lib/gitlab/ldap/config.rb | 2 +- lib/gitlab/o_auth/user.rb | 8 ++++- spec/lib/gitlab/ldap/config_spec.rb | 8 +++++ spec/lib/gitlab/o_auth/user_spec.rb | 4 +++ spec/models/identity_spec.rb | 33 +++++++++++++++++++ 7 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 changelogs/unreleased/fj-37528-error-after-disabling-ldap.yml diff --git a/app/models/identity.rb b/app/models/identity.rb index b3fa7d8176a..2b433e9b988 100644 --- a/app/models/identity.rb +++ b/app/models/identity.rb @@ -9,6 +9,7 @@ class Identity < ActiveRecord::Base validates :user_id, uniqueness: { scope: :provider } before_save :ensure_normalized_extern_uid, if: :extern_uid_changed? + after_destroy :clear_user_synced_attributes, if: :user_synced_attributes_metadata_from_provider? scope :with_provider, ->(provider) { where(provider: provider) } scope :with_extern_uid, ->(provider, extern_uid) do @@ -34,4 +35,12 @@ class Identity < ActiveRecord::Base self.extern_uid = Identity.normalize_uid(self.provider, self.extern_uid) end + + def user_synced_attributes_metadata_from_provider? + user.user_synced_attributes_metadata&.provider == provider + end + + def clear_user_synced_attributes + user.user_synced_attributes_metadata&.destroy + end end diff --git a/changelogs/unreleased/fj-37528-error-after-disabling-ldap.yml b/changelogs/unreleased/fj-37528-error-after-disabling-ldap.yml new file mode 100644 index 00000000000..1e35f2b537d --- /dev/null +++ b/changelogs/unreleased/fj-37528-error-after-disabling-ldap.yml @@ -0,0 +1,6 @@ +--- +title: Fixed error 500 when removing an identity with synced attributes and visiting + the profile page +merge_request: 17054 +author: +type: fixed diff --git a/lib/gitlab/ldap/config.rb b/lib/gitlab/ldap/config.rb index 47b3fce3e7a..a6bea98d631 100644 --- a/lib/gitlab/ldap/config.rb +++ b/lib/gitlab/ldap/config.rb @@ -15,7 +15,7 @@ module Gitlab end def self.servers - Gitlab.config.ldap.servers.values + Gitlab.config.ldap['servers']&.values || [] end def self.available_servers diff --git a/lib/gitlab/o_auth/user.rb b/lib/gitlab/o_auth/user.rb index a3e1c66c19f..ed5ab7b174d 100644 --- a/lib/gitlab/o_auth/user.rb +++ b/lib/gitlab/o_auth/user.rb @@ -198,9 +198,11 @@ module Gitlab end def update_profile + clear_user_synced_attributes_metadata + return unless sync_profile_from_provider? || creating_linked_ldap_user? - metadata = gl_user.user_synced_attributes_metadata || gl_user.build_user_synced_attributes_metadata + metadata = gl_user.build_user_synced_attributes_metadata if sync_profile_from_provider? UserSyncedAttributesMetadata::SYNCABLE_ATTRIBUTES.each do |key| @@ -221,6 +223,10 @@ module Gitlab end end + def clear_user_synced_attributes_metadata + gl_user.user_synced_attributes_metadata&.destroy + end + def log Gitlab::AppLogger end diff --git a/spec/lib/gitlab/ldap/config_spec.rb b/spec/lib/gitlab/ldap/config_spec.rb index ca2213cd112..e10837578a8 100644 --- a/spec/lib/gitlab/ldap/config_spec.rb +++ b/spec/lib/gitlab/ldap/config_spec.rb @@ -5,6 +5,14 @@ describe Gitlab::LDAP::Config do let(:config) { described_class.new('ldapmain') } + describe '.servers' do + it 'returns empty array if no server information is available' do + allow(Gitlab.config).to receive(:ldap).and_return('enabled' => false) + + expect(described_class.servers).to eq [] + end + end + describe '#initialize' do it 'requires a provider' do expect { described_class.new }.to raise_error ArgumentError diff --git a/spec/lib/gitlab/o_auth/user_spec.rb b/spec/lib/gitlab/o_auth/user_spec.rb index 03e0a9e2a03..b8455403bdb 100644 --- a/spec/lib/gitlab/o_auth/user_spec.rb +++ b/spec/lib/gitlab/o_auth/user_spec.rb @@ -724,6 +724,10 @@ describe Gitlab::OAuth::User do it "does not update the user location" do expect(gl_user.location).not_to eq(info_hash[:address][:country]) end + + it 'does not create associated user synced attributes metadata' do + expect(gl_user.user_synced_attributes_metadata).to be_nil + end end end diff --git a/spec/models/identity_spec.rb b/spec/models/identity_spec.rb index 7c66c98231b..a5ce245c21d 100644 --- a/spec/models/identity_spec.rb +++ b/spec/models/identity_spec.rb @@ -70,5 +70,38 @@ describe Identity do end end end + + context 'after_destroy' do + let!(:user) { create(:user) } + let(:ldap_identity) { create(:identity, provider: 'ldapmain', extern_uid: 'uid=john smith,ou=people,dc=example,dc=com', user: user) } + let(:ldap_user_synced_attributes) { { provider: 'ldapmain', name_synced: true, email_synced: true } } + let(:other_provider_user_synced_attributes) { { provider: 'other', name_synced: true, email_synced: true } } + + describe 'if user synced attributes metadada provider' do + context 'matches the identity provider ' do + it 'removes the user synced attributes' do + user.create_user_synced_attributes_metadata(ldap_user_synced_attributes) + + expect(user.user_synced_attributes_metadata.provider).to eq 'ldapmain' + + ldap_identity.destroy + + expect(user.reload.user_synced_attributes_metadata).to be_nil + end + end + + context 'does not matche the identity provider' do + it 'does not remove the user synced attributes' do + user.create_user_synced_attributes_metadata(other_provider_user_synced_attributes) + + expect(user.user_synced_attributes_metadata.provider).to eq 'other' + + ldap_identity.destroy + + expect(user.reload.user_synced_attributes_metadata.provider).to eq 'other' + end + end + end + end end end