From 464af1625349d557f688da9f845471ef8b80a5f9 Mon Sep 17 00:00:00 2001 From: erdgeist Date: Fri, 31 Jul 2026 18:14:30 +0200 Subject: Gate live-content changes on restricted surfaces publish_draft!, trash!, destroy_from_trash!, attach_asset! and Asset#destroy_witnessed! now refuse unless the acting user holds redaktion, and only when the subject is on a restricted surface: the front page, the updates tree that feeds ~100k subscribers, or disclosure. Drafting, autosaving, tagging and creating stay free everywhere for everyone. Enforcement is in the models rather than the controllers, since attach_asset! and the rest are reachable from rake tasks and internal paths. It follows the errors.add-plus-bare-raise pattern the rest of Node already uses, so every existing RecordInvalid rescue reports it with a localised message; only assets_controller#destroy needed a rescue added. A nil user is treated as a system context and bypasses the gate. The default nil on three of those verbs is what makes that reachable, and removing those defaults once every call site passes a user is the next tightening. --- test/controllers/nodes_controller_test.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'test/controllers') diff --git a/test/controllers/nodes_controller_test.rb b/test/controllers/nodes_controller_test.rb index 0b6e65ee..f15be067 100644 --- a/test/controllers/nodes_controller_test.rb +++ b/test/controllers/nodes_controller_test.rb @@ -770,6 +770,20 @@ class NodesControllerTest < ActionController::TestCase assert_select "form[action=?]", node_path(node), count: 1 end + test "publishing a restricted node without the redaktion role flashes and does not publish" do + login_as :quentin + updates = Node.root.children.create!(:slug => "updates") + node = updates.children.create!(:slug => "controller-gated") + node.reload.draft.update!(:title => "Entwurf") + + put :publish, params: { :id => node.id } + + assert_redirected_to node_path(node) + assert_match I18n.t("activerecord.errors.models.node.attributes.base.not_permitted"), + flash[:error] + assert_nil node.reload.head + end + test "show annotates history rows with their lifecycle" do login_as :quentin node = Node.root.children.create!(:slug => "history_annotation_test") -- cgit v1.3