permit 0.9.0
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/.gitignore +5 -0
- data/.yardopts +3 -0
- data/MIT-LICENSE +20 -0
- data/README.mkd +238 -0
- data/Rakefile +69 -0
- data/VERSION.yml +5 -0
- data/generators/permit/USAGE +40 -0
- data/generators/permit/permit_generator.rb +25 -0
- data/generators/permit/templates/authorization.rb +2 -0
- data/generators/permit/templates/initializer.rb +37 -0
- data/generators/permit/templates/migration.rb +28 -0
- data/generators/permit/templates/role.rb +2 -0
- data/init.rb +1 -0
- data/install.rb +1 -0
- data/lib/models/association.rb +89 -0
- data/lib/models/authorizable.rb +31 -0
- data/lib/models/authorization.rb +54 -0
- data/lib/models/person.rb +148 -0
- data/lib/models/role.rb +59 -0
- data/lib/permit/controller.rb +132 -0
- data/lib/permit/permit_rule.rb +198 -0
- data/lib/permit/permit_rules.rb +141 -0
- data/lib/permit/support.rb +67 -0
- data/lib/permit.rb +134 -0
- data/permit.gemspec +91 -0
- data/rails/init.rb +7 -0
- data/spec/models/alternate_models_spec.rb +54 -0
- data/spec/models/authorizable_spec.rb +78 -0
- data/spec/models/authorization_spec.rb +77 -0
- data/spec/models/person_spec.rb +278 -0
- data/spec/models/role_spec.rb +121 -0
- data/spec/permit/controller_spec.rb +308 -0
- data/spec/permit/permit_rule_spec.rb +452 -0
- data/spec/permit/permit_rules_spec.rb +273 -0
- data/spec/permit_spec.rb +58 -0
- data/spec/spec_helper.rb +73 -0
- data/spec/support/helpers.rb +13 -0
- data/spec/support/models.rb +38 -0
- data/spec/support/permits_controller.rb +7 -0
- data/tasks/permit_tasks.rake +4 -0
- data/uninstall.rb +1 -0
- metadata +107 -0
@@ -0,0 +1,278 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
module Permit::Specs
|
4
|
+
describe "Permit::Models::Extensions::permit_person" do
|
5
|
+
|
6
|
+
context "created instance methods" do
|
7
|
+
it "#authorizations should have all of the person's current authorizations" do
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
context "for checking authorizations" do
|
12
|
+
before do
|
13
|
+
@bob = Person.create :name => "bob"
|
14
|
+
@tom = Person.create :name => "tom"
|
15
|
+
@hotness = Project.create(:name => "hotness")
|
16
|
+
@maintenance = Project.create(:name => "maintenance")
|
17
|
+
Role.create :key => :site_admin, :name => 'site admin', :authorize_resource => false, :requires_resource => false
|
18
|
+
new_authz @bob, :site_admin, nil
|
19
|
+
new_authz @bob, :admin, @maintenance
|
20
|
+
new_authz @bob, :developer, @maintenance
|
21
|
+
new_authz @bob, :team_lead, @hotness
|
22
|
+
|
23
|
+
new_authz @tom, :admin, @hotness
|
24
|
+
end
|
25
|
+
|
26
|
+
context "#authorized?" do
|
27
|
+
it "should return true if the person has any of the roles for the resource" do
|
28
|
+
@bob.should be_authorized(:admin, @maintenance)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should return true if the person has any of the resources for the passed in Role object" do
|
32
|
+
r = Role.find_by_key 'admin'
|
33
|
+
@bob.should be_authorized(r, @maintenance)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should return false if the person does not have any of the roles for the resource" do
|
37
|
+
@bob.should_not be_authorized(:admin, @hotness)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should return false for a role that doesn't exist" do
|
41
|
+
@bob.should_not be_authorized(:lead_monkey_tech, @maintenance)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should return true if the person has a nil resource authorization for a role" do
|
45
|
+
@bob.should be_authorized(:site_admin, nil)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "#authorized_all?" do
|
50
|
+
it "should return true if the person matches all of the roles for the resource" do
|
51
|
+
@bob.should be_authorized_all([:admin, :developer], @maintenance)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should return true if the person matches all of the roles for the resource when a Role object is passed" do
|
55
|
+
r = Role.find_by_key 'developer'
|
56
|
+
@bob.should be_authorized_all([r, :admin], @maintenance)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should return false if the person does not match all of the roles for the resource" do
|
60
|
+
@tom.should_not be_authorized_all([:admin, :team_lead], @hotness)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should return false if one of the roles does not exist" do
|
64
|
+
@tom.should_not be_authorized_all([:admin, :slinky_analyst], @hotness)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "#authorize" do
|
70
|
+
before do
|
71
|
+
@sam = Person.create! :name => 'sam'
|
72
|
+
@superapp = Project.create! :name => 'superapp'
|
73
|
+
@dev = role(:developer)
|
74
|
+
@tester = role(:tester)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should authorize the person for all of the given roles" do
|
78
|
+
@sam.authorize([:developer, :tester], @superapp)
|
79
|
+
@sam.should have(2).authorizations
|
80
|
+
@sam.authorizations[0].role.key.should == 'developer'
|
81
|
+
@sam.authorizations[1].role.key.should == 'tester'
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should authorize the person if given a role object" do
|
85
|
+
@sam.authorize([:developer, @tester], @superapp)
|
86
|
+
@sam.should have(2).authorizations
|
87
|
+
@sam.authorizations[0].role.key.should == 'developer'
|
88
|
+
@sam.authorizations[1].role.key.should == 'tester'
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should authorize a person for a nil resource" do
|
92
|
+
@noresource = Role.create :key => 'noresource', :name => 'noresource', :requires_resource => false, :authorize_resource => false
|
93
|
+
@sam.authorize(@noresource, nil)
|
94
|
+
@sam.should have(1).authorization
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should not duplicate an existing authorization for a person" do
|
98
|
+
@sam.authorize(:developer, @superapp)
|
99
|
+
@sam.authorize(:developer, @superapp)
|
100
|
+
@sam.should have(1).authorization
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should raise an error if the authorization is invalid" do
|
104
|
+
lambda {
|
105
|
+
@sam.authorize(:chief_donkey_inspector, @superapp)
|
106
|
+
}.should raise_error(ActiveRecord::RecordInvalid, "Validation failed: Role can't be blank")
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should return true if authorization is successful" do
|
110
|
+
@sam.authorize(:tester, @superapp).should be_true
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should return true even if there are no authorizations to grant" do
|
114
|
+
@sam.authorize(:tester, @superapp)
|
115
|
+
@sam.authorize(:tester, @superapp).should be_true
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should perform the authorizations in a transaction" do
|
119
|
+
# TODO: Find a way to spec. Can't seem to be done with sqlite because
|
120
|
+
# of nested transactions not being allowed?
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context "revocations" do
|
125
|
+
before do
|
126
|
+
@sam = Person.create! :name => 'sam'
|
127
|
+
@superapp = Project.create! :name => 'superapp'
|
128
|
+
@lameapp = Project.create! :name => 'lameapp'
|
129
|
+
@dev = role(:developer)
|
130
|
+
@tester = role(:tester)
|
131
|
+
|
132
|
+
@sam.authorize [@dev, @tester], @superapp
|
133
|
+
@sam.authorize @dev, @lameapp
|
134
|
+
end
|
135
|
+
|
136
|
+
shared_examples_for "all revocations" do
|
137
|
+
it "should revoke all of the given roles on the given resource from the current person" do
|
138
|
+
@sam.send @revoke_method, [:developer, :tester], @superapp
|
139
|
+
@sam.should have(1).authorization
|
140
|
+
@sam.authorizations[0].resource.should == @lameapp
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should revoke an authorization when given a role object" do
|
144
|
+
@sam.send @revoke_method, [@dev, @tester], @superapp
|
145
|
+
@sam.should have(1).authorization
|
146
|
+
@sam.authorizations[0].resource.should == @lameapp
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should not revoke an identical authorization for another person" do
|
150
|
+
@bob = Person.create! :name => 'bob'
|
151
|
+
@bob.authorize :developer, @superapp
|
152
|
+
|
153
|
+
@sam.send @revoke_method, :developer, @superapp
|
154
|
+
@bob.should have(1).authorization
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should revoke an authorization with a nil resource" do
|
158
|
+
@noresource = Role.create :key => 'noresource', :name => 'noresource', :requires_resource => false, :authorize_resource => false
|
159
|
+
@sam.authorize(@noresource, nil)
|
160
|
+
|
161
|
+
@sam.send @revoke_method, :noresource, nil
|
162
|
+
@sam.should_not be_authorized(:noresource, nil)
|
163
|
+
end
|
164
|
+
|
165
|
+
it "should raise an error if a revocation fails" do
|
166
|
+
Authorization.stub!(@ar_remove_method).and_raise(ActiveRecord::ActiveRecordError)
|
167
|
+
lambda {
|
168
|
+
@sam.send @revoke_method, :developer, @superapp
|
169
|
+
}.should raise_error(ActiveRecord::ActiveRecordError)
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should perform revocations in a transaction" do
|
173
|
+
# TODO: Find a way to spec. Can't seem to be done with sqlite
|
174
|
+
# because of nested transactions not being allowed?
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
context "#revoke" do
|
180
|
+
before do
|
181
|
+
@revoke_method = :revoke
|
182
|
+
@ar_remove_method = :destroy_all
|
183
|
+
end
|
184
|
+
|
185
|
+
it_should_behave_like "all revocations"
|
186
|
+
|
187
|
+
it "should return the revoked roles" do
|
188
|
+
revoked = @sam.revoke([:developer, :tester], @superapp)
|
189
|
+
revoked.size.should == 2
|
190
|
+
revoked[0].resource.should == @superapp
|
191
|
+
revoked[0].role.should == @dev
|
192
|
+
revoked[1].resource.should == @superapp
|
193
|
+
revoked[1].role.should == @tester
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
context "#revoke!" do
|
198
|
+
before do
|
199
|
+
@revoke_method = :revoke!
|
200
|
+
@ar_remove_method = :delete_all
|
201
|
+
end
|
202
|
+
|
203
|
+
it_should_behave_like "all revocations"
|
204
|
+
|
205
|
+
it "should return the number of revoked roles" do
|
206
|
+
@sam.revoke!([:developer, :tester], @superapp).should == 2
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
context "for finding authorizations for a given resource" do
|
212
|
+
before do
|
213
|
+
@bob = Person.create :name => "bob"
|
214
|
+
@tom = Person.create :name => "tom"
|
215
|
+
@hotness = Project.create(:name => "hotness")
|
216
|
+
@maintenance = Project.create(:name => "maintenance")
|
217
|
+
Role.create :key => :site_admin, :name => 'site admin', :authorize_resource => false, :requires_resource => false
|
218
|
+
new_authz @bob, :site_admin, nil
|
219
|
+
new_authz @bob, :admin, @maintenance
|
220
|
+
new_authz @bob, :developer, @maintenance
|
221
|
+
new_authz @bob, :team_lead, @hotness
|
222
|
+
|
223
|
+
new_authz @tom, :admin, @hotness
|
224
|
+
end
|
225
|
+
|
226
|
+
it "#authorizations.roles_for should return the roles the current person has for the resource" do
|
227
|
+
roles = @bob.authorizations.roles_for @maintenance
|
228
|
+
roles.should have(2).items
|
229
|
+
roles[0].key.should == 'admin'
|
230
|
+
roles[1].key.should == 'developer'
|
231
|
+
end
|
232
|
+
|
233
|
+
it "#authorizations.for should return the authorizations the current person has for the resource" do
|
234
|
+
authz = @bob.authorizations.for @maintenance
|
235
|
+
authz.should have(2).items
|
236
|
+
authz[0].role.key.should == 'admin'
|
237
|
+
authz[0].resource.should == @maintenance
|
238
|
+
authz[1].role.key.should == 'developer'
|
239
|
+
authz[1].resource.should == @maintenance
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
context "for finding authorizations for given roles" do
|
244
|
+
before do
|
245
|
+
@bob = Person.create :name => "bob"
|
246
|
+
@tom = Person.create :name => "tom"
|
247
|
+
@hotness = Project.create(:name => "hotness")
|
248
|
+
@maintenance = Project.create(:name => "maintenance")
|
249
|
+
Role.create :key => :site_admin, :name => 'site admin', :authorize_resource => false, :requires_resource => false
|
250
|
+
new_authz @bob, :site_admin, nil
|
251
|
+
new_authz @bob, :admin, @maintenance
|
252
|
+
new_authz @bob, :developer, @maintenance
|
253
|
+
new_authz @bob, :team_lead, @hotness
|
254
|
+
new_authz @tom, :admin, @hotness
|
255
|
+
end
|
256
|
+
|
257
|
+
it "#authorizations.resources_as should return the roles the current person has for the resource" do
|
258
|
+
resources = @bob.authorizations.resources_as [:admin, :team_lead]
|
259
|
+
resources.should have(2).items
|
260
|
+
resources[0].should == @maintenance
|
261
|
+
resources[1].should == @hotness
|
262
|
+
end
|
263
|
+
|
264
|
+
it "#authorizations.resources_as should not return duplicates" do
|
265
|
+
resources = @bob.authorizations.resources_as [:admin, :developer]
|
266
|
+
resources.should have(1).item
|
267
|
+
end
|
268
|
+
|
269
|
+
it "#authorizations_as should return the authorizations the current person has for the given roles" do
|
270
|
+
authz = @bob.authorizations.as :admin
|
271
|
+
authz.should have(1).item
|
272
|
+
authz[0].role.key.should == 'admin'
|
273
|
+
authz[0].resource.should == @maintenance
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
module Permit::Specs
|
4
|
+
describe "Permit::Models::Role#permit_role" do
|
5
|
+
describe "validations" do
|
6
|
+
it "should be invalid without a key" do
|
7
|
+
r = Role.new
|
8
|
+
r.should_not be_valid
|
9
|
+
r.should have(1).error_on(:key)
|
10
|
+
r.errors[:key].should == "can't be blank"
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should be invalid with a non-unique key" do
|
14
|
+
Role.create :key => :test_role, :name => 'Test Role'
|
15
|
+
r = Role.new :key => 'test_role'
|
16
|
+
r.should_not be_valid
|
17
|
+
r.should have(1).error_on(:key)
|
18
|
+
r.errors[:key].should == "has already been taken"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should be invalid without a name" do
|
22
|
+
r = Role.new
|
23
|
+
r.should_not be_valid
|
24
|
+
r.should have(1).error_on(:name)
|
25
|
+
r.errors[:name].should == "can't be blank"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should be invalid if it requires a resource but doesn't allow resources" do
|
29
|
+
r = Role.new
|
30
|
+
r.authorize_resource = false
|
31
|
+
r.requires_resource = true
|
32
|
+
r.should_not be_valid
|
33
|
+
r.should have(1).error_on(:requires_resource)
|
34
|
+
r.errors[:requires_resource].should == "cannot be true if authorize_resource is false"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should be valid with valid attributes" do
|
38
|
+
r = Role.new
|
39
|
+
r.key = :project_admin
|
40
|
+
r.name = "Project Administrator"
|
41
|
+
r.should be_valid
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "resource requirement" do
|
46
|
+
it "should default authorize_resource to true" do
|
47
|
+
r = Role.new
|
48
|
+
r.authorize_resource.should be_true
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should default requires_resource to true" do
|
52
|
+
r = Role.new
|
53
|
+
r.requires_resource.should be_true
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "created instance methods" do
|
58
|
+
describe "setting the key" do
|
59
|
+
it "should convert the key to lower-case" do
|
60
|
+
r = Role.new
|
61
|
+
r.key = "Some_Role!"
|
62
|
+
r.key.should == "some_role!"
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should convert the key from a symbol to a string" do
|
66
|
+
r = Role.new
|
67
|
+
r.key = :symbol_role
|
68
|
+
r.key.should == "symbol_role"
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should not fail when given nil" do
|
72
|
+
r = Role.new :key => 'bob'
|
73
|
+
r.key = nil
|
74
|
+
r.key.should be_nil
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
context "for finding authorizations for a given resource" do
|
80
|
+
before do
|
81
|
+
@bob = Person.create :name => "bob"
|
82
|
+
@tom = Person.create :name => "tom"
|
83
|
+
@hotness = Project.create(:name => "hotness")
|
84
|
+
@maintenance = Project.create(:name => "maintenance")
|
85
|
+
Role.create :key => :site_admin, :name => 'site admin', :authorize_resource => false, :requires_resource => false
|
86
|
+
@admin = Role.create :key => 'admin', :name => 'admin'
|
87
|
+
new_authz @bob, :site_admin, nil
|
88
|
+
new_authz @bob, :developer, @maintenance
|
89
|
+
new_authz @bob, :team_lead, @hotness
|
90
|
+
@bob.authorize @admin, @maintenance
|
91
|
+
|
92
|
+
@tom.authorize @admin, @hotness
|
93
|
+
end
|
94
|
+
|
95
|
+
it "#authorizations.people_for should return the people authorized for the resource on the current role" do
|
96
|
+
@jack = Person.create :name => 'jack'
|
97
|
+
@jack.authorize @admin, @maintenance
|
98
|
+
people = @admin.authorizations.people_for @maintenance
|
99
|
+
people.should have(2).items
|
100
|
+
people[0].should == @bob
|
101
|
+
people[1].should == @jack
|
102
|
+
end
|
103
|
+
|
104
|
+
it "#authorizations.for should return the authorizations the current role has for the resource" do
|
105
|
+
authz = @admin.authorizations.for @maintenance
|
106
|
+
authz.should have(1).items
|
107
|
+
authz[0].role.key.should == 'admin'
|
108
|
+
authz[0].person.should == @bob
|
109
|
+
authz[0].resource.should == @maintenance
|
110
|
+
end
|
111
|
+
|
112
|
+
it "#authorizations should have all authorizations that apply to the current role" do
|
113
|
+
@admin.authorizations.should have(2).items
|
114
|
+
@admin.authorizations[0].person.should == @bob
|
115
|
+
@admin.authorizations[1].person.should == @tom
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,308 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
module Permit::Specs
|
4
|
+
class EmployeeAdmin < ActiveRecord::Base
|
5
|
+
end
|
6
|
+
|
7
|
+
class BaseController < ActionController::Base
|
8
|
+
include Permit::ControllerExtensions
|
9
|
+
|
10
|
+
def current_person; end
|
11
|
+
end
|
12
|
+
|
13
|
+
class ProjectsController < BaseController
|
14
|
+
permit :some_option => true do
|
15
|
+
deny :guest, :from => :all
|
16
|
+
allow :person, :to => :all
|
17
|
+
end
|
18
|
+
|
19
|
+
before_filter :something_after_permit
|
20
|
+
|
21
|
+
def index
|
22
|
+
render :text => 'index called'
|
23
|
+
end
|
24
|
+
|
25
|
+
def show
|
26
|
+
render :text => 'show called'
|
27
|
+
end
|
28
|
+
|
29
|
+
def something_after_permit; end
|
30
|
+
|
31
|
+
def access_denied
|
32
|
+
render :text => 'guest denied', :status => 401
|
33
|
+
end
|
34
|
+
|
35
|
+
#These methods are just to aid in testing
|
36
|
+
def pub_authorized?(roles, resource)
|
37
|
+
authorized?(roles, resource)
|
38
|
+
end
|
39
|
+
|
40
|
+
def pub_allowed?(roles, options = {})
|
41
|
+
allowed?(roles, options)
|
42
|
+
end
|
43
|
+
|
44
|
+
def pub_denied?(roles, options = {})
|
45
|
+
denied?(roles, options)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class TeamsController < BaseController
|
50
|
+
permit :default_access => :allow do
|
51
|
+
deny :guest, :from => :index
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class DefinedDenialsController < ActionController::Base
|
56
|
+
include Permit::ControllerExtensions
|
57
|
+
|
58
|
+
permit do
|
59
|
+
deny :everyone, :from => :all
|
60
|
+
end
|
61
|
+
|
62
|
+
def index;end
|
63
|
+
|
64
|
+
def current_person; end
|
65
|
+
|
66
|
+
def access_denied
|
67
|
+
render :text => 'base denied message', :status => 401
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
ActionController::Routing::Routes.draw do |map|
|
72
|
+
map.namespace :permit do |p|
|
73
|
+
p.namespace :specs do |s|
|
74
|
+
s.resources :projects
|
75
|
+
s.resources :defined_denials
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe ControllerExtensions, :type => :controller do
|
81
|
+
controller_name 'permit/specs/projects'
|
82
|
+
|
83
|
+
describe "#permit" do
|
84
|
+
it "should create the rules in permit_rules" do
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should send any given options to permit_rules" do
|
88
|
+
controller.permit_rules.options[:some_option].should be_true
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should have the same rules as another instance of the same controller" do
|
92
|
+
controller.permit_rules.should be(ProjectsController.new.permit_rules)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should not have the same rules as another controller" do
|
96
|
+
teams = TeamsController.new
|
97
|
+
teams.permit_rules.action_allow_rules.should have(0).item
|
98
|
+
teams.permit_rules.action_deny_rules.should have(1).item
|
99
|
+
team_deny_rule = teams.permit_rules.action_deny_rules[:index][0]
|
100
|
+
team_deny_rule.roles.should == [:guest]
|
101
|
+
|
102
|
+
controller.permit_rules.action_allow_rules.should have(1).item
|
103
|
+
controller.permit_rules.action_deny_rules.should have(1).item
|
104
|
+
|
105
|
+
project_allow_rule = controller.permit_rules.action_allow_rules[:all][0]
|
106
|
+
project_allow_rule.roles.should == [:person]
|
107
|
+
|
108
|
+
project_deny_rule = controller.permit_rules.action_deny_rules[:all][0]
|
109
|
+
project_deny_rule.roles.should == [:guest]
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe "checking authorizations" do
|
114
|
+
it "should properly call @@permit_rules#permitted? when checking authorizations" do
|
115
|
+
guest = Guest.new
|
116
|
+
controller.stub!(:current_person).and_return(guest)
|
117
|
+
controller.permit_rules.should_receive(:permitted?).with(guest, :show, instance_of(Binding)).and_return(false)
|
118
|
+
get :show, :id => 1
|
119
|
+
end
|
120
|
+
|
121
|
+
describe "when authorized" do
|
122
|
+
it "should call the action" do
|
123
|
+
controller.stub!(:current_person).and_return(Person.create :name => 'bob')
|
124
|
+
get :index
|
125
|
+
response.body.should == 'index called'
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe "when not authorized" do
|
130
|
+
before do
|
131
|
+
controller.stub!(:current_person).and_return(Guest.new)
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should stop the before_filter chain if not authorized" do
|
135
|
+
controller.should_not_receive(:something_after_permit)
|
136
|
+
get :index
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should not call the action" do
|
140
|
+
controller.should_not_receive(:index)
|
141
|
+
get :index
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should have a 401 status" do
|
145
|
+
get :index
|
146
|
+
response.status.should == '401 Unauthorized'
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should render a 401 error" do
|
150
|
+
get :index
|
151
|
+
response.body.should == "guest denied"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe "getting the authorization subject" do
|
156
|
+
it "should use the config value when present" do
|
157
|
+
Permit::Config.stub!(:controller_subject_method).and_return(:logged_user)
|
158
|
+
controller.should_receive(:logged_user).and_return(Guest.new)
|
159
|
+
get :index
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should infer the method name from the config person_class" do
|
163
|
+
Permit::Config.stub!(:person_class).and_return(Permit::Specs::EmployeeAdmin)
|
164
|
+
controller.should_receive(:current_employee_admin).and_return(Guest.new)
|
165
|
+
get :index
|
166
|
+
end
|
167
|
+
|
168
|
+
it "should default to 'current_person'" do
|
169
|
+
Permit::Config.stub!(:controller_subject_method).and_return(nil)
|
170
|
+
Permit::Config.stub!(:person_class).and_return(nil)
|
171
|
+
controller.should_receive(:current_person).and_return(Guest.new)
|
172
|
+
get :index
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
describe "helpers" do
|
178
|
+
describe "#authorized?" do
|
179
|
+
context "for a guest" do
|
180
|
+
before {controller.stub!(:current_person).and_return(Guest.new)}
|
181
|
+
|
182
|
+
it "should return false for a guest" do
|
183
|
+
controller.pub_authorized?(:some_role, :any).should be_false
|
184
|
+
end
|
185
|
+
|
186
|
+
it "should not try to call #authorized? on the guest" do
|
187
|
+
controller.current_person.should_not_receive(:authorized?)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
context "for an authenticated person" do
|
192
|
+
before do
|
193
|
+
@bob = Person.create! :name => 'bob'
|
194
|
+
new_authz @bob, :admin
|
195
|
+
|
196
|
+
controller.stub!(:current_person).and_return(@bob)
|
197
|
+
end
|
198
|
+
|
199
|
+
it "should properly call #authorized? on the person" do
|
200
|
+
@bob.should_receive(:authorized?).with(:admin, :any)
|
201
|
+
controller.pub_authorized?(:admin, :any)
|
202
|
+
end
|
203
|
+
|
204
|
+
it "should return false if the person is not authorized" do
|
205
|
+
controller.pub_authorized?(:monkey_tech, nil).should be_false
|
206
|
+
end
|
207
|
+
|
208
|
+
it "should return true if the person is authorized" do
|
209
|
+
controller.pub_authorized?(:admin, :any).should be_true
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
describe "#allowed?" do
|
215
|
+
it "should properly build the rule" do
|
216
|
+
controller.stub!(:current_person).and_return(Guest.new)
|
217
|
+
rule = PermitRule.new :admin, :on => :team
|
218
|
+
PermitRule.should_receive(:new).with(:admin, hash_including(:on => :team)).and_return(rule)
|
219
|
+
controller.pub_allowed?(:admin, :on => :team)
|
220
|
+
end
|
221
|
+
|
222
|
+
it "should properly call #matches? on the rule" do
|
223
|
+
bob = Person.create! :name => 'bob'
|
224
|
+
controller.stub!(:current_person).and_return(bob)
|
225
|
+
rule = PermitRule.new :guest
|
226
|
+
rule.should_receive(:matches?).with(bob, instance_of(Binding))
|
227
|
+
PermitRule.stub!(:new).and_return(rule)
|
228
|
+
controller.pub_allowed?(:guest)
|
229
|
+
end
|
230
|
+
|
231
|
+
it "should return the result of the rule match" do
|
232
|
+
controller.stub!(:current_person).and_return(Guest.new)
|
233
|
+
rule = PermitRule.new :guest
|
234
|
+
PermitRule.stub!(:new).and_return(rule)
|
235
|
+
|
236
|
+
rule.stub!(:matches?).and_return(true)
|
237
|
+
controller.pub_allowed?(:guest).should be_true
|
238
|
+
|
239
|
+
rule.stub!(:matches?).and_return(false)
|
240
|
+
controller.pub_allowed?(:guest).should be_false
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
describe "#denied?" do
|
245
|
+
it "should properly build the rule" do
|
246
|
+
controller.stub!(:current_person).and_return(Guest.new)
|
247
|
+
rule = PermitRule.new :admin, :on => :team
|
248
|
+
PermitRule.should_receive(:new).with(:admin, hash_including(:on => :team)).and_return(rule)
|
249
|
+
controller.pub_denied?(:admin, :on => :team)
|
250
|
+
end
|
251
|
+
|
252
|
+
it "should properly call #matches? on the rule" do
|
253
|
+
bob = Person.create! :name => 'bob'
|
254
|
+
controller.stub!(:current_person).and_return(bob)
|
255
|
+
rule = PermitRule.new :guest
|
256
|
+
rule.should_receive(:matches?).with(bob, instance_of(Binding))
|
257
|
+
PermitRule.stub!(:new).and_return(rule)
|
258
|
+
controller.pub_denied?(:guest)
|
259
|
+
end
|
260
|
+
|
261
|
+
it "should return the opposite of the rule match" do
|
262
|
+
controller.stub!(:current_person).and_return(Guest.new)
|
263
|
+
rule = PermitRule.new :guest
|
264
|
+
PermitRule.stub!(:new).and_return(rule)
|
265
|
+
|
266
|
+
rule.stub!(:matches?).and_return(true)
|
267
|
+
controller.pub_denied?(:guest).should be_false
|
268
|
+
|
269
|
+
rule.stub!(:matches?).and_return(false)
|
270
|
+
controller.pub_denied?(:guest).should be_true
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
describe "resetting core models" do
|
276
|
+
before {controller.stub!(:current_person).and_return(Guest.new)}
|
277
|
+
|
278
|
+
it "should reset the core models in development mode" do
|
279
|
+
# Can't find a good way to test this since development mode needs to be
|
280
|
+
# simulated before the controller is loaded.
|
281
|
+
|
282
|
+
#Rails.env.stub!(:development?).and_return(true)
|
283
|
+
#Permit::Config.should_receive(:reset_core_models)
|
284
|
+
#get :index
|
285
|
+
end
|
286
|
+
|
287
|
+
it "should not reset the core models when not in dev mode" do
|
288
|
+
controller.should_not_receive(:reset_permit_core)
|
289
|
+
Permit::Config.should_not_receive(:reset_core_models)
|
290
|
+
get :index
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
describe ControllerExtensions, :type => :controller do
|
296
|
+
controller_name 'permit/specs/defined_denials'
|
297
|
+
|
298
|
+
describe "checking authorizations" do
|
299
|
+
context "when #access_denied is previously defined in the class" do
|
300
|
+
it "should call the class's method" do
|
301
|
+
controller.stub!(:current_person).and_return(Guest.new)
|
302
|
+
get :index
|
303
|
+
response.body.should == 'base denied message'
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|