Added permissions per stage to cycle analytics endpoint
This commit is contained in:
parent
9aded5c8d4
commit
0fd397bba1
|
@ -6,7 +6,7 @@ class Projects::CycleAnalyticsController < Projects::ApplicationController
|
||||||
before_action :authorize_read_cycle_analytics!
|
before_action :authorize_read_cycle_analytics!
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@cycle_analytics = ::CycleAnalytics.new(@project, from: start_date(cycle_analytics_params))
|
@cycle_analytics = ::CycleAnalytics.new(@project, from: start_date(cycle_analytics_params), user: current_user)
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html
|
format.html
|
||||||
|
@ -54,7 +54,8 @@ class Projects::CycleAnalyticsController < Projects::ApplicationController
|
||||||
|
|
||||||
{
|
{
|
||||||
summary: summary,
|
summary: summary,
|
||||||
stats: stats
|
stats: stats,
|
||||||
|
permissions: @cycle_analytics.permissions
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
class CycleAnalytics
|
class CycleAnalytics
|
||||||
def initialize(project, from:)
|
STAGES = %i[issue plan code test review staging production].freeze
|
||||||
|
|
||||||
|
def initialize(project, from:, user:)
|
||||||
@project = project
|
@project = project
|
||||||
@from = from
|
@from = from
|
||||||
|
@user = user
|
||||||
@fetcher = Gitlab::CycleAnalytics::MetricsFetcher.new(project: project, from: from, branch: nil)
|
@fetcher = Gitlab::CycleAnalytics::MetricsFetcher.new(project: project, from: from, branch: nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -9,6 +12,10 @@ class CycleAnalytics
|
||||||
@summary ||= Summary.new(@project, from: @from)
|
@summary ||= Summary.new(@project, from: @from)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def permissions
|
||||||
|
Gitlab::CycleAnalytics::Permissions.get(user: @user, project: @project)
|
||||||
|
end
|
||||||
|
|
||||||
def issue
|
def issue
|
||||||
@fetcher.calculate_metric(:issue,
|
@fetcher.calculate_metric(:issue,
|
||||||
Issue.arel_table[:created_at],
|
Issue.arel_table[:created_at],
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
title: Added permissions per stage to cycle analytics endpoint
|
||||||
|
merge_request:
|
||||||
|
author:
|
|
@ -0,0 +1,49 @@
|
||||||
|
module Gitlab
|
||||||
|
module CycleAnalytics
|
||||||
|
class Permissions
|
||||||
|
STAGE_PERMISSIONS = {
|
||||||
|
read_build: [:test, :staging],
|
||||||
|
read_issue: [:issue, :production],
|
||||||
|
read_merge_request: [:code, :review]
|
||||||
|
}.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)
|
||||||
|
|
||||||
|
permissions_for_stage(stage).keys.each do |permission|
|
||||||
|
return false unless authorize_project(permission)
|
||||||
|
end
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def permissions_for_stage(stage)
|
||||||
|
STAGE_PERMISSIONS.select { |_permission, stages| stages.include?(stage) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def authorize_project(permission)
|
||||||
|
Ability.allowed?(@user, permission, @project)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -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
|
|
@ -6,7 +6,7 @@ describe 'CycleAnalytics#code', feature: true do
|
||||||
let(:project) { create(:project) }
|
let(:project) { create(:project) }
|
||||||
let(:from_date) { 10.days.ago }
|
let(:from_date) { 10.days.ago }
|
||||||
let(:user) { create(:user, :admin) }
|
let(:user) { create(:user, :admin) }
|
||||||
subject { CycleAnalytics.new(project, from: from_date) }
|
subject { CycleAnalytics.new(project, from: from_date, user: user) }
|
||||||
|
|
||||||
context 'with deployment' do
|
context 'with deployment' do
|
||||||
generate_cycle_analytics_spec(
|
generate_cycle_analytics_spec(
|
||||||
|
|
|
@ -6,7 +6,7 @@ describe 'CycleAnalytics#issue', models: true do
|
||||||
let(:project) { create(:project) }
|
let(:project) { create(:project) }
|
||||||
let(:from_date) { 10.days.ago }
|
let(:from_date) { 10.days.ago }
|
||||||
let(:user) { create(:user, :admin) }
|
let(:user) { create(:user, :admin) }
|
||||||
subject { CycleAnalytics.new(project, from: from_date) }
|
subject { CycleAnalytics.new(project, from: from_date, user: user) }
|
||||||
|
|
||||||
generate_cycle_analytics_spec(
|
generate_cycle_analytics_spec(
|
||||||
phase: :issue,
|
phase: :issue,
|
||||||
|
|
|
@ -6,7 +6,7 @@ describe 'CycleAnalytics#plan', feature: true do
|
||||||
let(:project) { create(:project) }
|
let(:project) { create(:project) }
|
||||||
let(:from_date) { 10.days.ago }
|
let(:from_date) { 10.days.ago }
|
||||||
let(:user) { create(:user, :admin) }
|
let(:user) { create(:user, :admin) }
|
||||||
subject { CycleAnalytics.new(project, from: from_date) }
|
subject { CycleAnalytics.new(project, from: from_date, user: user) }
|
||||||
|
|
||||||
generate_cycle_analytics_spec(
|
generate_cycle_analytics_spec(
|
||||||
phase: :plan,
|
phase: :plan,
|
||||||
|
|
|
@ -6,7 +6,7 @@ describe 'CycleAnalytics#production', feature: true do
|
||||||
let(:project) { create(:project) }
|
let(:project) { create(:project) }
|
||||||
let(:from_date) { 10.days.ago }
|
let(:from_date) { 10.days.ago }
|
||||||
let(:user) { create(:user, :admin) }
|
let(:user) { create(:user, :admin) }
|
||||||
subject { CycleAnalytics.new(project, from: from_date) }
|
subject { CycleAnalytics.new(project, from: from_date, user: user) }
|
||||||
|
|
||||||
generate_cycle_analytics_spec(
|
generate_cycle_analytics_spec(
|
||||||
phase: :production,
|
phase: :production,
|
||||||
|
|
|
@ -6,7 +6,7 @@ describe 'CycleAnalytics#review', feature: true do
|
||||||
let(:project) { create(:project) }
|
let(:project) { create(:project) }
|
||||||
let(:from_date) { 10.days.ago }
|
let(:from_date) { 10.days.ago }
|
||||||
let(:user) { create(:user, :admin) }
|
let(:user) { create(:user, :admin) }
|
||||||
subject { CycleAnalytics.new(project, from: from_date) }
|
subject { CycleAnalytics.new(project, from: from_date, user: user) }
|
||||||
|
|
||||||
generate_cycle_analytics_spec(
|
generate_cycle_analytics_spec(
|
||||||
phase: :review,
|
phase: :review,
|
||||||
|
|
|
@ -6,7 +6,7 @@ describe 'CycleAnalytics#staging', feature: true do
|
||||||
let(:project) { create(:project) }
|
let(:project) { create(:project) }
|
||||||
let(:from_date) { 10.days.ago }
|
let(:from_date) { 10.days.ago }
|
||||||
let(:user) { create(:user, :admin) }
|
let(:user) { create(:user, :admin) }
|
||||||
subject { CycleAnalytics.new(project, from: from_date) }
|
subject { CycleAnalytics.new(project, from: from_date, user: user) }
|
||||||
|
|
||||||
generate_cycle_analytics_spec(
|
generate_cycle_analytics_spec(
|
||||||
phase: :staging,
|
phase: :staging,
|
||||||
|
|
|
@ -4,7 +4,7 @@ describe CycleAnalytics::Summary, models: true do
|
||||||
let(:project) { create(:project) }
|
let(:project) { create(:project) }
|
||||||
let(:from) { Time.now }
|
let(:from) { Time.now }
|
||||||
let(:user) { create(:user, :admin) }
|
let(:user) { create(:user, :admin) }
|
||||||
subject { described_class.new(project, from: from) }
|
subject { described_class.new(project, from: from, user: user) }
|
||||||
|
|
||||||
describe "#new_issues" do
|
describe "#new_issues" do
|
||||||
it "finds the number of issues created after the 'from date'" do
|
it "finds the number of issues created after the 'from date'" do
|
||||||
|
|
|
@ -6,7 +6,7 @@ describe 'CycleAnalytics#test', feature: true do
|
||||||
let(:project) { create(:project) }
|
let(:project) { create(:project) }
|
||||||
let(:from_date) { 10.days.ago }
|
let(:from_date) { 10.days.ago }
|
||||||
let(:user) { create(:user, :admin) }
|
let(:user) { create(:user, :admin) }
|
||||||
subject { CycleAnalytics.new(project, from: from_date) }
|
subject { CycleAnalytics.new(project, from: from_date, user: user) }
|
||||||
|
|
||||||
generate_cycle_analytics_spec(
|
generate_cycle_analytics_spec(
|
||||||
phase: :test,
|
phase: :test,
|
||||||
|
|
Loading…
Reference in New Issue