Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filtering Input Parameters to Childchain/Watcher API depending on HTTP Method #1424

Merged
merged 41 commits into from
Apr 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
d5cf128
feat introduce method param filter plug
Mar 20, 2020
8474f91
test: POST /account.get_balance does not take query parameters.
Mar 24, 2020
bd2a266
fix: add render for 415
Mar 24, 2020
3d59df7
test: POST /transaction.get does not take query parameters.
Mar 25, 2020
e0b7de0
test: POST /block.get (child chain) does not take query parameters.
Mar 25, 2020
1891861
Merge branch 'mederic-p/1411-filter-params-http-method' of https://gi…
Mar 25, 2020
7de7f16
add: urlencoded to parsers
Mar 25, 2020
3ab64c4
update: pass any MIME type in endpoints
Mar 25, 2020
f7a3bc7
[fix]: pass
Mar 25, 2020
1949206
add: urlencoded
Mar 25, 2020
1bd5604
Merge branch 'master' of https://github.com/omisego/elixir-omg into 1…
Mar 26, 2020
c84af7a
add: removed plugs
Mar 26, 2020
b6a6007
[try]: remove method param filter
Mar 26, 2020
138c260
[fix]: end
Mar 26, 2020
3c60a7c
fix: end
Mar 26, 2020
a7fe0e2
add: multipart
Mar 26, 2020
4187a6a
Merge branch 'master' of https://github.com/omisego/elixir-omg into 1…
Apr 7, 2020
4d5061f
revert endpoint.ex to PR original
Apr 7, 2020
47867e4
tests: uncomment
Apr 9, 2020
dd3fc11
feat introduce method param filter plug
Mar 20, 2020
5681e62
test: POST /account.get_balance does not take query parameters.
Mar 24, 2020
de166ba
test: POST /transaction.get does not take query parameters.
Mar 25, 2020
3f025ff
test: POST /block.get (child chain) does not take query parameters.
Mar 25, 2020
51ed776
fix: add render for 415
Mar 24, 2020
e081bb9
add: urlencoded to parsers
Mar 25, 2020
3bf0953
update: pass any MIME type in endpoints
Mar 25, 2020
7d4f6d6
[fix]: pass
Mar 25, 2020
e859aee
add: urlencoded
Mar 25, 2020
db952a0
add: removed plugs
Mar 26, 2020
d39ecf2
[try]: remove method param filter
Mar 26, 2020
c686a62
[fix]: end
Mar 26, 2020
563b131
fix: end
Mar 26, 2020
7655eb6
add: multipart
Mar 26, 2020
7b087c1
tests: uncomment
Apr 9, 2020
41995cf
content type headers
Apr 10, 2020
8c05f0e
rem asdf files
Apr 10, 2020
aeb5ad3
Merge branch '1411-filter-params-http-method' of https://github.com/o…
Apr 10, 2020
4d1be26
remove pass */* and parse json only
Apr 10, 2020
a69a264
remove .tool-versions, distillery
Apr 10, 2020
c6a0742
remove :urlencoded
Apr 10, 2020
ce14a71
Merge branch 'master' of https://github.com/omisego/elixir-omg into 1…
Apr 10, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,6 @@ localchain_contract_addresses.env
# IntelliJ files
.idea/
*.iml

#vs code
.tool_versions
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ defmodule OMG.ChildChainRPC.Web.Controller.Fee do
"""

use OMG.ChildChainRPC.Web, :controller
plug(OMG.ChildChainRPC.Plugs.Health)
plug(OMG.ChildChainRPC.Web.Plugs.Health)
alias OMG.ChildChain

def fees_all(conn, params) do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ defmodule OMG.ChildChainRPC.Web.Controller.Transaction do

use OMG.ChildChainRPC.Web, :controller
# check for health before calling action
plug(OMG.ChildChainRPC.Plugs.Health)
plug(OMG.ChildChainRPC.Web.Plugs.Health)
alias OMG.ChildChain

def submit(conn, params) do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ defmodule OMG.ChildChainRPC.Web.Endpoint do

plug(
Plug.Parsers,
parsers: [:urlencoded, :multipart, :json],
pass: ["*/*"],
parsers: [:json],
pass: [],
json_decoder: Jason
)

