Add conditional filtering of param values
This commit is contained in:
parent
7384706871
commit
8eb23cef04
|
@ -45,6 +45,12 @@ Strip a parameter named `client_id` from a fuzzy path:
|
|||
use Rack::FilterParam, { param: :client_id, path: /\A\/oauth/ }
|
||||
```
|
||||
|
||||
Strip a parameter named `client_id` based on arbitrary logic:
|
||||
|
||||
```ruby
|
||||
use Rack::FilterParam, { param: :client_id, if: -> (value) { ... } }
|
||||
```
|
||||
|
||||
To filter multiple parameters, an array of parameters or options hashes can also be passed.
|
||||
|
||||
## Contributing
|
||||
|
|
|
@ -23,6 +23,8 @@ module Rack
|
|||
|
||||
def process_param(param)
|
||||
return unless path_matches?(param)
|
||||
return unless param_exists?(param)
|
||||
return unless affirmative_conditional?(param)
|
||||
|
||||
param = param[:param] if param.is_a?(Hash)
|
||||
|
||||
|
@ -43,6 +45,24 @@ module Rack
|
|||
false
|
||||
end
|
||||
|
||||
def param_exists?(param)
|
||||
param = param.is_a?(Hash) ? param[:param] : param
|
||||
params.has_key?(param.to_s)
|
||||
end
|
||||
|
||||
def params
|
||||
action_dispatch_parsed? ? action_dispatch_params : request.params
|
||||
end
|
||||
|
||||
def affirmative_conditional?(param)
|
||||
return true unless param.is_a?(Hash)
|
||||
|
||||
callable, param = param[:if], param[:param]
|
||||
return true if callable.nil?
|
||||
|
||||
callable.call(params[param.to_s])
|
||||
end
|
||||
|
||||
def delete_from_action_dispatch(param)
|
||||
action_dispatch_parsed? && !!action_dispatch_params.delete(param.to_s)
|
||||
end
|
||||
|
|
|
@ -36,6 +36,18 @@ RSpec.describe Rack::FilterParam do
|
|||
}
|
||||
end
|
||||
|
||||
shared_context 'middleware with conditional filter' do
|
||||
let(:app) {
|
||||
Rack::Builder.new do
|
||||
use Rack::FilterParam, {
|
||||
param: :x,
|
||||
if: ->(value) { value == 'yes' }
|
||||
}
|
||||
run -> (env) { [200, {}, ['OK']] }
|
||||
end.to_app
|
||||
}
|
||||
end
|
||||
|
||||
shared_examples 'core functionality' do
|
||||
context 'sending a param that is not expected to be filtered' do
|
||||
let(:params) { { 'a' => '1' } }
|
||||
|
@ -134,6 +146,35 @@ RSpec.describe Rack::FilterParam do
|
|||
end
|
||||
end
|
||||
|
||||
shared_examples 'conditional filtering' do
|
||||
context 'when the value should be filtered' do
|
||||
let(:params) { { 'x' => 'yes', 'y' => 'no' } }
|
||||
|
||||
it 'filters the param' do
|
||||
expect(params_to_test.keys).to eq ['y']
|
||||
end
|
||||
|
||||
it 'includes the param in `rack.filtered_params`' do
|
||||
expect(last_request.env['rack.filtered_params'])
|
||||
.to eq [['x', nil]]
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the value should not be filtered' do
|
||||
let(:params) { { 'x' => 'no', 'y' => 'no' } }
|
||||
|
||||
it 'does not filter the param' do
|
||||
expect(params_to_test)
|
||||
.to eq('x' => 'no', 'y' => 'no')
|
||||
end
|
||||
|
||||
it 'does not include the param in `rack.filtered_params`' do
|
||||
expect(last_request.env['rack.filtered_params'])
|
||||
.to be nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'GET request' do
|
||||
let(:method) { :get }
|
||||
|
||||
|
@ -146,6 +187,11 @@ RSpec.describe Rack::FilterParam do
|
|||
include_context 'middleware with filtered paths'
|
||||
include_examples 'path filtering'
|
||||
end
|
||||
|
||||
describe 'conditional filtering' do
|
||||
include_context 'middleware with conditional filter'
|
||||
include_examples 'conditional filtering'
|
||||
end
|
||||
end
|
||||
|
||||
context 'POST request' do
|
||||
|
@ -166,6 +212,11 @@ RSpec.describe Rack::FilterParam do
|
|||
include_context 'middleware with filtered paths'
|
||||
include_examples 'path filtering'
|
||||
end
|
||||
|
||||
describe 'conditional filtering' do
|
||||
include_context 'middleware with conditional filter'
|
||||
include_examples 'conditional filtering'
|
||||
end
|
||||
end
|
||||
|
||||
context 'Request previously parsed by ActionDispatch::ParamsParser' do
|
||||
|
@ -186,5 +237,10 @@ RSpec.describe Rack::FilterParam do
|
|||
include_context 'middleware with filtered paths'
|
||||
include_examples 'path filtering'
|
||||
end
|
||||
|
||||
describe 'conditional filtering' do
|
||||
include_context 'middleware with conditional filter'
|
||||
include_examples 'conditional filtering'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue