From 26629dc30a116204263ac4b515600649ba742ba0 Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Wed, 26 Sep 2018 18:14:32 +0200 Subject: Web UI for multiple identities --- shardweb/assets/js/app.js | 2 +- shardweb/config/config.exs | 2 +- shardweb/lib/application.ex | 8 ++--- shardweb/lib/shard_web.ex | 3 ++ .../shard_web/controllers/identity_controller.ex | 40 ++++++++++++++++++++++ .../lib/shard_web/controllers/page_controller.ex | 20 +++++++++++ .../lib/shard_web/controllers/peer_controller.ex | 25 -------------- .../lib/shard_web/controllers/room_controller.ex | 20 +---------- shardweb/lib/shard_web/router.ex | 27 +++++++++++++-- .../lib/shard_web/templates/identity/view.html.eex | 40 ++++++++++++++++++++++ .../lib/shard_web/templates/layout/app.html.eex | 1 + .../lib/shard_web/templates/page/index.html.eex | 2 +- .../lib/shard_web/templates/room/show.html.eex | 14 ++++---- shardweb/lib/shard_web/views/identity_view.ex | 11 ++++++ shardweb/lib/shard_web/views/layout_view.ex | 2 -- shardweb/lib/shard_web/views/room_view.ex | 2 +- shardweb/mix.exs | 4 +-- 17 files changed, 159 insertions(+), 64 deletions(-) create mode 100644 shardweb/lib/shard_web/controllers/identity_controller.ex delete mode 100644 shardweb/lib/shard_web/controllers/peer_controller.ex create mode 100644 shardweb/lib/shard_web/templates/identity/view.html.eex create mode 100644 shardweb/lib/shard_web/views/identity_view.ex diff --git a/shardweb/assets/js/app.js b/shardweb/assets/js/app.js index c98ec1b..53a0112 100644 --- a/shardweb/assets/js/app.js +++ b/shardweb/assets/js/app.js @@ -28,7 +28,7 @@ if (room_name != undefined) channel.on('shout', function (payload) { // listen to the 'shout' event var li = document.createElement("li"); // creaet new list item DOM element var name = payload.name || 'guest'; // get name from payload or set default - li.innerHTML = '' + name + ' ' + payload.pk16 + ': ' + payload.message; // set li contents + li.innerHTML = '<' + name + ' ' + payload.pk16 + '> ' + payload.message; // set li contents console.log(ul.scrollTop + ' ' + ul.scrollHeight + ' ' + ul.clientHeight); var must_scroll = (ul.scrollTop >= ul.scrollHeight - ul.clientHeight - 10); diff --git a/shardweb/config/config.exs b/shardweb/config/config.exs index 65f52bc..9bf5be6 100644 --- a/shardweb/config/config.exs +++ b/shardweb/config/config.exs @@ -10,7 +10,7 @@ config :shardweb, ShardWeb.Endpoint, url: [host: "localhost"], secret_key_base: "HvLjdQ89FJDqv/g+/ya+62cghndUE6lKqTXWcgls2E8VU5Dtmxg4y8OnYaCEiQun", render_errors: [view: ShardWeb.ErrorView, accepts: ~w(html json)], - pubsub: [name: Shardweb.PubSub, + pubsub: [name: ShardWeb.PubSub, adapter: Phoenix.PubSub.PG2] # Configures Elixir's Logger diff --git a/shardweb/lib/application.ex b/shardweb/lib/application.ex index 2de7bff..94b2f32 100644 --- a/shardweb/lib/application.ex +++ b/shardweb/lib/application.ex @@ -1,4 +1,4 @@ -defmodule Shardweb.Application do +defmodule ShardWeb.Application do use Application # See https://hexdocs.pm/elixir/Application.html @@ -10,13 +10,13 @@ defmodule Shardweb.Application do children = [ # Start the endpoint when the application starts supervisor(ShardWeb.Endpoint, []), - # Start your own worker by calling: Shardweb.Worker.start_link(arg1, arg2, arg3) - # worker(Shardweb.Worker, [arg1, arg2, arg3]), + # Start your own worker by calling: ShardWeb.Worker.start_link(arg1, arg2, arg3) + # worker(ShardWeb.Worker, [arg1, arg2, arg3]), ] # See https://hexdocs.pm/elixir/Supervisor.html # for other strategies and supported options - opts = [strategy: :one_for_one, name: Shardweb.Supervisor] + opts = [strategy: :one_for_one, name: ShardWeb.Supervisor] Supervisor.start_link(children, opts) end diff --git a/shardweb/lib/shard_web.ex b/shardweb/lib/shard_web.ex index 5192806..049da29 100644 --- a/shardweb/lib/shard_web.ex +++ b/shardweb/lib/shard_web.ex @@ -20,6 +20,7 @@ defmodule ShardWeb do def controller do quote do use Phoenix.Controller, namespace: ShardWeb + import PhoenixGon.Controller import Plug.Conn import ShardWeb.Router.Helpers import ShardWeb.Gettext @@ -37,6 +38,8 @@ defmodule ShardWeb do # Use all HTML functionality (forms, tags, etc) use Phoenix.HTML + import PhoenixGon.View + import ShardWeb.Router.Helpers import ShardWeb.ErrorHelpers import ShardWeb.Gettext diff --git a/shardweb/lib/shard_web/controllers/identity_controller.ex b/shardweb/lib/shard_web/controllers/identity_controller.ex new file mode 100644 index 0000000..a4f54e7 --- /dev/null +++ b/shardweb/lib/shard_web/controllers/identity_controller.ex @@ -0,0 +1,40 @@ +defmodule ShardWeb.IdentityController do + use ShardWeb, :controller + + def view(conn, _params) do + render conn, "view.html" + end + + def update(conn, params) do + pid = SApp.Identity.find_proc(conn.assigns.pk) + info = GenServer.call(pid, :get_info) + info = %{info | nick: params["nick"]} + GenServer.call(pid, {:set_info, info}) + redirect conn, to: identity_path(conn, :view) + end + + def switch(conn, params) do + case Base.decode16(params["pk"]) do + {:ok, pk} -> + if Shard.Keys.have_sk? pk do + conn + |> put_session(:pk, pk) + |> redirect(to: identity_path(conn, :view)) + else + conn + |> put_flash(:error, "No secret key found") + |> render("view.html") + end + _ -> + conn + |> put_flash(:error, "Bad argument") + |> render("view.html") + end + end + + def create(conn, _params) do + pk = Shard.Keys.new_identity + conn = put_session(conn, :pk, pk) + redirect conn, to: identity_path(conn, :view) + end +end diff --git a/shardweb/lib/shard_web/controllers/page_controller.ex b/shardweb/lib/shard_web/controllers/page_controller.ex index a590630..305e751 100644 --- a/shardweb/lib/shard_web/controllers/page_controller.ex +++ b/shardweb/lib/shard_web/controllers/page_controller.ex @@ -4,4 +4,24 @@ defmodule ShardWeb.PageController do def index(conn, _params) do render conn, "index.html" end + + def add_peer(conn, _params) do + try do + ip = conn.params["ip"] + port = conn.params["port"] + {:ok, ip_tuple} = case :inet.parse_address(to_charlist(ip)) do + {:ok, tup} -> {:ok, tup} + _ -> + case :inet.gethostbyname(to_charlist(ip)) do + {:ok, {:hostent, _, _, :inet, 4, [ip_tup | _]}} -> {:ok, ip_tup} + _ -> :error + end + end + {port_num, _} = Integer.parse port + Shard.Manager.add_peer(ip_tuple, port_num) + rescue + _ -> nil + end + redirect conn, to: page_path(conn, :index) + end end diff --git a/shardweb/lib/shard_web/controllers/peer_controller.ex b/shardweb/lib/shard_web/controllers/peer_controller.ex deleted file mode 100644 index 0bf6ded..0000000 --- a/shardweb/lib/shard_web/controllers/peer_controller.ex +++ /dev/null @@ -1,25 +0,0 @@ -defmodule ShardWeb.PeerController do - use ShardWeb, :controller - - require Logger - - def add(conn, _params) do - try do - ip = conn.params["ip"] - port = conn.params["port"] - {:ok, ip_tuple} = case :inet.parse_address(to_charlist(ip)) do - {:ok, tup} -> {:ok, tup} - _ -> - case :inet.gethostbyname(to_charlist(ip)) do - {:ok, {:hostent, _, _, :inet, 4, [ip_tup | _]}} -> {:ok, ip_tup} - _ -> :error - end - end - {port_num, _} = Integer.parse port - Shard.Manager.add_peer(ip_tuple, port_num) - rescue - _ -> nil - end - redirect conn, to: page_path(conn, :index) - end -end diff --git a/shardweb/lib/shard_web/controllers/room_controller.ex b/shardweb/lib/shard_web/controllers/room_controller.ex index 8c98aa6..d24649b 100644 --- a/shardweb/lib/shard_web/controllers/room_controller.ex +++ b/shardweb/lib/shard_web/controllers/room_controller.ex @@ -1,27 +1,9 @@ defmodule ShardWeb.RoomController do use ShardWeb, :controller - require Logger - import PhoenixGon.Controller - def show(conn, %{"room" => room}) do - pk = get_session(conn, :pk) - {pk, conn} = cond do - pk == nil || not Shard.Keys.have_sk? pk -> - pk = Shard.Keys.get_any_identity - conn = put_session(conn, :pk, pk) - {pk, conn} - true -> - {pk, conn} - end - - name = SApp.Identity.get_nick pk - conn = put_gon(conn, chat_room: room) - conn = put_gon(conn, pk: (pk|>Base.encode16)) render conn, "show.html", - room: room, - pk: pk, - name: name + room: room end end diff --git a/shardweb/lib/shard_web/router.ex b/shardweb/lib/shard_web/router.ex index 180ebdd..4311a29 100644 --- a/shardweb/lib/shard_web/router.ex +++ b/shardweb/lib/shard_web/router.ex @@ -8,6 +8,7 @@ defmodule ShardWeb.Router do plug :protect_from_forgery plug :put_secure_browser_headers plug Plug.Parsers, parsers: [:urlencoded] + plug :check_pk end pipeline :api do @@ -18,13 +19,35 @@ defmodule ShardWeb.Router do pipe_through :browser # Use the default browser stack get "/", PageController, :index - get "/room/:room", RoomController, :show + post "/peer/add", PageController, :add_peer + + get "/identity", IdentityController, :view + post "/identity", IdentityController, :update + post "/identity/switch", IdentityController, :switch + post "/identity/create", IdentityController, :create - post "/peer/add", PeerController, :add + get "/room/:room", RoomController, :show end # Other scopes may use custom stacks. # scope "/api", ShardWeb do # pipe_through :api # end + + def check_pk(conn, _kv) do + pk1 = get_session(conn, :pk) + {conn, pk} = if pk1 == nil || not Shard.Keys.have_sk? pk1 do + pk = Shard.Keys.get_any_identity + conn = put_session(conn, :pk, pk) + {conn, pk} + else + {conn, pk1} + end + nick = SApp.Identity.get_nick pk + conn + |> assign(:pk, pk) + |> assign(:nick, nick) + |> PhoenixGon.Controller.put_gon(pk: (pk|>Base.encode16)) + end + end diff --git a/shardweb/lib/shard_web/templates/identity/view.html.eex b/shardweb/lib/shard_web/templates/identity/view.html.eex new file mode 100644 index 0000000..b9210f2 --- /dev/null +++ b/shardweb/lib/shard_web/templates/identity/view.html.eex @@ -0,0 +1,40 @@ +

Identity

+ +<%= form_for @conn, identity_path(@conn, :update), [class: "form-horizontal"], fn f -> %> +
+ +
+ +
+
+
+ <%= label :nick, "Nickname:", class: ["col-sm-2 control-label"] %> +
+ <%= text_input f, :nick, [class: "form-control", value: @nick] %> +
+
+
+
+ <%= submit "Update", [class: "btn btn-default"] %> +
+
+<% end %> + +

Other identities

+ + + +<%= form_for @conn, identity_path(@conn, :create), [class: "form-inline"], fn f -> %> + <%= submit "Create new identity", [class: "btn btn-danger"] %> +<% end %> diff --git a/shardweb/lib/shard_web/templates/layout/app.html.eex b/shardweb/lib/shard_web/templates/layout/app.html.eex index 9903775..d4b2075 100644 --- a/shardweb/lib/shard_web/templates/layout/app.html.eex +++ b/shardweb/lib/shard_web/templates/layout/app.html.eex @@ -18,6 +18,7 @@ diff --git a/shardweb/lib/shard_web/templates/page/index.html.eex b/shardweb/lib/shard_web/templates/page/index.html.eex index 412cbe5..2efa030 100644 --- a/shardweb/lib/shard_web/templates/page/index.html.eex +++ b/shardweb/lib/shard_web/templates/page/index.html.eex @@ -21,7 +21,7 @@ <% end %> -<%= form_for @conn, peer_path(@conn, :add), [class: "form-inline"], fn f -> %> +<%= form_for @conn, page_path(@conn, :add_peer), [class: "form-inline"], fn f -> %> <%= text_input f, :ip, [class: "form-control", placeholder: "Hostname / IP address"] %> <%= text_input f, :port, [class: "form-control", placeholder: "Port", value: "4044"] %> <%= submit "Add peer", [class: "btn btn-default"] %> diff --git a/shardweb/lib/shard_web/templates/room/show.html.eex b/shardweb/lib/shard_web/templates/room/show.html.eex index bc1641a..e7b1166 100644 --- a/shardweb/lib/shard_web/templates/room/show.html.eex +++ b/shardweb/lib/shard_web/templates/room/show.html.eex @@ -12,11 +12,13 @@ -
-
- <%= @name %> -
-
- +
+
+
+ <<%= @nick %>> +
+
+ +
diff --git a/shardweb/lib/shard_web/views/identity_view.ex b/shardweb/lib/shard_web/views/identity_view.ex new file mode 100644 index 0000000..63d5a50 --- /dev/null +++ b/shardweb/lib/shard_web/views/identity_view.ex @@ -0,0 +1,11 @@ +defmodule ShardWeb.IdentityView do + use ShardWeb, :view + + def identity_list do + Shard.Keys.list_identities + end + + def get_nick(pk) do + SApp.Identity.get_nick pk + end +end diff --git a/shardweb/lib/shard_web/views/layout_view.ex b/shardweb/lib/shard_web/views/layout_view.ex index 514779b..4012c38 100644 --- a/shardweb/lib/shard_web/views/layout_view.ex +++ b/shardweb/lib/shard_web/views/layout_view.ex @@ -1,5 +1,3 @@ defmodule ShardWeb.LayoutView do use ShardWeb, :view - - import PhoenixGon.View end diff --git a/shardweb/lib/shard_web/views/room_view.ex b/shardweb/lib/shard_web/views/room_view.ex index 7c102cc..7ec961b 100644 --- a/shardweb/lib/shard_web/views/room_view.ex +++ b/shardweb/lib/shard_web/views/room_view.ex @@ -1,6 +1,6 @@ defmodule ShardWeb.RoomView do use ShardWeb, :view - + def shard_list do Shard.Manager.list_shards end diff --git a/shardweb/mix.exs b/shardweb/mix.exs index a28461a..809043d 100644 --- a/shardweb/mix.exs +++ b/shardweb/mix.exs @@ -1,4 +1,4 @@ -defmodule Shardweb.Mixfile do +defmodule ShardWeb.Mixfile do use Mix.Project def project do @@ -18,7 +18,7 @@ defmodule Shardweb.Mixfile do # Type `mix help compile.app` for more information. def application do [ - mod: {Shardweb.Application, []}, + mod: {ShardWeb.Application, []}, extra_applications: [:logger, :runtime_tools] ] end -- cgit v1.2.3