Expand All @@ -32,5 +32,6 @@ defmodule OMG.ChildChainRPC.Web.Endpoint do
if Application.get_env(:omg_child_chain_rpc, OMG.ChildChainRPC.Web.Endpoint)[:enable_cors],
do: plug(CORSPlug)

plug(OMG.ChildChainRPC.Web.Plugs.MethodParamFilter)
plug(OMG.ChildChainRPC.Web.Router)
end
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

defmodule OMG.ChildChainRPC.Plugs.Health do
defmodule OMG.ChildChainRPC.Web.Plugs.Health do
@moduledoc """
Observes the systems alarms and prevents calls towards an unhealthy one.
"""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright 2019-2020 OmiseGO Pte Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

defmodule OMG.ChildChainRPC.Web.Plugs.MethodParamFilter do
@moduledoc """
Filters the `query_params`, `body_params` and `params` of the conn
depending on the HTTP method used.

For a POST: `query_params` will be ignored and `body_params` will be
set to `params`.

For a GET: `body_params` will be ignored and `query_params` will be
set to `params`.
"""

def init(args), do: args

def call(%Plug.Conn{method: "POST", body_params: params} = conn, _) do
conn
|> Map.put(:query_params, %{})
|> Map.put(:params, params)
end

def call(%Plug.Conn{method: "GET", query_params: params} = conn, _) do
conn
|> Map.put(:body_params, %{})
|> Map.put(:params, params)
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,23 @@ defmodule OMG.ChildChainRPC.Web.Controller.BlockTest do
}
} = TestHelper.rpc_call(:post, "/block.get", missing_param)
end

@tag fixtures: [:phoenix_sandbox]
test "block.get returns bad request error if hash passed in as query parameter" do
valid_hash = "0x" <> String.duplicate("00", 32)

assert %{
"success" => false,
"data" => %{
"object" => "error",
"code" => "operation:bad_request",
"messages" => %{
"validation_error" => %{
"parameter" => "hash",
"validator" => ":hex"
}
}
}
} = TestHelper.rpc_call(:post, "/block.get?hash=#{valid_hash}")
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

defmodule OMG.ChildChainRPC.Plugs.HealthTest do
defmodule OMG.ChildChainRPC.Web.Plugs.HealthTest do
use ExUnitFixtures
use ExUnit.Case, async: false

Expand All @@ -35,7 +35,7 @@ defmodule OMG.ChildChainRPC.Plugs.HealthTest do
%{
"boot_in_progress" => %{
"node" => "nonode@nohost",
"reporter" => "Elixir.OMG.ChildChainRPC.Plugs.HealthTest"
"reporter" => "Elixir.OMG.ChildChainRPC.Web.Plugs.HealthTest"
}
}
],
Expand Down Expand Up @@ -80,7 +80,7 @@ defmodule OMG.ChildChainRPC.Plugs.HealthTest do
%{
"ethereum_connection_error" => %{
"node" => "nonode@nohost",
"reporter" => "Elixir.OMG.ChildChainRPC.Plugs.HealthTest"
"reporter" => "Elixir.OMG.ChildChainRPC.Web.Plugs.HealthTest"
}
}
],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Copyright 2019-2020 OmiseGO Pte Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

defmodule OMG.ChildChainRPC.Web.Plugs.MethodParamFilterTest do
use ExUnit.Case, async: true
use Plug.Test

alias OMG.ChildChainRPC.Web.Plugs.MethodParamFilter

