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/models/user_test.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'test/models/user_test.rb') diff --git a/test/models/user_test.rb b/test/models/user_test.rb index feccce25..9942385c 100644 --- a/test/models/user_test.rb +++ b/test/models/user_test.rb @@ -126,6 +126,22 @@ class UserTest < ActiveSupport::TestCase assert user.update(:email => "quentin@example.org") end + + test "may_change_live? gates restricted subjects on the redaktion role" do + editor = User.create!(:login => "gate_editor", :email => "ge@example.com", + :password => "secret", :password_confirmation => "secret") + redaktion = User.create!(:login => "gate_red", :email => "gr@example.com", + :password => "secret", :password_confirmation => "secret", + :roles => ["redaktion"]) + + restricted = Node.root + plain = Node.root.children.create!(:slug => "gate_plain") + + assert editor.may_change_live?(plain) + assert_not editor.may_change_live?(restricted) + assert redaktion.may_change_live?(plain) + assert redaktion.may_change_live?(restricted) + end protected def create_user(options = {}) -- cgit v1.3