summaryrefslogtreecommitdiff
path: root/app/models/node.rb
diff options
context:
space:
mode:
authorerdgeist <erdgeist@erdgeist.org>2026-07-17 19:30:43 +0200
committererdgeist <erdgeist@erdgeist.org>2026-07-17 19:30:43 +0200
commit04450e10866fc56890426525062fd5cdf56c4300 (patch)
tree952fb91c85aa9e03f9b7d3de93ee5af42b30324d /app/models/node.rb
parent5221c5400e193a64ab607d7de7c0450f5f15cd55 (diff)
Allowlist aggregate order columns and template names
Page.aggregate interpolated order_by into SQL unchecked while already allowlisting order_direction; the column is now normalized and checked against the sortable columns, falling back to pages.id. Its values arrive from editor-authored aggregate shortcodes, so this was editor-gated, but the asymmetry was wrong regardless. template_name and default_template_name now validate inclusion in Page.custom_templates -- names render as filesystem paths, so only names actually present in the template directory are acceptable. Validated only on change: legacy rows whose template file has since vanished stay saveable, and valid_template's render-time fallback to standard_template continues to cover them. Two tests that wrote fabricated template names through the front door now arrange their state correctly (update_column for the stale-name fallback test, a real template for the update-persists test).
Diffstat (limited to 'app/models/node.rb')
-rw-r--r--app/models/node.rb5
1 files changed, 5 insertions, 0 deletions
diff --git a/app/models/node.rb b/app/models/node.rb
index 4f585e1..70ed4da 100644
--- a/app/models/node.rb
+++ b/app/models/node.rb
@@ -22,6 +22,11 @@ class Node < ApplicationRecord
22 validates_uniqueness_of :slug, :scope => :parent_id, :unless => -> { parent_id.nil? } 22 validates_uniqueness_of :slug, :scope => :parent_id, :unless => -> { parent_id.nil? }
23 validates_presence_of :parent_id, :unless => -> { Node.root.nil? } 23 validates_presence_of :parent_id, :unless => -> { Node.root.nil? }
24 24
25 validates :default_template_name,
26 :inclusion => { :in => ->(_) { Page.custom_templates } },
27 :allow_nil => true,
28 :if => :default_template_name_changed?
29
25 # Class methods 30 # Class methods
26 31
27 # Returns a page for a given node. If no revision is supplied, it returns 32 # Returns a page for a given node. If no revision is supplied, it returns