diff options
author | jiahuili <Jiahui.Li@ibm.com> | 2021-11-02 23:42:39 -0500 |
---|---|---|
committer | Nick Vatamaniuc <nickva@users.noreply.github.com> | 2021-11-08 14:29:35 -0500 |
commit | 990b4944f50ab9c6a50a3c05ffa6cf41a07745da (patch) | |
tree | 635adc29debec7171f32b9cae958ef6477aea91d | |
parent | 283159f7be1f6c1aea3d5d73f075e76d84d02778 (diff) | |
download | couchdb-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.erl | 12 | ||||
-rw-r--r-- | src/chttpd/test/eunit/chttpd_db_test.erl | 32 |
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", |