diff options
-rw-r--r-- | app/controllers/concerns/authenticates_with_two_factor.rb | 6 | ||||
-rw-r--r-- | app/models/application_setting.rb | 18 | ||||
-rw-r--r-- | changelogs/unreleased/cat-time-precision-2fa-ldap.yml | 5 | ||||
-rw-r--r-- | changelogs/unreleased/sh-fix-backup-restore-race.yml | 5 | ||||
-rw-r--r-- | spec/lib/gitlab/current_settings_spec.rb | 10 | ||||
-rw-r--r-- | spec/models/application_setting_spec.rb | 10 | ||||
-rwxr-xr-x[-rw-r--r--] | vendor/gitignore/C++.gitignore | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | vendor/gitignore/Java.gitignore | 0 |
8 files changed, 53 insertions, 1 deletions
diff --git a/app/controllers/concerns/authenticates_with_two_factor.rb b/app/controllers/concerns/authenticates_with_two_factor.rb index d9e4a3a3aea..d61546fd5d7 100644 --- a/app/controllers/concerns/authenticates_with_two_factor.rb +++ b/app/controllers/concerns/authenticates_with_two_factor.rb @@ -125,6 +125,10 @@ module AuthenticatesWithTwoFactor def user_changed?(user) return false unless session[:user_updated_at] - user.updated_at != session[:user_updated_at] + # See: https://gitlab.com/gitlab-org/gitlab/-/issues/244638 + # Rounding errors happen when the user is updated, as the Rails ActiveRecord + # object has higher precision than what is stored in the database, therefore + # using .to_i to force truncation to the timestamp + user.updated_at.to_i != session[:user_updated_at].to_i end end diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index 425a0e05c7d..fdd27607bbf 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -430,6 +430,8 @@ class ApplicationSetting < ApplicationRecord end def self.create_from_defaults + check_schema! + transaction(requires_new: true) do super end @@ -438,6 +440,22 @@ class ApplicationSetting < ApplicationRecord current_without_cache end + # Due to the frequency with which settings are accessed, it is + # likely that during a backup restore a running GitLab process + # will insert a new `application_settings` row before the + # constraints have been added to the table. This would add an + # extra row with ID 1 and prevent the primary key constraint from + # being added, which made ActiveRecord throw a + # IrreversibleOrderError anytime the settings were accessed + # (https://gitlab.com/gitlab-org/gitlab/-/issues/36405). To + # prevent this from happening, we do a sanity check that the + # primary key constraint is present before inserting a new entry. + def self.check_schema! + return if ActiveRecord::Base.connection.primary_key(self.table_name).present? + + raise "The `#{self.table_name}` table is missing a primary key constraint in the database schema" + end + # By default, the backend is Rails.cache, which uses # ActiveSupport::Cache::RedisStore. Since loading ApplicationSetting # can cause a significant amount of load on Redis, let's cache it in diff --git a/changelogs/unreleased/cat-time-precision-2fa-ldap.yml b/changelogs/unreleased/cat-time-precision-2fa-ldap.yml new file mode 100644 index 00000000000..dc2cdaa8632 --- /dev/null +++ b/changelogs/unreleased/cat-time-precision-2fa-ldap.yml @@ -0,0 +1,5 @@ +--- +title: Update the 2FA user update check to account for rounding errors +merge_request: 41327 +author: +type: fixed diff --git a/changelogs/unreleased/sh-fix-backup-restore-race.yml b/changelogs/unreleased/sh-fix-backup-restore-race.yml new file mode 100644 index 00000000000..ab5d4d8fcb0 --- /dev/null +++ b/changelogs/unreleased/sh-fix-backup-restore-race.yml @@ -0,0 +1,5 @@ +--- +title: Fix ActiveRecord::IrreversibleOrderError during restore from backup +merge_request: 40789 +author: +type: fixed diff --git a/spec/lib/gitlab/current_settings_spec.rb b/spec/lib/gitlab/current_settings_spec.rb index bfd9980ee9c..fd772d39330 100644 --- a/spec/lib/gitlab/current_settings_spec.rb +++ b/spec/lib/gitlab/current_settings_spec.rb @@ -115,6 +115,16 @@ describe Gitlab::CurrentSettings do expect(settings).to have_attributes(settings_from_defaults) end + context 'when ApplicationSettings does not have a primary key' do + before do + allow(ActiveRecord::Base.connection).to receive(:primary_key).with('application_settings').and_return(nil) + end + + it 'raises an exception if ApplicationSettings does not have a primary key' do + expect { described_class.current_application_settings }.to raise_error(/table is missing a primary key constraint/) + end + end + context 'with pending migrations' do let(:current_settings) { described_class.current_application_settings } diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb index 96bf19439a1..0afcf42f056 100644 --- a/spec/models/application_setting_spec.rb +++ b/spec/models/application_setting_spec.rb @@ -653,6 +653,16 @@ describe ApplicationSetting do end end + context 'when ApplicationSettings does not have a primary key' do + before do + allow(ActiveRecord::Base.connection).to receive(:primary_key).with(described_class.table_name).and_return(nil) + end + + it 'raises an exception' do + expect { described_class.create_from_defaults }.to raise_error(/table is missing a primary key constraint/) + end + end + describe '#disabled_oauth_sign_in_sources=' do before do allow(Devise).to receive(:omniauth_providers).and_return([:github]) diff --git a/vendor/gitignore/C++.gitignore b/vendor/gitignore/C++.gitignore index 259148fa18f..259148fa18f 100644..100755 --- a/vendor/gitignore/C++.gitignore +++ b/vendor/gitignore/C++.gitignore diff --git a/vendor/gitignore/Java.gitignore b/vendor/gitignore/Java.gitignore index a1c2a238a96..a1c2a238a96 100644..100755 --- a/vendor/gitignore/Java.gitignore +++ b/vendor/gitignore/Java.gitignore |