permitted_params 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +20 -0
  3. data/README.md +75 -0
  4. data/lib/permitted_params.rb +106 -0
  5. metadata +46 -0
@@ -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.
@@ -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: []