diff --git a/lib/flipper/ui.rb b/lib/flipper/ui.rb index 3f6504319..70f857370 100644 --- a/lib/flipper/ui.rb +++ b/lib/flipper/ui.rb @@ -24,14 +24,19 @@ class << self # Public: Is feature creation allowed from the UI? Defaults to true. If # set to false, users of the UI cannot create features. All feature - # creation will need to be done through the conigured flipper instance. + # creation will need to be done through the configured flipper instance. attr_accessor :feature_creation_enabled + # Public: Is feature deletion allowed from the UI? Defaults to true. If + # set to false, users won't be able to delete features from the UI. + attr_accessor :feature_removal_enabled + # Public: Set attributes on this instance to customize UI text attr_reader :configuration end self.feature_creation_enabled = true + self.feature_removal_enabled = true def self.root @root ||= Pathname(__FILE__).dirname.expand_path.join('ui') diff --git a/lib/flipper/ui/actions/feature.rb b/lib/flipper/ui/actions/feature.rb index c687222bd..9fe8cf8da 100644 --- a/lib/flipper/ui/actions/feature.rb +++ b/lib/flipper/ui/actions/feature.rb @@ -21,6 +21,15 @@ def get end def delete + unless Flipper::UI.feature_removal_enabled + status 403 + + breadcrumb 'Home', '/' + breadcrumb 'Features', '/features' + + halt view_response(:feature_removal_disabled) + end + feature_name = Rack::Utils.unescape(request.path.split('/').last) feature = flipper[feature_name] feature.remove diff --git a/lib/flipper/ui/views/feature.erb b/lib/flipper/ui/views/feature.erb index a93092c06..de56f5371 100644 --- a/lib/flipper/ui/views/feature.erb +++ b/lib/flipper/ui/views/feature.erb @@ -192,19 +192,21 @@ -
-
-

<%= Flipper::UI.configuration.delete.title %>

-
-
-

- <%= Flipper::UI.configuration.delete.description %> -

+<% if Flipper::UI.feature_removal_enabled %> +
+
+

<%= Flipper::UI.configuration.delete.title %>

+
+
+

+ <%= Flipper::UI.configuration.delete.description %> +

-
- <%== csrf_input_tag %> - - -
+
+ <%== csrf_input_tag %> + + +
+
-
+<% end %> diff --git a/lib/flipper/ui/views/feature_removal_disabled.erb b/lib/flipper/ui/views/feature_removal_disabled.erb new file mode 100644 index 000000000..7be850024 --- /dev/null +++ b/lib/flipper/ui/views/feature_removal_disabled.erb @@ -0,0 +1,3 @@ +
+ Feature removal from the UI is disabled. To enable, you'll need to set Flipper::UI.feature_removal_enabled = true wherever flipper is running from. +
diff --git a/spec/flipper/ui/actions/feature_spec.rb b/spec/flipper/ui/actions/feature_spec.rb index eb05d1be0..b2fb97663 100644 --- a/spec/flipper/ui/actions/feature_spec.rb +++ b/spec/flipper/ui/actions/feature_spec.rb @@ -28,6 +28,23 @@ expect(last_response.status).to be(302) expect(last_response.headers['Location']).to eq('/features') end + + context 'when feature_removal_enabled is set to false' do + around do |example| + @original_feature_removal_enabled = Flipper::UI.feature_removal_enabled + Flipper::UI.feature_removal_enabled = false + example.run + Flipper::UI.feature_removal_enabled = @original_feature_removal_enabled + end + + it 'returns with 403 status' do + expect(last_response.status).to be(403) + end + + it 'renders feature removal disabled template' do + expect(last_response.body).to include('Feature removal from the UI is disabled') + end + end end describe 'POST /features/:feature with _method=DELETE' do