test "filters query params for POST" do
conn =
:post
|> conn("/some_endpoint?foo=bar", %{"foo_1" => "bar_1"})
|> Plug.Parsers.call({[:json], [], nil})
|> MethodParamFilter.call([])

assert conn.body_params == %{"foo_1" => "bar_1"}
assert conn.query_params == %{}
assert conn.params == %{"foo_1" => "bar_1"}
end

test "filters body params for GET" do
conn =
:get
|> conn("/some_endpoint?foo=bar", %{"foo_1" => "bar_1"})
|> Plug.Parsers.call({[:json], [], nil})
|> MethodParamFilter.call([])

assert conn.body_params == %{}
assert conn.query_params == %{"foo" => "bar"}
assert conn.params == %{"foo" => "bar"}
end
end
9 changes: 7 additions & 2 deletions apps/omg_watcher_rpc/lib/web/endpoint.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,14 @@ defmodule OMG.WatcherRPC.Web.Endpoint do
plug(Plug.RequestId)
plug(Plug.Logger, log: :debug)

if code_reloading? do
plug(Phoenix.CodeReloader)
end

plug(
thec00n marked this conversation as resolved.
Show resolved Hide resolved
Plug.Parsers,
parsers: [:urlencoded, :multipart, :json],
pass: ["*/*"],
parsers: [:json],
pass: [],
json_decoder: Jason
)

Expand All @@ -32,5 +36,6 @@ defmodule OMG.WatcherRPC.Web.Endpoint do
if Application.get_env(:omg_watcher_rpc, OMG.WatcherRPC.Web.Endpoint)[:enable_cors],
do: plug(CORSPlug)

plug(OMG.WatcherRPC.Web.Plugs.MethodParamFilter)
plug(OMG.WatcherRPC.Web.Router)
end
40 changes: 40 additions & 0 deletions apps/omg_watcher_rpc/lib/web/plugs/method_param_filter.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright 2019-2020 OmiseGO Pte Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

defmodule OMG.WatcherRPC.Web.Plugs.MethodParamFilter do
@moduledoc """
Filters the `query_params`, `body_params` and `params` of the conn
depending on the HTTP method used.

For a POST: `query_params` will be ignored and `body_params` will be
set to `params`.

For a GET: `body_params` will be ignored and `query_params` will be
set to `params`.
"""

def init(args), do: args

def call(%Plug.Conn{method: "POST", body_params: params} = conn, _) do
conn
|> Map.put(:query_params, %{})
|> Map.put(:params, params)
end

def call(%Plug.Conn{method: "GET", query_params: params} = conn, _) do
conn
|> Map.put(:body_params, %{})
|> Map.put(:params, params)
end
end
9 changes: 9 additions & 0 deletions apps/omg_watcher_rpc/lib/web/views/error.ex
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ defmodule OMG.WatcherRPC.Web.Views.Error do
|> WatcherRPCResponse.add_app_infos()
end

@doc """
Handles invalid input parsing errors, e.g. Content-Type not application/json
"""
def render("415.json", _) do
"operation:bad_request"
|> Error.serialize("Invalid Content-Type header, use application/json.")
|> WatcherRPCResponse.add_app_infos()
end

@doc """
Supports internal server error thrown by Phoenix.
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,25 @@ defmodule OMG.WatcherRPC.Web.Controller.AccountTest do
} == WatcherHelper.no_success?("account.get_balance", %{"address" => 1_234_567_890})
end

@tag fixtures: [:alice, :phoenix_ecto_sandbox]
test "account.get_balance returns bad request error if address is passed as a query parameter", %{
alice: alice
} do
%{"address" => address} = body_for(alice)

assert %{
"object" => "error",
"code" => "operation:bad_request",
"description" => "Parameters required by this operation are missing or incorrect.",
"messages" => %{
"validation_error" => %{
"parameter" => "address",
"validator" => ":hex"
}
}
} == WatcherHelper.no_success?("account.get_balance?address=#{address}")
end

describe "standard_exitable" do
@tag fixtures: [:phoenix_ecto_sandbox, :db_initialized, :carol]
test "no utxos are returned for non-existing addresses", %{carol: carol} do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,23 @@ defmodule OMG.WatcherRPC.Web.Controller.TransactionTest do
}
} == WatcherHelper.no_success?("transaction.get", %{"id" => "0x50e901b98fe3389e32d56166a13a88208b03ea75"})
end

@tag fixtures: [:phoenix_ecto_sandbox]
test "returns bad request error if transaction hash is passed as query parameter" do
txhash = insert(:transaction) |> Map.get(:txhash) |> Encoding.to_hex()

assert %{
"object" => "error",
"code" => "operation:bad_request",
"description" => "Parameters required by this operation are missing or incorrect.",
"messages" => %{
"validation_error" => %{
"parameter" => "id",
"validator" => ":hex"
}
}
} == WatcherHelper.no_success?("transaction.get?id=#{txhash}")
end
end

describe "/transaction.all" do
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Copyright 2019-2020 OmiseGO Pte Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

defmodule OMG.WatcherRPC.Web.Plugs.MethodParamFilterTest do
use ExUnit.Case, async: true
use Plug.Test

alias OMG.WatcherRPC.Web.Plugs.MethodParamFilter

test "filters query params for POST" do
conn =
:post
|> conn("/some_endpoint?foo=bar", %{"foo_1" => "bar_1"})
|> Plug.Parsers.call({[:json], [], nil})
|> MethodParamFilter.call([])

assert conn.body_params == %{"foo_1" => "bar_1"}
assert conn.query_params == %{}
assert conn.params == %{"foo_1" => "bar_1"}
end

test "filters body params for GET" do
conn =
:get
|> conn("/some_endpoint?foo=bar", %{"foo_1" => "bar_1"})
|> Plug.Parsers.call({[:json], [], nil})
|> MethodParamFilter.call([])

assert conn.body_params == %{}
assert conn.query_params == %{"foo" => "bar"}
assert conn.params == %{"foo" => "bar"}
end
end
2 changes: 1 addition & 1 deletion priv/cabbage/apps/itest/lib/child_chain_api/connection.ex
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ if Code.ensure_loaded?(ChildChainAPI.Connection) do

# Add any middleware here (authentication)
plug(Tesla.Middleware.BaseUrl, "http://localhost:9656")
plug(Tesla.Middleware.Headers, [{"user-agent", "Itest-Elixir"}])
plug(Tesla.Middleware.Headers, [{"user-agent", "Itest-Elixir"}, {"Content-Type", "application/json"}])
plug(Tesla.Middleware.EncodeJson, engine: Poison)

@doc """
Expand Down
2 changes: 1 addition & 1 deletion priv/cabbage/apps/itest/lib/watcher_info_api/connection.ex
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ if Code.ensure_loaded?(WatcherInfoAPI.Connection) do

# Add any middleware here (authentication)
plug(Tesla.Middleware.BaseUrl, "http://localhost:7534")
plug(Tesla.Middleware.Headers, [{"user-agent", "Itest-Elixir"}])
plug(Tesla.Middleware.Headers, [{"user-agent", "Itest-Elixir"}, {"Content-Type", "application/json"}])
plug(Tesla.Middleware.EncodeJson, engine: Poison)

@doc """
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ if Code.ensure_loaded?(WatcherSecurityCriticalAPI.Connection) do

# Add any middleware here (authentication)
plug(Tesla.Middleware.BaseUrl, "http://localhost:7434")
plug(Tesla.Middleware.Headers, [{"user-agent", "Elixir"}])
plug(Tesla.Middleware.Headers, [{"user-agent", "Elixir"}, {"Content-Type", "application/json"}])
plug(Tesla.Middleware.EncodeJson, engine: Poison)

@doc """
Expand Down
Loading