stronger_parameters 2.7.0 → 2.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 44698724e39acaded3b387e94f5c2c6e83b88555
4
- data.tar.gz: 49aa2b14a5d4d9348c92e79c58310552e1dcdddc
3
+ metadata.gz: 0765498e474bdda1bbd86952faeb949bb8dee68d
4
+ data.tar.gz: 552b525dd274336986326681a21a334139bfbb25
5
5
  SHA512:
6
- metadata.gz: 98d2d44613d8c56f59e42143d344160ab4a7240cca977555e6576c7f391908d1b6e5e3c7ac7222f49eb8ced23095a370382dc47d5f76d186162ce9bbd6567bb3
7
- data.tar.gz: f83fb3b52e66157edb4a8d9c184d8e3b594d65d7285f3a355d3d9c93bd8c60f3a0464072795ac63e9bce25d59a152bf90edee491ee2d196dc8d5c5e8dd6a4b2d
6
+ metadata.gz: f1317839557a9579b3710b15c314de07a02766e6ac511a84ef3b98fe3dd8fe8dd5c00c442d3c952d67f0287cc57589944eac80e41fe2e2eaa27101f8bb612f06
7
+ data.tar.gz: 5abbe1cc2b805bf72ff355c4d79de711bb09c18aaa1a4e97aceaf13d4e7bfe8c321d890f7d118fcef69036fb19ee5613f86dce9cfa2065c7e1f5d6f6c47d8e74
data/README.md CHANGED
@@ -158,6 +158,68 @@ Just want to log violations in production:
158
158
  ActionController::Parameters.action_on_invalid_parameters = :log
159
159
  ```
160
160
 
161
+ ## Controller support (compatible with Rails 3 and 4, untested on Rails 5)
162
+
163
+ Include `PermittedParameters` into a controller to force the developer
164
+ to explicitly permit params for every action.
165
+
166
+ Examples:
167
+
168
+ ```ruby
169
+ class TestController < ApplicationController
170
+ include StrongerParameters::ControllerSupport::PermittedParameters
171
+
172
+ permitted_parameters :all, locale: Parameters.string # permit :locale in all actions for this controller
173
+
174
+ permitted_parameters :show, id: Parameters.integer
175
+ def show
176
+ end
177
+
178
+ permitted_parameters :create, topic: { forum: { id: Parameters.integer } }
179
+ def create
180
+ end
181
+
182
+ permitted_parameters :index, {} # no parameters permitted
183
+ def index
184
+ end
185
+
186
+ permitted_parameters :update, :anything # all parameters permitted, use when migrating old controllers/actions
187
+ def update
188
+ end
189
+ ```
190
+
191
+
192
+ ### Log only mode
193
+
194
+ Just want to log violations in production, let all params pass through:
195
+
196
+ ```ruby
197
+ class MyController < ApplicationController
198
+ log_unpermitted_parameters! if Rails.env.production? # Still want other environments to raise
199
+
200
+ permitted_parameters :update, user: { name: Parameters.string }
201
+ def update
202
+ end
203
+ end
204
+ ```
205
+
206
+ ### Notifying users about unpermitted params
207
+
208
+ Add headers to all requests that have unpermitted params:
209
+
210
+ ```Ruby
211
+ # config/application.rb
212
+ config.stronger_parameters_violation_header = 'X-StrongerParameters-API-Warn'
213
+ ```
214
+
215
+ ```shell
216
+ curl -I 'http://localhost/api/users/1.json' -X POST -d '{ "user": { "id": 1 } }'
217
+ => HTTP/1.1 200 OK
218
+ => ...
219
+ => X-StrongerParameters-API-Warn: Removed restricted keys ["user.id"] from parameters
220
+ ```
221
+
222
+
161
223
  ## Types
162
224
 
163
225
  | Syntax | (Simplified) Definition |
@@ -0,0 +1,159 @@
1
+ require 'stronger_parameters/constraints'
2
+
3
+ module StrongerParameters
4
+ module ControllerSupport
5
+ module PermittedParameters
6
+ def self.included(klass)
7
+ klass.extend ClassMethods
8
+ if klass.respond_to?(:before_action)
9
+ klass.before_action :permit_parameters
10
+ else
11
+ klass.before_filter :permit_parameters
12
+ end
13
+ end
14
+
15
+ class PermittedParametersHash < Hash
16
+ def initialize(other = nil)
17
+ super()
18
+ merge!(other) unless other.nil?
19
+ end
20
+
21
+ def merge!(other)
22
+ other.each do |key, value|
23
+ value = sugar(value)
24
+
25
+ if value.is_a?(StrongerParameters::Constraint)
26
+ self[key] = value
27
+ else
28
+ self[key] ||= self.class.new
29
+ self[key].merge!(value)
30
+ end
31
+ end
32
+
33
+ self
34
+ end
35
+
36
+ def merge(other)
37
+ dup.merge!(other)
38
+ end
39
+
40
+ private
41
+
42
+ def sugar(value)
43
+ case value
44
+ when Array
45
+ ActionController::Parameters.array(*value.map { |v| sugar(v) })
46
+ when Hash
47
+ constraints = value.each_with_object({}) do |(key, v), memo|
48
+ memo[key] = sugar(v)
49
+ end
50
+ ActionController::Parameters.map(constraints)
51
+ else
52
+ value
53
+ end
54
+ end
55
+ end
56
+
57
+ DEFAULT_PERMITTED = PermittedParametersHash.new(
58
+ controller: ActionController::Parameters.anything,
59
+ action: ActionController::Parameters.anything,
60
+ format: ActionController::Parameters.anything,
61
+ authenticity_token: ActionController::Parameters.string
62
+ )
63
+
64
+ module ClassMethods
65
+ def self.extended(base)
66
+ base.send :class_attribute, :log_unpermitted_parameters, instance_accessor: false
67
+ end
68
+
69
+ def log_unpermitted_parameters!
70
+ self.log_unpermitted_parameters = true
71
+ end
72
+
73
+ def permitted_parameters(action, permitted)
74
+ if permit_parameters[action] == :anything && permitted != :anything
75
+ raise ArgumentError, "#{self}/#{action} can not add to :anything"
76
+ end
77
+
78
+ permit_parameters.deep_merge!(action => permitted)
79
+ end
80
+
81
+ def permitted_parameters_for(action)
82
+ unless for_action = permit_parameters[action]
83
+ location = instance_method(action).source_location
84
+ raise KeyError, "Action #{action} for #{self} does not have any permitted parameters (#{location.join(":")})"
85
+ end
86
+ return :anything if for_action == :anything
87
+ permit_parameters[:all].merge(for_action)
88
+ end
89
+
90
+ private
91
+
92
+ def permit_parameters
93
+ @permit_parameters ||= if superclass.respond_to?(:permit_parameters, true)
94
+ superclass.send(:permit_parameters).deep_dup
95
+ else
96
+ { all: DEFAULT_PERMITTED.dup }
97
+ end
98
+ end
99
+ end
100
+
101
+ private
102
+
103
+ def permit_parameters
104
+ action = params[:action].to_sym
105
+ permitted = self.class.permitted_parameters_for(action)
106
+
107
+ if permitted == :anything
108
+ Rails.logger.warn("#{params[:controller]}/#{params[:action]} does not filter parameters")
109
+ return
110
+ end
111
+
112
+ permitted_params = without_invalid_parameter_exceptions { params.permit(permitted) }
113
+ unpermitted_keys = flat_keys(params) - flat_keys(permitted_params)
114
+ log_unpermitted = self.class.log_unpermitted_parameters
115
+
116
+ show_unpermitted_keys(unpermitted_keys, log_unpermitted)
117
+
118
+ return if log_unpermitted
119
+
120
+ params.replace(permitted_params)
121
+ params.permit!
122
+ request.params.replace(permitted_params)
123
+
124
+ logged_params = request.send(:parameter_filter).filter(permitted_params) # Removing passwords, etc
125
+ Rails.logger.info(" Filtered Parameters: #{logged_params.inspect}")
126
+ end
127
+
128
+ def show_unpermitted_keys(unpermitted_keys, log_unpermitted)
129
+ return if unpermitted_keys.empty?
130
+
131
+ log_prefix = (log_unpermitted ? 'Found' : 'Removed')
132
+ message = "#{log_prefix} restricted keys #{unpermitted_keys.inspect} from parameters according to permitted list"
133
+
134
+ header = Rails.configuration.stronger_parameters_violation_header if Rails.configuration.respond_to?(:stronger_parameters_violation_header)
135
+ response.headers[header] = message if response && header
136
+
137
+ Rails.logger.info(" #{message}")
138
+ end
139
+
140
+ def without_invalid_parameter_exceptions
141
+ if self.class.log_unpermitted_parameters
142
+ begin
143
+ old = ActionController::Parameters.action_on_invalid_parameters
144
+ ActionController::Parameters.action_on_invalid_parameters = :log
145
+ yield
146
+ ensure
147
+ ActionController::Parameters.action_on_invalid_parameters = old
148
+ end
149
+ else
150
+ yield
151
+ end
152
+ end
153
+
154
+ def flat_keys(hash)
155
+ hash.flat_map { |k, v| v.is_a?(Hash) ? flat_keys(v).map { |x| "#{k}.#{x}" }.push(k) : k }
156
+ end
157
+ end
158
+ end
159
+ end
@@ -1,3 +1,3 @@
1
1
  module StrongerParameters
2
- VERSION = '2.7.0'
2
+ VERSION = '2.8.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stronger_parameters
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.0
4
+ version: 2.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mick Staugaard
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-05-15 00:00:00.000000000 Z
11
+ date: 2017-05-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -168,6 +168,7 @@ files:
168
168
  - lib/stronger_parameters/constraints/nil_string_constraint.rb
169
169
  - lib/stronger_parameters/constraints/regexp_constraint.rb
170
170
  - lib/stronger_parameters/constraints/string_constraint.rb
171
+ - lib/stronger_parameters/controller_support/permitted_parameters.rb
171
172
  - lib/stronger_parameters/errors.rb
172
173
  - lib/stronger_parameters/parameters.rb
173
174
  - lib/stronger_parameters/version.rb
@@ -191,7 +192,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
191
192
  version: '0'
192
193
  requirements: []
193
194
  rubyforge_project:
194
- rubygems_version: 2.5.1
195
+ rubygems_version: 2.4.5.1
195
196
  signing_key:
196
197
  specification_version: 4
197
198
  summary: Type checking and type casting of parameters for Action Pack