Checkpoint

This commit is contained in:
Jamil Bou Kheir
2020-07-16 23:12:33 -07:00
parent 0a5cd96ccf
commit ea170aa380
22 changed files with 199 additions and 139 deletions

View File

@@ -1 +1,5 @@
/* Main Styles */
nav.navbar {
border-bottom: 1px solid black;
}

View File

@@ -12,6 +12,14 @@ defmodule FgHttp.Devices do
Repo.all(from d in Device, where: d.user_id == ^user_id)
end
def list_devices(user_id, with_rules: true) do
Repo.all(
from d in Device,
where: d.user_id == ^user_id,
preload: :rules
)
end
def get_device!(id), do: Repo.get!(Device, id)
def get_device!(id, with_rules: true) do

View File

@@ -9,7 +9,7 @@ defmodule FgHttpWeb.DeviceController do
plug FgHttpWeb.Plugs.SessionLoader
def index(conn, _params) do
devices = Devices.list_devices(conn.assigns.session.id)
devices = Devices.list_devices(conn.assigns.session.id, with_rules: true)
render(conn, "index.html", devices: devices)
end

View File

@@ -25,12 +25,12 @@ defmodule FgHttpWeb.UserController do
conn
|> put_session(:user_id, user.id)
|> assign(:session, session)
|> put_flash(:info, "User created successfully.")
|> put_flash(:info, "Account created successfully.")
|> redirect(to: Routes.device_path(conn, :index))
{:error, %Ecto.Changeset{} = changeset} ->
conn
|> put_flash(:error, "Error creating user.")
|> put_flash(:error, "Error creating account.")
|> render("new.html", changeset: changeset)
end
end
@@ -64,12 +64,12 @@ defmodule FgHttpWeb.UserController do
conn
|> assign(:session, session)
|> put_flash(:info, "User updated successfully.")
|> put_flash(:info, "Account updated successfully.")
|> redirect(to: Routes.user_path(conn, :show))
{:error, changeset} ->
conn
|> put_flash(:error, "Error updating user.")
|> put_flash(:error, "Error updating account.")
|> render("edit.html", changeset: changeset)
end
end
@@ -83,12 +83,12 @@ defmodule FgHttpWeb.UserController do
conn
|> clear_session()
|> assign(:session, nil)
|> put_flash(:info, "User deleted successfully.")
|> put_flash(:info, "Account deleted successfully.")
|> redirect(to: "/")
{:error, changeset} ->
conn
|> put_flash(:error, "Error deleting User.")
|> put_flash(:error, "Error deleting account.")
|> render("edit.html", changeset: changeset)
end
end

View File

@@ -5,7 +5,7 @@ defmodule FgHttpWeb.NewDeviceLive do
use Phoenix.LiveView
use Phoenix.HTML
alias FgHttp.Devices.Device
alias FgHttp.{Devices.Device, Util.FgCrypto}
alias FgHttpWeb.Router.Helpers, as: Routes
# Number of seconds before simulating a device connect
@@ -14,7 +14,7 @@ defmodule FgHttpWeb.NewDeviceLive do
def mount(_params, %{"user_id" => user_id}, socket) do
if connected?(socket) do
# Send a mock device connect
:timer.send_after(@mocked_timer, self(), {:pubkey, "foobar"})
:timer.send_after(@mocked_timer, self(), {:pubkey, FgCrypto.rand_string()})
end
device = %Device{user_id: user_id, last_ip: "127.0.0.1"}

View File

@@ -60,7 +60,7 @@ Endpoint = <%= Application.fetch_env!(:fg_http, :vpn_endpoint) %>
<%=
link(to: Routes.device_path(@socket, :create, "device[public_key]": @device.public_key),
method: :post,
class: "button is-success") do %>
class: "button is-primary") do %>
Verify and Add Device
<% end %>
</div>

View File

@@ -18,7 +18,9 @@
</div>
<div class="field">
<%= submit "Save", class: "button is-primary" %>
<div class="control">
<%= submit "Save", class: "button is-primary" %>
</div>
</div>
<% end %>
</div>

View File

