summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Keiser <jkeiser@opscode.com>2014-07-24 18:07:59 -0600
committerJohn Keiser <jkeiser@opscode.com>2014-08-22 09:20:48 -0700
commit5c6c2a6921fe8c7d091854eb644ac0f42208126e (patch)
treed87cba99226b9ca00b5b5784e2c5a00d7f5071b1
parentc5d40545370510f764b834ba3096d2bd4eb301e5 (diff)
downloadchef-zero-5c6c2a6921fe8c7d091854eb644ac0f42208126e.tar.gz
Include both org owner and superuser in org acls
-rw-r--r--lib/chef_zero/data_store/default_facade.rb84
-rw-r--r--lib/chef_zero/endpoints/acl_base.rb17
-rw-r--r--spec/run_oc_pedant.rb2
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