diff options
author | GitLab Release Tools Bot <robert+release-tools@gitlab.com> | 2019-09-26 16:52:54 +0300 |
---|---|---|
committer | GitLab Release Tools Bot <robert+release-tools@gitlab.com> | 2019-09-26 16:52:54 +0300 |
commit | bbab7b62706eeaad91e60643e673a31678887dbc (patch) | |
tree | ecb709229028878693304d9e2d3fae0079682b2a /app | |
parent | 4be19d5f71e5ab912b9c09a46f356c996e9e0b0b (diff) | |
parent | 2daab029885e01f0c79994f86b01c212e4f7ae88 (diff) |
Merge branch 'security-cross-reference-fix-ce-12-2' into '12-2-stable'
Filter not accessible label events
See merge request gitlab/gitlabhq!3441
Diffstat (limited to 'app')
-rw-r--r-- | app/finders/resource_label_event_finder.rb | 41 | ||||
-rw-r--r-- | app/models/resource_label_event.rb | 10 | ||||
-rw-r--r-- | app/policies/resource_label_event_policy.rb | 14 |
3 files changed, 65 insertions, 0 deletions
diff --git a/app/finders/resource_label_event_finder.rb b/app/finders/resource_label_event_finder.rb new file mode 100644 index 00000000000..9aafd6e91b9 --- /dev/null +++ b/app/finders/resource_label_event_finder.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +class ResourceLabelEventFinder + include FinderMethods + + MAX_PER_PAGE = 100 + + attr_reader :params, :current_user, :eventable + + def initialize(current_user, eventable, params = {}) + @current_user = current_user + @eventable = eventable + @params = params + end + + def execute + events = eventable.resource_label_events.inc_relations + events = events.page(page).per(per_page) + events = visible_to_user(events) + + Kaminari.paginate_array(events) + end + + private + + def visible_to_user(events) + ResourceLabelEvent.preload_label_subjects(events) + + events.select do |event| + Ability.allowed?(current_user, :read_label, event) + end + end + + def per_page + [params[:per_page], MAX_PER_PAGE].compact.min + end + + def page + params[:page] || 1 + end +end diff --git a/app/models/resource_label_event.rb b/app/models/resource_label_event.rb index ad08f4763ae..21a167e3888 100644 --- a/app/models/resource_label_event.rb +++ b/app/models/resource_label_event.rb @@ -15,6 +15,7 @@ class ResourceLabelEvent < ApplicationRecord belongs_to :label scope :created_after, ->(time) { where('created_at > ?', time) } + scope :inc_relations, -> { includes(:label, :user) } validates :user, presence: { unless: :importing? }, on: :create validates :label, presence: { unless: :importing? }, on: :create @@ -32,6 +33,15 @@ class ResourceLabelEvent < ApplicationRecord %i(issue merge_request).freeze end + def self.preload_label_subjects(events) + labels = events.map(&:label).compact + project_labels, group_labels = labels.partition { |label| label.is_a? ProjectLabel } + + preloader = ActiveRecord::Associations::Preloader.new + preloader.preload(project_labels, { project: :project_feature }) + preloader.preload(group_labels, :group) + end + def issuable issue || merge_request end diff --git a/app/policies/resource_label_event_policy.rb b/app/policies/resource_label_event_policy.rb new file mode 100644 index 00000000000..de4748d9890 --- /dev/null +++ b/app/policies/resource_label_event_policy.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +class ResourceLabelEventPolicy < BasePolicy + condition(:can_read_label) { @subject.label_id.nil? || can?(:read_label, @subject.label) } + condition(:can_read_issuable) { can?(:"read_#{@subject.issuable.to_ability_name}", @subject.issuable) } + + rule { can_read_label }.policy do + enable :read_label + end + + rule { can_read_label & can_read_issuable }.policy do + enable :read_resource_label_event + end +end |