From ea127c4ca154123728301f641565d5d718250a76 Mon Sep 17 00:00:00 2001 From: Jamil Bou Kheir Date: Wed, 13 May 2020 00:39:51 -0500 Subject: [PATCH 1/4] Device creation works --- apps/fg_http/assets/js/hooks/hooks.js | 3 ++ apps/fg_http/lib/fg_http/devices.ex | 13 ++++++ apps/fg_http/lib/fg_http/devices/device.ex | 4 +- apps/fg_http/lib/fg_http/users/user.ex | 2 +- .../controllers/device_controller.ex | 19 ++++++++ .../lib/fg_http_web/live/new_device_live.ex | 10 +++-- .../live/new_device_live.html.leex | 45 +++++++++++++------ .../lib/fg_http_web/plugs/authenticator.ex | 5 ++- apps/fg_http/lib/fg_http_web/router.ex | 2 +- .../fg_http_web/templates/device/new.html.eex | 2 +- 10 files changed, 81 insertions(+), 24 deletions(-) diff --git a/apps/fg_http/assets/js/hooks/hooks.js b/apps/fg_http/assets/js/hooks/hooks.js index 96fdafdde..835c8b468 100644 --- a/apps/fg_http/assets/js/hooks/hooks.js +++ b/apps/fg_http/assets/js/hooks/hooks.js @@ -3,6 +3,9 @@ import { qrEncode } from "./qr_code.js" let Hooks = {} Hooks.QrEncode = { + mounted() { + qrEncode() + }, updated() { qrEncode() } diff --git a/apps/fg_http/lib/fg_http/devices.ex b/apps/fg_http/lib/fg_http/devices.ex index eef55d84a..b1638d20e 100644 --- a/apps/fg_http/lib/fg_http/devices.ex +++ b/apps/fg_http/lib/fg_http/devices.ex @@ -90,6 +90,19 @@ defmodule FgHttp.Devices do |> Repo.update() end + @doc """ + Verifies a Device. + + ## Examples + + iex> verify!(device.id) + {:ok, %Device{}} + """ + def verify(id) do + get_device!(id) + |> update_device(%{verified_at: DateTime.utc_now}) + end + @doc """ Deletes a device. diff --git a/apps/fg_http/lib/fg_http/devices/device.ex b/apps/fg_http/lib/fg_http/devices/device.ex index e37f4d936..57706dbc3 100644 --- a/apps/fg_http/lib/fg_http/devices/device.ex +++ b/apps/fg_http/lib/fg_http/devices/device.ex @@ -20,7 +20,7 @@ defmodule FgHttp.Devices.Device do @doc false def changeset(device, attrs) do device - |> cast(attrs, [:name, :public_key]) - |> validate_required([:name]) + |> cast(attrs, [:user_id, :verified_at, :name, :public_key]) + |> validate_required([:user_id]) end end diff --git a/apps/fg_http/lib/fg_http/users/user.ex b/apps/fg_http/lib/fg_http/users/user.ex index 5dbddfe94..c4fe12691 100644 --- a/apps/fg_http/lib/fg_http/users/user.ex +++ b/apps/fg_http/lib/fg_http/users/user.ex @@ -19,7 +19,7 @@ defmodule FgHttp.Users.User do def changeset(user, attrs \\ %{}) do user |> cast(attrs, [:email, :confirmed_at, :password_digest, :last_signed_in_at]) - |> validate_required([:email, :last_signed_in_at]) + |> validate_required([:email]) |> unique_constraint(:email) end end diff --git a/apps/fg_http/lib/fg_http_web/controllers/device_controller.ex b/apps/fg_http/lib/fg_http_web/controllers/device_controller.ex index 3763e3444..3dd2106eb 100644 --- a/apps/fg_http/lib/fg_http_web/controllers/device_controller.ex +++ b/apps/fg_http/lib/fg_http_web/controllers/device_controller.ex @@ -18,6 +18,25 @@ defmodule FgHttpWeb.DeviceController do render(conn, "new.html", changeset: changeset) end + def create(conn, %{"device" => device_params}) do + create_params = %{ + "user_id" => conn.assigns.current_user.id, + "verified_at" => DateTime.utc_now, + "name" => "Auto" + } + all_params = Map.merge(device_params, create_params) + IO.puts "Create device with params: " + IO.inspect all_params + case Devices.create_device(all_params) do + {:ok, device} -> + IO.inspect(device) + redirect(conn, to: Routes.device_path(conn, :show, device)) + {:error, %Ecto.Changeset{} = changeset} -> + IO.inspect(changeset) + render(conn, "new.html", changeset: changeset) + end + end + def show(conn, %{"id" => id}) do device = Devices.get_device!(id) render(conn, "show.html", device: device) diff --git a/apps/fg_http/lib/fg_http_web/live/new_device_live.ex b/apps/fg_http/lib/fg_http_web/live/new_device_live.ex index 5e59f69be..5e41759a6 100644 --- a/apps/fg_http/lib/fg_http_web/live/new_device_live.ex +++ b/apps/fg_http/lib/fg_http_web/live/new_device_live.ex @@ -1,19 +1,23 @@ defmodule FgHttpWeb.NewDeviceLive do use Phoenix.LiveView + use Phoenix.HTML + alias FgHttpWeb.Router.Helpers, as: Routes alias FgHttp.Devices.Device - def mount(_params, %{"current_user_id" => user_id}, socket) do + def mount(_params, %{}, socket) do + user_id = "1" + IO.inspect(socket) if connected?(socket), do: wait_for_device(socket) - device = %Device{user_id: user_id} + device = %Device{id: "1", user_id: user_id} {:ok, assign(socket, :device, device)} end defp wait_for_device(socket) do # TODO: pass socket to fg_vpn somehow IO.inspect(socket) - :timer.send_after(10000, self(), :update) + :timer.send_after(3000, self(), :update) end def handle_info(:update, socket) do diff --git a/apps/fg_http/lib/fg_http_web/live/new_device_live.html.leex b/apps/fg_http/lib/fg_http_web/live/new_device_live.html.leex index a36e33766..1bdcfd0a9 100644 --- a/apps/fg_http/lib/fg_http_web/live/new_device_live.html.leex +++ b/apps/fg_http/lib/fg_http_web/live/new_device_live.html.leex @@ -1,5 +1,5 @@

- Add the following to your Wireguard configuration file: + Add the following to your WireGuard™ configuration file:

@@ -18,16 +18,33 @@ Endpoint = <%= Application.fetch_env!(:fg_http, :vpn_endpoint) %>
-

- When we receive a connection from your device, we'll prompt you verify it here. -

- -

- Waiting for device connection... - - <%= if @device.public_key do %> - Connected! Device Public Key: <%= @device.public_key %> - Configure your device -> - <% end %> - -

+
+ <%= unless @device.public_key do %> +

+ Waiting for device connection... +

+

+ When we receive a connection from your device, we'll prompt you verify it here. +

+ <% else %> +

Connected!

+

+ Device Public Key: <%= @device.public_key %> +

+

+ <%# XXX: Use the public key sent by the actual device and not the one here %> + <%= + link("This looks good, verify and continue. ->", + to: Routes.device_path(@socket, :create, "device[public_key]": @device.public_key), + method: :post) + %> +

+

+ <%= + link("<- Something's wrong. Don't add this device and go back.", + to: Routes.device_path(@socket, :index), + method: :delete) + %> +

+ <% end %> +
diff --git a/apps/fg_http/lib/fg_http_web/plugs/authenticator.ex b/apps/fg_http/lib/fg_http_web/plugs/authenticator.ex index a6f05b9b1..0b99444d6 100644 --- a/apps/fg_http/lib/fg_http_web/plugs/authenticator.ex +++ b/apps/fg_http/lib/fg_http_web/plugs/authenticator.ex @@ -4,12 +4,13 @@ defmodule FgHttpWeb.Plugs.Authenticator do """ import Plug.Conn - alias FgHttp.Users.User + alias FgHttp.{Users.User, Repo} + def init(default), do: default def call(conn, _default) do - user = %User{id: 1, email: "dev_user@fireguard.network"} + user = Repo.one(User) assign(conn, :current_user, user) end end diff --git a/apps/fg_http/lib/fg_http_web/router.ex b/apps/fg_http/lib/fg_http_web/router.ex index 380657e26..a2c7a33d0 100644 --- a/apps/fg_http/lib/fg_http_web/router.ex +++ b/apps/fg_http/lib/fg_http_web/router.ex @@ -23,7 +23,7 @@ defmodule FgHttpWeb.Router do resources "/user", UserController, singleton: true, only: [:show, :edit, :update, :delete] resources "/users", UserController, only: [:new, :create] - resources "/devices", DeviceController, except: [:create] do + resources "/devices", DeviceController do resources "/rules", RuleController, only: [:new, :index, :create] end diff --git a/apps/fg_http/lib/fg_http_web/templates/device/new.html.eex b/apps/fg_http/lib/fg_http_web/templates/device/new.html.eex index a0d19778b..4e41714ba 100644 --- a/apps/fg_http/lib/fg_http_web/templates/device/new.html.eex +++ b/apps/fg_http/lib/fg_http_web/templates/device/new.html.eex @@ -1,6 +1,6 @@

New Device

-<%= live_render(@conn, FgHttpWeb.NewDeviceLive, session: %{"current_user_id" => 1}) %> +<%= live_render(@conn, FgHttpWeb.NewDeviceLive) %>

<%= link "Back", to: Routes.device_path(@conn, :index) %> From 805b5fefe0bc037bfc38593f3a7623fb12fdd2d6 Mon Sep 17 00:00:00 2001 From: Jamil Bou Kheir Date: Wed, 13 May 2020 00:50:24 -0500 Subject: [PATCH 2/4] Basic device create works --- apps/fg_http/lib/fg_http/devices.ex | 13 ------------- apps/fg_http/lib/fg_http/devices/device.ex | 3 +-- .../fg_http_web/controllers/device_controller.ex | 5 ----- .../fg_http/lib/fg_http_web/live/new_device_live.ex | 1 - .../lib/fg_http_web/templates/device/index.html.eex | 2 -- .../lib/fg_http_web/templates/device/show.html.eex | 5 ----- .../migrations/20200228145810_create_devices.exs | 1 - .../controllers/device_controller_test.exs | 10 ++++++++-- 8 files changed, 9 insertions(+), 31 deletions(-) diff --git a/apps/fg_http/lib/fg_http/devices.ex b/apps/fg_http/lib/fg_http/devices.ex index b1638d20e..eef55d84a 100644 --- a/apps/fg_http/lib/fg_http/devices.ex +++ b/apps/fg_http/lib/fg_http/devices.ex @@ -90,19 +90,6 @@ defmodule FgHttp.Devices do |> Repo.update() end - @doc """ - Verifies a Device. - - ## Examples - - iex> verify!(device.id) - {:ok, %Device{}} - """ - def verify(id) do - get_device!(id) - |> update_device(%{verified_at: DateTime.utc_now}) - end - @doc """ Deletes a device. diff --git a/apps/fg_http/lib/fg_http/devices/device.ex b/apps/fg_http/lib/fg_http/devices/device.ex index 57706dbc3..ecf4a34c5 100644 --- a/apps/fg_http/lib/fg_http/devices/device.ex +++ b/apps/fg_http/lib/fg_http/devices/device.ex @@ -9,7 +9,6 @@ defmodule FgHttp.Devices.Device do schema "devices" do field :name, :string field :public_key, :string - field :verified_at, :utc_datetime field :user_id, :id has_many :rules, FgHttp.Rules.Rule @@ -20,7 +19,7 @@ defmodule FgHttp.Devices.Device do @doc false def changeset(device, attrs) do device - |> cast(attrs, [:user_id, :verified_at, :name, :public_key]) + |> cast(attrs, [:user_id, :name, :public_key]) |> validate_required([:user_id]) end end diff --git a/apps/fg_http/lib/fg_http_web/controllers/device_controller.ex b/apps/fg_http/lib/fg_http_web/controllers/device_controller.ex index 3dd2106eb..f04053930 100644 --- a/apps/fg_http/lib/fg_http_web/controllers/device_controller.ex +++ b/apps/fg_http/lib/fg_http_web/controllers/device_controller.ex @@ -21,18 +21,13 @@ defmodule FgHttpWeb.DeviceController do def create(conn, %{"device" => device_params}) do create_params = %{ "user_id" => conn.assigns.current_user.id, - "verified_at" => DateTime.utc_now, "name" => "Auto" } all_params = Map.merge(device_params, create_params) - IO.puts "Create device with params: " - IO.inspect all_params case Devices.create_device(all_params) do {:ok, device} -> - IO.inspect(device) redirect(conn, to: Routes.device_path(conn, :show, device)) {:error, %Ecto.Changeset{} = changeset} -> - IO.inspect(changeset) render(conn, "new.html", changeset: changeset) end end diff --git a/apps/fg_http/lib/fg_http_web/live/new_device_live.ex b/apps/fg_http/lib/fg_http_web/live/new_device_live.ex index 5e41759a6..b4490f70f 100644 --- a/apps/fg_http/lib/fg_http_web/live/new_device_live.ex +++ b/apps/fg_http/lib/fg_http_web/live/new_device_live.ex @@ -7,7 +7,6 @@ defmodule FgHttpWeb.NewDeviceLive do def mount(_params, %{}, socket) do user_id = "1" - IO.inspect(socket) if connected?(socket), do: wait_for_device(socket) device = %Device{id: "1", user_id: user_id} diff --git a/apps/fg_http/lib/fg_http_web/templates/device/index.html.eex b/apps/fg_http/lib/fg_http_web/templates/device/index.html.eex index 85559e08b..3f60956b6 100644 --- a/apps/fg_http/lib/fg_http_web/templates/device/index.html.eex +++ b/apps/fg_http/lib/fg_http_web/templates/device/index.html.eex @@ -4,7 +4,6 @@ Name - Verified at Public key @@ -12,7 +11,6 @@ <%= for device <- @devices do %> <%= device.name %> - <%= device.verified_at %> <%= device.public_key %> diff --git a/apps/fg_http/lib/fg_http_web/templates/device/show.html.eex b/apps/fg_http/lib/fg_http_web/templates/device/show.html.eex index 9ca326d51..8db5dae66 100644 --- a/apps/fg_http/lib/fg_http_web/templates/device/show.html.eex +++ b/apps/fg_http/lib/fg_http_web/templates/device/show.html.eex @@ -6,11 +6,6 @@ <%= @device.name %> -

  • - Verified at: - <%= @device.verified_at %> -
  • -
  • Public key: <%= @device.public_key %> diff --git a/apps/fg_http/priv/repo/migrations/20200228145810_create_devices.exs b/apps/fg_http/priv/repo/migrations/20200228145810_create_devices.exs index 0a5dc8035..f2d57d058 100644 --- a/apps/fg_http/priv/repo/migrations/20200228145810_create_devices.exs +++ b/apps/fg_http/priv/repo/migrations/20200228145810_create_devices.exs @@ -4,7 +4,6 @@ defmodule FgHttp.Repo.Migrations.CreateDevices do def change do create table(:devices) do add :name, :string - add :verified_at, :utc_datetime add :public_key, :string add :user_id, references(:users, on_delete: :delete_all) diff --git a/apps/fg_http/test/fg_http_web/controllers/device_controller_test.exs b/apps/fg_http/test/fg_http_web/controllers/device_controller_test.exs index 58650e19e..9f594aab3 100644 --- a/apps/fg_http/test/fg_http_web/controllers/device_controller_test.exs +++ b/apps/fg_http/test/fg_http_web/controllers/device_controller_test.exs @@ -2,13 +2,19 @@ defmodule FgHttpWeb.DeviceControllerTest do use FgHttpWeb.ConnCase alias FgHttp.Devices + alias FgHttp.Users @create_attrs %{name: "some name"} @update_attrs %{name: "some updated name"} - @invalid_attrs %{name: nil} + @invalid_attrs %{user_id: nil} + + def fixture(:user) do + {:ok, user} = Users.create_user(%{email: "test"}) + user + end def fixture(:device) do - {:ok, device} = Devices.create_device(@create_attrs) + {:ok, device} = Devices.create_device(Map.merge(%{user_id: fixture(:user).id}, @create_attrs)) device end From 7a31b6f776781fc06f4e82a8f5a7178c9830af6f Mon Sep 17 00:00:00 2001 From: Jamil Bou Kheir Date: Wed, 13 May 2020 00:56:19 -0500 Subject: [PATCH 3/4] Fix more linting --- apps/fg_http/lib/fg_http/devices.ex | 4 +--- apps/fg_http/lib/fg_http/sessions.ex | 1 - apps/fg_http/lib/fg_http/users.ex | 2 -- .../lib/fg_http_web/controllers/device_controller.ex | 3 +++ .../fg_http_web/controllers/session_controller.ex | 2 +- apps/fg_http/lib/fg_http_web/endpoint.ex | 3 +-- apps/fg_http/lib/fg_http_web/live/new_device_live.ex | 12 +++++++----- apps/fg_http/lib/fg_http_web/plugs/authenticator.ex | 3 +-- 8 files changed, 14 insertions(+), 16 deletions(-) diff --git a/apps/fg_http/lib/fg_http/devices.ex b/apps/fg_http/lib/fg_http/devices.ex index eef55d84a..72ec5a3b7 100644 --- a/apps/fg_http/lib/fg_http/devices.ex +++ b/apps/fg_http/lib/fg_http/devices.ex @@ -32,12 +32,10 @@ defmodule FgHttp.Devices do } """ def new_device(attrs \\ %{}) do - device = %Device{ - } + device = %Device{} Map.merge(device, attrs) end - @doc """ Gets a single device. diff --git a/apps/fg_http/lib/fg_http/sessions.ex b/apps/fg_http/lib/fg_http/sessions.ex index 9f28bebc2..3d1f7d325 100644 --- a/apps/fg_http/lib/fg_http/sessions.ex +++ b/apps/fg_http/lib/fg_http/sessions.ex @@ -102,4 +102,3 @@ defmodule FgHttp.Sessions do Session.changeset(session, %{}) end end - diff --git a/apps/fg_http/lib/fg_http/users.ex b/apps/fg_http/lib/fg_http/users.ex index 9c90b2f6b..5fb224803 100644 --- a/apps/fg_http/lib/fg_http/users.ex +++ b/apps/fg_http/lib/fg_http/users.ex @@ -102,5 +102,3 @@ defmodule FgHttp.Users do User.changeset(user, %{}) end end - - diff --git a/apps/fg_http/lib/fg_http_web/controllers/device_controller.ex b/apps/fg_http/lib/fg_http_web/controllers/device_controller.ex index f04053930..6fe3802ba 100644 --- a/apps/fg_http/lib/fg_http_web/controllers/device_controller.ex +++ b/apps/fg_http/lib/fg_http_web/controllers/device_controller.ex @@ -23,10 +23,13 @@ defmodule FgHttpWeb.DeviceController do "user_id" => conn.assigns.current_user.id, "name" => "Auto" } + all_params = Map.merge(device_params, create_params) + case Devices.create_device(all_params) do {:ok, device} -> redirect(conn, to: Routes.device_path(conn, :show, device)) + {:error, %Ecto.Changeset{} = changeset} -> render(conn, "new.html", changeset: changeset) end diff --git a/apps/fg_http/lib/fg_http_web/controllers/session_controller.ex b/apps/fg_http/lib/fg_http_web/controllers/session_controller.ex index 8e255ba96..c2cd30e7a 100644 --- a/apps/fg_http/lib/fg_http_web/controllers/session_controller.ex +++ b/apps/fg_http/lib/fg_http_web/controllers/session_controller.ex @@ -4,7 +4,7 @@ defmodule FgHttpWeb.SessionController do """ use FgHttpWeb, :controller - alias FgHttp.{Repo, Users.User, Sessions.Session} + alias FgHttp.{Repo, Sessions.Session, Users.User} plug :redirect_authenticated when action in [:new] plug FgHttpWeb.Plugs.Authenticator when action in [:delete] diff --git a/apps/fg_http/lib/fg_http_web/endpoint.ex b/apps/fg_http/lib/fg_http_web/endpoint.ex index 60eaba97f..f77e492ee 100644 --- a/apps/fg_http/lib/fg_http_web/endpoint.ex +++ b/apps/fg_http/lib/fg_http_web/endpoint.ex @@ -10,8 +10,7 @@ defmodule FgHttpWeb.Endpoint do signing_salt: "Z9eq8iof" ] - socket "/live", Phoenix.LiveView.Socket, - websocket: [connect_info: [session: @session_options]] + socket "/live", Phoenix.LiveView.Socket, websocket: [connect_info: [session: @session_options]] socket "/socket", FgHttpWeb.UserSocket, websocket: true, diff --git a/apps/fg_http/lib/fg_http_web/live/new_device_live.ex b/apps/fg_http/lib/fg_http_web/live/new_device_live.ex index b4490f70f..5a13536e5 100644 --- a/apps/fg_http/lib/fg_http_web/live/new_device_live.ex +++ b/apps/fg_http/lib/fg_http_web/live/new_device_live.ex @@ -1,9 +1,12 @@ defmodule FgHttpWeb.NewDeviceLive do + @moduledoc """ + Manages LiveView for New Devices + """ + use Phoenix.LiveView use Phoenix.HTML - alias FgHttpWeb.Router.Helpers, as: Routes - alias FgHttp.Devices.Device + alias FgHttpWeb.Router.Helpers, as: Routes def mount(_params, %{}, socket) do user_id = "1" @@ -13,9 +16,8 @@ defmodule FgHttpWeb.NewDeviceLive do {:ok, assign(socket, :device, device)} end - defp wait_for_device(socket) do - # TODO: pass socket to fg_vpn somehow - IO.inspect(socket) + defp wait_for_device(_socket) do + # XXX: pass socket to fg_vpn somehow :timer.send_after(3000, self(), :update) end diff --git a/apps/fg_http/lib/fg_http_web/plugs/authenticator.ex b/apps/fg_http/lib/fg_http_web/plugs/authenticator.ex index 0b99444d6..53c347906 100644 --- a/apps/fg_http/lib/fg_http_web/plugs/authenticator.ex +++ b/apps/fg_http/lib/fg_http_web/plugs/authenticator.ex @@ -4,8 +4,7 @@ defmodule FgHttpWeb.Plugs.Authenticator do """ import Plug.Conn - alias FgHttp.{Users.User, Repo} - + alias FgHttp.{Repo, Users.User} def init(default), do: default From 7d88274536c97386018d263fa96f489d6444dabf Mon Sep 17 00:00:00 2001 From: Jamil Bou Kheir Date: Wed, 13 May 2020 01:16:13 -0500 Subject: [PATCH 4/4] Mock authentication for tests --- apps/fg_http/lib/fg_http_web/live/new_device_live.ex | 7 +++---- apps/fg_http/lib/fg_http_web/templates/device/new.html.eex | 2 +- .../fg_http_web/controllers/device_controller_test.exs | 3 +++ 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/apps/fg_http/lib/fg_http_web/live/new_device_live.ex b/apps/fg_http/lib/fg_http_web/live/new_device_live.ex index 5a13536e5..8e68ccf47 100644 --- a/apps/fg_http/lib/fg_http_web/live/new_device_live.ex +++ b/apps/fg_http/lib/fg_http_web/live/new_device_live.ex @@ -8,15 +8,14 @@ defmodule FgHttpWeb.NewDeviceLive do alias FgHttp.Devices.Device alias FgHttpWeb.Router.Helpers, as: Routes - def mount(_params, %{}, socket) do - user_id = "1" - if connected?(socket), do: wait_for_device(socket) + def mount(_params, %{"current_user_id" => user_id}, socket) do + if connected?(socket), do: wait_for_device_connect(socket) device = %Device{id: "1", user_id: user_id} {:ok, assign(socket, :device, device)} end - defp wait_for_device(_socket) do + defp wait_for_device_connect(_socket) do # XXX: pass socket to fg_vpn somehow :timer.send_after(3000, self(), :update) end diff --git a/apps/fg_http/lib/fg_http_web/templates/device/new.html.eex b/apps/fg_http/lib/fg_http_web/templates/device/new.html.eex index 4e41714ba..b2ff5a818 100644 --- a/apps/fg_http/lib/fg_http_web/templates/device/new.html.eex +++ b/apps/fg_http/lib/fg_http_web/templates/device/new.html.eex @@ -1,6 +1,6 @@

    New Device

    -<%= live_render(@conn, FgHttpWeb.NewDeviceLive) %> +<%= live_render(@conn, FgHttpWeb.NewDeviceLive, session: %{"current_user_id" => @conn.assigns.current_user.id}) %>

    <%= link "Back", to: Routes.device_path(@conn, :index) %> diff --git a/apps/fg_http/test/fg_http_web/controllers/device_controller_test.exs b/apps/fg_http/test/fg_http_web/controllers/device_controller_test.exs index 9f594aab3..0b5f37b0e 100644 --- a/apps/fg_http/test/fg_http_web/controllers/device_controller_test.exs +++ b/apps/fg_http/test/fg_http_web/controllers/device_controller_test.exs @@ -27,6 +27,9 @@ defmodule FgHttpWeb.DeviceControllerTest do describe "new device" do test "renders form", %{conn: conn} do + # Mock authentication + conn = Plug.Conn.assign(conn, :current_user, fixture(:user)) + conn = get(conn, Routes.device_path(conn, :new)) assert html_response(conn, 200) =~ "New Device" end