anchor.diff:              throw({not_found, Name});
           #chef_environment{authz_id = AuthzId} ->
               AuthzId
  -    end;
  -fetch_id(organization, _DbContext, _Name, _OrgId) ->
  -    % TODO: implement; this is different than all the others
  -    error(not_implemented).
  +    end.
   
   % TODO: bespoke code; cookbooks retrieval is by orgname instead of ID
   fetch_cookbook_id(DbContext, Name, OrgName) ->
  
positive.code:                       OrgName, DbContext).
  
  validate_authz_id(Req, State, AclState, Type, OrgId, OrgName, DbContext) ->
      Name = chef_wm_util:object_name(Type, Req),
      io:format("---val got name: ~p~n", [Name]),
      try
          AuthzId = case Type of
                        cookbook ->
                            fetch_cookbook_id(DbContext, Name, OrgName);
                        Other ->
                            fetch_id(Other, DbContext, Name, OrgId)
                    end,
          io:format("---val got authzId: ~p~n", [AuthzId]),
          AclState1 = AclState#acl_state{authz_id = AuthzId},
  
negative.code:             Other
      end.
  
  convert_group_ids_to_names(AuthzIds) ->
      oc_chef_group:find_groups_names(AuthzIds, fun chef_sql:select_rows/1).
  
  convert_actor_ids_to_names(AuthzIds) ->
      {ClientNames, RemainingAuthzIds} =
          oc_chef_group:find_clients_names(AuthzIds, fun chef_sql:select_rows/1),
      {UserNames, DefunctActorAuthzIds} =
          oc_chef_group:find_users_names(RemainingAuthzIds, fun chef_sql:select_rows/1),
      {ClientNames ++ UserNames, DefunctActorAuthzIds}.
  
  process_part(Part, Record) ->
      io:format("---part: ~p~n", [Part]),
      Members = ej:get({Part}, Record),
      ActorIds = ej:get({<<"actors">>}, Members),
      GroupIds = ej:get({<<"groups">>}, Members),
      {ActorNames, DefunctActorAuthzIds} = convert_actor_ids_to_names(ActorIds),
      {GroupNames, DefunctGroupAuthzIds} = convert_group_ids_to_names(GroupIds),
      % We do this for groups, probably good to do it here too
      oc_chef_authz_cleanup:add_authz_ids(DefunctActorAuthzIds, DefunctGroupAuthzIds),
      Members1 = ej:set({<<"actors">>}, Members, ActorNames),
      Members2 = ej:set({<<"groups">>}, Members1, GroupNames),
      ej:set({Part}, Record, Members2).
  
  ids_to_names(Record) ->
      Record1 = process_part(<<"create">>, Record),
      Record2 = process_part(<<"read">>, Record1),
      Record3 = process_part(<<"update">>, Record2),
      Record4 = process_part(<<"delete">>, Record3),
      process_part(<<"grant">>, Record4).
  
  from_json(Req, #base_state{requestor_id = RequestorId,
                             organization_guid = OrgId,
                             resource_state = AclState} = State) ->
      io:format("---from json~n", []),
      case update_from_json(AclState, OrgId, RequestorId) of
          forbidden ->
              {{halt, 403}, Req, State#base_state{log_msg = acl_not_found}};
          _Other ->
              {true, Req, State}
      end.
  
  update_from_json(#acl_state{type = Type, authz_id = AuthzId, acl_data = Data}, OrgId,
                   RequestorId) ->
      % This is probably dangerous (in that one type of permission could be
      % updated, and a future type could fail); however, I'm not sure what can
      % be really done about it.  It theoretically shouldn't happen in practice,
      % but you know what they say about theory and practice
      try
          update_part(<<"create">>, Data, Type, AuthzId, OrgId, RequestorId),
          update_part(<<"read">>, Data, Type, AuthzId, OrgId, RequestorId),
          update_part(<<"delete">>, Data, Type, AuthzId, OrgId, RequestorId),
          update_part(<<"update">>, Data, Type, AuthzId, OrgId, RequestorId),
          update_part(<<"grant">>, Data, Type, AuthzId, OrgId, RequestorId)
      catch
          throw:forbidden ->
              forbidden
      end.
  
  convert_group_names_to_ids(GroupNames, OrgId) ->
      oc_chef_group:find_group_authz_ids(GroupNames, OrgId, fun chef_sql:select_rows/1).
  
  convert_actor_names_to_ids(Names, OrgId) ->
      ClientIds = oc_chef_group:find_client_authz_ids(Names, OrgId,
                                                      fun chef_sql:select_rows/1),
      UserIds = oc_chef_group:find_user_authz_ids(Names, fun chef_sql:select_rows/1),
      ClientIds ++ UserIds.
  
  names_to_ids(Ace, OrgId) ->
      ActorNames = ej:get({<<"actors">>}, Ace),
      GroupNames = ej:get({<<"groups">>}, Ace),
      ActorIds = convert_actor_names_to_ids(ActorNames, OrgId),
      GroupIds = convert_group_names_to_ids(GroupNames, OrgId),
      Ace1 = ej:set({<<"actors">>}, Ace, ActorIds),
      ej:set({<<"groups">>}, Ace1, GroupIds).
  
  update_part(Part, AclRecord, Type, AuthzId, OrgId, RequestorId) ->
      io:format("---update part: ~p~n", [Part]),
      Slice = names_to_ids(ej:get({Part}, AclRecord), OrgId),
      Path = acl_path(Type, AuthzId) ++ "/" ++ Part,
      Result = oc_chef_authz_http:request(Path, put, ?DEFAULT_HEADERS, Slice, RequestorId),
      case Result of
          {error, forbidden} ->
              throw(forbidden);
          Other ->
              Other
      end.
  