Commit 0a460e88 authored by Francisco Javier López's avatar Francisco Javier López Committed by Paul Slaughter

Access based on policies

parent 9d31459f
......@@ -2,7 +2,7 @@ module SourcegraphGon
extend ActiveSupport::Concern
def push_sourcegraph_gon
return unless enabled?
return unless can?(current_user, :access_sourcegraph, sourcegraph_project)
gon.push({
sourcegraph_enabled: true,
......@@ -10,20 +10,9 @@ module SourcegraphGon
})
end
private
private
def enabled?
current_user&.sourcegraph_enabled && project_enabled?
end
def project_enabled?
return false unless project && Gitlab::Sourcegraph.feature_enabled?(project)
return project.public? if Gitlab::CurrentSettings.sourcegraph_public_only
true
end
def project
@target_project || @project
def sourcegraph_project
@target_project || project
end
end
......@@ -461,6 +461,26 @@ class ProjectPolicy < BasePolicy
prevent :create_pipeline
end
condition(:user_sourcegraph_enabled?) do
@user&.sourcegraph_enabled
end
condition(:sourcegraph_feature_enabled?) do
Gitlab::CurrentSettings.sourcegraph_enabled && Gitlab::Sourcegraph.feature_enabled?(@subject)
end
condition(:sourcegraph_public_only?) do
public_project? && Gitlab::CurrentSettings.sourcegraph_public_only
end
condition(:sourcegraph_generally_available?) do
can?(:read_project) && !Gitlab::CurrentSettings.sourcegraph_public_only
end
rule do
(user_sourcegraph_enabled? & sourcegraph_feature_enabled? & (sourcegraph_public_only? | sourcegraph_generally_available?))
end.enable :access_sourcegraph
private
def team_member?
......
# frozen_string_literal: true
require 'spec_helper'
describe SourcegraphGon do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :public) }
controller(Projects::ApplicationController) do
include SourcegraphGon # rubocop:disable RSpec/DescribedClass
def index; end
end
describe '#push_sourcegraph_gon' do
let(:application_setting_sourcegraph_url) { 'http://gitlab.com' }
let(:sourcegraph_access) { true }
subject { get(:index, params: { namespace_id: project.namespace, project_id: project })}
before do
stub_application_setting(sourcegraph_url: application_setting_sourcegraph_url)
allow(controller).to receive(:current_user).and_return(user)
allow(controller).to receive(:can?).and_return(true)
allow(controller).to receive(:can?).with(user, :access_sourcegraph, project).and_return(sourcegraph_access)
subject
end
context 'with access to use sourcegraph' do
it 'enables sourcegraph' do
expect(Gon.sourcegraph_enabled).to be_truthy
expect(Gon.sourcegraph_url).to eq application_setting_sourcegraph_url
end
end
context 'with no access to use sourcegraph' do
let(:sourcegraph_access) { false }
it 'does not enable sourcegraph' do
expect(Gon.sourcegraph_enabled).to be_nil
expect(Gon.sourcegraph_url).to be_nil
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe SourcegraphHelper do
let(:application_setting) { true }
let(:public_only_setting) { true }
let(:feature_conditional) { false }
subject { helper.sourcegraph_help_message }
before do
allow(Gitlab::CurrentSettings).to receive(:sourcegraph_enabled).and_return(application_setting)
allow(Gitlab::CurrentSettings).to receive(:sourcegraph_public_only).and_return(public_only_setting)
allow(Gitlab::Sourcegraph).to receive(:feature_conditional?).and_return(feature_conditional)
end
context '#sourcegraph_help_message' do
context 'when application setting sourcegraph_enabled is disabled' do
let(:application_setting) { false }
it { is_expected.to be_nil }
end
context 'when application setting sourcegraph_enabled is enabled' do
context 'when feature is conditional' do
let(:feature_conditional) { true }
it do
is_expected.to eq "This feature is experimental and has been limited to only certain projects."
end
end
context 'when feature is enabled globally' do
before do
stub_feature_flags(sourcegraph: true)
end
context 'when only works with public projects' do
it do
is_expected.to eq "This feature is experimental and also limited to only public projects."
end
end
context 'when it works with all projects' do
let(:public_only_setting) { false }
it do
is_expected.to eq "This feature is experimental."
end
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::Sourcegraph do
let_it_be(:user) { create(:user) }
let(:feature) { :sourcegraph }
describe '.feature_conditional?' do
subject { described_class.feature_conditional? }
context 'when feature is enabled globally' do
it 'returns false' do
Feature.enable(feature)
is_expected.to be_falsey
end
end
context 'when feature is enabled only to a resource' do
it 'returns true' do
Feature.enable(feature, user)
is_expected.to be_truthy
end
end
end
describe '.feature_available?' do
subject { described_class.feature_available? }
context 'when feature is enabled globally' do
it 'returns true' do
Feature.enable(feature)
is_expected.to be_truthy
end
end
context 'when feature is enabled only to a resource' do
it 'returns true' do
Feature.enable(feature, user)
is_expected.to be_truthy
end
end
end
describe '.feature_enabled?' do
let_it_be(:other_user) { create(:user) }
let(:current_user) { nil }
subject { described_class.feature_enabled?(current_user) }
context 'when feature is enabled globally' do
it 'returns true' do
Feature.enable(feature)
is_expected.to be_truthy
end
end
context 'when feature is enabled only to a resource' do
context 'for the same resource' do
let(:current_user) { user }
it 'returns true' do
Feature.enable(feature, user)
is_expected.to be_truthy
end
end
context 'for a different resource' do
let(:current_user) { other_user }
it 'returns false' do
Feature.enable(feature, user)
is_expected.to be_falsey
end
end
end
end
end
......@@ -495,6 +495,15 @@ describe ApplicationSetting do
it { is_expected.not_to allow_value(nil).for(:static_objects_external_storage_auth_token) }
end
end
context 'sourcegraph settings' do
it 'is invalid if sourcegraph is enabled and no url is provided' do
allow(subject).to receive(:sourcegraph_enabled).and_return(true)
expect(subject.sourcegraph_url).to be_nil
is_expected.to be_invalid
end
end
end
context 'restrict creating duplicates' do
......@@ -583,5 +592,29 @@ describe ApplicationSetting do
end
end
context 'sourcegraph_enabled' do
let(:flag_value) { true }
before do
allow(Gitlab::Sourcegraph).to receive(:feature_available?).and_return(flag_value)
setting.sourcegraph_enabled = true
end
context 'when feature flag sourcegraph is enabled' do
it 'returns the stored value' do
expect(setting.sourcegraph_enabled).to be_truthy
end
end
context 'when feature flag sourcegraph is disabled' do
let(:flag_value) { false }
it 'returns false' do
expect(setting.sourcegraph_enabled).to be_falsey
end
end
end
it_behaves_like 'application settings examples'
end
......@@ -3,7 +3,8 @@
require 'spec_helper'
describe UserPreference do
let(:user_preference) { create(:user_preference) }
let_it_be(:user) { create(:user) }
let(:user_preference) { create(:user_preference, user: user) }
describe '#set_notes_filter' do
let(:issuable) { build_stubbed(:issue) }
......@@ -79,4 +80,27 @@ describe UserPreference do
expect(user_preference.timezone).to eq(Time.zone.tzinfo.name)
end
end
describe 'sourcegraph_enabled' do
let(:user_preference) { create(:user_preference, sourcegraph_enabled: true, user: user) }
let(:application_setting_sourcegraph_enabled) { true }
before do
stub_application_setting(sourcegraph_enabled: application_setting_sourcegraph_enabled)
end
context 'when sourcegraph_enabled application setting is enabled' do
it 'returns true' do
expect(user_preference.sourcegraph_enabled).to be_truthy
end
end
context 'when sourcegraph_enabled application setting is disabled' do
let(:application_setting_sourcegraph_enabled) { false }
it 'returns false' do
expect(user_preference.sourcegraph_enabled).to be_falsey
end
end
end
end
......@@ -529,4 +529,88 @@ describe ProjectPolicy do
end
end
end
describe 'access_sourcegraph' do
let_it_be(:private_project) { create(:project, :private, namespace: owner.namespace) }
let(:sourcegraph_flag) { true }
let(:application_setting_sourcegraph_enabled) { true }
let(:user_sourcegraph_enabled) { true }
let(:current_user) { owner }
subject { described_class.new(current_user, project) }
before do
stub_feature_flags(sourcegraph: sourcegraph_flag)
stub_application_setting(sourcegraph_enabled: application_setting_sourcegraph_enabled)
stub_application_setting(sourcegraph_public_only: application_setting_sourcegraph_public_only)
allow(Gitlab::Sourcegraph).to receive(:feature_enabled?).and_return(sourcegraph_flag)
allow(current_user).to receive(:sourcegraph_enabled).and_return(user_sourcegraph_enabled) if current_user
end
shared_examples 'disabled setting requirements' do
context 'when feature flag is disabled' do
let(:sourcegraph_flag) { false }
it { expect_disallowed(:access_sourcegraph) }
end
context 'when user setting is disabled' do
let(:user_sourcegraph_enabled) { false }
it { expect_disallowed(:access_sourcegraph) }
end
context 'when application setting is disabled' do
let(:application_setting_sourcegraph_enabled) { false }
it { expect_disallowed(:access_sourcegraph) }
end
end
context 'when sourcegraph setting is enabled for public projects only' do
let(:application_setting_sourcegraph_public_only) { true }
context 'when the project is public' do
it { expect_allowed(:access_sourcegraph) }
it_behaves_like 'disabled setting requirements'
context 'when the user is not authenticated' do
let(:current_user) { nil }
it { expect_disallowed(:access_sourcegraph) }
end
end
context 'when the project is not public' do
let(:project) { private_project }
it { expect_disallowed(:access_sourcegraph) }
end
end
context 'when sourcegraph setting is enabled for all projects' do
let(:application_setting_sourcegraph_public_only) { false }
context 'when the project is public' do
it { expect_allowed(:access_sourcegraph) }
it_behaves_like 'disabled setting requirements'
end
context 'when the project is not public' do
let(:project) { private_project }
it { expect_allowed(:access_sourcegraph) }
it_behaves_like 'disabled setting requirements'
context 'when the user cannot read project' do
let(:current_user) { create(:user) }
it { expect_disallowed(:access_sourcegraph) }
end
end
end
end
end
......@@ -19,7 +19,9 @@ describe API::Settings, 'Settings' do
expect(json_response['plantuml_enabled']).to be_falsey
expect(json_response['plantuml_url']).to be_nil
expect(json_response['default_ci_config_path']).to be_nil
expect(json_response['sourcegraph_enabled']).to be_falsey
expect(json_response['sourcegraph_url']).to be_nil
expect(json_response['sourcegraph_public_only']).to be_truthy
expect(json_response['default_project_visibility']).to be_a String
expect(json_response['default_snippet_visibility']).to be_a String
expect(json_response['default_group_visibility']).to be_a String
......
# frozen_string_literal: true
require 'spec_helper'
describe 'admin/application_settings/integrations.html.haml' do
let(:app_settings) { build(:application_setting) }
describe 'sourcegraph integration' do
let(:sourcegraph_flag) { true }
before do
assign(:application_setting, app_settings)
allow(Gitlab::Sourcegraph).to receive(:feature_available?).and_return(sourcegraph_flag)
end
context 'when sourcegraph feature is enabled' do
it 'show the form' do
render
expect(rendered).to have_field('application_setting_sourcegraph_enabled')
end
end
context 'when sourcegraph feature is disabled' do
let(:sourcegraph_flag) { false }
it 'show the form' do
render
expect(rendered).not_to have_field('application_setting_sourcegraph_enabled')
end
end
end
end
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