summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjiahuili <Jiahui.Li@ibm.com>2021-11-02 23:42:39 -0500
committerNick Vatamaniuc <nickva@users.noreply.github.com>2021-11-08 14:29:35 -0500
commit990b4944f50ab9c6a50a3c05ffa6cf41a07745da (patch)
tree635adc29debec7171f32b9cae958ef6477aea91d
parent283159f7be1f6c1aea3d5d73f075e76d84d02778 (diff)
downloadcouchdb-990b4944f50ab9c6a50a3c05ffa6cf41a07745da.tar.gz
Using _bulk_docs with new_edits false and without _rev should responds 400 Bad Request
-rw-r--r--src/chttpd/src/chttpd_db.erl12
-rw-r--r--src/chttpd/test/eunit/chttpd_db_test.erl32
2 files changed, 43 insertions, 1 deletions
diff --git a/src/chttpd/src/chttpd_db.erl b/src/chttpd/src/chttpd_db.erl
index 95457ff94..8d45eb779 100644
--- a/src/chttpd/src/chttpd_db.erl
+++ b/src/chttpd/src/chttpd_db.erl
@@ -535,15 +535,17 @@ db_req(#httpd{method='POST',path_parts=[_,<<"_bulk_docs">>], user_ctx=Ctx}=Req,
_ ->
Options = [{user_ctx,Ctx}, {w,W}]
end,
+ NewEdits = couch_util:get_value(<<"new_edits">>, JsonProps, true),
Docs = lists:map(fun(JsonObj) ->
Doc = couch_db:doc_from_json_obj_validate(Db, JsonObj),
+ validate_revs(Doc, NewEdits),
validate_attachment_names(Doc),
case Doc#doc.id of
<<>> -> Doc#doc{id = couch_uuids:new()};
_ -> Doc
end
end, DocsArray),
- case couch_util:get_value(<<"new_edits">>, JsonProps, true) of
+ case NewEdits of
true ->
Options2 =
case couch_util:get_value(<<"all_or_nothing">>, JsonProps) of
@@ -1960,6 +1962,14 @@ validate_security_can_be_edited(DbName) ->
{_,_} -> ok
end.
+validate_revs(_Doc, true) ->
+ ok;
+validate_revs(#doc{revs = {0, []}}, false) ->
+ throw({bad_request, ?l2b("When `new_edits: false`, " ++
+ "the document needs `_rev` or `_revisions` specified")});
+validate_revs(_Doc, false) ->
+ ok.
+
validate_attachment_names(Doc) ->
lists:foreach(fun(Att) ->
Name = couch_att:fetch(name, Att),
diff --git a/src/chttpd/test/eunit/chttpd_db_test.erl b/src/chttpd/test/eunit/chttpd_db_test.erl
index 6ae5ad061..15e75393c 100644
--- a/src/chttpd/test/eunit/chttpd_db_test.erl
+++ b/src/chttpd/test/eunit/chttpd_db_test.erl
@@ -62,6 +62,8 @@ all_test_() ->
fun setup/0, fun teardown/1,
[
fun should_return_ok_true_on_bulk_update/1,
+ fun should_return_201_new_edits_false_with_revs_on_bulk_update/1,
+ fun should_return_400_new_edits_false_no_revs_on_bulk_update/1,
fun should_return_ok_true_on_ensure_full_commit/1,
fun should_return_404_for_ensure_full_commit_on_no_db/1,
fun should_accept_live_as_an_alias_for_continuous/1,
@@ -106,6 +108,36 @@ should_return_ok_true_on_bulk_update(Url) ->
end)}.
+should_return_201_new_edits_false_with_revs_on_bulk_update(Url) ->
+ {timeout, ?TIMEOUT, ?_test(
+ begin
+ {ok, _, _, Body} = create_doc(Url, "dochasrev"),
+ {Json} = ?JSON_DECODE(Body),
+ Ref = couch_util:get_value(<<"rev">>, Json, undefined),
+ NewDoc = "{\"docs\": [{\"_rev\": \"" ++ ?b2l(Ref) ++
+ "\", \"_id\": \"dochasrev\"}], \"new_edits\": false}",
+ {ok, Status, _, ResultBody} = test_request:post(Url ++
+ "/_bulk_docs/", [?CONTENT_JSON, ?AUTH], NewDoc),
+ ?assertEqual(201, Status),
+ ?assertEqual([], ?JSON_DECODE(ResultBody))
+ end)}.
+
+
+should_return_400_new_edits_false_no_revs_on_bulk_update(Url) ->
+ {timeout, ?TIMEOUT, ?_test(
+ begin
+ {ok, _, _, _} = create_doc(Url, "docnorev"),
+ NewDoc = "{\"docs\": [{\"_id\": \"docnorev\"}], "
+ ++ "\"new_edits\": false}",
+ {ok, Status, _, ResultBody} = test_request:post(Url ++
+ "/_bulk_docs/", [?CONTENT_JSON, ?AUTH], NewDoc),
+ {ResultJson} = ?JSON_DECODE(ResultBody),
+ ?assertEqual(400, Status),
+ ?assertEqual(<<"bad_request">>,
+ couch_util:get_value(<<"error">>, ResultJson))
+ end)}.
+
+
should_return_ok_true_on_ensure_full_commit(Url0) ->
{timeout, ?TIMEOUT, ?_test(begin
Url = Url0 ++ "/_ensure_full_commit",