Add check for repeated `partition` definitions
authorGarren Smith <garren.smith@gmail.com>
Tue, 5 Feb 2019 14:47:39 +0000 (16:47 +0200)
committerPaul J. Davis <paul.joseph.davis@gmail.com>
Thu, 7 Feb 2019 17:58:33 +0000 (11:58 -0600)
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 <garren.smith@gmail.com>
src/chttpd/src/chttpd_db.erl
test/elixir/test/partition_view_test.exs

index 7a00d2b..003b0d8 100644 (file)
@@ -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
index b9fbf17..0a55c24 100644 (file)
@@ -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]