From b60d99dc2f2ba7ee7f7f986753d225ff721804b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=9Aled=C5=BA?= Date: Tue, 4 Apr 2023 20:37:21 +0200 Subject: [PATCH 1/4] Add HTTP requests authorization --- lib/jellyfish/client.ex | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/jellyfish/client.ex b/lib/jellyfish/client.ex index 6f01549..1376b68 100644 --- a/lib/jellyfish/client.ex +++ b/lib/jellyfish/client.ex @@ -32,12 +32,15 @@ defmodule Jellyfish.Client do ## Parameters * `address` - url or IP address of the Jellyfish server instance + * `token` - token used for authorizing HTTP requests. It's the same + token as one configured in Jellyfish. """ - @spec new(String.t()) :: t() - def new(address) do + @spec new(String.t(), String.t()) :: t() + def new(address, token) do middleware = [ {Tesla.Middleware.BaseUrl, address}, - Tesla.Middleware.JSON + {Tesla.Middleware.BearerAuth, token: token}, + Tesla.Middleware.JSON, ] adapter = Application.get_env(:jellyfish, :tesla_adapter, Tesla.Adapter.Mint) From a12ac3068c8336e451378dfe388e274d2a07fc51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Wala?= Date: Wed, 5 Apr 2023 17:01:32 +0200 Subject: [PATCH 2/4] Add 'Unauthorized' error handling, fix tests --- lib/jellyfish/client.ex | 2 +- lib/jellyfish/room.ex | 3 +++ test/jellyfish/client_test.exs | 4 +++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/jellyfish/client.ex b/lib/jellyfish/client.ex index 1376b68..c134702 100644 --- a/lib/jellyfish/client.ex +++ b/lib/jellyfish/client.ex @@ -40,7 +40,7 @@ defmodule Jellyfish.Client do middleware = [ {Tesla.Middleware.BaseUrl, address}, {Tesla.Middleware.BearerAuth, token: token}, - Tesla.Middleware.JSON, + Tesla.Middleware.JSON ] adapter = Application.get_env(:jellyfish, :tesla_adapter, Tesla.Adapter.Mint) diff --git a/lib/jellyfish/room.ex b/lib/jellyfish/room.ex index 25263f8..62c64af 100644 --- a/lib/jellyfish/room.ex +++ b/lib/jellyfish/room.ex @@ -216,6 +216,9 @@ defmodule Jellyfish.Room do defp handle_response_error({:ok, %Env{body: %{"errors" => error}}}), do: {:error, "Request failed: #{error}"} + defp handle_response_error({:ok, %Env{body: error}}) when is_binary(error), + do: {:error, "Request failed: #{error}"} + defp handle_response_error({:ok, %Env{body: _body}}), do: raise(ResponseStructureError) defp handle_response_error({:error, reason}), do: {:error, reason} end diff --git a/test/jellyfish/client_test.exs b/test/jellyfish/client_test.exs index 6f9edab..8607b75 100644 --- a/test/jellyfish/client_test.exs +++ b/test/jellyfish/client_test.exs @@ -7,13 +7,15 @@ defmodule Jellyfish.ClientTest do describe "sdk" do test "creates client struct" do - client = Client.new(@url) + token = "mock_token" + client = Client.new(@url, token) assert %Client{ http_client: %Tesla.Client{ adapter: {Tesla.Adapter.Mint, :call, [[]]}, pre: [ {Tesla.Middleware.BaseUrl, :call, [@url]}, + {Tesla.Middleware.BearerAuth, :call, [[token: ^token]]}, {Tesla.Middleware.JSON, :call, [[]]} ] } From 42efadce9e825406e53152a1dae806d8d420598c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=9Aled=C5=BA?= Date: Thu, 6 Apr 2023 12:14:58 +0200 Subject: [PATCH 3/4] Add auth test --- lib/jellyfish/client.ex | 4 +-- lib/jellyfish/room.ex | 3 --- test/jellyfish/room_test.exs | 50 +++++++++++++++++++++++++++++++----- 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/lib/jellyfish/client.ex b/lib/jellyfish/client.ex index c134702..f707906 100644 --- a/lib/jellyfish/client.ex +++ b/lib/jellyfish/client.ex @@ -5,7 +5,7 @@ defmodule Jellyfish.Client do By default, Mint adapter for [Tesla](https://github.com/elixir-tesla/tesla) is used to make HTTP requests, but it can be changed: ``` # config.exs - config :jellyfish, tesla_adapter: Tesla.Adapter.Hackney + config :jellyfish_server_sdk, tesla_adapter: Tesla.Adapter.Hackney # mix.exs defp deps do @@ -43,7 +43,7 @@ defmodule Jellyfish.Client do Tesla.Middleware.JSON ] - adapter = Application.get_env(:jellyfish, :tesla_adapter, Tesla.Adapter.Mint) + adapter = Application.get_env(:jellyfish_server_sdk, :tesla_adapter, Tesla.Adapter.Mint) http_client = Tesla.client(middleware, adapter) %__MODULE__{http_client: http_client} diff --git a/lib/jellyfish/room.ex b/lib/jellyfish/room.ex index 62c64af..25263f8 100644 --- a/lib/jellyfish/room.ex +++ b/lib/jellyfish/room.ex @@ -216,9 +216,6 @@ defmodule Jellyfish.Room do defp handle_response_error({:ok, %Env{body: %{"errors" => error}}}), do: {:error, "Request failed: #{error}"} - defp handle_response_error({:ok, %Env{body: error}}) when is_binary(error), - do: {:error, "Request failed: #{error}"} - defp handle_response_error({:ok, %Env{body: _body}}), do: raise(ResponseStructureError) defp handle_response_error({:error, reason}), do: {:error, reason} end diff --git a/test/jellyfish/room_test.exs b/test/jellyfish/room_test.exs index 0b3bed6..ed3ba8d 100644 --- a/test/jellyfish/room_test.exs +++ b/test/jellyfish/room_test.exs @@ -5,6 +5,8 @@ defmodule Jellyfish.RoomTest do alias Jellyfish.{Client, Component, Peer, Room} + @token "testtoken" + @url "http://mockurl.com" @invalid_url "http://invalid-url.com" @@ -29,15 +31,49 @@ defmodule Jellyfish.RoomTest do @error_message "Mock error message" setup do - middleware = [ - {Tesla.Middleware.BaseUrl, @url}, - Tesla.Middleware.JSON - ] + current_adapter = Application.get_env(:jellyfish_server_sdk, :tesla_adapter) + + Application.put_env(:jellyfish_server_sdk, :tesla_adapter, Tesla.Mock) + + on_exit(fn -> + if current_adapter == nil do + Application.delete_env(:jellyfish_server_sdk, :tesla_adapter) + else + Application.put_env(:jellyfish_server_sdk, :tesla_adapter, current_adapter) + end + end) + + %{client: Client.new(@url, @token)} + end + + describe "auth" do + setup do + valid_body = Jason.encode!(%{"maxPeers" => @max_peers}) + + mock(fn %{ + method: :post, + url: "#{@url}/room", + body: ^valid_body + } = env -> + case Tesla.get_header(env, "authorization") do + "Bearer " <> @token -> + json(%{"data" => build_room_json(true)}, status: 201) + + "Bearer " <> _other -> + json(%{"errors" => "Invalid token"}, status: 401) + end + end) + end - adapter = Tesla.Mock - http_client = Tesla.client(middleware, adapter) + test "correct token", %{client: client} do + assert {:ok, room} = Room.create(client, max_peers: @max_peers) + assert room == build_room(true) + end - %{client: %Client{http_client: http_client}} + test "invalid token" do + client = Client.new(@url, "invalid" <> @token) + assert {:error, _reason} = Room.create(client, max_peers: @max_peers) + end end describe "Room.create/2" do From f31008c5a264b74324e2fc1f2963b0aea1478944 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=9Aled=C5=BA?= Date: Thu, 6 Apr 2023 12:46:43 +0200 Subject: [PATCH 4/4] Update lib/jellyfish/client.ex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ɓukasz Wala <84684231+LVala@users.noreply.github.com> --- lib/jellyfish/client.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/jellyfish/client.ex b/lib/jellyfish/client.ex index f707906..b3f4182 100644 --- a/lib/jellyfish/client.ex +++ b/lib/jellyfish/client.ex @@ -33,7 +33,7 @@ defmodule Jellyfish.Client do * `address` - url or IP address of the Jellyfish server instance * `token` - token used for authorizing HTTP requests. It's the same - token as one configured in Jellyfish. + token as the one configured in Jellyfish. """ @spec new(String.t(), String.t()) :: t() def new(address, token) do