From 09925e3fc6006ebfe6c1e1700a4dcb00efc96045 Mon Sep 17 00:00:00 2001 From: Robert J Samson Date: Fri, 24 Jun 2016 11:39:00 -0400 Subject: [PATCH 1/6] Add API Key reset API --- lib/stackfooter/api_key_registry.ex | 10 ++++++++++ test/otp/api_key_registry_test.exs | 8 ++++++++ 2 files changed, 18 insertions(+) diff --git a/lib/stackfooter/api_key_registry.ex b/lib/stackfooter/api_key_registry.ex index fd1abec..1052682 100644 --- a/lib/stackfooter/api_key_registry.ex +++ b/lib/stackfooter/api_key_registry.ex @@ -25,8 +25,18 @@ defmodule Stackfooter.ApiKeyRegistry do end end + def reset_api_keys(pid) do + GenServer.call(pid, :reset) + end + + def handle_call(:reset, _from, api_keys) do + :ets.delete_all_objects(api_keys) + {:reply, :ok, api_keys} + end + def handle_call({:add_key, api_key, account}, _from, api_keys) do :ets.insert(api_keys, {api_key, account}) + {:reply, {:ok, {api_key, account}}, api_keys} end end diff --git a/test/otp/api_key_registry_test.exs b/test/otp/api_key_registry_test.exs index d0256f1..56d7a67 100644 --- a/test/otp/api_key_registry_test.exs +++ b/test/otp/api_key_registry_test.exs @@ -3,6 +3,7 @@ defmodule Stackfooter.ApiKeyRegistryTest do alias Stackfooter.ApiKeyRegistry setup do + Stackfooter.ApiKeyRegistry.reset_api_keys(Stackfooter.ApiKeyRegistry) Stackfooter.ApiKeyRegistry.add_key(Stackfooter.ApiKeyRegistry, "4cy7uf63Lw2Sx6652YmLwBKy662weU4q", "admin") Stackfooter.ApiKeyRegistry.add_key(Stackfooter.ApiKeyRegistry, "7eWeGhc8n0va5bjT66C0Vl1fBw2618BJ", "rjsamson") @@ -14,4 +15,11 @@ defmodule Stackfooter.ApiKeyRegistryTest do assert all_accounts == ["RJSAMSON", "ADMIN"] end + + test "resets all API keys" do + Stackfooter.ApiKeyRegistry.reset_api_keys(Stackfooter.ApiKeyRegistry) + all_accounts = ApiKeyRegistry.all_account_names(ApiKeyRegistry) + + assert all_accounts == [] + end end From d911b197994c3041c0744e95049281423fc3a388 Mon Sep 17 00:00:00 2001 From: Robert J Samson Date: Fri, 24 Jun 2016 11:42:37 -0400 Subject: [PATCH 2/6] Import test helpers --- test/support/channel_case.ex | 2 +- test/support/conn_case.ex | 1 + test/support/model_case.ex | 1 + test/support/test_helpers.ex | 12 ++++++++++++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/test/support/channel_case.ex b/test/support/channel_case.ex index 22c2f6e..a8e6b57 100644 --- a/test/support/channel_case.ex +++ b/test/support/channel_case.ex @@ -25,7 +25,7 @@ defmodule Stackfooter.ChannelCase do import Ecto.Changeset import Ecto.Query, only: [from: 1, from: 2] - + import Stackfooter.TestHelpers # The default endpoint for testing @endpoint Stackfooter.Endpoint end diff --git a/test/support/conn_case.ex b/test/support/conn_case.ex index 47f5688..01e81c7 100644 --- a/test/support/conn_case.ex +++ b/test/support/conn_case.ex @@ -26,6 +26,7 @@ defmodule Stackfooter.ConnCase do import Ecto.Query, only: [from: 1, from: 2] import Stackfooter.Router.Helpers + import Stackfooter.TestHelpers # The default endpoint for testing @endpoint Stackfooter.Endpoint diff --git a/test/support/model_case.ex b/test/support/model_case.ex index e1bf8c2..38c1d9c 100644 --- a/test/support/model_case.ex +++ b/test/support/model_case.ex @@ -22,6 +22,7 @@ defmodule Stackfooter.ModelCase do import Ecto.Changeset import Ecto.Query, only: [from: 1, from: 2] import Stackfooter.ModelCase + import Stackfooter.TestHelpers end end diff --git a/test/support/test_helpers.ex b/test/support/test_helpers.ex index 458f139..0e8ae5e 100644 --- a/test/support/test_helpers.ex +++ b/test/support/test_helpers.ex @@ -8,4 +8,16 @@ defmodule Stackfooter.TestHelpers do changeset = Stackfooter.User.changeset(%Stackfooter.User{}, params) Stackfooter.Repo.insert!(changeset) end + + def set_api_keys do + Stackfooter.ApiKeyRegistry.reset_api_keys(Stackfooter.ApiKeyRegistry) + + default_api_key = Application.get_env(:stackfooter, :bootstrap)[:default_api_key] + default_account = Application.get_env(:stackfooter, :bootstrap)[:default_account] + + # Default API key(s) to be added on application start. + # Add more here, and in config/env.secret.exs + + Stackfooter.ApiKeyRegistry.add_key(Stackfooter.ApiKeyRegistry, default_api_key, default_account) + end end From a806fc20d6ad88d3cab0f9928f37e34b67ab12cd Mon Sep 17 00:00:00 2001 From: Robert J Samson Date: Fri, 24 Jun 2016 11:50:24 -0400 Subject: [PATCH 3/6] Reset API Keys before running tests --- test/controllers/admin_controller_test.exs | 4 ++++ test/controllers/api_controller_test.exs | 5 +++++ test/controllers/page_controller_test.exs | 5 +++++ test/controllers/score_controller_test.exs | 2 ++ test/controllers/venue_controller_test.exs | 5 +++++ test/support/conn_case.ex | 1 + test/support/test_helpers.ex | 2 +- 7 files changed, 23 insertions(+), 1 deletion(-) diff --git a/test/controllers/admin_controller_test.exs b/test/controllers/admin_controller_test.exs index aa84e68..bddc8cb 100644 --- a/test/controllers/admin_controller_test.exs +++ b/test/controllers/admin_controller_test.exs @@ -6,6 +6,8 @@ defmodule Stackfooter.AdminControllerTest do @non_admin_apikey "KVi7irGjY8ZhYg6B20QU7H6IIbhWmyt0" setup_all do + reset_api_keys() + ApiKeyRegistry.add_key(Stackfooter.ApiKeyRegistry, "KVi7irGjY8ZhYg6B20QU7H6IIbhWmyt0", "rjsamson1234") :ok @@ -27,6 +29,8 @@ defmodule Stackfooter.AdminControllerTest do Venue.place_order(venue, %{direction: "sell", symbol: "NYC", qty: 7, price: x, account: "admin", orderType: "limit"}) end) + ApiKeyRegistry.add_key(Stackfooter.ApiKeyRegistry, "KVi7irGjY8ZhYg6B20QU7H6IIbhWmyt0", "rjsamson1234") + :ok end diff --git a/test/controllers/api_controller_test.exs b/test/controllers/api_controller_test.exs index 393727d..1b8fcfc 100644 --- a/test/controllers/api_controller_test.exs +++ b/test/controllers/api_controller_test.exs @@ -1,6 +1,11 @@ defmodule Stackfooter.ApiControllerTest do use Stackfooter.ConnCase + setup_all do + reset_api_keys() + :ok + end + test "API Heartbeat", %{conn: conn} do conn = get(conn, "/ob/api/heartbeat") resp = json_response(conn, 200) diff --git a/test/controllers/page_controller_test.exs b/test/controllers/page_controller_test.exs index 107701b..ff69e4b 100644 --- a/test/controllers/page_controller_test.exs +++ b/test/controllers/page_controller_test.exs @@ -1,6 +1,11 @@ defmodule Stackfooter.PageControllerTest do use Stackfooter.ConnCase + setup_all do + reset_api_keys() + :ok + end + test "GET /", %{conn: conn} do conn = get conn, "/" assert html_response(conn, 200) =~ "Stackfooter" diff --git a/test/controllers/score_controller_test.exs b/test/controllers/score_controller_test.exs index 5c84deb..e9f0dc2 100644 --- a/test/controllers/score_controller_test.exs +++ b/test/controllers/score_controller_test.exs @@ -6,6 +6,8 @@ defmodule Stackfooter.ScoreControllerTest do @non_admin_apikey "KVi7irGjY8ZhYg6B20QU7H6IIbhWmyt0" setup_all do + reset_api_keys() + ApiKeyRegistry.add_key(Stackfooter.ApiKeyRegistry, "KVi7irGjY8ZhYg6B20QU7H6IIbhWmyt0", "rjsamson1234") {:ok, venue} = VenueRegistry.lookup(Stackfooter.VenueRegistry, "OBEX") diff --git a/test/controllers/venue_controller_test.exs b/test/controllers/venue_controller_test.exs index 6c07f12..d0b546f 100644 --- a/test/controllers/venue_controller_test.exs +++ b/test/controllers/venue_controller_test.exs @@ -4,6 +4,11 @@ defmodule Stackfooter.VenueControllerTest do @apikey "4cy7uf63Lw2Sx6652YmLwBKy662weU4q" + setup_all do + reset_api_keys() + :ok + end + test "returns all open venues" do conn = get(build_conn(), "/ob/api/venues/") resp = json_response(conn, 200) diff --git a/test/support/conn_case.ex b/test/support/conn_case.ex index 01e81c7..3168ec8 100644 --- a/test/support/conn_case.ex +++ b/test/support/conn_case.ex @@ -37,6 +37,7 @@ defmodule Stackfooter.ConnCase do # unless tags[:async] do # Ecto.Adapters.SQL.restart_test_transaction(Stackfooter.Repo, []) # end + :ok = Ecto.Adapters.SQL.Sandbox.checkout(Stackfooter.Repo) unless tags[:async] do diff --git a/test/support/test_helpers.ex b/test/support/test_helpers.ex index 0e8ae5e..9664714 100644 --- a/test/support/test_helpers.ex +++ b/test/support/test_helpers.ex @@ -9,7 +9,7 @@ defmodule Stackfooter.TestHelpers do Stackfooter.Repo.insert!(changeset) end - def set_api_keys do + def reset_api_keys do Stackfooter.ApiKeyRegistry.reset_api_keys(Stackfooter.ApiKeyRegistry) default_api_key = Application.get_env(:stackfooter, :bootstrap)[:default_api_key] From 49e36b8071c8fdcbb4718a105dfad4f0dfe9f744 Mon Sep 17 00:00:00 2001 From: Robert J Samson Date: Fri, 24 Jun 2016 14:31:02 -0400 Subject: [PATCH 4/6] Fix insert_user test helper --- test/support/test_helpers.ex | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/support/test_helpers.ex b/test/support/test_helpers.ex index 9664714..5cffc42 100644 --- a/test/support/test_helpers.ex +++ b/test/support/test_helpers.ex @@ -1,8 +1,12 @@ defmodule Stackfooter.TestHelpers do def insert_user(attrs \\ %{}) do + default_api_key = Application.get_env(:stackfooter, :bootstrap)[:default_api_key] + default_account = Application.get_env(:stackfooter, :bootstrap)[:default_account] + params = Dict.merge(%{ - username: "user#{Base.encode16(:crypto.rand_bytes(8))}", - password: "securepassword" + username: default_account, + password: "securepassword", + api_keys: [default_api_key] }, attrs) changeset = Stackfooter.User.changeset(%Stackfooter.User{}, params) From 2530fec69c3b05ae45f68f407be6eb85d7ce5cc0 Mon Sep 17 00:00:00 2001 From: Robert J Samson Date: Fri, 24 Jun 2016 14:45:41 -0400 Subject: [PATCH 5/6] Add API key to key registry on user creation in test helper --- test/support/test_helpers.ex | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/support/test_helpers.ex b/test/support/test_helpers.ex index 5cffc42..eaa6fab 100644 --- a/test/support/test_helpers.ex +++ b/test/support/test_helpers.ex @@ -10,7 +10,13 @@ defmodule Stackfooter.TestHelpers do }, attrs) changeset = Stackfooter.User.changeset(%Stackfooter.User{}, params) - Stackfooter.Repo.insert!(changeset) + user = Stackfooter.Repo.insert!(changeset) + + api_keys = user.api_keys + acct = user.username + + Enum.map(api_keys, fn(key) -> Stackfooter.ApiKeyRegistry.add_key(Stackfooter.ApiKeyRegistry, key, acct) end) + user end def reset_api_keys do From 3809b2a4b5574aaa183291e6bb862786915a0456 Mon Sep 17 00:00:00 2001 From: Robert J Samson Date: Fri, 24 Jun 2016 15:02:37 -0400 Subject: [PATCH 6/6] Add authentication test coverage --- test/controllers/console_controller_test.exs | 29 ++++++++++++++++++++ test/controllers/trade_controller_test.exs | 29 ++++++++++++++++++++ web/controllers/trade_controller.ex | 1 - 3 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 test/controllers/console_controller_test.exs create mode 100644 test/controllers/trade_controller_test.exs diff --git a/test/controllers/console_controller_test.exs b/test/controllers/console_controller_test.exs new file mode 100644 index 0000000..5b7faeb --- /dev/null +++ b/test/controllers/console_controller_test.exs @@ -0,0 +1,29 @@ +defmodule Stackfooter.ConsoleControllerTest do + use Stackfooter.ConnCase + + @apikey "4cy7uf63Lw2Sx6652YmLwBKy662weU4q" + + setup config do + reset_api_keys() + + if username = config[:login_as] do + user = insert_user(username: username, api_keys: [@apikey]) + conn = assign(build_conn(), :current_user, user) + + {:ok, conn: conn, user: user} + else + {:ok, conn: build_conn()} + end + end + + @tag login_as: "rjsamson1234" + test "Trade path is authenticated", %{conn: conn, user: _user} do + conn = get(conn, "/console") + assert html_response(conn, 200) =~ "rjsamson1234" + end + + test "Redirects if not authenticated", %{conn: conn} do + conn = get(conn, "/console") + assert redirected_to(conn) == session_path(conn, :new) + end +end diff --git a/test/controllers/trade_controller_test.exs b/test/controllers/trade_controller_test.exs new file mode 100644 index 0000000..d43425a --- /dev/null +++ b/test/controllers/trade_controller_test.exs @@ -0,0 +1,29 @@ +defmodule Stackfooter.TradeControllerTest do + use Stackfooter.ConnCase + + @apikey "4cy7uf63Lw2Sx6652YmLwBKy662weU4q" + + setup config do + reset_api_keys() + + if username = config[:login_as] do + user = insert_user(username: username, api_keys: [@apikey]) + conn = assign(build_conn(), :current_user, user) + + {:ok, conn: conn, user: user} + else + {:ok, conn: build_conn()} + end + end + + @tag login_as: "rjsamson1234" + test "Trade path is authenticated", %{conn: conn, user: _user} do + conn = get(conn, "/trade") + assert html_response(conn, 200) =~ "rjsamson1234" + end + + test "Redirects if not authenticated", %{conn: conn} do + conn = get(conn, "/trade") + assert redirected_to(conn) == session_path(conn, :new) + end +end diff --git a/web/controllers/trade_controller.ex b/web/controllers/trade_controller.ex index dd02cec..119e023 100644 --- a/web/controllers/trade_controller.ex +++ b/web/controllers/trade_controller.ex @@ -7,7 +7,6 @@ defmodule Stackfooter.TradeController do def index(conn, _params) do username = conn.assigns.current_user.username venues = VenueRegistry.all_venue_names(VenueRegistry) - IO.inspect venues render conn, "index.html", username: username, venues: venues end end