From 3433f8656fcce2a41d3eac7e1e319d2c8136b16b Mon Sep 17 00:00:00 2001 From: Jan Sandbrink Date: Wed, 3 Jun 2026 13:49:48 +0200 Subject: [PATCH] Delete relation page links through service Allows to enforce delete permissions through contract. --- .../relation_page_links/delete_contract.rb | 37 ++++++++++++++++++ .../wikis/relation_page_links_controller.rb | 12 ++++-- modules/wikis/app/models/wikis/page_link.rb | 2 + .../relation_page_links/delete_service.rb | 36 +++++++++++++++++ .../delete_service_spec.rb | 39 +++++++++++++++++++ 5 files changed, 122 insertions(+), 4 deletions(-) create mode 100644 modules/wikis/app/contracts/wikis/relation_page_links/delete_contract.rb create mode 100644 modules/wikis/app/services/wikis/relation_page_links/delete_service.rb create mode 100644 modules/wikis/spec/services/wikis/relation_page_links/delete_service_spec.rb diff --git a/modules/wikis/app/contracts/wikis/relation_page_links/delete_contract.rb b/modules/wikis/app/contracts/wikis/relation_page_links/delete_contract.rb new file mode 100644 index 00000000000..83bfab31131 --- /dev/null +++ b/modules/wikis/app/contracts/wikis/relation_page_links/delete_contract.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +module Wikis + module RelationPageLinks + class DeleteContract < ::DeleteContract + delete_permission(:manage_wiki_page_links) + end + end +end diff --git a/modules/wikis/app/controllers/wikis/relation_page_links_controller.rb b/modules/wikis/app/controllers/wikis/relation_page_links_controller.rb index dd48dd4a471..f97ae804bc8 100644 --- a/modules/wikis/app/controllers/wikis/relation_page_links_controller.rb +++ b/modules/wikis/app/controllers/wikis/relation_page_links_controller.rb @@ -47,11 +47,15 @@ module Wikis end def destroy - # TODO: Wikis::PageLinks::DeleteService page_link = find_page_link - page_link.destroy! - - turbo_redirect_for_linkable(page_link.linkable) + service_result = Wikis::RelationPageLinks::DeleteService.new(user: current_user, model: page_link).call + if service_result.success? + turbo_redirect_for_linkable(page_link.linkable) + else + message = service_result.errors.full_messages.join(" ") + render_error_flash_message_via_turbo_stream(message:) + respond_to_with_turbo_streams + end end def confirm_delete_dialog diff --git a/modules/wikis/app/models/wikis/page_link.rb b/modules/wikis/app/models/wikis/page_link.rb index 31625739faa..12898199dde 100644 --- a/modules/wikis/app/models/wikis/page_link.rb +++ b/modules/wikis/app/models/wikis/page_link.rb @@ -35,6 +35,8 @@ module Wikis belongs_to :provider belongs_to :linkable, polymorphic: true + delegate :project, to: :linkable + def relation? = false def inline? = false diff --git a/modules/wikis/app/services/wikis/relation_page_links/delete_service.rb b/modules/wikis/app/services/wikis/relation_page_links/delete_service.rb new file mode 100644 index 00000000000..431aae7de2d --- /dev/null +++ b/modules/wikis/app/services/wikis/relation_page_links/delete_service.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +module Wikis + module RelationPageLinks + class DeleteService < ::BaseServices::Delete + end + end +end diff --git a/modules/wikis/spec/services/wikis/relation_page_links/delete_service_spec.rb b/modules/wikis/spec/services/wikis/relation_page_links/delete_service_spec.rb new file mode 100644 index 00000000000..42af5ce30fb --- /dev/null +++ b/modules/wikis/spec/services/wikis/relation_page_links/delete_service_spec.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See COPYRIGHT and LICENSE files for more details. +#++ + +require "spec_helper" + +require "services/base_services/behaves_like_delete_service" + +RSpec.describe Wikis::RelationPageLinks::DeleteService, type: :model do + it_behaves_like "BaseServices delete service" do + let(:factory) { :relation_wiki_page_link } + end +end