diff --git a/app/overrides/controllers/hyrax/file_sets_controller_override.rb b/app/overrides/controllers/hyrax/file_sets_controller_override.rb new file mode 100644 index 000000000..978a2ca17 --- /dev/null +++ b/app/overrides/controllers/hyrax/file_sets_controller_override.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true +# https://github.com/samvera/hyrax/blob/3.5/app/controllers/hyrax/file_sets_controller.rb + +Hyrax::FileSetsController.class_eval do + # [hyc-override] Only allow deletions by admins + before_action :ensure_admin!, only: :destroy + + private + + def ensure_admin! + authorize! :read, :admin_dashboard + end +end diff --git a/app/views/hyrax/file_sets/_actions.html.erb b/app/views/hyrax/file_sets/_actions.html.erb new file mode 100644 index 000000000..c486b0464 --- /dev/null +++ b/app/views/hyrax/file_sets/_actions.html.erb @@ -0,0 +1,57 @@ +<%# [hyc-override] Overriding to see if user can delete the work, to be able to delete the fileset %> +<%# https://github.com/samvera/hyrax/blob/hyrax-v3.6.0/app/views/hyrax/file_sets/_actions.html.erb %> +<% if (can?(:download, file_set.id) || can?(:destroy, file_set.id) || can?(:edit, file_set.id)) && !workflow_restriction?(@parent) %> + <% if can?(:download, file_set.id) && !(can?(:edit, file_set.id) || can?(:destroy, file_set.id)) %> + <%= link_to t('.download'), + hyrax.download_path(file_set), + class: 'btn btn-default btn-sm', + title: t('.download_title', file_set: file_set), + target: "_blank", + id: "file_download", + data: { label: file_set.id, work_id: @presenter.id, collection_ids: @presenter.member_of_collection_ids } %> + <% else %> +
+ + + +
+ <% end %> +<% end %> diff --git a/app/views/hyrax/file_sets/_show_actions.html.erb b/app/views/hyrax/file_sets/_show_actions.html.erb new file mode 100644 index 000000000..b3ce15804 --- /dev/null +++ b/app/views/hyrax/file_sets/_show_actions.html.erb @@ -0,0 +1,22 @@ +<%# [hyc-override] Overriding to make only admins able to delete a fileset %> +<%# https://github.com/samvera/hyrax/blob/hyrax-v3.6.0/app/views/hyrax/file_sets/_show_actions.html.erb %> +
+ <% if Hyrax.config.analytics? && Hyrax.config.analytics_provider != 'ga4' %> + <%# turbolinks needs to be turned off or the page will use the cache and the %> + <%# analytics graph will not show unless the page is refreshed. %> + <%= link_to t('.analytics'), @presenter.stats_path, id: 'stats', class: 'btn btn-default', data: { turbolinks: false } %> + <% end %> + + <% if @presenter.editor? && !workflow_restriction?(@presenter) %> + <%= link_to t(".edit_this", type: @presenter.human_readable_type), edit_polymorphic_path([main_app, @presenter]), + class: 'btn btn-default' %> + <%# [hyc-override] only admins may delete the fileset %> + <% if current_ability.admin? %> + <%= link_to t(".delete_this", type: @presenter.human_readable_type), [main_app, @presenter], + class: 'btn btn-danger', data: { confirm: t(".confirm_delete_this", type: @presenter.human_readable_type) }, + method: :delete %> + <% end %> + <% end %> + + <%= render 'social_media' %> +
diff --git a/spec/controllers/hyrax/file_sets_controller_spec.rb b/spec/controllers/hyrax/file_sets_controller_spec.rb new file mode 100644 index 000000000..9fd23bd05 --- /dev/null +++ b/spec/controllers/hyrax/file_sets_controller_spec.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true +require 'rails_helper' +require Rails.root.join('app/overrides/controllers/hyrax/file_sets_controller_override.rb') + +RSpec.describe Hyrax::FileSetsController do + let(:user) { FactoryBot.create(:user) } + let(:admin_user) { FactoryBot.create(:admin) } + routes { Rails.application.routes } + + describe '#destroy' do + let(:file_set) { FactoryBot.create(:file_set, :public, :with_original_file, user: user) } + let(:work) { FactoryBot.create(:work, title: ['test title'], user: user) } + + before do + allow(Hyrax::VirusCheckerService).to receive(:file_has_virus?) { false } + work.ordered_members << file_set + work.save! + end + + context 'as a non-admin' do + before do + sign_in user + end + + it 'is not successful' do + delete :destroy, params: { id: file_set } + expect(response).to redirect_to '/?locale=en' + expect(flash[:alert]).to eq 'You are not authorized to access this page.' + expect(response.status).to eq 302 + end + end + + context 'as an admin' do + before do + file_set + sign_in admin_user + expect(controller).to receive(:guard_for_workflow_restriction_on!).and_return(true) + end + + it 'is successful' do + expect { delete :destroy, params: { id: file_set } } + .to change { FileSet.exists?(file_set.id) } + .from(true) + .to(false) + expect(response).to redirect_to '/concern/generals/' + work.id + '?locale=en' + expect(flash[:notice]).to eq 'The file has been deleted.' + expect(response.status).to eq 302 + end + end + + context 'as an unauthenticated user' do + it 'is not successful' do + delete :destroy, params: { id: file_set } + expect(response.status).to redirect_to '/users/sign_in' + expect(flash[:alert]).to eq 'You need to sign in or sign up before continuing.' + end + end + end +end diff --git a/spec/views/hyrax/file_sets/_actions.html.erb_spec.rb b/spec/views/hyrax/file_sets/_actions.html.erb_spec.rb new file mode 100644 index 000000000..8c9050714 --- /dev/null +++ b/spec/views/hyrax/file_sets/_actions.html.erb_spec.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true +# [hyc-override] only admins may see delete option in fileset action dropdown +require 'rails_helper' + +RSpec.describe 'hyrax/file_sets/_actions.html.erb', type: :view do + let(:solr_document) { double('Solr Doc', id: 'file_set_id') } + let(:file_set_model) { FactoryBot.create(:file_set) } + let(:user) { FactoryBot.create(:user) } + let(:ability) { Ability.new(user) } + let(:file_set) { Hyrax::FileSetPresenter.new(solr_document, ability) } + let(:work_solr_document) do + SolrDocument.new(id: '900', title_tesim: ['My Title']) + end + let(:parent_presenter) { Hyrax::WorkShowPresenter.new(work_solr_document, ability) } + + before do + allow(controller).to receive(:current_ability).and_return(ability) + allow(file_set).to receive(:parent).and_return(:parent) + allow(file_set).to receive(:id).and_return('fake') + assign(:presenter, parent_presenter) + allow(view).to receive(:workflow_restriction?).and_return(false) + allow(view).to receive(:can?).with(:edit, file_set.id).and_return(true) + allow(view).to receive(:can?).with(:destroy, file_set.id).and_return(true) + allow(view).to receive(:can?).with(:download, file_set.id).and_return(true) + allow(solr_document).to receive(:to_model).and_return(file_set_model) + end + + context 'as an admin' do + before do + allow(ability).to receive(:admin?).and_return(true) + render 'hyrax/file_sets/actions', file_set: file_set + end + + it 'shows delete action in dropdown' do + expect(rendered).to have_link('Delete') + end + end + + context 'as a regular user' do + before do + allow(ability).to receive(:admin?).and_return(false) + render 'hyrax/file_sets/actions', file_set: file_set + end + + it 'does not show delete action in dropdown' do + expect(rendered).not_to have_link('Delete') + end + end +end diff --git a/spec/views/hyrax/file_sets/_show_actions.html.erb_spec.rb b/spec/views/hyrax/file_sets/_show_actions.html.erb_spec.rb new file mode 100644 index 000000000..8bfe95023 --- /dev/null +++ b/spec/views/hyrax/file_sets/_show_actions.html.erb_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true +# [hyc-override] only admins may view delete filesets button +require 'rails_helper' + +RSpec.describe 'hyrax/file_sets/_show_actions.html.erb', type: :view do + let(:user) { FactoryBot.create(:user) } + let(:object_profile) { ["{'id':'999'}"] } + let(:contributor) { ['Frodo'] } + let(:creator) { ['Bilbo'] } + let(:solr_document) do + SolrDocument.new( + id: '999', + object_profile_ssm: object_profile, + has_model_ssim: ['FileSet'], + human_readable_type_tesim: ['File'], + contributor_tesim: contributor, + creator_tesim: creator, + rights_tesim: ['http://creativecommons.org/licenses/by/3.0/us/'] + ) + end + let(:decorated_solr_document) { Hyrax::SolrDocument::OrderedMembers.decorate(solr_document) } + let(:ability) { Ability.new(user) } + let(:presenter) do + Hyrax::WorkShowPresenter.new(solr_document, ability) + end + let(:page) { Capybara::Node::Simple.new(rendered) } + + before do + allow(controller).to receive(:current_ability).and_return(ability) + allow(presenter).to receive(:editor?).and_return(true) + allow(view).to receive(:workflow_restriction?).and_return(false) + assign(:presenter, presenter) + end + + context 'as an admin' do + before do + allow(ability).to receive(:admin?).and_return(true) + view.lookup_context.view_paths.push 'app/views/hyrax/base' + render + end + + it 'shows delete button' do + expect(page).to have_link('Delete This File') + end + end + + context 'as a regular user' do + before do + allow(ability).to receive(:admin?).and_return(false) + view.lookup_context.view_paths.push 'app/views/hyrax/base' + render + end + + it 'does not show delete button' do + expect(page).not_to have_link('Delete This File') + end + end +end