Skip to content
This repository was archived by the owner on Aug 17, 2017. It is now read-only.

Add regex support for permitting params #21

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ You can also use permit on nested parameters, like:

Thanks to Nick Kallen for the permit idea!

You can also easily permit similarly named parameters using regular expressions:

params.permit(/^company_\d$/ => [:name, :location, /^quarter_\d_profit$/])

== Todos

* Automatically permit parameters coming from a signed form [Yehuda]
Expand Down
24 changes: 21 additions & 3 deletions lib/action_controller/parameters.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,25 @@ def permit(*filters)
case filter
when Symbol then
params[filter] = self[filter] if has_key?(filter)
when Regexp then
self.each do |key, value|
params[key] = self[key] if key =~ filter
end
when Hash then
self.slice(*filter.keys).each do |key, value|
expanded_filter = expand_regexp_filters(filter)

self.slice(*expanded_filter.keys).each do |key, value|
return unless value

key = key.to_sym

params[key] = each_element(value) do |value|
# filters are a Hash, so we expect value to be a Hash too
next if filter.is_a?(Hash) && !value.is_a?(Hash)
next if expanded_filter.is_a?(Hash) && !value.is_a?(Hash)

value = self.class.new(value) if !value.respond_to?(:permit)

value.permit(*Array.wrap(filter[key]))
value.permit(*Array.wrap(expanded_filter[key]))
end
end
end
Expand Down Expand Up @@ -97,6 +103,18 @@ def each_element(object)
yield object
end
end

def expand_regexp_filters(filter)
expanded_filter = filter.select{|k,v| !k.is_a?(Regexp) }
filter.each do |filter_key, filter_value|
if filter_key.is_a?(Regexp)
self.select {|k,v| k =~ filter_key }.each do |k, v|
expanded_filter[k] = filter_value
end
end
end
self.class.new(expanded_filter)
end
end

module StrongParameters
Expand Down
36 changes: 36 additions & 0 deletions test/regexp_parameters_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
require 'test_helper'
require 'action_controller/parameters'

class RegexpParametersTest < ActiveSupport::TestCase
test "permitted parameters defined by regexp" do
params = ActionController::Parameters.new({
:object_1 => {
:safe_param_1 => 'value',
:safe_param_2 => 'value',
:malicious => 'haxored!'
},
:object_2 => {
:safe_param_1 => 'value',
:safe_param_2 => 'value',
:malicious => 'haxored!'
},
:bad_object => {
:param => 'value'
}
})

expected = ActionController::Parameters.new({
:object_1 => {
:safe_param_1 => 'value',
:safe_param_2 => 'value'
},
:object_2 => {
:safe_param_1 => 'value',
:safe_param_2 => 'value'
}
})

permitted = params.permit(/^object_\d$/ => [/^safe_param_\d$/])
assert_equal expected, permitted
end
end