diff options
author | John Keiser <jkeiser@opscode.com> | 2014-07-24 18:07:59 -0600 |
---|---|---|
committer | John Keiser <jkeiser@opscode.com> | 2014-08-22 09:20:48 -0700 |
commit | 5c6c2a6921fe8c7d091854eb644ac0f42208126e (patch) | |
tree | d87cba99226b9ca00b5b5784e2c5a00d7f5071b1 | |
parent | c5d40545370510f764b834ba3096d2bd4eb301e5 (diff) | |
download | chef-zero-5c6c2a6921fe8c7d091854eb644ac0f42208126e.tar.gz |
Include both org owner and superuser in org acls
-rw-r--r-- | lib/chef_zero/data_store/default_facade.rb | 84 | ||||
-rw-r--r-- | lib/chef_zero/endpoints/acl_base.rb | 17 | ||||
-rw-r--r-- | spec/run_oc_pedant.rb | 2 |
3 files changed, 78 insertions, 25 deletions
diff --git a/lib/chef_zero/data_store/default_facade.rb b/lib/chef_zero/data_store/default_facade.rb index a44e3e0..9912f16 100644 --- a/lib/chef_zero/data_store/default_facade.rb +++ b/lib/chef_zero/data_store/default_facade.rb @@ -3,10 +3,10 @@ require 'chef_zero/data_store/interface_v2' module ChefZero module DataStore class DefaultFacade < ChefZero::DataStore::InterfaceV2 - def initialize(real_store, osc_compat, superusers = [ 'pivotal' ]) + def initialize(real_store, osc_compat, superusers = nil) @real_store = real_store @osc_compat = osc_compat - @superusers = superusers + @superusers = superusers || (osc_compat ? [] : DefaultFacade::DEFAULT_SUPERUSERS) clear end @@ -14,6 +14,8 @@ module ChefZero attr_reader :osc_compat attr_reader :superusers + DEFAULT_SUPERUSERS = [ 'pivotal' ] + def default(path, name=nil) value = @defaults for part in path @@ -72,7 +74,12 @@ module ChefZero real_store.clear if real_store.respond_to?(:clear) @defaults = { 'organizations' => {}, - 'acls' => {} + 'acls' => {}, + 'metadata' => { + 'owners' => { + '' => superusers.inject({}) { |result,key| result[key] = '{}'; result } + } + } } unless osc_compat @defaults['users'] = {} @@ -101,10 +108,12 @@ module ChefZero options_hash = options.last requestor = options_hash.is_a?(Hash) ? options_hash[:requestor] : nil if path.size == 1 - @defaults['organizations'][name] ||= org_defaults(name, requestor) + orgname = name else - @defaults['organizations'][path[1]] ||= org_default(path[1], requestor) + orgname = path[1] end + @defaults['organizations'][orgname] ||= DefaultFacade.org_defaults(orgname, requestor, superusers, osc_compat) + @defaults['metadata']['owners']["organizations/#{orgname}"] = { requestor => '{}' } if requestor end end @@ -126,9 +135,9 @@ module ChefZero options_hash = options.last requestor = options_hash.is_a?(Hash) ? options_hash[:requestor] : nil if path.size == 1 - @defaults['organizations'][name] ||= org_defaults(name, options[:requestor]) + @defaults['organizations'][name] ||= DefaultFacade.org_defaults(name, options[:requestor], superusers, osc_compat) else - @defaults['organizations'][path[1]] ||= org_defaults(path[1], options[:requestor]) + @defaults['organizations'][path[1]] ||= DefaultFacade.org_defaults(path[1], options[:requestor], suepruserse, osc_compat) end end end @@ -183,6 +192,7 @@ module ChefZero end def list(path) + puts "Defaults #{@defaults['metadata']}" if path[0] == 'metadata' default_results = default(path) default_results = default_results.keys if default_results begin @@ -209,7 +219,37 @@ module ChefZero real_store.exists_dir?(path) || default(path) end - def org_defaults(name, requestor) + def self.is_created_with_org?(path, osc_compat = false) + return false if path.size == 0 || path[0] != 'organizations' + value = org_defaults(path[1], 'pivotal', [], osc_compat) + for part in path[2..-1] + break if !value + value = value[part] + end + return !!value + end + + def self.list_metadata(data, path, metadata_type, *options) + begin + result = data.list([ 'metadata', metadata_type, path.join('/') ]) + rescue DataNotFoundError + result = [] + end + if options.include?(:recurse_up) && path.size >= 1 + result = list_metadata(data, path[0..-2], metadata_type, *options) | result + end + return result + end + + def self.owners_of(data, path) +# if is_created_with_org?(path, false) +# return owners_of(data, []) +# else + list_metadata(data, path, 'owners', :recurse_up) +# end + end + + def self.org_defaults(name, creator, superusers, osc_compat) result = { 'clients' => { "#{name}-validator" => '{ "validator": true }' @@ -240,10 +280,10 @@ module ChefZero 'sandboxes' => '{}' }, 'groups' => { - 'admins' => admins_group(requestor), + 'admins' => admins_group(creator), 'billing-admins' => '{}', 'clients' => clients_group, - 'users' => users_group(requestor), + 'users' => users_group(creator), }, 'acls' => { 'clients' => {}, @@ -284,11 +324,11 @@ module ChefZero }', 'groups' => '{}', 'containers' => %'{ - "create": { "actors": [ "#{requestor}" ] }, - "read": { "actors": [ "#{requestor}" ], "groups": [ "admins", "users" ] }, - "update": { "actors": [ "#{requestor}" ] }, - "delete": { "actors": [ "#{requestor}" ] }, - "grant": { "actors": [ "#{requestor}" ] } + "create": { "actors": [ #{creator.inspect} ] }, + "read": { "actors": [ #{creator.inspect} ], "groups": [ "admins", "users" ] }, + "update": { "actors": [ #{creator.inspect} ] }, + "delete": { "actors": [ #{creator.inspect} ] }, + "grant": { "actors": [ #{creator.inspect} ] } }', 'sandboxes' => '{ "create": { "groups": [ "admins", "users" ] } @@ -325,20 +365,20 @@ module ChefZero }', 'sandboxes' => {} }, - 'association_requests' => {}, + 'association_requests' => {} } if osc_compat result['users']['admin'] = '{ "admin": "true" }' result['clients']["#{name}-webui"] = '{ "admin": true }' else - result['users'][requestor] = '{}' + result['users'][creator] = '{}' end result end - def admins_group(requestor) + def self.admins_group(creator) proc do |data, path| admins = data.list(path[0..1] + [ 'users' ]).select do |name| user = JSON.parse(data.get(path[0..1] + [ 'users', name ]), :create_additions => false) @@ -348,21 +388,21 @@ module ChefZero client = JSON.parse(data.get(path[0..1] + [ 'clients', name ]), :create_additions => false) client['admin'] end - JSON.pretty_generate({ 'actors' => ([ requestor ] + admins).uniq }) + JSON.pretty_generate({ 'actors' => ([ creator ] + admins).uniq }) end end - def clients_group + def self.clients_group proc do |data, path| clients = data.list(path[0..1] + [ 'clients' ]) JSON.pretty_generate({ 'clients' => clients }) end end - def users_group(requestor) + def self.users_group(creator) proc do |data, path| users = data.list(path[0..1] + [ 'users' ]) - JSON.pretty_generate({ 'users' => ([ requestor ] + users).uniq }) + JSON.pretty_generate({ 'users' => ([ creator ] + users).uniq }) end end end diff --git a/lib/chef_zero/endpoints/acl_base.rb b/lib/chef_zero/endpoints/acl_base.rb index 75eacf4..b527ff0 100644 --- a/lib/chef_zero/endpoints/acl_base.rb +++ b/lib/chef_zero/endpoints/acl_base.rb @@ -1,5 +1,7 @@ require 'json' require 'chef_zero/rest_base' +require 'chef_zero/data_normalizer' +require 'chef_zero/data_store/default_facade' module ChefZero module Endpoints @@ -18,10 +20,21 @@ module ChefZero acls = JSON.parse(acls, :create_additions => false) container_acls = get_container_acls(request, path) if container_acls - DataNormalizer.merge_container_acls(acls, container_acls) + acls = DataNormalizer.merge_container_acls(acls, container_acls) + # If we're grabbing our actors from the container, we still want to + # include superusers, but we don't want to include org owner (who + # should already be in the container anyway) + owners = DataStore::DefaultFacade.owners_of(data_store, []) else - acls + # We merge owners into every acl, because we're awesome like that. + owners = DataStore::DefaultFacade.owners_of(data_store, path) end + %w(create read update delete grant).each do |perm| + acls[perm] ||= {} + acls[perm]['actors'] ||= [] + acls[perm]['actors'] = owners | acls[perm]['actors'] + end + acls end def get_container_acls(request, path) diff --git a/spec/run_oc_pedant.rb b/spec/run_oc_pedant.rb index 3eb2641..43366f2 100644 --- a/spec/run_oc_pedant.rb +++ b/spec/run_oc_pedant.rb @@ -13,7 +13,7 @@ begin require 'chef_zero/data_store/raw_file_store' tmpdir = Dir.mktmpdir data_store = ChefZero::DataStore::RawFileStore.new(tmpdir, true) - data_store = ChefZero::DataStore::DefaultFacade.new(data_store) + data_store = ChefZero::DataStore::DefaultFacade.new(data_store, false) server = ChefZero::Server.new(:port => 8889, :single_org => false, :data_store => data_store) server.start_background |