anchor.diff:                doc,          %% {ok, riak_object()}|{error, term()} - the object found
                 bucketprops,  %% proplist() - properties of the bucket
                 method,       %% atom() - HTTP method for the request
  -              counter_op    :: integer() | undefined %% The amount to add to the counter
  +              counter_op    :: integer() | undefined, %% The amount to add to the counter
  +              security      %% security context
                }).
   %% @type link() = {{Bucket::binary(), Key::binary()}, Tag::binary()}
   %% @type index_field() = {Key::string(), Value::string()}
  
positive.code: -export([
           init/1,
           service_available/2,
           forbidden/2,
           allowed_methods/2,
           malformed_request/2,
  
negative.code:              Ctx}
      end.
  
  is_authorized(ReqData, Ctx) ->
      case riak_api_web_security:is_authorized(ReqData) of
          false ->
              {"Basic realm=\"Riak\"", ReqData, Ctx};
          {true, SecContext} ->
              {true, ReqData, Ctx#ctx{security=SecContext}};
          insecure ->
              %% XXX 301 may be more appropriate here, but since the http and
              %% https port are different and configurable, it is hard to figure
              %% out the redirect URL to serve.
              {{halt, 426}, wrq:append_to_resp_body(<<"Security is enabled and "
                      "Riak does not accept credentials over HTTP. Try HTTPS "
                      "instead.">>, ReqData), Ctx}
      end.
  
  forbidden(RD, Ctx=#ctx{security = undefined}) ->
      {riak_kv_wm_utils:is_forbidden(RD), RD, Ctx};
  forbidden(RD, Ctx=#ctx{security=Security}) ->
      case riak_kv_wm_utils:is_forbidden(RD) of
          true ->
              {true, RD, Ctx};
          false ->
              Perm = case Ctx#ctx.method of
                  'POST' ->
                      "riak_kv.put";
                  'GET' ->
                      "riak_kv.get"
              end,
  
              Res = riak_core_security:check_permission({Perm,
                                                             {<<"default">>,
                                                              Ctx#ctx.bucket}},
                                                             Security),
              case Res of
                  {false, Error, _} ->
                      RD1 = wrq:set_resp_header("Content-Type", "text/plain", RD),
                      {true, wrq:append_to_resp_body(list_to_binary(Error), RD1), Ctx};
                  {true, _} ->
                      {false, RD, Ctx}
              end
      end.
  
  allowed_methods(RD, Ctx) ->
      {['GET', 'POST'], RD, Ctx}.
  