diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-03 01:07:33 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-03 01:07:33 +0300 |
commit | 0eb0daa071d5caa34385aba190ba5aece09b1527 (patch) | |
tree | 3e8c447803f0f6456e9ce17956c3727005475fea /app/models/concerns/exportable.rb | |
parent | f91c598db1bfae546441b87715180b9925a85264 (diff) |
Add latest changes from gitlab-org/security/gitlab@15-11-stable-ee
Diffstat (limited to 'app/models/concerns/exportable.rb')
-rw-r--r-- | app/models/concerns/exportable.rb | 69 |
1 files changed, 54 insertions, 15 deletions
diff --git a/app/models/concerns/exportable.rb b/app/models/concerns/exportable.rb index 066a44912be..c305d272a14 100644 --- a/app/models/concerns/exportable.rb +++ b/app/models/concerns/exportable.rb @@ -3,19 +3,6 @@ module Exportable extend ActiveSupport::Concern - def readable_records(association, current_user: nil) - association_records = try(association) - return unless association_records.present? - - if has_many_association?(association) - DeclarativePolicy.user_scope do - association_records.select { |record| readable_record?(record, current_user) } - end - else - readable_record?(association_records, current_user) ? association_records : nil - end - end - def exportable_association?(association, current_user: nil) return false unless respond_to?(association) return true if has_many_association?(association) @@ -30,8 +17,17 @@ module Exportable exportable_restricted_associations & keys end - def has_many_association?(association_name) - self.class.reflect_on_association(association_name)&.macro == :has_many + def to_authorized_json(keys_to_authorize, current_user, options) + modified_options = filtered_associations_opts(options, keys_to_authorize) + record_hash = as_json(modified_options).with_indifferent_access + + keys_to_authorize.each do |key| + next unless record_hash.key?(key) + + record_hash[key] = authorized_association_records(key, current_user, options) + end + + record_hash.to_json end private @@ -47,4 +43,47 @@ module Exportable record.readable_by?(user) end end + + def has_many_association?(association_name) + self.class.reflect_on_association(association_name)&.macro == :has_many + end + + def readable_records(association, current_user: nil) + association_records = try(association) + return unless association_records.present? + + if has_many_association?(association) + DeclarativePolicy.user_scope do + association_records.select { |record| readable_record?(record, current_user) } + end + else + readable_record?(association_records, current_user) ? association_records : nil + end + end + + def authorized_association_records(key, current_user, options) + records = readable_records(key, current_user: current_user) + empty_assoc = has_many_association?(key) ? [] : nil + return empty_assoc unless records.present? + + assoc_opts = association_options(key, options)&.dig(key) + records.as_json(assoc_opts) + end + + def filtered_associations_opts(options, associations) + options_copy = options.deep_dup + + associations.each do |key| + assoc_opts = association_options(key, options_copy) + next unless assoc_opts + + assoc_opts[key] = { only: [:id] } + end + + options_copy + end + + def association_options(key, options) + options[:include].find { |assoc| assoc.key?(key) } + end end |