+1

On Apr 19, 2009, at 11:38 AM, Brice Figureau wrote:

>
> Introduces a new auth.conf directive (auth or authenticated) which
> takes an argument (on,yes/off,no).
> This can be used to restrict an ACL to only some state of
> authentication of a REST request.
> If no auth directive is given, both type of requests are used.
>
> Signed-off-by: Brice Figureau <[email protected]>
> ---
> lib/puppet/network/authconfig.rb |    7 +++++-
> lib/puppet/network/rights.rb     |   26 ++++++++++++++++++++----
> spec/unit/network/authconfig.rb  |   34 +++++++++++++++++++++++++++++ 
> ++++
> spec/unit/network/rights.rb      |   39 +++++++++++++++++++++++++++++ 
> ++++++--
> 4 files changed, 97 insertions(+), 9 deletions(-)
>
> diff --git a/lib/puppet/network/authconfig.rb b/lib/puppet/network/ 
> authconfig.rb
> index 3e40c9d..41f8f1c 100644
> --- a/lib/puppet/network/authconfig.rb
> +++ b/lib/puppet/network/authconfig.rb
> @@ -111,7 +111,7 @@ module Puppet
>                             end
>                             name.chomp!
>                             right = newrights.newright(name, count,  
> @file)
> -                        when /^\s*(allow|deny|method|environment)\s+ 
> (.+)$/
> +                        when /^\s*(allow|deny|method|environment| 
> auth(?:enticated)?)\s+(.+)$/
>                             parse_right_directive(right, $1, $2,  
> count)
>                         else
>                             raise ConfigurationError, "Invalid line  
> %s: %s" % [count, line]
> @@ -155,6 +155,11 @@ module Puppet
>                     raise ConfigurationError, "'environment'  
> directive not allowed in namespace ACL at line %s of %s" % [count,  
> @config]
>                 end
>                 modify_right(right, :restrict_environment, value,  
> "adding environment %s", count)
> +            when /auth(?:enticated)?/
> +                unless right.acl_type == :regex
> +                    raise ConfigurationError, "'authenticated'  
> directive not allowed in namespace ACL at line %s of %s" % [count,  
> @config]
> +                end
> +                modify_right(right, :restrict_authenticated, value,  
> "adding authentication %s", count)
>             else
>                 raise ConfigurationError,
>                     "Invalid argument '%s' at line %s" % [var, count]
> diff --git a/lib/puppet/network/rights.rb b/lib/puppet/network/ 
> rights.rb
> index 75005d8..fc2d685 100755
> --- a/lib/puppet/network/rights.rb
> +++ b/lib/puppet/network/rights.rb
> @@ -14,7 +14,7 @@ class Rights
>
>     # We basically just proxy directly to our rights.  Each Right  
> stores
>     # its own auth abilities.
> -    [:allow, :deny, :restrict_method, :restrict_environment].each  
> do |method|
> +     
> [:allow 
> , :deny 
> , :restrict_method 
> , :restrict_environment, :restrict_authenticated].each do |method|
>         define_method(method) do |name, *args|
>             if obj = self[name]
>                 obj.send(method, *args)
> @@ -27,7 +27,7 @@ class Rights
>     # Check that name is allowed or not
>     def allowed?(name, *args)
>         begin
> -            fail_on_deny(name, *args)
> +            fail_on_deny(name, :node => args[0], :ip => args[1])
>         rescue AuthorizationError
>             return false
>         rescue ArgumentError
> @@ -59,10 +59,12 @@ class Rights
>
>         # if we end here, then that means we either didn't match
>         # or failed, in any case will throw an error to the outside  
> world
> -        if name =~ /^\//
> +        if name =~ /^\// or right
>             # we're a patch ACL, let's fail
>             msg = "%s access to %s [%s]" % [ (args[:node].nil? ?  
> args[:ip] : "#{args[:node]}(#{args[:ip]})"), name, args[:method] ]
>
> +            msg += " authenticated " if args[:authenticated]
> +
>             error = AuthorizationError.new("Forbidden request: " +  
> msg)
>             if right
>                 error.file = right.file
> @@ -121,7 +123,7 @@ class Rights
>     # A right.
>     class Right < Puppet::Network::AuthStore
>         attr_accessor :name, :key, :acl_type, :line, :file
> -        attr_accessor :methods, :environment
> +        attr_accessor :methods, :environment, :authentication
>
>         ALL = [:save, :destroy, :find, :search]
>
> @@ -130,6 +132,7 @@ class Rights
>         def initialize(name, line, file)
>             @methods = []
>             @environment = []
> +            @authentication = nil
>             @name = name
>             @line = line || 0
>             @file = file
> @@ -173,9 +176,10 @@ class Rights
>         # if this right is too restrictive (ie we don't match this  
> access method)
>         # then return :dunno so that upper layers have a chance to  
> try another right
>         # tailored to the given method
> -        def allowed?(name, ip, args)
> +        def allowed?(name, ip, args = {})
>             return :dunno if acl_type == :regex and not  
> @methods.include?(args[:method])
>             return :dunno if acl_type == :regex and  
> @environment.size > 0 and not @environment.include? 
> (args[:environment])
> +            return :dunno if acl_type == :regex and not  
> @authentication.nil? and args[:authenticated] != @authentication
>
>             begin
>                 # make sure any capture are replaced if needed
> @@ -216,6 +220,18 @@ class Rights
>             @environment << env
>         end
>
> +        def restrict_authenticated(authentication)
> +            case authentication
> +            when "yes", "on", "true", true
> +                authentication = true
> +            when "no", "off", "false", false
> +                authentication = false
> +            else
> +                raise ArgumentError, "'%s' incorrect authenticated  
> value: %s" % [name, authentication]
> +            end
> +            @authentication = authentication
> +        end
> +
>         def match?(key)
>             # if we are a namespace compare directly
>             return self.key == namespace_to_key(key) if acl_type  
> == :name
> diff --git a/spec/unit/network/authconfig.rb b/spec/unit/network/ 
> authconfig.rb
> index 21af89b..f666523 100644
> --- a/spec/unit/network/authconfig.rb
> +++ b/spec/unit/network/authconfig.rb
> @@ -253,6 +253,40 @@ describe Puppet::Network::AuthConfig do
>             lambda { @authconfig.read }.should raise_error
>         end
>
> +        it "should inform the current ACL if we get the 'auth'  
> directive" do
> +            acl = stub 'acl', :info
> +            acl.stubs(:acl_type).returns(:regex)
> +
> +            @fd.stubs(:each).multiple_yields('path /certificates',  
> 'auth yes')
> +            @rights.stubs(:newright).with("/certificates", 1,  
> 'dummy').returns(acl)
> +
> +            acl.expects(:restrict_authenticated).with('yes')
> +
> +            @authconfig.read
> +        end
> +
> +        it "should also allow the longest 'authenticated'  
> directive" do
> +            acl = stub 'acl', :info
> +            acl.stubs(:acl_type).returns(:regex)
> +
> +            @fd.stubs(:each).multiple_yields('path /certificates',  
> 'authenticated yes')
> +            @rights.stubs(:newright).with("/certificates", 1,  
> 'dummy').returns(acl)
> +
> +            acl.expects(:restrict_authenticated).with('yes')
> +
> +            @authconfig.read
> +        end
> +
> +        it "should raise an error if the 'auth' directive is used  
> in a right different than a path/regex one" do
> +            acl = stub 'acl', :info
> +            acl.stubs(:acl_type).returns(:regex)
> +
> +            @fd.stubs(:each).multiple_yields('[puppetca]', 'auth  
> yes')
> +            @rights.stubs(:newright).with("puppetca", 1,  
> 'dummy').returns(acl)
> +
> +            lambda { @authconfig.read }.should raise_error
> +        end
> +
>     end
>
> end
> diff --git a/spec/unit/network/rights.rb b/spec/unit/network/rights.rb
> index be1db72..f98249a 100644
> --- a/spec/unit/network/rights.rb
> +++ b/spec/unit/network/rights.rb
> @@ -9,7 +9,7 @@ describe Puppet::Network::Rights do
>         @right = Puppet::Network::Rights.new
>     end
>
> -    [:allow, :deny, :restrict_method, :restrict_environment].each  
> do |m|
> +     
> [:allow 
> , :deny 
> , :restrict_method 
> , :restrict_environment, :restrict_authenticated].each do |m|
>         it "should have a #{m} method" do
>             @right.should respond_to(m)
>         end
> @@ -150,9 +150,9 @@ describe Puppet::Network::Rights do
>         end
>
>         it "should delegate to fail_on_deny" do
> -            @right.expects(:fail_on_deny).with("namespace", :args)
> +            @right.expects(:fail_on_deny).with("namespace", :node  
> => "host.domain.com", :ip => "127.0.0.1")
>
> -            @right.allowed?("namespace", :args)
> +            @right.allowed?("namespace", "host.domain.com",  
> "127.0.0.1")
>         end
>
>         it "should return true if fail_on_deny doesn't fail" do
> @@ -397,6 +397,10 @@ describe Puppet::Network::Rights do
>             @acl.methods.should == Puppet::Network::Rights::Right::ALL
>         end
>
> +        it "should allow all request authentication state by  
> default" do
> +            @acl.authentication.should be_nil
> +        end
> +
>         it "should allow modification of the methods filters" do
>             @acl.restrict_method(:save)
>
> @@ -424,6 +428,22 @@ describe Puppet::Network::Rights do
>             @acl.environment.should == [:env]
>         end
>
> +        ["on", "yes", "true", true].each do |auth|
> +            it "should allow filtering on authenticated requests  
> with '#{auth}'" do
> +                @acl.restrict_authenticated(auth)
> +
> +                @acl.authentication.should be_true
> +            end
> +        end
> +
> +        ["off", "no", "false", false].each do |auth|
> +            it "should allow filtering on unauthenticated requests  
> with '#{auth}'" do
> +                @acl.restrict_authenticated(auth)
> +
> +                @acl.authentication.should be_false
> +            end
> +        end
> +
>         describe "when checking right authorization" do
>             it "should return :dunno if this right is not restricted  
> to the given method" do
>                 @acl.restrict_method(:destroy)
> @@ -446,6 +466,19 @@ describe Puppet::Network::Rights do
>                 @acl.allowed?("me","127.0.0.1", { :method  
> => :save, :environment => :development }).should == :dunno
>             end
>
> +            it "should return :dunno if this right is not  
> restricted to the given request authentication state" do
> +                @acl.restrict_authenticated(true)
> +
> +                @acl.allowed?("me","127.0.0.1", { :method  
> => :save, :authenticated => false }).should == :dunno
> +            end
> +
> +            it "should return allow/deny if this right is  
> restricted to the given request authentication state" do
> +                @acl.restrict_authenticated(false)
> +                @acl.allow("127.0.0.1")
> +
> +                @acl.allowed?("me","127.0.0.1", { :authenticated =>  
> false }).should be_true
> +            end
> +
>             it "should interpolate allow/deny patterns with the  
> given match" do
>                 @acl.expects(:interpolate).with(:match)
>
> -- 
> 1.6.0.2
>
>
> >


-- 
There is no expedient to which a man will not go to avoid the labor
of thinking. --Thomas A. Edison
---------------------------------------------------------------------
Luke Kanies | http://reductivelabs.com | http://madstop.com


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to