chef_fixie 0.1.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/bin/chef_fixie +2 -2
- data/doc/AccessingSQL.md +33 -1
- data/doc/BulkFixup.md +33 -0
- data/doc/CommonTasks.md +14 -3
- data/lib/chef_fixie.rb +7 -6
- data/lib/chef_fixie/authz_mapper.rb +26 -28
- data/lib/chef_fixie/authz_objects.rb +51 -41
- data/lib/chef_fixie/bulk_edit_permissions.rb +161 -0
- data/lib/chef_fixie/check_org_associations.rb +56 -59
- data/lib/chef_fixie/config.rb +58 -23
- data/lib/chef_fixie/console.rb +17 -12
- data/lib/chef_fixie/context.rb +2 -4
- data/lib/chef_fixie/sql.rb +12 -12
- data/lib/chef_fixie/sql_objects.rb +107 -31
- data/lib/chef_fixie/utility_helpers.rb +13 -9
- data/lib/chef_fixie/version.rb +1 -1
- data/spec/chef_fixie/acl_spec.rb +23 -25
- data/spec/chef_fixie/assoc_invite_spec.rb +5 -8
- data/spec/chef_fixie/check_org_associations_spec.rb +14 -17
- data/spec/chef_fixie/groups_spec.rb +7 -11
- data/spec/chef_fixie/org_spec.rb +4 -5
- data/spec/chef_fixie/orgs_spec.rb +6 -9
- data/spec/spec_helper.rb +5 -6
- metadata +13 -49
- data/bin/bundler +0 -16
- data/bin/chef-apply +0 -16
- data/bin/chef-client +0 -16
- data/bin/chef-shell +0 -16
- data/bin/chef-solo +0 -16
- data/bin/chef-zero +0 -16
- data/bin/coderay +0 -16
- data/bin/edit_json.rb +0 -16
- data/bin/erubis +0 -16
- data/bin/ffi-yajl-bench +0 -16
- data/bin/fixie~ +0 -231
- data/bin/htmldiff +0 -16
- data/bin/knife +0 -16
- data/bin/ldiff +0 -16
- data/bin/net-dhcp +0 -16
- data/bin/ohai +0 -16
- data/bin/prettify_json.rb +0 -16
- data/bin/pry +0 -16
- data/bin/rackup +0 -16
- data/bin/rake +0 -16
- data/bin/rdoc +0 -16
- data/bin/restclient +0 -16
- data/bin/ri +0 -16
- data/bin/rspec +0 -16
- data/bin/s3sh +0 -16
- data/bin/sequel +0 -16
- data/bin/serverspec-init +0 -16
- data/doc/AccessingSQL.md~ +0 -32
- data/doc/BulkFixup.md~ +0 -28
- data/doc/CommonTasks.md~ +0 -0
- data/doc/GETTING_STARTED.md~ +0 -6
- data/spec/chef_fixie/assoc_invite_spec.rb~ +0 -26
- data/spec/chef_fixie/check_org_associations_spec.rb~ +0 -34
- data/spec/chef_fixie/org_spec.rb~ +0 -53
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 | 
            -
             | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 2 | 
            +
            SHA256:
         | 
| 3 | 
            +
              metadata.gz: 2b7aaa7e7efbd722314241465a721c57ed73c0abdfab5f13dcd7a1ddd3058157
         | 
| 4 | 
            +
              data.tar.gz: 1b5c3d001760bb3e2cee276bee33b8a49521af5e91604910c3d1d49f07c20d0d
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: c12b81f65474fd9691018a4e0aeea14e247ea108aee4cd71563412949c76047c0568b9e4aebb65eadc2bfba15ad33b4e15984718e3473cdd70d9f5cb6baea131
         | 
| 7 | 
            +
              data.tar.gz: 259ed111d9a4ca24437f2eb2c6091a86d97b07bfee10ce4085ee08a0b289eea58ff95128c60b58c4f2af14980debc118f2f58b03d582ea67d3a0714af2450acd
         | 
    
        data/bin/chef_fixie
    CHANGED
    
    
    
        data/doc/AccessingSQL.md
    CHANGED
    
    | @@ -5,7 +5,22 @@ Basics: | |
| 5 5 | 
             
            Underneath everything is the Ruby Sequel library; there are a number
         | 
| 6 6 | 
             
            of ways to access it.
         | 
| 7 7 |  | 
| 8 | 
            -
            Check out http://ricostacruz.com/cheatsheets/sequel.html  | 
