This file is indexed.

/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