3
require File.dirname(__FILE__) + '/../../spec_helper'
5
require 'puppet/network/rights'
7
describe Puppet::Network::Rights do
9
@right = Puppet::Network::Rights.new
12
[:allow, :deny, :restrict_method, :restrict_environment, :restrict_authenticated].each do |m|
13
it "should have a #{m} method" do
14
@right.should respond_to(m)
17
describe "when using #{m}" do
18
it "should delegate to the correct acl" do
20
@right.stubs(:[]).returns(acl)
22
acl.expects(m).with("me")
24
@right.send(m, 'thisacl', "me")
29
it "should throw an error if type can't be determined" do
30
lambda { @right.newright("name") }.should raise_error
33
describe "when creating new namespace ACLs" do
35
it "should throw an error if the ACL already exists" do
36
@right.newright("[name]")
38
lambda { @right.newright("[name]") }.should raise_error
41
it "should create a new ACL with the correct name" do
42
@right.newright("[name]")
44
@right["name"].key.should == :name
47
it "should create an ACL of type Puppet::Network::AuthStore" do
48
@right.newright("[name]")
50
@right["name"].should be_a_kind_of(Puppet::Network::AuthStore)
54
describe "when creating new path ACLs" do
55
it "should not throw an error if the ACL already exists" do
56
@right.newright("/name")
58
lambda { @right.newright("/name")}.should_not raise_error
61
it "should throw an error if the acl uri path is not absolute" do
62
lambda { @right.newright("name")}.should raise_error
65
it "should create a new ACL with the correct path" do
66
@right.newright("/name")
68
@right["/name"].should_not be_nil
71
it "should create an ACL of type Puppet::Network::AuthStore" do
72
@right.newright("/name")
74
@right["/name"].should be_a_kind_of(Puppet::Network::AuthStore)
78
describe "when creating new regex ACLs" do
79
it "should not throw an error if the ACL already exists" do
80
@right.newright("~ .rb$")
82
lambda { @right.newright("~ .rb$")}.should_not raise_error
85
it "should create a new ACL with the correct regex" do
86
@right.newright("~ .rb$")
88
@right.include?(".rb$").should_not be_nil
91
it "should be able to lookup the regex" do
92
@right.newright("~ .rb$")
94
@right[".rb$"].should_not be_nil
97
it "should be able to lookup the regex by its full name" do
98
@right.newright("~ .rb$")
100
@right["~ .rb$"].should_not be_nil
103
it "should create an ACL of type Puppet::Network::AuthStore" do
104
@right.newright("~ .rb$").should be_a_kind_of(Puppet::Network::AuthStore)
108
describe "when checking ACLs existence" do
109
it "should return false if there are no matching rights" do
110
@right.include?("name").should be_false
113
it "should return true if a namespace rights exist" do
114
@right.newright("[name]")
116
@right.include?("name").should be_true
119
it "should return false if no matching namespace rights exist" do
120
@right.newright("[name]")
122
@right.include?("notname").should be_false
125
it "should return true if a path right exists" do
126
@right.newright("/name")
128
@right.include?("/name").should be_true
131
it "should return false if no matching path rights exist" do
132
@right.newright("/name")
134
@right.include?("/differentname").should be_false
137
it "should return true if a regex right exists" do
138
@right.newright("~ .rb$")
140
@right.include?(".rb$").should be_true
143
it "should return false if no matching path rights exist" do
144
@right.newright("~ .rb$")
146
@right.include?(".pp$").should be_false
150
describe "when checking if right is allowed" do
152
@right.stubs(:right).returns(nil)
154
@pathacl = stub 'pathacl', :acl_type => :regex, :"<=>" => 1, :line => 0, :file => 'dummy'
155
Puppet::Network::Rights::Right.stubs(:new).returns(@pathacl)
158
it "should delegate to fail_on_deny" do
159
@right.expects(:fail_on_deny).with("namespace", :node => "host.domain.com", :ip => "127.0.0.1")
161
@right.allowed?("namespace", "host.domain.com", "127.0.0.1")
164
it "should return true if fail_on_deny doesn't fail" do
165
@right.stubs(:fail_on_deny)
166
@right.allowed?("namespace", :args).should be_true
169
it "should return false if fail_on_deny raises an AuthorizationError" do
170
@right.stubs(:fail_on_deny).raises(Puppet::Network::AuthorizationError.new("forbidden"))
171
@right.allowed?("namespace", :args1, :args2).should be_false
174
it "should first check namespace rights" do
175
acl = stub 'acl', :acl_type => :name, :key => :namespace
176
Puppet::Network::Rights::Right.stubs(:new).returns(acl)
178
@right.newright("[namespace]")
179
acl.expects(:match?).returns(true)
180
acl.expects(:allowed?).with { |node,ip,h| node == "node" and ip == "ip" }.returns(true)
182
@right.fail_on_deny("namespace", { :node => "node", :ip => "ip" } )
185
it "should then check for path rights if no namespace match" do
186
acl = stub 'nmacl', :acl_type => :name, :key => :namespace, :"<=>" => -1, :line => 0, :file => 'dummy'
187
acl.stubs(:match?).returns(false)
188
Puppet::Network::Rights::Right.stubs(:new).with("[namespace]").returns(acl)
190
@right.newright("[namespace]")
191
@right.newright("/path/to/there", 0, nil)
193
@pathacl.stubs(:match?).returns(true)
195
acl.expects(:allowed?).never
196
@pathacl.expects(:allowed?).returns(true)
198
@right.fail_on_deny("/path/to/there", {})
201
it "should pass the match? return to allowed?" do
202
@right.newright("/path/to/there")
204
@pathacl.expects(:match?).returns(:match)
205
@pathacl.expects(:allowed?).with { |node,ip,h| h[:match] == :match }.returns(true)
207
@right.fail_on_deny("/path/to/there", {})
210
describe "with namespace acls" do
211
it "should raise an error if this namespace right doesn't exist" do
212
lambda{ @right.fail_on_deny("namespace") }.should raise_error
216
describe "with path acls" do
218
@long_acl = stub 'longpathacl', :name => "/path/to/there", :acl_type => :regex, :line => 0, :file => 'dummy'
219
Puppet::Network::Rights::Right.stubs(:new).with("/path/to/there", 0, nil).returns(@long_acl)
221
@short_acl = stub 'shortpathacl', :name => "/path/to", :acl_type => :regex, :line => 0, :file => 'dummy'
222
Puppet::Network::Rights::Right.stubs(:new).with("/path/to", 0, nil).returns(@short_acl)
224
@long_acl.stubs(:"<=>").with(@short_acl).returns(0)
225
@short_acl.stubs(:"<=>").with(@long_acl).returns(0)
228
it "should select the first match" do
229
@right.newright("/path/to/there", 0)
230
@right.newright("/path/to", 0)
232
@long_acl.stubs(:match?).returns(true)
233
@short_acl.stubs(:match?).returns(true)
235
@long_acl.expects(:allowed?).returns(true)
236
@short_acl.expects(:allowed?).never
238
@right.fail_on_deny("/path/to/there/and/there", {})
241
it "should select the first match that doesn't return :dunno" do
242
@right.newright("/path/to/there", 0, nil)
243
@right.newright("/path/to", 0, nil)
245
@long_acl.stubs(:match?).returns(true)
246
@short_acl.stubs(:match?).returns(true)
248
@long_acl.expects(:allowed?).returns(:dunno)
249
@short_acl.expects(:allowed?).returns(true)
251
@right.fail_on_deny("/path/to/there/and/there", {})
254
it "should not select an ACL that doesn't match" do
255
@right.newright("/path/to/there", 0)
256
@right.newright("/path/to", 0)
258
@long_acl.stubs(:match?).returns(false)
259
@short_acl.stubs(:match?).returns(true)
261
@long_acl.expects(:allowed?).never
262
@short_acl.expects(:allowed?).returns(true)
264
@right.fail_on_deny("/path/to/there/and/there", {})
267
it "should not raise an AuthorizationError if allowed" do
268
@right.newright("/path/to/there", 0)
270
@long_acl.stubs(:match?).returns(true)
271
@long_acl.stubs(:allowed?).returns(true)
273
lambda { @right.fail_on_deny("/path/to/there/and/there", {}) }.should_not raise_error(Puppet::Network::AuthorizationError)
276
it "should raise an AuthorizationError if the match is denied" do
277
@right.newright("/path/to/there", 0, nil)
279
@long_acl.stubs(:match?).returns(true)
280
@long_acl.stubs(:allowed?).returns(false)
282
lambda{ @right.fail_on_deny("/path/to/there", {}) }.should raise_error(Puppet::Network::AuthorizationError)
285
it "should raise an AuthorizationError if no path match" do
286
lambda { @right.fail_on_deny("/nomatch", {}) }.should raise_error(Puppet::Network::AuthorizationError)
290
describe "with regex acls" do
292
@regex_acl1 = stub 'regex_acl1', :name => "/files/(.*)/myfile", :acl_type => :regex, :line => 0, :file => 'dummy'
293
Puppet::Network::Rights::Right.stubs(:new).with("~ /files/(.*)/myfile", 0, nil).returns(@regex_acl1)
295
@regex_acl2 = stub 'regex_acl2', :name => "/files/(.*)/myfile/", :acl_type => :regex, :line => 0, :file => 'dummy'
296
Puppet::Network::Rights::Right.stubs(:new).with("~ /files/(.*)/myfile/", 0, nil).returns(@regex_acl2)
298
@regex_acl1.stubs(:"<=>").with(@regex_acl2).returns(0)
299
@regex_acl2.stubs(:"<=>").with(@regex_acl1).returns(0)
302
it "should select the first match" do
303
@right.newright("~ /files/(.*)/myfile", 0)
304
@right.newright("~ /files/(.*)/myfile/", 0)
306
@regex_acl1.stubs(:match?).returns(true)
307
@regex_acl2.stubs(:match?).returns(true)
309
@regex_acl1.expects(:allowed?).returns(true)
310
@regex_acl2.expects(:allowed?).never
312
@right.fail_on_deny("/files/repository/myfile/other", {})
315
it "should select the first match that doesn't return :dunno" do
316
@right.newright("~ /files/(.*)/myfile", 0)
317
@right.newright("~ /files/(.*)/myfile/", 0)
319
@regex_acl1.stubs(:match?).returns(true)
320
@regex_acl2.stubs(:match?).returns(true)
322
@regex_acl1.expects(:allowed?).returns(:dunno)
323
@regex_acl2.expects(:allowed?).returns(true)
325
@right.fail_on_deny("/files/repository/myfile/other", {})
328
it "should not select an ACL that doesn't match" do
329
@right.newright("~ /files/(.*)/myfile", 0)
330
@right.newright("~ /files/(.*)/myfile/", 0)
332
@regex_acl1.stubs(:match?).returns(false)
333
@regex_acl2.stubs(:match?).returns(true)
335
@regex_acl1.expects(:allowed?).never
336
@regex_acl2.expects(:allowed?).returns(true)
338
@right.fail_on_deny("/files/repository/myfile/other", {})
341
it "should not raise an AuthorizationError if allowed" do
342
@right.newright("~ /files/(.*)/myfile", 0)
344
@regex_acl1.stubs(:match?).returns(true)
345
@regex_acl1.stubs(:allowed?).returns(true)
347
lambda { @right.fail_on_deny("/files/repository/myfile/other", {}) }.should_not raise_error(Puppet::Network::AuthorizationError)
350
it "should raise an error if no regex acl match" do
351
lambda{ @right.fail_on_deny("/path", {}) }.should raise_error(Puppet::Network::AuthorizationError)
354
it "should raise an AuthorizedError on deny" do
355
lambda { @right.fail_on_deny("/path", {}) }.should raise_error(Puppet::Network::AuthorizationError)
361
describe Puppet::Network::Rights::Right do
363
@acl = Puppet::Network::Rights::Right.new("/path",0, nil)
366
describe "with path" do
367
it "should say it's a regex ACL" do
368
@acl.acl_type.should == :regex
371
it "should match up to its path length" do
372
@acl.match?("/path/that/works").should_not be_nil
375
it "should match up to its path length" do
376
@acl.match?("/paththatalsoworks").should_not be_nil
379
it "should return nil if no match" do
380
@acl.match?("/notpath").should be_nil
384
describe "with regex" do
386
@acl = Puppet::Network::Rights::Right.new("~ .rb$",0, nil)
389
it "should say it's a regex ACL" do
390
@acl.acl_type.should == :regex
393
it "should match as a regex" do
394
@acl.match?("this shoud work.rb").should_not be_nil
397
it "should return nil if no match" do
398
@acl.match?("do not match").should be_nil
402
it "should allow all rest methods by default" do
403
@acl.methods.should == Puppet::Network::Rights::Right::ALL
406
it "should allow only authenticated request by default" do
407
@acl.authentication.should be_true
410
it "should allow modification of the methods filters" do
411
@acl.restrict_method(:save)
413
@acl.methods.should == [:save]
416
it "should stack methods filters" do
417
@acl.restrict_method(:save)
418
@acl.restrict_method(:destroy)
420
@acl.methods.should == [:save, :destroy]
423
it "should raise an error if the method is already filtered" do
424
@acl.restrict_method(:save)
426
lambda { @acl.restrict_method(:save) }.should raise_error
429
it "should allow setting an environment filters" do
430
Puppet::Node::Environment.stubs(:new).with(:environment).returns(:env)
432
@acl.restrict_environment(:environment)
434
@acl.environment.should == [:env]
437
["on", "yes", "true", true].each do |auth|
438
it "should allow filtering on authenticated requests with '#{auth}'" do
439
@acl.restrict_authenticated(auth)
441
@acl.authentication.should be_true
445
["off", "no", "false", false].each do |auth|
446
it "should allow filtering on unauthenticated requests with '#{auth}'" do
447
@acl.restrict_authenticated(auth)
449
@acl.authentication.should be_false
453
["all", "any", :all, :any].each do |auth|
454
it "should not use request authenticated state filtering with '#{auth}'" do
455
@acl.restrict_authenticated(auth)
457
@acl.authentication.should be_nil
461
describe "when checking right authorization" do
462
it "should return :dunno if this right is not restricted to the given method" do
463
@acl.restrict_method(:destroy)
465
@acl.allowed?("me","127.0.0.1", { :method => :save } ).should == :dunno
468
it "should return allow/deny if this right is restricted to the given method" do
469
@acl.restrict_method(:save)
470
@acl.allow("127.0.0.1")
472
@acl.allowed?("me","127.0.0.1", { :method => :save }).should be_true
475
it "should return :dunno if this right is not restricted to the given environment" do
476
Puppet::Node::Environment.stubs(:new).returns(:production)
478
@acl.restrict_environment(:production)
480
@acl.allowed?("me","127.0.0.1", { :method => :save, :environment => :development }).should == :dunno
483
it "should return :dunno if this right is not restricted to the given request authentication state" do
484
@acl.restrict_authenticated(true)
486
@acl.allowed?("me","127.0.0.1", { :method => :save, :authenticated => false }).should == :dunno
489
it "should return allow/deny if this right is restricted to the given request authentication state" do
490
@acl.restrict_authenticated(false)
491
@acl.allow("127.0.0.1")
493
@acl.allowed?("me","127.0.0.1", { :authenticated => false }).should be_true
496
it "should interpolate allow/deny patterns with the given match" do
497
@acl.expects(:interpolate).with(:match)
499
@acl.allowed?("me","127.0.0.1", { :method => :save, :match => :match, :authenticated => true })
502
it "should reset interpolation after the match" do
503
@acl.expects(:reset_interpolation)
505
@acl.allowed?("me","127.0.0.1", { :method => :save, :match => :match, :authenticated => true })
508
# mocha doesn't allow testing super...
509
# it "should delegate to the AuthStore for the result" do
512
# @acl.expects(:allowed?).with("me","127.0.0.1")
514
# @acl.allowed?("me","127.0.0.1", :save)