Class: ActiveRecordSaferQuery::Checker::Whitelist

Inherits:
Object
  • Object
show all
Defined in:
lib/active_record_safer_query/checker.rb

Defined Under Namespace

Classes: Entry

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(entries) ⇒ Whitelist

Returns a new instance of Whitelist.



115
116
117
# File 'lib/active_record_safer_query/checker.rb', line 115

def initialize(entries)
  @entries = entries
end

Class Method Details

.default_paths(root) ⇒ Object



82
83
84
# File 'lib/active_record_safer_query/checker.rb', line 82

def self.default_paths(root)
  DEFAULT_WHITELIST_FILES.map { |path| root.join(path) }.select(&:file?)
end

.entries_from(path) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/active_record_safer_query/checker.rb', line 96

def self.entries_from(path)
  config = YAML.safe_load(path.read, permitted_classes: [], aliases: false) || {}
  entries = if config.is_a?(Array)
              config
            elsif config.is_a?(Hash)
              config.fetch('whitelist', config.fetch('allowlist', []))
            else
              raise ArgumentError, "whitelist file must contain a hash or array: #{path}"
            end

  unless entries.is_a?(Array)
    raise ArgumentError, "whitelist entries must be an array: #{path}"
  end

  entries.map { |entry| Entry.new(entry, path) }
rescue Psych::SyntaxError => e
  raise ArgumentError, "invalid whitelist YAML: #{path}: #{e.message}"
end

.explicit_paths(root, paths) ⇒ Object



86
87
88
89
90
91
92
93
94
# File 'lib/active_record_safer_query/checker.rb', line 86

def self.explicit_paths(root, paths)
  paths.map do |path|
    candidate = Pathname.new(path)
    absolute_path = candidate.absolute? ? candidate : root.join(candidate)
    raise ArgumentError, "whitelist file does not exist: #{path}" unless absolute_path.file?

    absolute_path
  end
end

.load(root:, paths:) ⇒ Object



75
76
77
78
79
80
# File 'lib/active_record_safer_query/checker.rb', line 75

def self.load(root:, paths:)
  config_paths = default_paths(root) + explicit_paths(root, paths)
  entries = config_paths.flat_map { |path| entries_from(path) }

  new(entries)
end

Instance Method Details

#match?(finding) ⇒ Boolean

Returns:

  • (Boolean)


119
120
121
# File 'lib/active_record_safer_query/checker.rb', line 119

def match?(finding)
  @entries.any? { |entry| entry.match?(finding) }
end