summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBessenyei Balázs Donát <bessbd@apache.org>2020-06-17 20:09:11 +0200
committergarren smith <garren.smith@gmail.com>2020-06-18 14:40:22 +0200
commit6659dbbd7c556b8dc00c075e331d7b106d44088d (patch)
tree953ef9bae888ef63eda95a6215ca30d2fea4812c
parenta7803fb2023b72b684f8d2f1198363b9d6723400 (diff)
downloadcouchdb-6659dbbd7c556b8dc00c075e331d7b106d44088d.tar.gz
Make restricted partition search parameters return bad request
According to https://docs.couchdb.org/en/master/ddocs/search.html there are parameters for searches that are not allowed for partitioned queries. Those restrictions were not enforced, thus making the software and docs inconsistent. This commit adds them to validation so that the behavior matches the one described in the docs.
-rw-r--r--src/dreyfus/src/dreyfus_httpd.erl22
-rw-r--r--src/dreyfus/test/elixir/test/partition_search_test.exs36
2 files changed, 50 insertions, 8 deletions
diff --git a/src/dreyfus/src/dreyfus_httpd.erl b/src/dreyfus/src/dreyfus_httpd.erl
index 346f5ede6..f0a130ef2 100644
--- a/src/dreyfus/src/dreyfus_httpd.erl
+++ b/src/dreyfus/src/dreyfus_httpd.erl
@@ -447,10 +447,15 @@ validate_search_restrictions(Db, DDoc, Args) ->
q = Query,
partition = Partition,
grouping = Grouping,
- limit = Limit
+ limit = Limit,
+ counts = Counts,
+ drilldown = Drilldown,
+ ranges = Ranges
} = Args,
#grouping{
- by = GroupBy
+ by = GroupBy,
+ limit = GroupLimit,
+ sort = GroupSort
} = Grouping,
case Query of
@@ -496,9 +501,18 @@ validate_search_restrictions(Db, DDoc, Args) ->
parse_non_negative_int_param("limit", Limit, "max_limit", MaxLimit)
end,
- case GroupBy /= nil andalso is_binary(Partition) of
+ DefaultArgs = #index_query_args{},
+
+ case is_binary(Partition) andalso (
+ Counts /= DefaultArgs#index_query_args.counts
+ orelse Drilldown /= DefaultArgs#index_query_args.drilldown
+ orelse Ranges /= DefaultArgs#index_query_args.ranges
+ orelse GroupSort /= DefaultArgs#index_query_args.grouping#grouping.sort
+ orelse GroupBy /= DefaultArgs#index_query_args.grouping#grouping.by
+ orelse GroupLimit /= DefaultArgs#index_query_args.grouping#grouping.limit
+ ) of
true ->
- Msg5 = <<"`group_by` and `partition` are incompatible">>,
+ Msg5 = <<"`partition` and any of `drilldown`, `ranges`, `group_field`, `group_sort`, `group_limit` or `group_by` are incompatible">>,
throw({bad_request, Msg5});
false ->
ok
diff --git a/src/dreyfus/test/elixir/test/partition_search_test.exs b/src/dreyfus/test/elixir/test/partition_search_test.exs
index 19a915ad3..121995449 100644
--- a/src/dreyfus/test/elixir/test/partition_search_test.exs
+++ b/src/dreyfus/test/elixir/test/partition_search_test.exs
@@ -21,7 +21,7 @@ defmodule PartitionSearchTest do
}
end
- resp = Couch.post("/#{db_name}/_bulk_docs", body: %{:docs => docs}, query: %{w: 3})
+ resp = Couch.post("/#{db_name}/_bulk_docs", headers: ["Content-Type": "application/json"], body: %{:docs => docs}, query: %{w: 3})
assert resp.status_code in [201, 202]
end
@@ -166,7 +166,7 @@ defmodule PartitionSearchTest do
resp = Couch.get(url, query: %{q: "some:field"})
assert resp.status_code == 200
ids = get_ids(resp)
- assert ids == ["bar:1", "bar:5", "bar:9", "foo:2", "bar:3", "foo:4", "foo:6", "bar:7", "foo:8", "foo:10"]
+ assert Enum.sort(ids) == Enum.sort(["bar:1", "bar:5", "bar:9", "foo:2", "bar:3", "foo:4", "foo:6", "bar:7", "foo:8", "foo:10"])
end
@tag :with_db
@@ -179,7 +179,7 @@ defmodule PartitionSearchTest do
resp = Couch.get(url, query: %{q: "some:field"})
assert resp.status_code == 200
ids = get_ids(resp)
- assert ids == ["bar:1", "bar:5", "bar:9", "foo:2", "bar:3", "foo:4", "foo:6", "bar:7", "foo:8", "foo:10"]
+ assert Enum.sort(ids) == Enum.sort(["bar:1", "bar:5", "bar:9", "foo:2", "bar:3", "foo:4", "foo:6", "bar:7", "foo:8", "foo:10"])
end
@tag :with_db
@@ -192,7 +192,7 @@ defmodule PartitionSearchTest do
resp = Couch.get(url, query: %{q: "some:field", limit: 3})
assert resp.status_code == 200
ids = get_ids(resp)
- assert ids == ["bar:1", "bar:5", "bar:9"]
+ assert Enum.sort(ids) == Enum.sort(["bar:1", "bar:5", "bar:9"])
end
@tag :with_db
@@ -216,4 +216,32 @@ defmodule PartitionSearchTest do
resp = Couch.post(url, body: %{q: "some:field", partition: "bar"})
assert resp.status_code == 400
end
+
+ @tag :with_partitioned_db
+ test "restricted parameters are not allowed in query or body", context do
+ db_name = context[:db_name]
+ create_search_docs(db_name)
+ create_ddoc(db_name)
+
+ body = %{q: "some:field", partition: "foo"}
+
+ Enum.each(
+ [
+ {:counts, "[\"type\"]"},
+ {:group_field, "some"},
+ {:ranges, :jiffy.encode(%{price: %{cheap: "[0 TO 100]"}})},
+ {:drilldown, "[\"key\",\"a\"]"},
+ ],
+ fn {key, value} ->
+ url = "/#{db_name}/_partition/foo/_design/library/_search/books"
+ bannedparam = Map.put(body, key, value)
+ get_resp = Couch.get(url, query: bannedparam)
+ %{:body => %{"reason" => get_reason}} = get_resp
+ assert Regex.match?(~r/are incompatible/, get_reason)
+ post_resp = Couch.post(url, body: bannedparam)
+ %{:body => %{"reason" => post_reason}} = post_resp
+ assert Regex.match?(~r/are incompatible/, post_reason)
+ end
+ )
+ end
end