summaryrefslogtreecommitdiff
path: root/app/models/application_record.rb
diff options
context:
space:
mode:
authorGitLab Release Tools Bot <robert+release-tools@gitlab.com>2019-04-25 10:39:09 +0000
committerGitLab Release Tools Bot <robert+release-tools@gitlab.com>2019-04-25 10:39:09 +0000
commitfee6e478d6ffa548d9c39e2aafb452507a41124b (patch)
tree5bd919eab4d793e26297ecd46c768b82f38ed777 /app/models/application_record.rb
parent4282e390ea105c99fdba714a9c0976de2dbbe810 (diff)
parent208338fde6750ad327fb8ab57877869435520436 (diff)
downloadgitlab-ce-fee6e478d6ffa548d9c39e2aafb452507a41124b.tar.gz
Merge branch 'security-approval-race-condition' into 'master'
Add ApplicationRecord#safe_ensure_unique method See merge request gitlab/gitlabhq!3054
Diffstat (limited to 'app/models/application_record.rb')
-rw-r--r--app/models/application_record.rb17
1 files changed, 14 insertions, 3 deletions
diff --git a/app/models/application_record.rb b/app/models/application_record.rb
index 9d71f250466..d1d01368972 100644
--- a/app/models/application_record.rb
+++ b/app/models/application_record.rb
@@ -17,6 +17,19 @@ class ApplicationRecord < ActiveRecord::Base
where(nil).pluck(self.primary_key)
end
+ def self.safe_ensure_unique(retries: 0)
+ transaction(requires_new: true) do
+ yield
+ end
+ rescue ActiveRecord::RecordNotUnique
+ if retries > 0
+ retries -= 1
+ retry
+ end
+
+ false
+ end
+
def self.safe_find_or_create_by!(*args)
safe_find_or_create_by(*args).tap do |record|
record.validate! unless record.persisted?
@@ -24,10 +37,8 @@ class ApplicationRecord < ActiveRecord::Base
end
def self.safe_find_or_create_by(*args)
- transaction(requires_new: true) do
+ safe_ensure_unique(retries: 1) do
find_or_create_by(*args)
end
- rescue ActiveRecord::RecordNotUnique
- retry
end
end