| 8 | 
            +
            Check out http://ricostacruz.com/cheatsheets/sequel.html or the Sequel
         | 
| 9 | 
            +
            gem docs for details of the sequel library.
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            Many objects in fixie have the accessor inner, which exposes the
         | 
| 12 | 
            +
            Sequel selector. This includes:
         | 
| 13 | 
            +
            * The constants ORGS, USERS, ASSOCIATIONS, and INVITES
         | 
| 14 | 
            +
            ```ruby
         | 
| 15 | 
            +
            ORGS.inner.first
         | 
| 16 | 
            +
            #< @values={:id=>"7ddaee6b42e8f6a0a8e9d5d5efe644f8", :authz_id=>"f46b2e53869968ce115b97d2fd8bfee0", :name=>"ponyville", :full_name=>"ponyville", :assigned_at=>2015-07-21 18:22:34 UTC, :last_updated_by=>"08076ed32f7d5c62721607dd2c309c55", :created_at=>2015-07-21 18:22:34 UTC, :updated_at=>2015-07-21 18:22:34 UTC}>
         | 
| 17 | 
            +
            ```
         | 
| 18 | 
            +
            * Any of the by_XXXX accessors
         | 
| 19 | 
            +
            ```ruby
         | 
| 20 | 
            +
            ORGS['
         | 
| 21 | 
            +
             | 
| 22 | 
            +
             | 
| 23 | 
            +
            ```
         | 
| 9 24 |  | 
| 10 25 |  | 
| 11 26 |  | 
| @@ -34,3 +49,20 @@ now = Sequel.function(:NOW) | |
| 34 49 | 
             
            ASSOCS.inner.insert(:org_id=>o.id, :user_id=>u.id, :last_updated_by=>pivotal.authz_id,
         | 
| 35 50 | 
             
            	:created_at=>now, :updated_at=>now )
         | 
| 36 51 | 
             
            ```
         | 
| 52 | 
            +
             | 
| 53 | 
            +
             | 
| 54 | 
            +
            * Fixing a group that lost its authz object.
         | 
| 55 | 
            +
            We've seen the users group in hosted loose it's authz entry
         | 
| 56 | 
            +
             | 
| 57 | 
            +
            ```ruby
         | 
| 58 | 
            +
            a = Fixie::AuthzApi.new
         | 
| 59 | 
            +
            # create a new authz group
         | 
| 60 | 
            +
            g = a.post("groups",{})
         | 
| 61 | 
            +
            # check that only one group is returned
         | 
| 62 | 
            +
            ORGS['acme'].groups.by_name('users').inner.all
         | 
| 63 | 
            +
            # alter the group and insert the new authz id
         | 
| 64 | 
            +
            ORGS['acme'].groups.by_name('users').inner.update(:authz_id=>g.id)
         | 
| 65 | 
            +
            ```
         | 
| 66 | 
            +
             | 
| 67 | 
            +
            This does not add the users back to the usergs group, or re-add users
         | 
| 68 | 
            +
            all the acls that used to have the users group in them.
         | 
    
        data/doc/BulkFixup.md
    ADDED
    
    | @@ -0,0 +1,33 @@ | |
| 1 | 
            +
            Restoring acl permissions globally
         | 
| 2 | 
            +
            ============
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            If a key group is deleted (such as users)
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            * Verify that the org has issues
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            * Create/restore the group
         | 
| 9 | 
            +
            (TBW)
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            * Add the users/groups back to the group
         | 
| 12 | 
            +
            (TBW)
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            * Set the group ACL appropriately
         | 
| 15 | 
            +
            ```ruby
         | 
| 16 | 
            +
            users_group.ace_add([:create,:read,:update,:delete], org.groups['admins'])
         | 
| 17 | 
            +
            users_group.ace_add([:create,:read,:update,:delete], USERS['pivotal'])
         | 
| 18 | 
            +
            ```
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            * Restore users to the appropriate container ACLs
         | 
| 21 | 
            +
            ```ruby
         | 
| 22 | 
            +
            org = ORGS[THE_ORG]
         | 
| 23 | 
            +
            cl = %w(cookbooks data nodes roles environments policies policy_groups cookbook_artifacts)
         | 
| 24 | 
            +
            cl.each {|c| o.containers[c].ace_add([:create,:read,:update,:delete], org.groups['users']) }
         | 
| 25 | 
            +
            %w(clients).each { |c| org.containers[c].ace_add([:read,:delete], org.groups['users']) }
         | 
