summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean McGivern <sean@mcgivern.me.uk>2016-11-21 16:07:27 +0000
committerSean McGivern <sean@mcgivern.me.uk>2016-11-21 16:07:27 +0000
commit80eaed1651e6a278af87e015f6b414d4f943a352 (patch)
tree1875bd34606e7d636b9f75afe741ff57bb04bf05
parenta207c3d12f75644d72c7ea720949b8c58c89faa9 (diff)
parent9b691688583ad46d5608320ec64873dd2eb9a647 (diff)
downloadgitlab-ce-80eaed1651e6a278af87e015f6b414d4f943a352.tar.gz
Merge branch 'fix/cycle-analytics-permissions' into 'master'
Added permissions per stage to cycle analytics endpoint See merge request !7613
-rw-r--r--app/controllers/projects/cycle_analytics_controller.rb3
-rw-r--r--app/models/cycle_analytics.rb6
-rw-r--r--changelogs/unreleased/fix-cycle-analytics-permissions.yml4
-rw-r--r--lib/gitlab/cycle_analytics/permissions.rb44
-rw-r--r--spec/lib/gitlab/cycle_analytics/permissions_spec.rb127
5 files changed, 183 insertions, 1 deletions
diff --git a/app/controllers/projects/cycle_analytics_controller.rb b/app/controllers/projects/cycle_analytics_controller.rb
index 96eb75a0547..00ecdcbd1b9 100644
--- a/app/controllers/projects/cycle_analytics_controller.rb
+++ b/app/controllers/projects/cycle_analytics_controller.rb
@@ -54,7 +54,8 @@ class Projects::CycleAnalyticsController < Projects::ApplicationController
{
summary: summary,
- stats: stats
+ stats: stats,
+ permissions: @cycle_analytics.permissions(user: current_user)
}
end
end
diff --git a/app/models/cycle_analytics.rb b/app/models/cycle_analytics.rb
index 314a1ce9b63..cb8e088d21d 100644
--- a/app/models/cycle_analytics.rb
+++ b/app/models/cycle_analytics.rb
@@ -1,4 +1,6 @@
class CycleAnalytics
+ STAGES = %i[issue plan code test review staging production].freeze
+
def initialize(project, from:)
@project = project
@from = from
@@ -9,6 +11,10 @@ class CycleAnalytics
@summary ||= Summary.new(@project, from: @from)
end
+ def permissions(user:)
+ Gitlab::CycleAnalytics::Permissions.get(user: user, project: @project)
+ end
+
def issue
@fetcher.calculate_metric(:issue,
Issue.arel_table[:created_at],
diff --git a/changelogs/unreleased/fix-cycle-analytics-permissions.yml b/changelogs/unreleased/fix-cycle-analytics-permissions.yml
new file mode 100644
index 00000000000..ddcf78d705f
--- /dev/null
+++ b/changelogs/unreleased/fix-cycle-analytics-permissions.yml
@@ -0,0 +1,4 @@
+---
+title: Added permissions per stage to cycle analytics endpoint
+merge_request:
+author:
diff --git a/lib/gitlab/cycle_analytics/permissions.rb b/lib/gitlab/cycle_analytics/permissions.rb
new file mode 100644
index 00000000000..bef3b95ff1b
--- /dev/null
+++ b/lib/gitlab/cycle_analytics/permissions.rb
@@ -0,0 +1,44 @@
+module Gitlab
+ module CycleAnalytics
+ class Permissions
+ STAGE_PERMISSIONS = {
+ issue: :read_issue,
+ code: :read_merge_request,
+ test: :read_build,
+ review: :read_merge_request,
+ staging: :read_build,
+ production: :read_issue,
+ }.freeze
+
+ def self.get(*args)
+ new(*args).get
+ end
+
+ def initialize(user:, project:)
+ @user = user
+ @project = project
+ @stage_permission_hash = {}
+ end
+
+ def get
+ ::CycleAnalytics::STAGES.each do |stage|
+ @stage_permission_hash[stage] = authorized_stage?(stage)
+ end
+
+ @stage_permission_hash
+ end
+
+ private
+
+ def authorized_stage?(stage)
+ return false unless authorize_project(:read_cycle_analytics)
+
+ STAGE_PERMISSIONS[stage] ? authorize_project(STAGE_PERMISSIONS[stage]) : true
+ end
+
+ def authorize_project(permission)
+ Ability.allowed?(@user, permission, @project)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/cycle_analytics/permissions_spec.rb b/spec/lib/gitlab/cycle_analytics/permissions_spec.rb
new file mode 100644
index 00000000000..dc4f7dc69db
--- /dev/null
+++ b/spec/lib/gitlab/cycle_analytics/permissions_spec.rb
@@ -0,0 +1,127 @@
+require 'spec_helper'
+
+describe Gitlab::CycleAnalytics::Permissions do
+ let(:project) { create(:empty_project) }
+ let(:user) { create(:user) }
+
+ subject { described_class.get(user: user, project: project) }
+
+ context 'user with no relation to the project' do
+ it 'has no permissions to issue stage' do
+ expect(subject[:issue]).to eq(false)
+ end
+
+ it 'has no permissions to test stage' do
+ expect(subject[:test]).to eq(false)
+ end
+
+ it 'has no permissions to staging stage' do
+ expect(subject[:staging]).to eq(false)
+ end
+
+ it 'has no permissions to production stage' do
+ expect(subject[:production]).to eq(false)
+ end
+
+ it 'has no permissions to code stage' do
+ expect(subject[:code]).to eq(false)
+ end
+
+ it 'has no permissions to review stage' do
+ expect(subject[:review]).to eq(false)
+ end
+
+ it 'has no permissions to plan stage' do
+ expect(subject[:plan]).to eq(false)
+ end
+ end
+
+ context 'user is master' do
+ before do
+ project.team << [user, :master]
+ end
+
+ it 'has permissions to issue stage' do
+ expect(subject[:issue]).to eq(true)
+ end
+
+ it 'has permissions to test stage' do
+ expect(subject[:test]).to eq(true)
+ end
+
+ it 'has permissions to staging stage' do
+ expect(subject[:staging]).to eq(true)
+ end
+
+ it 'has permissions to production stage' do
+ expect(subject[:production]).to eq(true)
+ end
+
+ it 'has permissions to code stage' do
+ expect(subject[:code]).to eq(true)
+ end
+
+ it 'has permissions to review stage' do
+ expect(subject[:review]).to eq(true)
+ end
+
+ it 'has permissions to plan stage' do
+ expect(subject[:plan]).to eq(true)
+ end
+ end
+
+ context 'user has no build permissions' do
+ before do
+ project.team << [user, :guest]
+ end
+
+ it 'has permissions to issue stage' do
+ expect(subject[:issue]).to eq(true)
+ end
+
+ it 'has no permissions to test stage' do
+ expect(subject[:test]).to eq(false)
+ end
+
+ it 'has no permissions to staging stage' do
+ expect(subject[:staging]).to eq(false)
+ end
+ end
+
+ context 'user has no merge request permissions' do
+ before do
+ project.team << [user, :guest]
+ end
+
+ it 'has permissions to issue stage' do
+ expect(subject[:issue]).to eq(true)
+ end
+
+ it 'has no permissions to code stage' do
+ expect(subject[:code]).to eq(false)
+ end
+
+ it 'has no permissions to review stage' do
+ expect(subject[:review]).to eq(false)
+ end
+ end
+
+ context 'user has no issue permissions' do
+ before do
+ project.team << [user, :developer]
+ project.project_feature.update_attribute(:issues_access_level, ProjectFeature::DISABLED)
+ end
+
+ it 'has permissions to code stage' do
+ expect(subject[:code]).to eq(true)
+ end
+
+ it 'has no permissions to issue stage' do
+ expect(subject[:issue]).to eq(false)
+ end
+
+ it 'has no permissions to production stage' do
+ expect(subject[:production]).to eq(false)
+ end
+ end
+end