From ba00ce4485e68ae5bda4a9a8408293cefb9a4b98 Mon Sep 17 00:00:00 2001 From: Garren Smith Date: Tue, 5 Feb 2019 16:47:39 +0200 Subject: Add check for repeated `partition` definitions This is a usability improvement. If someone specifies the a `partition` value in the query string that is different than the `partition` value in the URL path it is not clear which value would be used. This allows specifying it in both places as long as the query string matches the URL path and throws a 400 Bad Request error otherwise. Co-Authored-By: Garren Smith --- src/chttpd/src/chttpd_db.erl | 8 +++++++- test/elixir/test/partition_view_test.exs | 10 ++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/chttpd/src/chttpd_db.erl b/src/chttpd/src/chttpd_db.erl index 7a00d2b1b..003b0d8dc 100644 --- a/src/chttpd/src/chttpd_db.erl +++ b/src/chttpd/src/chttpd_db.erl @@ -282,7 +282,13 @@ handle_partition_req(#httpd{path_parts=[DbName, _, PartId | Rest]}=Req, Db) -> true -> couch_partition:validate_partition(PartId), QS = chttpd:qs(Req), - NewQS = lists:ukeysort(1, [{"partition", ?b2l(PartId)} | QS]), + PartIdStr = ?b2l(PartId), + QSPartIdStr = couch_util:get_value("partition", QS, PartIdStr), + if QSPartIdStr == PartIdStr -> ok; true -> + Msg = <<"Conflicting value for `partition` in query string">>, + throw({bad_request, Msg}) + end, + NewQS = lists:ukeysort(1, [{"partition", PartIdStr} | QS]), NewReq = Req#httpd{ path_parts = [DbName | Rest], qs = NewQS diff --git a/test/elixir/test/partition_view_test.exs b/test/elixir/test/partition_view_test.exs index b9fbf179f..0a55c2443 100644 --- a/test/elixir/test/partition_view_test.exs +++ b/test/elixir/test/partition_view_test.exs @@ -106,6 +106,16 @@ defmodule ViewPartitionTest do assert Enum.dedup(partitions) == ["bar"] end + test "conflicting partitions in path and query string rejected", context do + db_name = context[:db_name] + + url = "/#{db_name}/_partition/foo/_design/map/_view/some" + resp = Couch.get(url, query: %{partition: "bar"}) + assert resp.status_code == 400 + %{:body => %{"reason" => reason}} = resp + assert Regex.match?(~r/Conflicting value/, reason) + end + test "query will return zero results for wrong inputs", context do db_name = context[:db_name] -- cgit v1.2.1