Class: Json2sql::QueryPolicy

Inherits:
Object
  • Object
show all
Defined in:
lib/json2sql/query_policy.rb

Overview

Sanitizes a query input Hash before passing it to any Runner.

Parameters:

mode:   :allow (default) — only tables listed in `tables:` are accessible.
                           Tables absent from `tables:` are blocked entirely.
                           Empty `tables:` = no restriction.
        :deny            — all tables pass. After column filtering, tables
                           with no remaining accessible columns are removed.
                           Same rule applies to children and parents.
tables: Per-table configuration Hash (recursive):
  { table_name => { columns: [...],
                    children: { child_table => { columns: [...], ... } },
                    parents:  { parent_table => { columns: [...], ... } },
                    where: { "and" => { col => val } } } }
  columns:  column list — filtered by `mode` (allowed or denied).
            nil or absent = no column restriction for that table.
  children: nested hash of allowed/denied child tables with their own config.
            nil or absent = no restriction on children.
            In :deny mode: a child relation is removed only when all its
            columns are denied (result is empty array).
  parents:  nested hash of allowed/denied parent tables with their own config.
            nil or absent = no restriction on parents.
            In :deny mode: same rules as children.
  where:    server-side conditions merged into "and". Forced keys overwrite
            user-supplied values — primary IDOR guard.

Usage:

policy = Json2sql::QueryPolicy.new(
  mode:   :allow,
  tables: {
    orders: {
      columns:  %w[id total status],
      children: { order_items: { columns: %w[id price] } },
      parents:  { users: { columns: %w[id name] } },
      where:    { "and" => { "user_id" => 42 } }
    }
  }
)
safe_input = policy.apply(raw_params)
sql = Json2sql::SelectRunner.build(safe_input)

Instance Method Summary collapse

Constructor Details

#initialize(mode: :allow, tables: {}) ⇒ QueryPolicy

Returns a new instance of QueryPolicy.



46
47
48
49
50
51
# File 'lib/json2sql/query_policy.rb', line 46

def initialize(mode: :allow, tables: {})

  @mode = mode

  @tables = Json2sql.normalize(tables)
end

Instance Method Details

#apply(input) ⇒ Object

Returns a sanitized copy of input ready to pass to any Runner. Runners remain unmodified — they receive only the clean Hash.



56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/json2sql/query_policy.rb', line 56

def apply(input)

  input = Json2sql.normalize(input)
  
  filter_tables(input, @tables)

  input.each { |table, params| sanitize_table(params, @tables[table]) }

  input.reject! { |_, params| empty_columns?(params) }

  input
end