pundit 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +77 -2
- data/lib/generators/pundit/install/templates/application_policy.rb +1 -1
- data/lib/pundit.rb +10 -0
- data/lib/pundit/version.rb +1 -1
- data/pundit.gemspec +2 -1
- data/spec/pundit_spec.rb +12 -0
- metadata +40 -24
data/README.md
CHANGED
@@ -98,7 +98,7 @@ and the given record. It then infers from the action name, that it should call
|
|
98
98
|
raise "not authorized" unless PostPolicy.new(current_user, @post).create?
|
99
99
|
```
|
100
100
|
|
101
|
-
You can pass a second
|
101
|
+
You can pass a second argument to `authorize` if the name of the permission you
|
102
102
|
want to check doesn't match the action name. For example:
|
103
103
|
|
104
104
|
``` ruby
|
@@ -133,6 +133,18 @@ class ApplicationController < ActionController::Base
|
|
133
133
|
end
|
134
134
|
```
|
135
135
|
|
136
|
+
Likewise, pundit also adds `verify_policy_scoped` to your controller. This
|
137
|
+
will raise an exception in the vein of `verify_authorized`. However it tracks
|
138
|
+
if `policy_scoped` is used instead of `authorize`. This is mostly useful for
|
139
|
+
controller actions like `index` which find collections with a scope and don't
|
140
|
+
authorize individual instances.
|
141
|
+
|
142
|
+
``` ruby
|
143
|
+
class ApplicationController < ActionController::Base
|
144
|
+
after_filter :verify_policy_scoped, :only => :index
|
145
|
+
end
|
146
|
+
```
|
147
|
+
|
136
148
|
## Scopes
|
137
149
|
|
138
150
|
Often, you will want to have some kind of view listing records which a
|
@@ -191,7 +203,7 @@ You can, and are encouraged to, use this method in views:
|
|
191
203
|
|
192
204
|
``` erb
|
193
205
|
<% policy_scope(@user.posts).each do |post| %>
|
194
|
-
<p><% link_to
|
206
|
+
<p><% link_to post.title, post_path(post) %></p>
|
195
207
|
<% end %>
|
196
208
|
```
|
197
209
|
|
@@ -270,6 +282,69 @@ Pundit.policy_scope(user, Post)
|
|
270
282
|
The bang methods will raise an exception if the policy does not exist, whereas
|
271
283
|
those without the bang will return nil.
|
272
284
|
|
285
|
+
## Pundit and strong_parameters
|
286
|
+
|
287
|
+
In Rails 3 using [strong_parameters](https://github.com/rails/strong_parameters)
|
288
|
+
or a standard Rails 4 setup, mass-assignment protection is handled in the controller.
|
289
|
+
Pundit helps you permit different attributes for different users.
|
290
|
+
|
291
|
+
```ruby
|
292
|
+
class PostPolicy < Struct.new(:user, :post)
|
293
|
+
def permitted_attributes
|
294
|
+
if user.admin? || user.owner_of?(post)
|
295
|
+
[:title, :body]
|
296
|
+
else
|
297
|
+
[:body]
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
class PostsController < ApplicationController
|
303
|
+
def update
|
304
|
+
# ...
|
305
|
+
if @post.update_attributes(post_attributes)
|
306
|
+
# ...
|
307
|
+
end
|
308
|
+
|
309
|
+
private
|
310
|
+
|
311
|
+
def post_attributes
|
312
|
+
params.require(:post).permit(policy(@post).permitted_attributes)
|
313
|
+
end
|
314
|
+
end
|
315
|
+
```
|
316
|
+
|
317
|
+
## RSpec
|
318
|
+
|
319
|
+
Pundit includes a mini-DSL for writing expressive tests for your policies in RSpec.
|
320
|
+
Require `pundit/rspec` in your `spec_helper.rb`:
|
321
|
+
|
322
|
+
``` ruby
|
323
|
+
require "pundit/rspec"
|
324
|
+
```
|
325
|
+
|
326
|
+
Then put your policy specs in `spec/policies`, and make them look somewhat like this:
|
327
|
+
|
328
|
+
``` ruby
|
329
|
+
describe PostPolicy do
|
330
|
+
subject { PostPolicy }
|
331
|
+
|
332
|
+
permissions :create? do
|
333
|
+
it "denies access if post is published" do
|
334
|
+
should_not permit(User.new(:admin => false), Post.new(:published => true))
|
335
|
+
end
|
336
|
+
|
337
|
+
it "grants access if post is published and user is an admin" do
|
338
|
+
should permit(User.new(:admin => true), Post.new(:published => true))
|
339
|
+
end
|
340
|
+
|
341
|
+
it "grants access if post is unpublished" do
|
342
|
+
should permit(User.new(:admin => false), Post.new(:published => false))
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
```
|
347
|
+
|
273
348
|
# License
|
274
349
|
|
275
350
|
Licensed under the MIT license, see the separate LICENSE.txt file.
|
data/lib/pundit.rb
CHANGED
@@ -35,12 +35,21 @@ module Pundit
|
|
35
35
|
helper_method :policy_scope
|
36
36
|
helper_method :policy
|
37
37
|
end
|
38
|
+
if respond_to?(:hide_action)
|
39
|
+
hide_action :authorize
|
40
|
+
hide_action :verify_authorized
|
41
|
+
hide_action :verify_policy_scoped
|
42
|
+
end
|
38
43
|
end
|
39
44
|
|
40
45
|
def verify_authorized
|
41
46
|
raise NotAuthorizedError unless @_policy_authorized
|
42
47
|
end
|
43
48
|
|
49
|
+
def verify_policy_scoped
|
50
|
+
raise NotAuthorizedError unless @_policy_scoped
|
51
|
+
end
|
52
|
+
|
44
53
|
def authorize(record, query=nil)
|
45
54
|
query ||= params[:action].to_s + "?"
|
46
55
|
@_policy_authorized = true
|
@@ -51,6 +60,7 @@ module Pundit
|
|
51
60
|
end
|
52
61
|
|
53
62
|
def policy_scope(scope)
|
63
|
+
@_policy_scoped = true
|
54
64
|
Pundit.policy_scope!(current_user, scope)
|
55
65
|
end
|
56
66
|
|
data/lib/pundit/version.rb
CHANGED
data/pundit.gemspec
CHANGED
@@ -17,7 +17,8 @@ Gem::Specification.new do |gem|
|
|
17
17
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
18
|
gem.require_paths = ["lib"]
|
19
19
|
|
20
|
-
gem.add_dependency "
|
20
|
+
gem.add_dependency "activesupport", ">= 3.0.0"
|
21
|
+
gem.add_development_dependency "activerecord", ">= 3.0.0"
|
21
22
|
gem.add_development_dependency "rspec", "~>2.0"
|
22
23
|
gem.add_development_dependency "pry"
|
23
24
|
gem.add_development_dependency "rake"
|
data/spec/pundit_spec.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "pundit"
|
2
2
|
require "pry"
|
3
|
+
require "active_support/core_ext"
|
3
4
|
require "active_model/naming"
|
4
5
|
|
5
6
|
class PostPolicy < Struct.new(:user, :post)
|
@@ -194,6 +195,17 @@ describe Pundit do
|
|
194
195
|
end
|
195
196
|
end
|
196
197
|
|
198
|
+
describe "#verify_policy_scoped" do
|
199
|
+
it "does nothing when policy_scope is used" do
|
200
|
+
controller.policy_scope(Post)
|
201
|
+
controller.verify_policy_scoped
|
202
|
+
end
|
203
|
+
|
204
|
+
it "raises an exception when policy_scope is not used" do
|
205
|
+
expect { controller.verify_policy_scoped }.to raise_error(Pundit::NotAuthorizedError)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
197
209
|
describe "#authorize" do
|
198
210
|
it "infers the policy name and authorized based on it" do
|
199
211
|
controller.authorize(post).should be_true
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pundit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,88 +10,104 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-06-18 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
|
-
name:
|
17
|
-
prerelease: false
|
16
|
+
name: activesupport
|
18
17
|
requirement: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
19
|
requirements:
|
20
|
-
- -
|
20
|
+
- - ! '>='
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
23
|
-
none: false
|
22
|
+
version: 3.0.0
|
24
23
|
type: :runtime
|
24
|
+
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
26
27
|
requirements:
|
27
|
-
- -
|
28
|
+
- - ! '>='
|
28
29
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
30
|
+
version: 3.0.0
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: activerecord
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
30
34
|
none: false
|
35
|
+
requirements:
|
36
|
+
- - ! '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: 3.0.0
|
39
|
+
type: :development
|
40
|
+
prerelease: false
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 3.0.0
|
31
47
|
- !ruby/object:Gem::Dependency
|
32
48
|
name: rspec
|
33
|
-
prerelease: false
|
34
49
|
requirement: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
35
51
|
requirements:
|
36
52
|
- - ~>
|
37
53
|
- !ruby/object:Gem::Version
|
38
54
|
version: '2.0'
|
39
|
-
none: false
|
40
55
|
type: :development
|
56
|
+
prerelease: false
|
41
57
|
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
42
59
|
requirements:
|
43
60
|
- - ~>
|
44
61
|
- !ruby/object:Gem::Version
|
45
62
|
version: '2.0'
|
46
|
-
none: false
|
47
63
|
- !ruby/object:Gem::Dependency
|
48
64
|
name: pry
|
49
|
-
prerelease: false
|
50
65
|
requirement: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
51
67
|
requirements:
|
52
68
|
- - ! '>='
|
53
69
|
- !ruby/object:Gem::Version
|
54
70
|
version: '0'
|
55
|
-
none: false
|
56
71
|
type: :development
|
72
|
+
prerelease: false
|
57
73
|
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
58
75
|
requirements:
|
59
76
|
- - ! '>='
|
60
77
|
- !ruby/object:Gem::Version
|
61
78
|
version: '0'
|
62
|
-
none: false
|
63
79
|
- !ruby/object:Gem::Dependency
|
64
80
|
name: rake
|
65
|
-
prerelease: false
|
66
81
|
requirement: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
67
83
|
requirements:
|
68
84
|
- - ! '>='
|
69
85
|
- !ruby/object:Gem::Version
|
70
86
|
version: '0'
|
71
|
-
none: false
|
72
87
|
type: :development
|
88
|
+
prerelease: false
|
73
89
|
version_requirements: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
74
91
|
requirements:
|
75
92
|
- - ! '>='
|
76
93
|
- !ruby/object:Gem::Version
|
77
94
|
version: '0'
|
78
|
-
none: false
|
79
95
|
- !ruby/object:Gem::Dependency
|
80
96
|
name: yard
|
81
|
-
prerelease: false
|
82
97
|
requirement: !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
83
99
|
requirements:
|
84
100
|
- - ! '>='
|
85
101
|
- !ruby/object:Gem::Version
|
86
102
|
version: '0'
|
87
|
-
none: false
|
88
103
|
type: :development
|
104
|
+
prerelease: false
|
89
105
|
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
90
107
|
requirements:
|
91
108
|
- - ! '>='
|
92
109
|
- !ruby/object:Gem::Version
|
93
110
|
version: '0'
|
94
|
-
none: false
|
95
111
|
description: Object oriented authorization for Rails applications
|
96
112
|
email:
|
97
113
|
- jonas.nicklas@gmail.com
|
@@ -125,20 +141,20 @@ rdoc_options: []
|
|
125
141
|
require_paths:
|
126
142
|
- lib
|
127
143
|
required_ruby_version: !ruby/object:Gem::Requirement
|
144
|
+
none: false
|
128
145
|
requirements:
|
129
146
|
- - ! '>='
|
130
147
|
- !ruby/object:Gem::Version
|
131
148
|
version: '0'
|
132
|
-
none: false
|
133
149
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
150
|
+
none: false
|
134
151
|
requirements:
|
135
152
|
- - ! '>='
|
136
153
|
- !ruby/object:Gem::Version
|
137
154
|
version: '0'
|
138
|
-
none: false
|
139
155
|
requirements: []
|
140
156
|
rubyforge_project:
|
141
|
-
rubygems_version: 1.8.
|
157
|
+
rubygems_version: 1.8.25
|
142
158
|
signing_key:
|
143
159
|
specification_version: 3
|
144
160
|
summary: OO authorization for Rails
|