| 26 | 
            +
            %w(groups containers).each { |c| org.containers[c].ace_add([:read], org.groups['users']) }
         | 
| 27 | 
            +
            %w(sandboxes).each { |c| org.containers[c].ace_add([:create], org.groups['users']) }
         | 
| 28 | 
            +
            ```
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            * Then update the objects from the containers:
         | 
| 31 | 
            +
            ```ruby
         | 
| 32 | 
            +
            Fixie::BulkEditPermissions::copy_from_containers(org)
         | 
| 33 | 
            +
            ```
         | 
    
        data/doc/CommonTasks.md
    CHANGED
    
    | @@ -9,12 +9,23 @@ points | |
| 9 9 |  | 
| 10 10 | 
             
            First of all, run the automated org association checker:
         | 
| 11 11 |  | 
| 12 | 
            -
            fixie:0 > Fixie::CheckOrgAssociations.check_associations("acme")
         | 
| 13 | 
            -
            Org acme is ok (6 users)
         | 
| 12 | 
            +
                fixie:0 > Fixie::CheckOrgAssociations.check_associations("acme")
         | 
| 13 | 
            +
                Org acme is ok (6 users)
         | 
| 14 14 |  | 
| 15 15 | 
             
            If it reports a problem with a user, you may be able to fix it
         | 
| 16 16 | 
             
            automatically:
         | 
| 17 17 |  | 
| 18 | 
            -
            fixie:0 > Fixie::CheckOrgAssociations.fix_association("acme", "mary")
         | 
| 18 | 
            +
                fixie:0 > Fixie::CheckOrgAssociations.fix_association("acme", "mary")
         | 
| 19 19 |  | 
| 20 20 | 
             
            This might need to be run multiple times to fix all of the errors.
         | 
| 21 | 
            +
             | 
| 22 | 
            +
             | 
| 23 | 
            +
            Removing a user completely from an org
         | 
| 24 | 
            +
            -----------
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                [1] fixie(main)> ChefFixie::CheckOrgAssociations.remove_association('the_org', 'the_user')
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            This removes the user from the org, and removes them from all org
         | 
| 29 | 
            +
            groups. However, if the user has been individually added to an ACL we
         | 
| 30 | 
            +
            don't fix that up; it would require enumeration of the whole org, and
         | 
| 31 | 
            +
            that hasn't been implemented.
         | 
    
        data/lib/chef_fixie.rb
    CHANGED
    
    | @@ -1,5 +1,5 @@ | |
| 1 1 | 
             
            #
         | 
| 2 | 
            -
            # Copyright (c) 2014-2015 Chef Software Inc. | 
| 2 | 
            +
            # Copyright (c) 2014-2015 Chef Software Inc.
         | 
| 3 3 | 
             
            # License :: Apache License, Version 2.0
         | 
| 4 4 | 
             
            #
         | 
| 5 5 | 
             
            # Licensed under the Apache License, Version 2.0 (the "License");
         | 
| @@ -16,12 +16,13 @@ | |
| 16 16 | 
             
            #
         | 
| 17 17 | 
             
            # Author: Mark Anderson <mark@chef.io>
         | 
| 18 18 |  | 
| 19 | 
            -
            require  | 
| 20 | 
            -
             | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 19 | 
            +
            require "sequel"
         | 
| 20 | 
            +
            require_relative "chef_fixie/config"
         | 
| 21 | 
            +
            require_relative "chef_fixie/sql"
         | 
| 22 | 
            +
            require_relative "chef_fixie/sql_objects"
         | 
| 23 23 |  | 
| 24 24 | 
             
            # This doesn't work because of initialization order, figure it out.
         | 
| 25 | 
            -
             | 
| 25 | 
            +
            require_relative "chef_fixie/check_org_associations"
         | 
| 26 | 
            +
            require_relative "chef_fixie/bulk_edit_permissions"
         | 
| 26 27 |  | 
| 27 28 | 
             
            Sequel.extension :inflector
         | 
| @@ -1,5 +1,5 @@ | |
| 1 1 | 
             
            #
         | 
| 2 | 
            -
            # Copyright (c) 2014-2015 Chef Software Inc. | 
| 2 | 
            +
            # Copyright (c) 2014-2015 Chef Software Inc.
         | 
| 3 3 | 
             
            # License :: Apache License, Version 2.0
         | 
| 4 4 | 
             
            #
         | 
| 5 5 | 
             
            # Licensed under the Apache License, Version 2.0 (the "License");
         | 
| @@ -17,9 +17,9 @@ | |
| 17 17 | 
             
            # Author: Mark Anderson <mark@chef.io>
         | 
| 18 18 | 
             
            #
         | 
| 19 19 |  | 
| 20 | 
            -
            require  | 
| 21 | 
            -
             | 
| 22 | 
            -
             | 
| 20 | 
            +
            require "pp"
         | 
| 21 | 
            +
            require_relative "config"
         | 
| 22 | 
            +
            require_relative "authz_objects"
         | 
| 23 23 |  | 
| 24 24 | 
             
            module ChefFixie
         | 
| 25 25 | 
             
              module AuthzMapper
         | 
| @@ -32,7 +32,7 @@ module ChefFixie | |
| 32 32 | 
             
                #
         | 
| 33 33 | 
             
                # Much of this might be better folded up into a sql stored procedure
         | 
| 34 34 | 
             
                #
         | 
| 35 | 
            -
             | 
| 35 | 
            +
             | 
| 36 36 | 
             
                def self.included(base)
         | 
| 37 37 | 
             
                  base.extend(ClassMethods)
         | 
| 38 38 | 
             
                end
         | 
| @@ -44,9 +44,9 @@ module ChefFixie | |
| 44 44 | 
             
                  if objects.count == 1
         | 
| 45 45 | 
             
                    object = objects.first
         | 
| 46 46 | 
             
                    name = object.name
         | 
| 47 | 
            -
                    scope = | 
| 48 | 
            -
                      if object.respond_to?(:org_id) | 
| 49 | 
            -
             | 
| 47 | 
            +
                    scope =
         | 
| 48 | 
            +
                      if object.respond_to?(:org_id)
         | 
| 49 | 
            +
                        ChefFixie::Sql::Orgs.org_guid_to_name(object.org_id)
         | 
| 50 50 | 
             
                      else
         | 
| 51 51 | 
             
                        :global
         | 
| 52 52 | 
             
                      end
         | 
| @@ -57,12 +57,12 @@ module ChefFixie | |
| 57 57 | 
             
                end
         | 
| 58 58 |  | 
| 59 59 | 
             
                class ReverseMapper
         | 
| 60 | 
            -
                  attr_reader :names | 
| 61 | 
            -
             | 
| 60 | 
            +
                  attr_reader :names, :by_type, :instance
         | 
| 61 | 
            +
             | 
| 62 62 | 
             
                  def initialize
         | 
| 63 63 | 
             
                    # name of object map
         | 
| 64 64 | 
             
                    @names ||= {}
         | 
| 65 | 
            -
                    @by_type ||= {:actor=>{}, :container=>{}, :group=>{}, :object=>{}}
         | 
| 65 | 
            +
                    @by_type ||= { :actor => {}, :container => {}, :group => {}, :object => {} }
         | 
| 66 66 | 
             
                    # maps class to a pre-created instance for efficiency
         | 
| 67 67 | 
             
                    @instance ||= {}
         | 
| 68 68 | 
             
                  end
         | 
| @@ -75,14 +75,14 @@ module ChefFixie | |
| 75 75 | 
             
                    names[name] = klass
         | 
| 76 76 | 
             
                    by_type[type][name] = klass
         | 
| 77 77 | 
             
                  end
         | 
| 78 | 
            -
             | 
| 78 | 
            +
             | 
| 79 79 | 
             
                  def dump
         | 
| 80 80 | 
             
                    pp names
         | 
| 81 81 | 
             
                  end
         | 
| 82 82 |  | 
| 83 | 
            -
                  def authz_to_name(authz_id, ctype=nil)
         | 
| 83 | 
            +
                  def authz_to_name(authz_id, ctype = nil)
         | 
| 84 84 | 
             
                    types = if ctype.nil?
         | 
| 85 | 
            -
                              AuthzUtils:: | 
| 85 | 
            +
                              AuthzUtils::TYPES
         | 
| 86 86 | 
             
                            else
         | 
| 87 87 | 
             
                              [ctype]
         | 
| 88 88 | 
             
                            end
         | 
| @@ -92,52 +92,50 @@ module ChefFixie | |
| 92 92 | 
             
                        return result if result != :unknown
         | 
| 93 93 | 
             
                      end
         | 
| 94 94 | 
             
                    end
         | 
| 95 | 
            -
                     | 
| 95 | 
            +
                    :unknown
         | 
| 96 96 | 
             
                  end
         | 
| 97 97 | 
             
                end
         | 
| 98 98 |  | 
| 99 99 | 
             
                def self.mapper
         | 
| 100 100 | 
             
                  @mapper ||= ReverseMapper.new
         | 
| 101 101 | 
             
                end
         | 
| 102 | 
            -
             | 
| 102 | 
            +
             | 
| 103 103 | 
             
                def self.register(klass, name, type)
         | 
| 104 | 
            -
                   | 
| 104 | 
            +
                  mapper.register(klass, name, type)
         | 
| 105 105 | 
             
                end
         | 
| 106 106 |  | 
| 107 107 | 
             
                # Translates the json from authz for group membership and acls into a human readable form
         | 
| 108 108 | 
             
                # This makes some assumptions about the shape of the data structure, but works well enough to
         | 
| 109 109 | 
             
                # be quite useful
         | 
| 110 110 | 
             
                def self.struct_to_name(s)
         | 
| 111 | 
            -
                  mapper = AuthzMapper | 
| 111 | 
            +
                  mapper = AuthzMapper.mapper
         | 
| 112 112 | 
             
                  if s.kind_of?(Hash)
         | 
| 113 113 | 
             
                    s.keys.inject({}) do |h, k|
         | 
| 114 114 | 
             
                      v = s[k]
         | 
| 115 115 | 
             
                      if v.kind_of?(Array)
         | 
| 116 116 | 
             
                        case k
         | 
| 117 | 
            -
                        when  | 
| 118 | 
            -
                          h[k] = v.map {|a| mapper.authz_to_name(a | 
| 119 | 
            -
                        when  | 
| 120 | 
            -
                          h[k] = v.map {|a| mapper.authz_to_name(a | 
| 117 | 
            +
                        when "actors"
         | 
| 118 | 
            +
                          h[k] = v.map { |a| mapper.authz_to_name(a, :actor) } #.sort We should sort these, but the way we're returning unknown causes sort
         | 
| 119 | 
            +
                        when "groups"
         | 
| 120 | 
            +
                          h[k] = v.map { |a| mapper.authz_to_name(a, :group) } #.sort to fail
         | 
| 121 121 | 
             
                        else
         | 
| 122 122 | 
             
                          h[k] = v
         | 
| 123 123 | 
             
                        end
         | 
| 124 124 | 
             
                      else
         | 
| 125 | 
            -
                        h[k] =  | 
| 125 | 
            +
                        h[k] = struct_to_name(v)
         | 
| 126 126 | 
             
                      end
         | 
| 127 127 | 
             
                      h
         | 
| 128 128 | 
             
                    end
         | 
| 129 129 | 
             
                  end
         | 
| 130 130 | 
             
                end
         | 
| 131 | 
            -
             | 
| 131 | 
            +
             | 
| 132 132 | 
             
                module ClassMethods
         | 
| 133 133 | 
             
                  # TODO: We should be able to automatically figure out the type somehow.
         | 
| 134 134 | 
             
                  # At minimum should figure out a self check
         | 
| 135 135 | 
             
                  def register_authz(name, type)
         | 
| 136 | 
            -
                    AuthzMapper | 
| 136 | 
            +
                    AuthzMapper.register(self, name, type)
         | 
| 137 137 | 
             
                  end
         | 
| 138 138 | 
             
                end
         | 
| 139 | 
            -
             | 
| 139 | 
            +
             | 
| 140 140 | 
             
              end
         | 
| 141 141 | 
             
            end
         | 
| 142 | 
            -
             | 
| 143 | 
            -
              
         | 
| @@ -17,16 +17,16 @@ | |
| 17 17 | 
             
            # Author: Mark Anderson <mark@chef.io>
         | 
| 18 18 | 
             
            #
         | 
| 19 19 |  | 
| 20 | 
            -
            require  | 
| 21 | 
            -
            require  | 
| 22 | 
            -
            require  | 
| 20 | 
            +
            require "pp"
         | 
| 21 | 
            +
            require "ffi_yajl"
         | 
| 22 | 
            +
            require "chef/http"
         | 
| 23 23 |  | 
| 24 | 
            -
             | 
| 24 | 
            +
            require_relative "config"
         | 
| 25 25 |  | 
| 26 26 | 
             
            module ChefFixie
         | 
| 27 27 |  | 
| 28 28 | 
             
              class AuthzApi
         | 
| 29 | 
            -
                def initialize(user=nil)
         | 
| 29 | 
            +
                def initialize(user = nil)
         | 
| 30 30 | 
             
                  @requestor_authz = user ? user : ChefFixie.configure { |x| x.superuser_id }
         | 
| 31 31 | 
             
                  @auth_uri ||= ChefFixie.configure { |x| x.authz_uri }
         | 
| 32 32 | 
             
                  @rest = Chef::HTTP.new(@auth_uri)
         | 
| @@ -42,38 +42,41 @@ module ChefFixie | |
| 42 42 |  | 
| 43 43 | 
             
                def get(resource)
         | 
| 44 44 | 
             
                  result = @rest.get(resource,
         | 
| 45 | 
            -
                                      | 
| 46 | 
            -
                                      | 
| 47 | 
            -
                                      | 
| 45 | 
            +
                                     "Content-Type" => "application/json",
         | 
| 46 | 
            +
                                     "Accept" => "application/json",
         | 
| 47 | 
            +
                                     "X-Ops-Requesting-Actor-Id" => @requestor_authz)
         | 
| 48 48 | 
             
                  FFI_Yajl::Parser.parse(result)
         | 
| 49 49 | 
             
                end
         | 
| 50 | 
            +
             | 
| 50 51 | 
             
                def put(resource, data)
         | 
| 51 | 
            -
                  result = @rest.put(resource,  | 
| 52 | 
            -
                                      | 
| 53 | 
            -
                                      | 
| 54 | 
            -
                                      | 
| 52 | 
            +
                  result = @rest.put(resource, json_helper(data),
         | 
| 53 | 
            +
                                     "Content-Type" => "application/json",
         | 
| 54 | 
            +
                                     "Accept" => "application/json",
         | 
| 55 | 
            +
                                     "X-Ops-Requesting-Actor-Id" => @requestor_authz)
         | 
| 55 56 | 
             
                  FFI_Yajl::Parser.parse(result)
         | 
| 56 57 | 
             
                end
         | 
| 58 | 
            +
             | 
| 57 59 | 
             
                def post(resource, data)
         | 
| 58 | 
            -
                  result = @rest.post(resource,  | 
| 59 | 
            -
                                       | 
| 60 | 
            -
                                       | 
| 61 | 
            -
                                       | 
| 60 | 
            +
                  result = @rest.post(resource, json_helper(data),
         | 
| 61 | 
            +
                                      "Content-Type" => "application/json",
         | 
| 62 | 
            +
                                      "Accept" => "application/json",
         | 
| 63 | 
            +
                                      "X-Ops-Requesting-Actor-Id" => @requestor_authz)
         | 
| 62 64 | 
             
                  FFI_Yajl::Parser.parse(result)
         | 
| 63 65 | 
             
                end
         | 
| 66 | 
            +
             | 
| 64 67 | 
             
                def delete(resource)
         | 
| 65 68 | 
             
                  result = @rest.delete(resource,
         | 
| 66 | 
            -
                                         | 
| 67 | 
            -
                                         | 
| 68 | 
            -
                                         | 
| 69 | 
            +
                                        "Content-Type" => "application/json",
         | 
| 70 | 
            +
                                        "Accept" => "application/json",
         | 
| 71 | 
            +
                                        "X-Ops-Requesting-Actor-Id" => @requestor_authz)
         | 
| 69 72 | 
             
                  FFI_Yajl::Parser.parse(result)
         | 
| 70 73 | 
             
                end
         | 
| 71 74 |  | 
| 72 75 | 
             
              end
         | 
| 73 76 |  | 
| 74 77 | 
             
              module AuthzUtils
         | 
| 75 | 
            -
                 | 
| 76 | 
            -
                 | 
| 78 | 
            +
                TYPES = [:object, :actor, :group, :container] # order is an attempt to optimize by most probable.
         | 
| 79 | 
            +
                ACTIONS = [:create, :read, :update, :delete, :grant]
         | 
| 77 80 |  | 
| 78 81 | 
             
                def to_resource(t)
         | 
| 79 82 | 
             
                  # This is a rails thing... t.to_s.pluralize
         | 
| @@ -81,20 +84,20 @@ module ChefFixie | |
| 81 84 | 
             
                end
         | 
| 82 85 |  | 
| 83 86 | 
             
                def get_type(id)
         | 
| 84 | 
            -
                   | 
| 87 | 
            +
                  TYPES.each do |t|
         | 
| 85 88 | 
             
                    begin
         | 
| 86 | 
            -
                      r = AuthzApi.get("#{ | 
| 89 | 
            +
                      r = AuthzApi.get("#{to_resource(t)}/#{id}")
         | 
| 87 90 | 
             
                      return t
         | 
| 88 | 
            -
                    rescue RestClient::ResourceNotFound=>e
         | 
| 91 | 
            +
                    rescue RestClient::ResourceNotFound => e
         | 
| 89 92 | 
             
                      # expected if not found
         | 
| 90 93 | 
             
                    end
         | 
| 91 94 | 
             
                  end
         | 
| 92 | 
            -
                   | 
| 95 | 
            +
                  :none
         | 
| 93 96 | 
             
                end
         | 
| 94 97 |  | 
| 95 98 | 
             
                def check_action(action)
         | 
| 96 99 | 
             
                  # TODO Improve; stack trace isn't the best way to communicate with the user
         | 
| 97 | 
            -
                  raise "#{action} not one of #{ | 
| 100 | 
            +
                  raise "#{action} not one of #{ACTIONS.join(', ')} " if !ACTIONS.member?(action)
         | 
| 98 101 | 
             
                end
         | 
| 99 102 |  | 
| 100 103 | 
             
                def check_actor_or_group(a_or_g)
         | 
| @@ -102,7 +105,7 @@ module ChefFixie | |
| 102 105 | 
             
                end
         | 
| 103 106 |  | 
| 104 107 | 
             
                def resourcify_actor_or_group(a_or_g)
         | 
| 105 | 
            -
                  return a_or_g if  | 
| 108 | 
            +
                  return a_or_g if %w{actors groups}.member?(a_or_g)
         | 
| 106 109 | 
             
                  check_actor_or_group(a_or_g)
         | 
| 107 110 | 
             
                  to_resource(a_or_g)
         | 
| 108 111 | 
             
                end
         | 
| @@ -131,10 +134,9 @@ module ChefFixie | |
| 131 134 | 
             
                end
         | 
| 132 135 |  | 
| 133 136 | 
             
                def authz_api
         | 
| 134 | 
            -
             | 
| 137 | 
            +
                  @@authz_api_as_superuser ||= AuthzApi.new
         | 
| 135 138 | 
             
                end
         | 
| 136 139 |  | 
| 137 | 
            -
             | 
| 138 140 | 
             
                # we expect to be mixed in with a class that has the authz_id method
         | 
| 139 141 | 
             
                def prefix
         | 
| 140 142 | 
             
                  "#{to_resource(type)}/#{authz_id}"
         | 
| @@ -145,9 +147,14 @@ module ChefFixie | |
| 145 147 | 
             
                  [:unparsed, result] # todo figure this out in more detail
         | 
| 146 148 | 
             
                end
         | 
| 147 149 |  | 
| 150 | 
            +
                def authz_delete
         | 
| 151 | 
            +
                  authz_api.delete(prefix)
         | 
| 152 | 
            +
                end
         | 
| 153 | 
            +
             | 
| 148 154 | 
             
                def acl_raw
         | 
| 149 155 | 
             
                  authz_api.get("#{prefix}/acl")
         | 
| 150 156 | 
             
                end
         | 
| 157 | 
            +
             | 
| 151 158 | 
             
                # Todo: filter this by scope and type
         | 
| 152 159 | 
             
                def acl
         | 
| 153 160 | 
             
                  ChefFixie::AuthzMapper.struct_to_name(acl_raw)
         | 
| @@ -161,11 +168,11 @@ module ChefFixie | |
| 161 168 | 
             
                  [resource, ace]
         | 
| 162 169 | 
             
                end
         | 
| 163 170 |  | 
| 164 | 
            -
             | 
| 165 171 | 
             
                def ace_raw(action)
         | 
| 166 | 
            -
                  resource,ace = ace_get_util(action)
         | 
| 172 | 
            +
                  resource, ace = ace_get_util(action)
         | 
| 167 173 | 
             
                  ace
         | 
| 168 174 | 
             
                end
         | 
| 175 | 
            +
             | 
| 169 176 | 
             
                # Todo: filter this by scope and type
         | 
| 170 177 | 
             
                def ace(action)
         | 
| 171 178 | 
             
                  ChefFixie::AuthzMapper.struct_to_name(ace_raw(action))
         | 
| @@ -173,14 +180,11 @@ module ChefFixie | |
| 173 180 |  | 
| 174 181 | 
             
                def expand_actions(action)
         | 
| 175 182 | 
             
                  if action == :all
         | 
| 176 | 
            -
                    action = AuthzUtils:: | 
| 183 | 
            +
                    action = AuthzUtils::ACTIONS
         | 
| 177 184 | 
             
                  end
         | 
| 178 185 | 
             
                  action.is_a?(Array) ? action : [action]
         | 
| 179 | 
            -
                end
         | 
| 180 | 
            -
             | 
| 181 | 
            -
             | 
| 186 | 
            +
                end # add actor or group to acl
         | 
| 182 187 |  | 
| 183 | 
            -
                # add actor or group to acl
         | 
| 184 188 | 
             
                def ace_add_raw(action, actor_or_group, entity)
         | 
| 185 189 | 
             
                  # groups or actors
         | 
| 186 190 | 
             
                  a_or_g_resource = resourcify_actor_or_group(actor_or_group)
         | 
| @@ -190,9 +194,10 @@ module ChefFixie | |
| 190 194 | 
             
                  ace[a_or_g_resource].uniq!
         | 
| 191 195 | 
             
                  authz_api.put("#{resource}", ace)
         | 
| 192 196 | 
             
                end
         | 
| 197 | 
            +
             | 
| 193 198 | 
             
                def ace_add(action, entity)
         | 
| 194 199 | 
             
                  actions = expand_actions(action)
         | 
| 195 | 
            -
                  actions.each {|a| ace_add_raw(a, entity.type, entity) }
         | 
| 200 | 
            +
                  actions.each { |a| ace_add_raw(a, entity.type, entity) }
         | 
| 196 201 | 
             
                end
         | 
| 197 202 |  | 
| 198 203 | 
             
                def ace_delete_raw(action, actor_or_group, entity)
         | 
| @@ -207,7 +212,7 @@ module ChefFixie | |
| 207 212 |  | 
| 208 213 | 
             
                def ace_delete(action, entity)
         | 
| 209 214 | 
             
                  actions = expand_actions(action)
         | 
| 210 | 
            -
                  actions.each {|a| ace_delete_raw(a, entity.type, entity) }
         | 
| 215 | 
            +
                  actions.each { |a| ace_delete_raw(a, entity.type, entity) }
         | 
| 211 216 | 
             
                end
         | 
| 212 217 |  | 
| 213 218 | 
             
                def ace_member?(action, entity)
         | 
| @@ -216,7 +221,6 @@ module ChefFixie | |
| 216 221 | 
             
                  ace[a_or_g_resource].member?(entity.authz_id)
         | 
| 217 222 | 
             
                end
         | 
| 218 223 |  | 
| 219 | 
            -
             | 
| 220 224 | 
             
                def acl_add_from_object(object)
         | 
| 221 225 | 
             
                  src = object.acl_raw
         | 
| 222 226 |  | 
| @@ -254,15 +258,21 @@ module ChefFixie | |
| 254 258 | 
             
                def group_raw
         | 
| 255 259 | 
             
                  authz_api.get("#{prefix}")
         | 
| 256 260 | 
             
                end
         | 
| 261 | 
            +
             | 
| 257 262 | 
             
                # Todo: filter this by scope and type
         | 
| 258 263 | 
             
                def group
         | 
| 259 264 | 
             
                  ChefFixie::AuthzMapper.struct_to_name(group_raw)
         | 
| 260 265 | 
             
                end
         | 
| 261 266 |  | 
| 267 | 
            +
                def list
         | 
| 268 | 
            +
                  group
         | 
| 269 | 
            +
                end
         | 
| 270 | 
            +
             | 
| 262 271 | 
             
                def group_add_raw(actor_or_group, entity)
         | 
| 263 272 | 
             
                  entity_resource = to_resource(actor_or_group)
         | 
| 264 | 
            -
                  authz_api.put("#{prefix}/#{entity_resource}/#{entity.authz_id}",{})
         | 
| 273 | 
            +
                  authz_api.put("#{prefix}/#{entity_resource}/#{entity.authz_id}", {})
         | 
| 265 274 | 
             
                end
         | 
| 275 | 
            +
             | 
| 266 276 | 
             
                def group_add(entity)
         | 
| 267 277 | 
             
                  group_add_raw(entity.type, entity)
         | 
| 268 278 | 
             
                end
         | 
| @@ -278,7 +288,7 @@ module ChefFixie | |
| 278 288 |  | 
| 279 289 | 
             
                def member?(entity)
         | 
| 280 290 | 
             
                  members = group_raw
         | 
| 281 | 
            -
                   | 
| 291 | 
            +
                  members[resourcify_actor_or_group(entity.type)].member?(entity.authz_id)
         | 
| 282 292 | 
             
                end
         | 
| 283 293 | 
             
              end
         | 
| 284 294 |  |