Merge pull request #18 from CloudFire-LLC/device-create

Device creation works
This commit is contained in:
Jamil
2020-05-13 10:40:33 -05:00
committed by GitHub
18 changed files with 83 additions and 48 deletions

View File

@@ -3,6 +3,9 @@ import { qrEncode } from "./qr_code.js"
let Hooks = {}
Hooks.QrEncode = {
mounted() {
qrEncode()
},
updated() {
qrEncode()
}

View File

@@ -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.

View File

@@ -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, [:name, :public_key])
|> validate_required([:name])
|> cast(attrs, [:user_id, :name, :public_key])
|> validate_required([:user_id])
end
end

View File

@@ -102,4 +102,3 @@ defmodule FgHttp.Sessions do
Session.changeset(session, %{})
end
end

View File

@@ -102,5 +102,3 @@ defmodule FgHttp.Users do
User.changeset(user, %{})
end
end

View File

@@ -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

View File

@@ -18,6 +18,23 @@ 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,
"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
end
def show(conn, %{"id" => id}) do
device = Devices.get_device!(id)
render(conn, "show.html", device: device)

View File

@@ -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]

View File

@@ -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,

View File

@@ -1,19 +1,23 @@
defmodule FgHttpWeb.NewDeviceLive do
use Phoenix.LiveView
@moduledoc """
Manages LiveView for New Devices
"""
use Phoenix.LiveView
use Phoenix.HTML
alias FgHttp.Devices.Device
alias FgHttpWeb.Router.Helpers, as: Routes
def mount(_params, %{"current_user_id" => user_id}, socket) do
if connected?(socket), do: wait_for_device(socket)
if connected?(socket), do: wait_for_device_connect(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)
defp wait_for_device_connect(_socket) do
# XXX: pass socket to fg_vpn somehow
:timer.send_after(3000, self(), :update)
end
def handle_info(:update, socket) do

View File

@@ -1,5 +1,5 @@
<p>
Add the following to your Wireguard configuration file:
Add the following to your WireGuard configuration file:
</p>
<div class="cf">
@@ -18,16 +18,33 @@ Endpoint = <%= Application.fetch_env!(:fg_http, :vpn_endpoint) %>
</div>
</div>
<p>
When we receive a connection from your device, we'll prompt you verify it here.
</p>
<p>
Waiting for device connection...
<span phx-hook="QrEncode">
<%= if @device.public_key do %>
Connected! Device Public Key: <%= @device.public_key %>
<a href="#">Configure your device -></a>
<% end %>
</span>
</p>
<div phx-hook="QrEncode">
<%= unless @device.public_key do %>
<h4>
Waiting for device connection...
</h4>
<p>
When we receive a connection from your device, we'll prompt you verify it here.
</p>
<% else %>
<h4>Connected!</h4>
<p>
Device Public Key: <%= @device.public_key %>
</p>
<p>
<%# 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)
%>
</p>
<p>
<%=
link("<- Something's wrong. Don't add this device and go back.",
to: Routes.device_path(@socket, :index),
method: :delete)
%>
</p>
<% end %>
</div>

View File

@@ -4,12 +4,12 @@ defmodule FgHttpWeb.Plugs.Authenticator do
"""
import Plug.Conn
alias FgHttp.Users.User
alias FgHttp.{Repo, Users.User}
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

View File

@@ -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

View File

@@ -4,7 +4,6 @@
<tbody>
<tr class="striped--near-white">
<th class="pv2 ph3 tl f6 fw6 ttu">Name</th>
<th class="pv2 ph3 tl f6 fw6 ttu">Verified at</th>
<th class="pv2 ph3 tl f6 fw6 ttu">Public key</th>
<th></th>
@@ -12,7 +11,6 @@
<%= for device <- @devices do %>
<tr class="striped--near-white">
<td class="pv2 ph3 tl f6 fw6 ttu"><%= device.name %></td>
<td class="pv2 ph3 tl f6 fw6 ttu"><%= device.verified_at %></td>
<td class="pv2 ph3 tl f6 fw6 ttu"><%= device.public_key %></td>
<td>

View File

@@ -1,6 +1,6 @@
<h1>New Device</h1>
<%= live_render(@conn, FgHttpWeb.NewDeviceLive, session: %{"current_user_id" => 1}) %>
<%= live_render(@conn, FgHttpWeb.NewDeviceLive, session: %{"current_user_id" => @conn.assigns.current_user.id}) %>
<p>
<%= link "Back", to: Routes.device_path(@conn, :index) %>

View File

@@ -6,11 +6,6 @@
<%= @device.name %>
</li>
<li>
<strong>Verified at:</strong>
<%= @device.verified_at %>
</li>
<li>
<strong>Public key:</strong>
<%= @device.public_key %>

View File

@@ -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)

View File

@@ -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
@@ -21,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