Commit e716346c authored by James Fargher's avatar James Fargher

Check instance cluster feature at policy level

Try to simplify feature flag checks by using policies
parent 6fd70b24
...@@ -4,12 +4,9 @@ ...@@ -4,12 +4,9 @@
# #
# Automatically sets the layout and ensures an administrator is logged in # Automatically sets the layout and ensures an administrator is logged in
class Admin::ApplicationController < ApplicationController class Admin::ApplicationController < ApplicationController
before_action :authenticate_admin! include EnforcesAdminAuthentication
layout 'admin'
def authenticate_admin! layout 'admin'
render_404 unless current_user.admin?
end
end end
Admin::ApplicationController.prepend(EE::Admin::ApplicationController) Admin::ApplicationController.prepend(EE::Admin::ApplicationController)
# frozen_string_literal: true # frozen_string_literal: true
class Admin::Clusters::ApplicationsController < Clusters::ApplicationsController class Admin::Clusters::ApplicationsController < Clusters::ApplicationsController
include EnforcesAdminAuthentication
private private
def clusterable def clusterable
......
# frozen_string_literal: true # frozen_string_literal: true
class Admin::ClustersController < Clusters::ClustersController class Admin::ClustersController < Clusters::ClustersController
prepend_before_action :check_instance_clusters_feature_flag! include EnforcesAdminAuthentication
layout 'admin' layout 'admin'
private private
def clusterable def clusterable
@clusterable ||= InstanceClusterablePresenter.fabricate(cluster_instance, current_user: current_user) @clusterable ||= InstanceClusterablePresenter.fabricate(Clusters::Instance.new, current_user: current_user)
end
def cluster_instance
@cluster_instance ||= Clusters::Instance.new
end
def check_instance_clusters_feature_flag!
render_404 unless instance_clusters_enabled?
end
def instance_clusters_enabled?
cluster_instance.instance_clusters_enabled?
end end
end end
# frozen_string_literal: true
# == EnforcesAdminAuthentication
#
# Controller concern to enforce that users are authenticated as admins
#
# Upon inclusion, adds `authenticate_admin!` as a before_action
#
module EnforcesAdminAuthentication
extend ActiveSupport::Concern
included do
before_action :authenticate_admin!
end
def authenticate_admin!
render_404 unless current_user.admin?
end
end
...@@ -286,6 +286,10 @@ module ApplicationSettingsHelper ...@@ -286,6 +286,10 @@ module ApplicationSettingsHelper
def expanded_by_default? def expanded_by_default?
Rails.env.test? Rails.env.test?
end end
def instance_clusters_enabled?
can?(current_user, :read_cluster, Clusters::Instance.new)
end
end end
ApplicationSettingsHelper.prepend(EE::ApplicationSettingsHelper) # rubocop: disable Cop/InjectEnterpriseEditionModule ApplicationSettingsHelper.prepend(EE::ApplicationSettingsHelper) # rubocop: disable Cop/InjectEnterpriseEditionModule
......
...@@ -6,8 +6,9 @@ module Clusters ...@@ -6,8 +6,9 @@ module Clusters
condition(:has_clusters, scope: :subject) { clusterable_has_clusters? } condition(:has_clusters, scope: :subject) { clusterable_has_clusters? }
condition(:can_have_multiple_clusters) { multiple_clusters_available? } condition(:can_have_multiple_clusters) { multiple_clusters_available? }
condition(:instance_clusters_enabled, scope: :subject) { @subject.instance_clusters_enabled? }
rule { admin }.policy do rule { admin & instance_clusters_enabled }.policy do
enable :read_cluster enable :read_cluster
enable :add_cluster enable :add_cluster
enable :create_cluster enable :create_cluster
......
...@@ -145,17 +145,18 @@ ...@@ -145,17 +145,18 @@
%strong.fly-out-top-item-name %strong.fly-out-top-item-name
= _('License') = _('License')
= nav_link(controller: :clusters) do - if instance_clusters_enabled?
= link_to admin_clusters_path do = nav_link(controller: :clusters) do
.nav-icon-container = link_to admin_clusters_path do
= sprite_icon('cloud-gear') .nav-icon-container
%span.nav-item-name = sprite_icon('cloud-gear')
= _('Kubernetes') %span.nav-item-name
%ul.sidebar-sub-level-items.is-fly-out-only = _('Kubernetes')
= nav_link(controller: :clusters, html_options: { class: "fly-out-top-item" } ) do %ul.sidebar-sub-level-items.is-fly-out-only
= link_to admin_clusters_path do = nav_link(controller: :clusters, html_options: { class: "fly-out-top-item" } ) do
%strong.fly-out-top-item-name = link_to admin_clusters_path do
= _('Kubernetes') %strong.fly-out-top-item-name
= _('Kubernetes')
- if akismet_enabled? - if akismet_enabled?
= nav_link(controller: :spam_logs) do = nav_link(controller: :spam_logs) do
......
...@@ -13,6 +13,16 @@ describe Admin::Clusters::ApplicationsController do ...@@ -13,6 +13,16 @@ describe Admin::Clusters::ApplicationsController do
it { expect { subject }.to be_allowed_for(:admin) } it { expect { subject }.to be_allowed_for(:admin) }
it { expect { subject }.to be_denied_for(:user) } it { expect { subject }.to be_denied_for(:user) }
it { expect { subject }.to be_denied_for(:external) } it { expect { subject }.to be_denied_for(:external) }
context 'when instance clusters are disabled' do
before do
stub_feature_flags(instance_clusters: false)
end
it 'returns 404' do
is_expected.to have_http_status(:not_found)
end
end
end end
let(:cluster) { create(:cluster, :instance, :provided_by_gcp) } let(:cluster) { create(:cluster, :instance, :provided_by_gcp) }
......
# frozen_string_literal: true
require 'spec_helper'
describe EnforcesAdminAuthentication do
let(:user) { create(:user) }
before do
sign_in(user)
end
controller(ApplicationController) do
# `described_class` is not available in this context
include EnforcesAdminAuthentication # rubocop:disable RSpec/DescribedClass
def index
head :ok
end
end
describe 'authenticate_admin!' do
context 'as an admin' do
let(:user) { create(:admin) }
it 'renders ok' do
get :index
expect(response).to have_gitlab_http_status(200)
end
end
context 'as a user' do
it 'renders a 404' do
get :index
expect(response).to have_gitlab_http_status(404)
end
end
end
end
...@@ -3,9 +3,8 @@ ...@@ -3,9 +3,8 @@
require 'spec_helper' require 'spec_helper'
describe Clusters::InstancePolicy do describe Clusters::InstancePolicy do
let(:cluster) { create(:cluster, :instance) }
let(:user) { create(:user) } let(:user) { create(:user) }
let(:policy) { described_class.new(user, cluster) } let(:policy) { described_class.new(user, Clusters::Instance.new) }
describe 'rules' do describe 'rules' do
context 'when user' do context 'when user' do
...@@ -17,9 +16,21 @@ describe Clusters::InstancePolicy do ...@@ -17,9 +16,21 @@ describe Clusters::InstancePolicy do
context 'when admin' do context 'when admin' do
let(:user) { create(:admin) } let(:user) { create(:admin) }
it { expect(policy).to be_allowed :read_cluster } context 'with instance_level_clusters enabled' do
it { expect(policy).to be_allowed :update_cluster } it { expect(policy).to be_allowed :read_cluster }
it { expect(policy).to be_allowed :admin_cluster } it { expect(policy).to be_allowed :update_cluster }
it { expect(policy).to be_allowed :admin_cluster }
end
context 'with instance_level_clusters disabled' do
before do
stub_feature_flags(instance_clusters: false)
end
it { expect(policy).to be_disallowed :read_cluster }
it { expect(policy).to be_disallowed :update_cluster }
it { expect(policy).to be_disallowed :admin_cluster }
end
end end
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