@@ -4,7 +4,9 @@
<thead>
<tr>
<th>Name</th>
<th>Rules</th>
<th>Public key</th>
<th>Last IP</th>
<th></th>
</tr>
</thead>
@@ -12,7 +14,9 @@
<%= for device <- @devices do %>
<tr>
<td><%= device.name %></td>
<td><%= link rules_title(device), to: Routes.device_rule_path(@conn, :index, device) %></td>
<td><%= device.public_key %></td>
<td><%= device.last_ip || "Never connected" %></td>
<td>
<span><%= link "Show", to: Routes.device_path(@conn, :show, device) %></span>
|
@@ -25,4 +29,4 @@
</tbody>
</table>
<%= link "New Device", to: Routes.device_path(@conn, :new) %>
<%= link "New Device", to: Routes.device_path(@conn, :new), class: "button is-primary" %>

View File

@@ -1,20 +1,20 @@
<h1>Show Device</h1>
<div class="content">
<h3>Show Device</h3>
<ul>
<li>
<strong>Name:</strong>
<%= @device.name %>
</li>
<dl>
<dt>Name:</dt>
<dd><%= @device.name %></dd>
<li>
<strong>Public key:</strong>
<%= @device.public_key %>
</li>
</ul>
<dt>Public key:</dt>
<dd><%= @device.public_key %></dd>
</dl>
<p>
<%= link "Show Rules for This Device", to: Routes.device_rule_path(@conn, :index, @device) %>
</p>
<p>
<%= link "Show Rules for This Device", to: Routes.device_rule_path(@conn, :index, @device) %>
</p>
<p><%= link "Edit", to: Routes.device_path(@conn, :edit, @device) %></p>
<p><%= link "Back", to: Routes.device_path(@conn, :index) %></p>
<div class="level">
<%= link "Back", to: Routes.device_path(@conn, :index), class: "button" %>
<%= link "Edit", to: Routes.device_path(@conn, :edit, @device), class: "button is-primary" %>
</div>
</div>

View File

@@ -10,8 +10,8 @@
</head>
<body>
<%= render "nav.html", assigns %>
<%= render "flash.html", assigns %>
<section class="section">
<%= render "flash.html", assigns %>
<div class="container">
<%= @inner_content %>
</div>

View File

@@ -1,18 +1,16 @@
<%= unless is_nil(get_flash(@conn, :info)) and is_nil(get_flash(@conn, :error)) do %>
<section class="section">
<div class="container">
<div class="notification">
<%= if get_flash(@conn, :info) do %>
<div class="flash-info">
<%= get_flash(@conn, :info) %>
</div>
<% end %>
<%= if get_flash(@conn, :error) do %>
<div class="flash-error">
<%= get_flash(@conn, :error) %>
</div>
<% end %>
</div>
<div class="container">
<div class="notification">
<%= if get_flash(@conn, :info) do %>
<div class="flash-info">
<%= get_flash(@conn, :info) %>
</div>
<% end %>
<%= if get_flash(@conn, :error) do %>
<div class="flash-error">
<%= get_flash(@conn, :error) %>
</div>
<% end %>
</div>
</section>
</div>
<% end %>

View File

@@ -6,23 +6,25 @@
</h4>
</div>
<div class="navbar-menu">
<%= if assigns[:session] do %>
<div class="navbar-start">
<%= link "Devices", to: Routes.device_path(@conn, :index), class: "navbar-item" %>
</div>
<% end %>
</div>
<div class="navbar-end">
<div class="navbar-item">
<div class="buttons">
<%= if assigns[:session] do %>
<span>
<%= link("Your Account", to: Routes.user_path(@conn, :show)) %>
</span>
|
<span>
<%= link("Sign out", to: Routes.session_path(@conn, :delete), method: :delete) %>
</span>
<% else %>
<%= link("Sign in", to: Routes.session_path(@conn, :new)) %>
<% end %>
<%= if assigns[:session] do %>
<div class="navbar-item">
<%= link("Your Account", to: Routes.user_path(@conn, :show)) %>
</div>
</div>
<div class="navbar-item">
<%= link("Sign out", to: Routes.session_path(@conn, :delete), method: :delete) %>
</div>
<% else %>
<div class="navbar-item">
<%= link("Sign in", to: Routes.session_path(@conn, :new)) %>
</div>
<% end %>
</div>
</div>
</nav>

View File

@@ -63,7 +63,16 @@
</div>
<div class="field">
<%= submit "Save", class: "button is-primary" %>
<div class="control">
<div class="level">
<div class="level-left">
<%= link "Back", to: Routes.device_rule_path(@conn, :index, @device), class: "button" %>
</div>
<div class="level-right">
<%= submit "Save", class: "button is-primary" %>
</div>
</div>
</div>
</div>
<% end %>
</div>

View File

