Commit 186048a4 authored by Rémy Coutable's avatar Rémy Coutable

Allow to enable the performance bar per user or Flipper group

A `performance_team` Flipper group has been created. By default this
group is nil but this can be customized in `gitlab.yml` via the
performance_bar.allowed_group setting.
Signed-off-by: default avatarRémy Coutable <remy@rymai.me>
parent afd5c34d
......@@ -9,7 +9,7 @@ class ApplicationController < ActionController::Base
include SentryHelper
include WorkhorseHelper
include EnforcesTwoFactorAuthentication
include Peek::Rblineprof::CustomControllerHelpers
include WithPerformanceBar
before_action :authenticate_user_from_private_token!
before_action :authenticate_user_from_rss_token!
......@@ -68,21 +68,6 @@ class ApplicationController < ActionController::Base
end
end
def peek_enabled?
return false unless Gitlab::PerformanceBar.enabled?
return false unless current_user
if RequestStore.active?
if RequestStore.store.key?(:peek_enabled)
RequestStore.store[:peek_enabled]
else
RequestStore.store[:peek_enabled] = cookies[:perf_bar_enabled].present?
end
else
cookies[:perf_bar_enabled].present?
end
end
protected
# This filter handles both private tokens and personal access tokens
......
module WithPerformanceBar
extend ActiveSupport::Concern
included do
include Peek::Rblineprof::CustomControllerHelpers
end
def peek_enabled?
return false unless Gitlab::PerformanceBar.enabled?(current_user)
if RequestStore.active?
RequestStore.fetch(:peek_enabled) { cookies[:perf_bar_enabled].present? }
else
cookies[:perf_bar_enabled].present?
end
end
end
......@@ -459,6 +459,11 @@ production: &base
# is the normal way to deploy Gitaly.
token:
# Performance bar settings
performance_bar:
# This setting controls what group can see the performance bar.
# allowed_group: performance-group
#
# 4. Advanced settings
# ==========================
......
......@@ -485,6 +485,12 @@ Settings.rack_attack.git_basic_auth['bantime'] ||= 1.hour
Settings['gitaly'] ||= Settingslogic.new({})
Settings.gitaly['enabled'] = true if Settings.gitaly['enabled'].nil?
#
# Performance bar
#
Settings['performance_bar'] ||= Settingslogic.new({})
Settings.performance_bar['allowed_group'] = 'gitlab-org' if Settings.performance_bar['allowed_group'].nil?
#
# Webpack settings
#
......
......@@ -54,7 +54,15 @@ class Feature
adapter = Flipper::Adapters::ActiveRecord.new(
feature_class: FlipperFeature, gate_class: FlipperGate)
Flipper.new(adapter)
Flipper.new(adapter).tap do
register_feature_groups
end
end
end
def register_feature_groups
Flipper.register(:performance_team) do |actor|
Gitlab::PerformanceBar.allowed_actor?(actor)
end
end
end
......
module Gitlab
module PerformanceBar
def self.enabled?
Feature.enabled?('gitlab_performance_bar')
def self.enabled?(current_user = nil)
Feature.enabled?(:gitlab_performance_bar, current_user)
end
def self.allowed_actor?(actor)
group = allowed_group
return false unless actor&.is_a?(User) && group
GroupMembersFinder.new(group)
.execute
.where(user_id: actor.id)
.any?
end
def self.allowed_group
return nil unless Gitlab.config.performance_bar.allowed_group
Group.by_path(Gitlab.config.performance_bar.allowed_group)
end
end
end
require 'spec_helper'
describe Gitlab::PerformanceBar do
describe '.enabled?' do
it 'returns false when given user is nil' do
expect(described_class.enabled?(nil)).to be_falsy
end
it 'returns false when feature is disabled' do
user = double('user')
expect(Feature).to receive(:enabled?)
.with(:gitlab_performance_bar, user).and_return(false)
expect(described_class.enabled?(user)).to be_falsy
end
it 'returns true when feature is enabled' do
user = double('user')
expect(Feature).to receive(:enabled?)
.with(:gitlab_performance_bar, user).and_return(true)
expect(described_class.enabled?(user)).to be_truthy
end
end
describe '.allowed_actor?' do
it 'returns false when given actor is not a User' do
actor = double
expect(described_class.allowed_actor?(actor)).to be_falsy
end
context 'when given actor is a User' do
let(:actor) { create(:user) }
before do
stub_performance_bar_setting(allowed_group: 'my-group')
end
context 'when allowed group does not exist' do
it 'returns false' do
expect(described_class.allowed_actor?(actor)).to be_falsy
end
end
context 'when allowed group exists' do
let!(:my_group) { create(:group, path: 'my-group') }
context 'when user is not a member of the allowed group' do
it 'returns false' do
expect(described_class.allowed_actor?(actor)).to be_falsy
end
end
context 'when user is a member of the allowed group' do
before do
my_group.add_developer(actor)
end
it 'returns true' do
expect(described_class.allowed_actor?(actor)).to be_truthy
end
end
end
end
end
describe '.allowed_group' do
before do
stub_performance_bar_setting(allowed_group: 'my-group')
end
context 'when allowed group does not exist' do
it 'returns false' do
expect(described_class.allowed_group).to be_falsy
end
end
context 'when allowed group exists' do
let!(:my_group) { create(:group, path: 'my-group') }
context 'when user is not a member of the allowed group' do
it 'returns false' do
expect(described_class.allowed_group).to eq(my_group)
end
end
end
end
end
......@@ -29,6 +29,10 @@ module StubConfiguration
allow(Gitlab.config.omniauth).to receive_messages(messages)
end
def stub_performance_bar_setting(messages)
allow(Gitlab.config.performance_bar).to receive_messages(messages)
end
private
# Modifies stubbed messages to also stub possible predicate versions
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment