permitted_params 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +20 -0
- data/README.md +75 -0
- data/lib/permitted_params.rb +106 -0
- metadata +46 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bc6f54f9bb3a7230d920553c7defd0017d8bfae0
|
4
|
+
data.tar.gz: 440ab938bf3e56db771a9e39dea2e9d1931d7d87
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 855848a2a11215791b3eaa9984b6e6473f1567d83747c2908af312796dfd01b21c45da1d72b36a9aca0cbe86260ff24bc1b543679ebc8582c2afd5c5d2fc49c7
|
7
|
+
data.tar.gz: 2a528993c319fef9637f271ef437fec27b192111bbde5668d5b62f2224ddd7cdc3a3adbeb3017c23f7f76481c7d360e9e803645d47c1aa5d4dedace9aa85ef67
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 Amitree
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
permitted\_params
|
2
|
+
================
|
3
|
+
|
4
|
+
The move from **attr_accessible** to Strong Parameters arguably improved
|
5
|
+
security by increasing developers' awareness and visibility of which
|
6
|
+
attributes were whitelisted for mass assignment. But once you get
|
7
|
+
beyond toy applications, the standard practice of defining a
|
8
|
+
`foo_params` method in each `FooController` leads to a lot of duplicated
|
9
|
+
code, as you find yourself nesting the same structure in many different
|
10
|
+
places.
|
11
|
+
|
12
|
+
The `permitted_params` gem addresses this problem by allowing you to
|
13
|
+
specify the mass-assignment rules in a single location using a very
|
14
|
+
simple DSL.
|
15
|
+
|
16
|
+
This work was inspired by
|
17
|
+
[RailsCast #371](http://railscasts.com/episodes/371-strong-parameters).
|
18
|
+
Thanks, [ryanb](https://github.com/ryanb)!
|
19
|
+
|
20
|
+
Usage
|
21
|
+
-----
|
22
|
+
|
23
|
+
Add to your Gemfile:
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
gem 'permitted_params'
|
27
|
+
```
|
28
|
+
|
29
|
+
Then create an initializer, `config/initializers/permitted_params.rb`:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
PermittedParams.setup do |config|
|
33
|
+
config.user do
|
34
|
+
# We always permit username and password to be mass-assigned
|
35
|
+
scalar :username, :password
|
36
|
+
|
37
|
+
# email can be mass-assigned from create (but not from update)
|
38
|
+
scalar :email if action_is(:create)
|
39
|
+
|
40
|
+
# Only admins can change the is_admin flag. Note that we can call
|
41
|
+
# any controller methods (including current_user) from this scope.
|
42
|
+
scalar :is_admin if current_user.admin?
|
43
|
+
|
44
|
+
# We permit job_ids to be an array of scalar values
|
45
|
+
array :job_ids
|
46
|
+
|
47
|
+
# We permit person_attributes containing the whitelisted attributes
|
48
|
+
# of person (see definition below)
|
49
|
+
nested :person
|
50
|
+
end
|
51
|
+
|
52
|
+
config.person do
|
53
|
+
# Inheritance!
|
54
|
+
inherits :thing_with_name
|
55
|
+
end
|
56
|
+
|
57
|
+
config.thing_with_name do
|
58
|
+
scalar :name
|
59
|
+
end
|
60
|
+
end
|
61
|
+
```
|
62
|
+
|
63
|
+
Now in your controllers, you can simply write:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
@user = User.create(permitted_params.user)
|
67
|
+
```
|
68
|
+
|
69
|
+
or:
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
user_attributes = { ... some hash ... }
|
73
|
+
@user = User.create(permitted_params.user(user_attributes))
|
74
|
+
```
|
75
|
+
|
@@ -0,0 +1,106 @@
|
|
1
|
+
class PermittedParams < Struct.new(:params, :controller)
|
2
|
+
def method_missing(method, *args, &block)
|
3
|
+
if method.match /_attributes\z/
|
4
|
+
super
|
5
|
+
else
|
6
|
+
params_hash = args.length > 0 ? args[0] : params[method]
|
7
|
+
permit(params_hash, method)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def permit(params, as_type)
|
12
|
+
attrs_method = "#{as_type}_attributes".to_sym
|
13
|
+
permitted_params = send(attrs_method)
|
14
|
+
begin
|
15
|
+
params.try(:permit, *permitted_params)
|
16
|
+
rescue => e
|
17
|
+
Rails.logger.warn "Exception caught in PermittedParams"
|
18
|
+
Rails.logger.warn "params: #{params.inspect}"
|
19
|
+
Rails.logger.warn "permitted_params: #{permitted_params.inspect}"
|
20
|
+
raise e
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.define(symbol, &block)
|
25
|
+
define_method("#{symbol}_attributes") do
|
26
|
+
attrs = Attributes.new(self)
|
27
|
+
attrs.instance_eval(&block)
|
28
|
+
attrs.attributes
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.setup(&block)
|
33
|
+
block.call(Configurator.new)
|
34
|
+
end
|
35
|
+
|
36
|
+
class Configurator
|
37
|
+
def method_missing(method, *args, &block)
|
38
|
+
::PermittedParams.define(method, &block)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class Attributes
|
43
|
+
attr_accessor :attributes
|
44
|
+
|
45
|
+
def initialize(permitted_params)
|
46
|
+
@attributes = []
|
47
|
+
@permitted_params = permitted_params
|
48
|
+
end
|
49
|
+
|
50
|
+
def scalar(*attrs)
|
51
|
+
self.attributes += attrs
|
52
|
+
end
|
53
|
+
|
54
|
+
def array(*attrs)
|
55
|
+
attrs.each do |attr|
|
56
|
+
self.attributes << {attr => []}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def nested(*attrs_or_options)
|
61
|
+
attrs = attrs_or_options
|
62
|
+
if attrs_or_options.last.is_a? Hash
|
63
|
+
options = attrs_or_options.pop
|
64
|
+
else
|
65
|
+
options = {}
|
66
|
+
end
|
67
|
+
|
68
|
+
attrs.each do |attr|
|
69
|
+
# attr is like questions or questions_attributes
|
70
|
+
attr = attr.to_s.gsub(/_attributes\z/, '')
|
71
|
+
singular_attr = attr.singularize
|
72
|
+
|
73
|
+
child_attrs = @permitted_params.send("#{singular_attr}_attributes")
|
74
|
+
child_attrs << :id
|
75
|
+
child_attrs << :_destroy if options[:allow_destroy]
|
76
|
+
self.attributes << {"#{attr}_attributes".to_sym => child_attrs}
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def inherits(*other_attrs)
|
81
|
+
other_attrs.each do |other_attr|
|
82
|
+
self.attributes += @permitted_params.send("#{other_attr}_attributes")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def action_is(action_name)
|
87
|
+
@permitted_params.params[:action].to_sym == action_name.to_sym
|
88
|
+
end
|
89
|
+
|
90
|
+
def method_missing(method, *args, &block)
|
91
|
+
controller = @permitted_params.controller
|
92
|
+
if controller.respond_to? method
|
93
|
+
controller.send(method, *args, &block)
|
94
|
+
else
|
95
|
+
super
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
class ActionController::Base
|
102
|
+
protected
|
103
|
+
def permitted_params
|
104
|
+
PermittedParams.new(params, self)
|
105
|
+
end
|
106
|
+
end
|
metadata
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: permitted_params
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tony Novak
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-02-08 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Permitted Params
|
14
|
+
email: tony@amitree.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/permitted_params.rb
|
20
|
+
- LICENSE
|
21
|
+
- README.md
|
22
|
+
homepage: http://rubygems.org/gems/permitted_params
|
23
|
+
licenses:
|
24
|
+
- MIT
|
25
|
+
metadata: {}
|
26
|
+
post_install_message:
|
27
|
+
rdoc_options: []
|
28
|
+
require_paths:
|
29
|
+
- lib
|
30
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - '>='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
requirements: []
|
41
|
+
rubyforge_project:
|
42
|
+
rubygems_version: 2.0.3
|
43
|
+
signing_key:
|
44
|
+
specification_version: 4
|
45
|
+
summary: Permitted Params
|
46
|
+
test_files: []
|