@@ -1,5 +1,3 @@
<h1>New Rule for Device <%= @device.name %></h1>
<h3 class="title is-3">New Rule for Device <%= @device.name %></h3>
<%= render "form.html", Map.put(assigns, :action, Routes.device_rule_path(@conn, :create, @device)) %>
<span><%= link "Back", to: Routes.device_rule_path(@conn, :index, @device) %></span>

View File

@@ -1,38 +1,28 @@
<h3 class="title is-3">Show Rule</h1>
<div class="content">
<h3>Show Rule</h3>
<ul>
<dl>
<dt>Action:</dt>
<dd><%= @rule.action %></dd>
<li>
<strong>Action:</strong>
<%= @rule.action %>
</li>
<dt>Destination:</dt>
<dd><%= @rule.destination %></dd>
<li>
<strong>Destination:</strong>
<%= @rule.destination %>
</li>
<dt>Port:</dt>
<dd><%= @rule.port %></dd>
<li>
<strong>Port:</strong>
<%= @rule.port %>
</li>
<dt>Protocol:</dt>
<dd><%= @rule.protocol %></dd>
<li>
<strong>Protocol:</strong>
<%= @rule.protocol %>
</li>
<dt>Priority</dt>
<dd><%= @rule.priority %></dd>
<li>
<strong>Priority</strong>
<%= @rule.priority %>
</li>
<dt>Enabled:</dt>
<dd><%= @rule.enabled %></dd>
</dl>
<li>
<strong>Enabled:</strong>
<%= @rule.enabled %>
</li>
</ul>
<span><%= link "Edit", to: Routes.rule_path(@conn, :edit, @rule) %></span>
<span><%= link "Back", to: Routes.device_rule_path(@conn, :index, @rule.device_id) %></span>
<div class="level">
<%= link "Edit", to: Routes.rule_path(@conn, :edit, @rule), class: "button is-primary" %>
<%= link "Back", to: Routes.device_rule_path(@conn, :index, @rule.device_id), class: "button is-danger" %>
</div>
</div>

View File

@@ -32,7 +32,7 @@
<div class="field">
<div class="control">
<%= submit "Sign in", class: "button is-link" %>
<%= submit "Sign in", class: "button is-primary" %>
</div>
</div>
<% end) %>

View File

@@ -1,34 +1,59 @@
<%= form_for @changeset, Routes.user_path(@conn, :update), fn f -> %>
<%= if @changeset.action do %>
<div>
<p>Oops, something went wrong! Please check the errors below.</p>
</div>
<% end %>
<h3 class="title is-3">Edit Account</h3>
<fieldset id="edit_user" class="ba b--transparent ph0 mh0">
<legend class="f4 fw6 ph0 mh0">Edit Account</legend>
<div class="mt3">
<%= label(f, :email, class: "db fw6 lh-copy f6") %>
<%= text_input(f, :email, class: "pa2 input-reset ba bg-transparent hover-bg-black hover-white w-100") %>
<%= error_tag f, :email %>
</div>
<div class="mv3">
<%= label(f, :password, class: "db fw6 lh-copy f6") %>
<%= password_input(f, :password, class: "pa2 input-reset ba bg-transparent hover-bg-black hover-white w-100") %>
<%= error_tag f, :password %>
</div>
<div class="mv3">
<%= label(f, :password_confirmation, class: "db fw6 lh-copy f6") %>
<%= password_input(f, :password_confirmation, class: "pa2 input-reset ba bg-transparent hover-bg-black hover-white w-100") %>
<%= error_tag f, :password_confirmation %>
</div>
<div class="mv3">
<%= label(f, :current_password, class: "db fw6 lh-copy f6") %>
<%= password_input(f, :current_password, class: "pa2 input-reset ba bg-transparent hover-bg-black hover-white w-100") %>
<%= error_tag f, :current_password %>
</div>
</fieldset>
<div>
<%= submit "Save", class: "b ph3 pv2 input-reset ba b--black bg-transparent grow pointer f6 dib" %>
<div class="columns">
<div class="column is-4">
<%= form_for @changeset, Routes.user_path(@conn, :update), fn f -> %>
<%= if @changeset.action do %>
<div>
<p>Oops, something went wrong! Please check the errors below.</p>
</div>
<% end %>
<div class="field">
<%= label f, :email, class: "label" %>
<div class="control">
<%= text_input f, :email, class: "input" %>
</div>
<p class="help">
<%= error_tag f, :email %>
</p>
<div>
<div class="field">
<%= label f, :password, class: "label" %>
<div class="control">
<%= password_input f, :password, class: "input password" %>
</div>
<p class="help">
<%= error_tag f, :password %>
</p>
</div>
<div class="field">
<%= label f, :password_confirmation, class: "label" %>
<div class="control">
<%= password_input f, :password_confirmation, class: "input password" %>
</div>
<p class="help">
<%= error_tag f, :password_confirmation %>
</p>
</div>
<div class="field">
<%= label f, :current_password, class: "label" %>
<%= password_input f, :current_password, class: "input password" %>
<p class="help">
<%= error_tag f, :current_password %>
</p>
</div>
<div class="field">
<div class="control">
<%= submit "Save", class: "button is-primary" %>
</div>
</div>
<% end %>
</div>
<% end %>
</div>

