summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Paradise <marc@chef.io>2016-08-26 17:33:10 -0400
committerMarc Paradise <marc@chef.io>2016-08-26 18:37:52 -0400
commit0fa7040ce0d59fc76cd2f31343a3d7b1d3b8569c (patch)
treec12db79358d00fe96002377b04b6bee5b2bf41f6
parent19622a4459d3905a25a80ca842e46e62e6623373 (diff)
downloadchef-zero-mp/SPOOL-340.tar.gz
store ACEs by client/usermp/SPOOL-340
Chef Server has the ability to return users and clients separately within an GET ACL request when `detail=granular`. To support that, we need to store them separately and determine if we want to present `actors` or `users` and `clients` at the time of the request. This change makes a reasonable best effort at capturing the creator type (user v client) correctly and uses that for determining its assignment in acls.
-rw-r--r--lib/chef_zero/chef_data/data_normalizer.rb4
-rw-r--r--lib/chef_zero/chef_data/default_creator.rb51
-rw-r--r--lib/chef_zero/endpoints/acls_endpoint.rb11
3 files changed, 52 insertions, 14 deletions
diff --git a/lib/chef_zero/chef_data/data_normalizer.rb b/lib/chef_zero/chef_data/data_normalizer.rb
index 0df7fe5..58b0d26 100644
--- a/lib/chef_zero/chef_data/data_normalizer.rb
+++ b/lib/chef_zero/chef_data/data_normalizer.rb
@@ -14,8 +14,8 @@ module ChefZero
# is the final list of actors that a subsequent GET will
# provide. Each list is guaranteed to be unique, but the
# combined list is not.
- acls[perm]["actors"] = acls[perm].delete("users").uniq +
- acls[perm].delete("clients").uniq
+ acls[perm]["actors"] = acls[perm]["clients"].uniq +
+ acls[perm]["users"].uniq
else
# this gets doubled sometimes, for reasons.
(acls[perm]["actors"] ||= []).uniq!
diff --git a/lib/chef_zero/chef_data/default_creator.rb b/lib/chef_zero/chef_data/default_creator.rb
index 1ce6253..0618176 100644
--- a/lib/chef_zero/chef_data/default_creator.rb
+++ b/lib/chef_zero/chef_data/default_creator.rb
@@ -346,8 +346,7 @@ module ChefZero
end
def get_owners(acl_path)
- owners = []
-
+ unknown_owners = []
path = AclPath.get_object_path(acl_path)
if path
@@ -356,10 +355,10 @@ module ChefZero
begin
client = FFI_Yajl::Parser.parse(data.get(path), :create_additions => false)
if !client["validator"]
- owners |= [ path[3] ]
+ unknown_owners |= [ path[3] ]
end
rescue
- owners |= [ path[3] ]
+ unknown_owners |= [ path[3] ]
end
# Add creators as owners (except any validator clients).
@@ -370,33 +369,60 @@ module ChefZero
next if client["validator"]
rescue
end
- owners |= [ creator ]
+ unknown_owners |= [ creator ]
end
end
else
- owners |= @creators[path] if @creators[path]
+ unknown_owners |= @creators[path] if @creators[path]
end
+ owners = filter_owners(path, unknown_owners)
#ANGRY
# Non-default containers do not get superusers added to them,
# because reasons.
unless path.size == 4 && path[0] == "organizations" && path[2] == "containers" && !exists?(path)
- owners += superusers
+ owners[:users] += superusers
end
+ else
+ owners = { clients: [], users: [] }
end
- # we don't de-dup this list, because pedant expects to see ["pivotal", "pivotal"] in some cases.
+ owners[:users].uniq!
+ owners[:clients].uniq!
+ owners
+ end
+
+ # Figures out if an object was created by a user or client.
+ # If the object does not exist in the context
+ # of an organization, it can only be a user
+ #
+ # This isn't perfect, because we are never explicitly told
+ # if a requestor creating an object is a user or client -
+ # but it gets us reasonably close
+ def filter_owners(path, unknown_owners)
+ owners = { clients: [], users: [] }
+ unknown_owners.each do |entity|
+ if path[0] == "organizations" && path.length > 2
+ begin
+ data.get(["organizations", path[1], "clients", entity])
+ owners[:clients] |= [ entity ]
+ rescue
+ owners[:users] |= [ entity ]
+ end
+ else
+ owners[:users] |= [ entity ]
+ end
+ end
owners
end
def default_acl(acl_path, acl = {})
- owners = nil
+ owners = get_owners(acl_path)
container_acl = nil
PERMISSIONS.each do |perm|
acl[perm] ||= {}
- acl[perm]["actors"] ||= begin
- owners ||= get_owners(acl_path)
- end
+ acl[perm]["users"] = owners[:users]
+ acl[perm]["clients"] = owners[:clients]
acl[perm]["groups"] ||= begin
# When we create containers, we don't merge groups (not sure why).
if acl_path[0] == "organizations" && acl_path[3] == "containers"
@@ -406,6 +432,7 @@ module ChefZero
(container_acl[perm] ? container_acl[perm]["groups"] : []) || []
end
end
+ acl[perm]["actors"] = acl[perm]["clients"] + acl[perm]["users"]
end
acl
end
diff --git a/lib/chef_zero/endpoints/acls_endpoint.rb b/lib/chef_zero/endpoints/acls_endpoint.rb
index 8565eea..f0ca047 100644
--- a/lib/chef_zero/endpoints/acls_endpoint.rb
+++ b/lib/chef_zero/endpoints/acls_endpoint.rb
@@ -22,6 +22,17 @@ module ChefZero
end
acls = FFI_Yajl::Parser.parse(get_data(request, acl_path), :create_additions => false)
acls = ChefData::DataNormalizer.normalize_acls(acls)
+ if request.query_params["detail"] == "granular"
+ acls.each do |perm, ace|
+ acls[perm]["actors"] = []
+ end
+ else
+ acls.each do |perm, ace|
+ acls[perm].delete("clients")
+ acls[perm].delete("users")
+ end
+ end
+
json_response(200, acls)
end
end