diff options
author | Brice Figureau <brice-puppet@daysofwonder.com> | 2009-04-21 23:53:48 +0200 |
---|---|---|
committer | Brice Figureau <brice-puppet@daysofwonder.com> | 2009-04-23 20:52:03 +0200 |
commit | dc1cd6fb6b143b6525953e619a716f04e678727c (patch) | |
tree | ab38c7fac99ba1cddab062176142ba071caea831 /lib/puppet/network/rest_authconfig.rb | |
parent | 85233768f080b4cbc4e20eb0c354b6d859a2fb23 (diff) | |
download | puppet-dc1cd6fb6b143b6525953e619a716f04e678727c.tar.gz puppet-dc1cd6fb6b143b6525953e619a716f04e678727c.tar.xz puppet-dc1cd6fb6b143b6525953e619a716f04e678727c.zip |
Fix #1875 - Add a REST authorization system
This patch introduces a new configuration file (and configuration
setting to set it).
Each REST request is checked against this configuration file, and is
either allowed or denied.
The configuration file has the following format:
path /uripath
method <methods>
allow <ip> or <name>
deny <ip> or <name>
or
path ~ <regex>
method <methods>
allow <ip> or <name>
deny <ip> or <name>
where regex is a ruby regex.
This last syntax allows deny/allow interpolation from
the regex captures:
path ~ /files[^/]+/files/([^/]+)/([^/])/
method find
allow $2.$1
If you arrange your files/ directory to have files in
'domain.com/host/', then only the referenced host will
be able to access their files, other hosts will be denied.
For instance:
files/reductivelabs.com/dns/...
files/reductivelabs.com/www/...
then only files in dns can be accessible by dns.reductivelabs.com
and so on...
If the auth.conf file doesn't exist puppet uses sane defaults that allows
clients to check-in and ask for their configurations...
Signed-off-by: Brice Figureau <brice-puppet@daysofwonder.com>
Diffstat (limited to 'lib/puppet/network/rest_authconfig.rb')
-rw-r--r-- | lib/puppet/network/rest_authconfig.rb | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/lib/puppet/network/rest_authconfig.rb b/lib/puppet/network/rest_authconfig.rb new file mode 100644 index 000000000..58708e120 --- /dev/null +++ b/lib/puppet/network/rest_authconfig.rb @@ -0,0 +1,72 @@ +require 'puppet/network/authconfig' + +module Puppet + class Network::RestAuthConfig < Network::AuthConfig + + attr_accessor :rights + + DEFAULT_ACL = { + :facts => { :acl => "/facts", :method => [:save, :find] }, + :catalog => { :acl => "/catalog", :method => :find }, + # this one will allow all file access, and thus delegate + # to fileserver.conf + :file => { :acl => "/file" }, + :cert => { :acl => "/certificate", :method => :find }, + :reports => { :acl => "/report", :method => :save } + } + + def self.main + add_acl = @main.nil? + super + @main.insert_default_acl if add_acl and !@main.exists? + @main + end + + # check wether this request is allowed in our ACL + def allowed?(request) + read() + return @rights.allowed?(build_uri(request), request.node, request.ip, request.method) + end + + def initialize(file = nil, parsenow = true) + super(file || Puppet[:rest_authconfig], parsenow) + + # if we didn't read a file (ie it doesn't exist) + # make sure we can create some default rights + @rights ||= Puppet::Network::Rights.new + end + + def parse() + super() + insert_default_acl + end + + # force regular ACLs to be present + def insert_default_acl + DEFAULT_ACL.each do |name, acl| + unless rights[acl[:acl]] + Puppet.warning "Inserting default '#{acl[:acl]}' acl because none were found in '%s'" % ( @file || "no file configured") + mk_acl(acl[:acl], acl[:method]) + end + end + # queue an empty (ie deny all) right for every other path + # actually this is not strictly necessary as the rights system + # denies not explicitely allowed paths + rights.newright("/") unless rights["/"] + end + + def mk_acl(path, method = nil) + @rights.newright(path) + @rights.allow(path, "*") + + if method + method = [method] unless method.is_a?(Array) + method.each { |m| @rights.restrict_method(path, m) } + end + end + + def build_uri(request) + "/#{request.indirection_name}/#{request.key}" + end + end +end |