/usr/lib/ruby/vendor_ruby/chef_zero/chef_data/acl_path.rb is in chef-zero 4.5.0-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | module ChefZero
module ChefData
# Manages translations between REST and ACL data paths
# and parent paths.
#
# Suggestions
# - make /organizations/ORG/_acl and deprecate organization/_acl and organizations/_acl
# - add endpoints for /containers/(users|organizations|containers)(/_acl)
# - add PUT for */_acl
# - add endpoints for /organizations/ORG/data/containers and /organizations/ORG/cookbooks/containers
# - sane, fully documented ACL model
# - sane inheritance / override model: if actors or groups are explicitly
# specified on X, they are not inherited from X's parent
# - stop adding pivotal to acls (he already has access to what he needs)
module AclPath
ORG_DATA_TYPES = %w(clients cookbook_artifacts cookbooks containers data environments groups
nodes policies policy_groups roles sandboxes)
TOP_DATA_TYPES = %w(containers organizations users)
# ACL data paths for a partition are:
# / -> /acls/root
# /TYPE -> /acls/containers/TYPE
# /TYPE/NAME -> /acls/TYPE/NAME
#
# The root partition "/" has its own acls, so it looks like this:
#
# / -> /acls/root
# /users -> /acls/containers/users
# /organizations -> /acls/containers/organizations
# /users/schlansky -> /acls/users/schlansky
#
# Each organization is its own partition, so it looks like this:
#
# /organizations/blah -> /organizations/blah/acls/root
# /organizations/blah/roles -> /organizations/blah/acls/containers/roles
# /organizations/blah/roles/web -> /organizations/blah/acls/roles/web
# /organizations/ORG is its own partition. ACLs for anything under it follow
# This method takes a Chef REST path and returns the chef-zero path
# used to look up the ACL. If an object does not have an ACL directly,
# it will return nil. Paths like /organizations/ORG/data/bag/item will
# return nil, because it is the parent path (data/bag) that has an ACL.
def self.get_acl_data_path(path)
# Things under organizations have their own acls hierarchy
if path[0] == 'organizations' && path.size >= 2
under_org = partition_acl_data_path(path[2..-1], ORG_DATA_TYPES)
if under_org
path[0..1] + under_org
end
else
partition_acl_data_path(path, TOP_DATA_TYPES)
end
end
#
# Reverse transform from acl_data_path to path.
# /acls/root -> /
# /acls/** -> /**
# /organizations/ORG/acls/root -> /organizations/ORG
# /organizations/ORG/acls/** -> /organizations/ORG/**
#
# This means that /acls/containers/nodes maps to
# /containers/nodes, not /nodes.
#
def self.get_object_path(acl_data_path)
if acl_data_path[0] == 'acls'
if acl_data_path[1] == 'root'
[]
else
acl_data_path[1..-1]
end
elsif acl_data_path[0] == 'organizations' && acl_data_path[2] == 'acls'
if acl_data_path[3] == 'root'
acl_data_path[0..1]
else
acl_data_path[0..1] + acl_data_path[3..-1]
end
end
end
# Method *assumes* acl_data_path is valid.
# /organizations/BLAH's parent is /organizations
#
# An example traversal up the whole tree:
# /organizations/foo/acls/nodes/mario ->
# /organizations/foo/acls/containers/nodes ->
# /organizations/foo/acls/containers/containers ->
# /organizations/foo/acls/root ->
# /acls/containers/organizations ->
# /acls/containers/containers ->
# /acls/root ->
# nil
def self.parent_acl_data_path(acl_data_path)
if acl_data_path[0] == 'organizations'
under_org = partition_parent_acl_data_path(acl_data_path[2..-1])
if under_org
acl_data_path[0..1] + under_org
else
# ACL data path is /organizations/X/acls/root; therefore parent is "/organizations"
[ 'acls', 'containers', 'organizations' ]
end
else
partition_parent_acl_data_path(acl_data_path)
end
end
private
# /acls/root -> nil
# /acls/containers/containers -> /acls/root
# /acls/TYPE/X -> /acls/containers/TYPE
#
# Method *assumes* acl_data_path is valid.
# Returns nil if the path is /acls/root
def self.partition_parent_acl_data_path(acl_data_path)
if acl_data_path.size == 3
if acl_data_path == %w(acls containers containers)
[ 'acls', 'root' ]
else
[ 'acls', 'containers', acl_data_path[1]]
end
else
nil
end
end
def self.partition_acl_data_path(path, data_types)
if path.size == 0
[ 'acls', 'root']
elsif data_types.include?(path[0])
if path.size == 0
[ 'acls', 'containers', path[0] ]
elsif path.size == 2
[ 'acls', path[0], path[1] ]
end
end
end
end
end
end
|