summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/controllers/concerns/authenticates_with_two_factor.rb6
-rw-r--r--app/models/application_setting.rb18
-rw-r--r--changelogs/unreleased/cat-time-precision-2fa-ldap.yml5
-rw-r--r--changelogs/unreleased/sh-fix-backup-restore-race.yml5
-rw-r--r--spec/lib/gitlab/current_settings_spec.rb10
-rw-r--r--spec/models/application_setting_spec.rb10
-rwxr-xr-x[-rw-r--r--]vendor/gitignore/C++.gitignore0
-rwxr-xr-x[-rw-r--r--]vendor/gitignore/Java.gitignore0
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