From ef6ba24d90f2be67f5d33640c65378ce2e1920d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20G=C3=BCnther?= Date: Tue, 21 Apr 2026 12:06:51 +0200 Subject: [PATCH] Prevent moving of projects when using documents update service --- .../app/contracts/documents/base_contract.rb | 20 ++++++++++++++-- .../v3/documents/documents_resource_spec.rb | 24 +++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/modules/documents/app/contracts/documents/base_contract.rb b/modules/documents/app/contracts/documents/base_contract.rb index aec8b375b67..590c873e5eb 100644 --- a/modules/documents/app/contracts/documents/base_contract.rb +++ b/modules/documents/app/contracts/documents/base_contract.rb @@ -31,6 +31,7 @@ module Documents class BaseContract < ::ModelContract include Attachments::ValidateReplacements + include UnchangedProject def self.model Document @@ -43,11 +44,26 @@ module Documents attribute :description attribute :content_binary - validate :validate_manage_allowed + validate :validate_manage_allowed_in_source_project + validate :validate_manage_allowed_in_destination_project private - def validate_manage_allowed + def validate_manage_allowed_in_source_project + if model.new_record? + errors.add :base, :error_unauthorized unless user.allowed_in_project?(:manage_documents, model.project) + return + end + + with_unchanged_project_id do + errors.add :base, :error_unauthorized unless user.allowed_in_project?(:manage_documents, model.project) + end + end + + def validate_manage_allowed_in_destination_project + return if model.new_record? + return unless model.project_id_changed? + unless user.allowed_in_project?(:manage_documents, model.project) errors.add :base, :error_unauthorized end diff --git a/modules/documents/spec/requests/api/v3/documents/documents_resource_spec.rb b/modules/documents/spec/requests/api/v3/documents/documents_resource_spec.rb index 05eb85f605d..533e31ae334 100644 --- a/modules/documents/spec/requests/api/v3/documents/documents_resource_spec.rb +++ b/modules/documents/spec/requests/api/v3/documents/documents_resource_spec.rb @@ -170,6 +170,30 @@ RSpec.describe "API v3 documents resource" do expect(subject.status) .to be(403) end + + context "when trying to move document to another project where user can manage documents" do + let(:target_project) { create(:project) } + let(:target_role) { create(:project_role, permissions: %i(view_documents manage_documents)) } + let(:request_body) do + { + project_id: target_project.id, + title: "Moved Document Title" + } + end + + before do + create(:member, principal: current_user, project: target_project, roles: [target_role]) + document # ensure the source document exists before patching + end + + it "returns 403 FORBIDDEN" do + expect(subject.status).to be(403) + end + + it "does not move the document to another project" do + expect(document.reload.project_id).to eq(project.id) + end + end end context "when lacking view permissions" do