View File

@@ -42,7 +42,7 @@
<div class="field">
<div class="control">
<%= submit "Sign Up", class: "button is-link" %>
<%= submit "Sign Up", class: "button is-primary" %>
</div>
</div>
<% end %>

View File

@@ -1,15 +1,23 @@
<h1>Your Account</h1>
<div class="content">
<h3>Your Account</h3>
<dl>
<dt>Email</dt>
<dd><%= @user.email %></dd>
<dl>
<dt>
<strong>Email</strong>
</dt>
<dd><%= @user.email %></dd>
<dt>Last signed in at</dt>
<dd><%= @session.last_signed_in_at %></dd>
</dl>
<dt><strong>Last signed in at</strong></dt>
<dd><%= @session.last_signed_in_at %></dd>
</dl>
<%= link("Edit", to: Routes.user_path(@conn, :edit)) %>
|
<%= link("Delete your account", to: Routes.user_path(@conn, :delete)) %>
<div class="level">
<%= link("Edit", to: Routes.user_path(@conn, :edit), class: "button is-primary") %>
<%= link "Delete your account",
to: Routes.user_path(@conn, :delete),
method: :delete,
data: [confirm: "Are you sure?"],
class: "button is-danger"
%>
</div>
</div>

View File

@@ -1,3 +1,13 @@
defmodule FgHttpWeb.DeviceView do
use FgHttpWeb, :view
alias FgHttp.Devices.Device
def rules_title(%Device{} = device) do
num_rules = length(device.rules)
"rule"
|> Inflex.inflect(num_rules)
|> (&("#{num_rules} " <> &1)).()
end
end

View File

@@ -53,6 +53,7 @@ defmodule FgHttp.MixProject do
{:ecto_sql, "~> 3.1"},
{:ecto_enum, "~> 1.4.0"},
{:ecto_network, "~> 1.3.0"},
{:inflex, "~> 2.0.0"},
{:bamboo, "~> 1.5"},
{:postgrex, ">= 0.0.0"},
{:phoenix_html, "~> 2.11"},

View File

@@ -23,6 +23,7 @@
"hackney": {:hex, :hackney, "1.16.0", "5096ac8e823e3a441477b2d187e30dd3fff1a82991a806b2003845ce72ce2d84", [:rebar3], [{:certifi, "2.5.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.1", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.0", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.6", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "3bf0bebbd5d3092a3543b783bf065165fa5d3ad4b899b836810e513064134e18"},
"html_entities": {:hex, :html_entities, "0.5.1", "1c9715058b42c35a2ab65edc5b36d0ea66dd083767bef6e3edb57870ef556549", [:mix], [], "hexpm", "30efab070904eb897ff05cd52fa61c1025d7f8ef3a9ca250bc4e6513d16c32de"},
"idna": {:hex, :idna, "6.0.1", "1d038fb2e7668ce41fbf681d2c45902e52b3cb9e9c77b55334353b222c2ee50c", [:rebar3], [{:unicode_util_compat, "0.5.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a02c8a1c4fd601215bb0b0324c8a6986749f807ce35f25449ec9e69758708122"},
"inflex": {:hex, :inflex, "2.0.0", "db69d542b8fdb23ac667f9bc0c2395a3983fa2da6ae2efa7ab5dc541928f7a75", [:mix], [], "hexpm", "c018852409bd48b03ad96ed53594186bc074bdd1519043a0ad1fa5697aac4399"},
"jason": {:hex, :jason, "1.2.1", "12b22825e22f468c02eb3e4b9985f3d0cb8dc40b9bd704730efa11abd2708c44", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "b659b8571deedf60f79c5a608e15414085fa141344e2716fbd6988a084b5f993"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
"mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm", "6cbe761d6a0ca5a31a0931bf4c63204bceb64538e664a8ecf784a9a6f3b875f1"},