diff --git a/app/controllers/projects/cycle_analytics/events_controller.rb b/app/controllers/projects/cycle_analytics/events_controller.rb index 8c2fb98a120c2f5ee1e77f2b2c332eb37f4307c8..d5e98228ddc91e948e831b7b1e96b6f5687b7455 100644 --- a/app/controllers/projects/cycle_analytics/events_controller.rb +++ b/app/controllers/projects/cycle_analytics/events_controller.rb @@ -5,7 +5,9 @@ module Projects before_action :authorize_read_cycle_analytics! before_action :authorize_builds!, only: [:test, :staging] - + before_action :authorize_read_issue!, only: [:issue, :production] + before_action :authorize_read_merge_request!, only: [:code, :review] + def issue render_events(events.issue_events) end @@ -60,7 +62,11 @@ module Projects end def authorize_builds! - return access_denied! unless current_user.can?(:read_build, project) + return access_denied! unless can?(current_user, :read_build, project) + end + + def authorize_read_issue! + return access_denied! unless can?(current_user, :read_issue, project) end end end diff --git a/lib/gitlab/cycle_analytics/author_updater.rb b/lib/gitlab/cycle_analytics/author_updater.rb index ab18f292bc3ced7f00afd2138af53f9545b5ecb7..87d26701d3a5e7bf0b82fb7fd4b36b3fe0511b82 100644 --- a/lib/gitlab/cycle_analytics/author_updater.rb +++ b/lib/gitlab/cycle_analytics/author_updater.rb @@ -1,26 +1,8 @@ module Gitlab module CycleAnalytics - class AuthorUpdater - def self.update!(*args) - new(*args).update! - end - - def initialize(event_result) - @event_result = event_result - end - - def update! - @event_result.each do |event| - event['author'] = users[event.delete('author_id').to_i].first - end - end - - def user_ids - @event_result.map { |event| event['author_id'] } - end - - def users - @users ||= User.find(user_ids).group_by { |user| user['id'] } + class AuthorUpdater < Updater + def self.update!(event_result) + new(event_result, User, :author).update! end end end diff --git a/lib/gitlab/cycle_analytics/build_updater.rb b/lib/gitlab/cycle_analytics/build_updater.rb new file mode 100644 index 0000000000000000000000000000000000000000..c1190d9e7a97a13f60ea2c98cc98c9f4b13011c0 --- /dev/null +++ b/lib/gitlab/cycle_analytics/build_updater.rb @@ -0,0 +1,9 @@ +module Gitlab + module CycleAnalytics + class BuildUpdater < Updater + def self.update!(event_result) + new(event_result, ::Ci::Build, :build, 'id').update! + end + end + end +end diff --git a/lib/gitlab/cycle_analytics/code_event.rb b/lib/gitlab/cycle_analytics/code_event.rb index 02a3a44d544d15b9f965f93cc21b2b86058ce9bd..2afdf0b8518b487d643c77fb77694373db601953 100644 --- a/lib/gitlab/cycle_analytics/code_event.rb +++ b/lib/gitlab/cycle_analytics/code_event.rb @@ -1,6 +1,8 @@ module Gitlab module CycleAnalytics class CodeEvent < BaseEvent + include MergeRequestAllowed + def initialize(*args) @stage = :code @start_time_attrs = issue_metrics_table[:first_mentioned_in_commit_at] @@ -21,10 +23,6 @@ module Gitlab def serialize(event) AnalyticsMergeRequestSerializer.new(project: @project).represent(event).as_json end - - def allowed_ids - @allowed_ids ||= MergeRequestsFinder.new(@options[:current_user], project_id: @project.id).execute.where(id: event_result_ids).pluck(:id) - end end end end diff --git a/lib/gitlab/cycle_analytics/issue_allowed.rb b/lib/gitlab/cycle_analytics/issue_allowed.rb new file mode 100644 index 0000000000000000000000000000000000000000..a7652a7064193adcd78e9c0be82ca5861fdeaa3c --- /dev/null +++ b/lib/gitlab/cycle_analytics/issue_allowed.rb @@ -0,0 +1,9 @@ +module Gitlab + module CycleAnalytics + module IssueAllowed + def allowed_ids + @allowed_ids ||= IssuesFinder.new(@options[:current_user], project_id: @project.id).execute.where(id: event_result_ids).pluck(:id) + end + end + end +end diff --git a/lib/gitlab/cycle_analytics/issue_event.rb b/lib/gitlab/cycle_analytics/issue_event.rb index 36a990d62225877267cadd0a9db35b4033302abd..705b7e5ce24871addc58d903a45f25b52b878a4f 100644 --- a/lib/gitlab/cycle_analytics/issue_event.rb +++ b/lib/gitlab/cycle_analytics/issue_event.rb @@ -1,6 +1,8 @@ module Gitlab module CycleAnalytics class IssueEvent < BaseEvent + include IssueAllowed + def initialize(*args) @stage = :issue @start_time_attrs = issue_table[:created_at] @@ -20,10 +22,6 @@ module Gitlab def serialize(event) AnalyticsIssueSerializer.new(project: @project).represent(event).as_json end - - def allowed_ids - @allowed_ids ||= IssuesFinder.new(@options[:current_user], project_id: @project.id).execute.where(id: event_result_ids).pluck(:id) - end end end end diff --git a/lib/gitlab/cycle_analytics/merge_request_allowed.rb b/lib/gitlab/cycle_analytics/merge_request_allowed.rb new file mode 100644 index 0000000000000000000000000000000000000000..28f6db447594864e0f0b667b6e4ff67b58b75896 --- /dev/null +++ b/lib/gitlab/cycle_analytics/merge_request_allowed.rb @@ -0,0 +1,9 @@ +module Gitlab + module CycleAnalytics + module MergeRequestAllowed + def allowed_ids + @allowed_ids ||= MergeRequestsFinder.new(@options[:current_user], project_id: @project.id).execute.where(id: event_result_ids).pluck(:id) + end + end + end +end diff --git a/lib/gitlab/cycle_analytics/production_event.rb b/lib/gitlab/cycle_analytics/production_event.rb index fcf2dbe349045b8fcbb769bf93edbdddb7aedca6..4868c3c62373d942bea2d10bade2160cfbf1969e 100644 --- a/lib/gitlab/cycle_analytics/production_event.rb +++ b/lib/gitlab/cycle_analytics/production_event.rb @@ -1,6 +1,8 @@ module Gitlab module CycleAnalytics class ProductionEvent < BaseEvent + include IssueAllowed + def initialize(*args) @stage = :production @start_time_attrs = issue_table[:created_at] @@ -19,10 +21,6 @@ module Gitlab def serialize(event) AnalyticsIssueSerializer.new(project: @project).represent(event).as_json end - - def allowed_ids - @allowed_ids ||= IssuesFinder.new(@options[:current_user], project_id: @project.id).execute.where(id: event_result_ids).pluck(:id) - end end end end diff --git a/lib/gitlab/cycle_analytics/review_event.rb b/lib/gitlab/cycle_analytics/review_event.rb index 30650537afe8716c007eba21a07971918f9f38ad..b394a02cc529f173f578e2d66490b91f649b6c0e 100644 --- a/lib/gitlab/cycle_analytics/review_event.rb +++ b/lib/gitlab/cycle_analytics/review_event.rb @@ -1,6 +1,8 @@ module Gitlab module CycleAnalytics class ReviewEvent < BaseEvent + include MergeRequestAllowed + def initialize(*args) @stage = :review @start_time_attrs = mr_table[:created_at] @@ -18,10 +20,6 @@ module Gitlab def serialize(event) AnalyticsMergeRequestSerializer.new(project: @project).represent(event).as_json end - - def allowed_ids - @allowed_ids ||= MergeRequestsFinder.new(@options[:current_user], project_id: @project.id).execute.where(id: event_result_ids).pluck(:id) - end end end end diff --git a/lib/gitlab/cycle_analytics/staging_event.rb b/lib/gitlab/cycle_analytics/staging_event.rb index 800b2b786dddc763eb509143a83cc37abd30c632..6c42b1a3a603b661ff30c80816171515744952c6 100644 --- a/lib/gitlab/cycle_analytics/staging_event.rb +++ b/lib/gitlab/cycle_analytics/staging_event.rb @@ -11,6 +11,12 @@ module Gitlab super(*args) end + def fetch + BuildUpdater.update!(event_result) + + super + end + def custom_query(base_query) base_query.join(build_table).on(mr_metrics_table[:pipeline_id].eq(build_table[:commit_id])) end @@ -18,9 +24,7 @@ module Gitlab private def serialize(event) - build = ::Ci::Build.find(event['id']) - - AnalyticsBuildSerializer.new.represent(build).as_json + AnalyticsBuildSerializer.new.represent(event['build']).as_json end end end diff --git a/lib/gitlab/cycle_analytics/updater.rb b/lib/gitlab/cycle_analytics/updater.rb new file mode 100644 index 0000000000000000000000000000000000000000..38cbfa030302b17e29f1c88e0c210cbde5323763 --- /dev/null +++ b/lib/gitlab/cycle_analytics/updater.rb @@ -0,0 +1,30 @@ +module Gitlab + module CycleAnalytics + class Updater + def self.update!(*args) + new(*args).update! + end + + def initialize(event_result, update_klass, update_key, column = nil) + @event_result = event_result + @update_klass = update_klass + @update_key = update_key.to_s + @column = column || "#{@update_key}_id" + end + + def update! + @event_result.each do |event| + event[@update_key] = items[event.delete(@column).to_i].first + end + end + + def result_ids + @event_result.map { |event| event[@column] } + end + + def items + @items ||= @update_klass.find(result_ids).group_by { |item| item['id'] } + end + end + end +end diff --git a/spec/lib/gitlab/cycle_analytics/author_updater_spec.rb b/spec/lib/gitlab/cycle_analytics/author_updater_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..f9e4d1714e62540ac553f25791736ad224b93702 --- /dev/null +++ b/spec/lib/gitlab/cycle_analytics/author_updater_spec.rb @@ -0,0 +1,12 @@ +require 'spec_helper' + +describe Gitlab::CycleAnalytics::AuthorUpdater do + let(:user) { create(:user) } + let(:events) { [{ 'author_id' => user.id }] } + + it 'maps the correct user' do + described_class.update!(events) + + expect(events.first['author']).to eq(user) + end +end diff --git a/spec/lib/gitlab/cycle_analytics/build_updater_spec.rb b/spec/lib/gitlab/cycle_analytics/build_updater_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..8e461f6c6ea1250cdbf4496ec6e63771b46b8717 --- /dev/null +++ b/spec/lib/gitlab/cycle_analytics/build_updater_spec.rb @@ -0,0 +1,12 @@ +require 'spec_helper' + +describe Gitlab::CycleAnalytics::BuildUpdater do + let(:build) { create(:ci_build) } + let(:events) { [{ 'id' => build.id }] } + + it 'maps the correct user' do + described_class.update!(events) + + expect(events.first['build']).to eq(build) + end +end