diff options
author | GitLab Release Tools Bot <robert+release-tools@gitlab.com> | 2019-04-25 10:39:09 +0000 |
---|---|---|
committer | GitLab Release Tools Bot <robert+release-tools@gitlab.com> | 2019-04-25 10:39:09 +0000 |
commit | fee6e478d6ffa548d9c39e2aafb452507a41124b (patch) | |
tree | 5bd919eab4d793e26297ecd46c768b82f38ed777 /app | |
parent | 4282e390ea105c99fdba714a9c0976de2dbbe810 (diff) | |
parent | 208338fde6750ad327fb8ab57877869435520436 (diff) | |
download | gitlab-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')
-rw-r--r-- | app/models/application_record.rb | 17 |
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 |