permit 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|