diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/rook/application.ex | 3 | ||||
| -rw-r--r-- | lib/rook/request.ex | 77 | ||||
| -rw-r--r-- | lib/rook/share.ex | 7 | ||||
| -rw-r--r-- | lib/rook_web/channels/request_channel.ex | 20 | ||||
| -rw-r--r-- | lib/rook_web/channels/share_channel.ex | 4 | ||||
| -rw-r--r-- | lib/rook_web/channels/user_socket.ex | 1 | ||||
| -rw-r--r-- | lib/rook_web/controllers/app_controller.ex | 4 | ||||
| -rw-r--r-- | lib/rook_web/templates/app/request.html.eex | 8 |
8 files changed, 114 insertions, 10 deletions
diff --git a/lib/rook/application.ex b/lib/rook/application.ex index 27879e3..537fe70 100644 --- a/lib/rook/application.ex +++ b/lib/rook/application.ex @@ -15,7 +15,8 @@ defmodule Rook.Application do RookWeb.Endpoint, # Start a worker by calling: Rook.Worker.start_link(arg) # {Rook.Worker, arg} - {Registry, keys: :unique, name: Registry.Share} + {Registry, keys: :unique, name: Registry.Share}, + {Registry, keys: :unique, name: Registry.Request} ] # See https://hexdocs.pm/elixir/Supervisor.html diff --git a/lib/rook/request.ex b/lib/rook/request.ex new file mode 100644 index 0000000..b795c5c --- /dev/null +++ b/lib/rook/request.ex @@ -0,0 +1,77 @@ +defmodule Rook.Request do + use GenServer + + defmodule State do + @type t :: %__MODULE__{ + token: String.t(), + share_token: String.t(), + channel_pid: pid() + } + + defstruct [:token, :share_token, :channel_pid] + end + + ## Client + + def init([token, share_token, channel_pid]) do + Process.flag(:trap_exit, true) + Process.link(channel_pid) + Rook.Share.new_request(share_token, token) + {:ok, %State{token: token, share_token: share_token, channel_pid: channel_pid}} + end + + def start(token, share_token) do + GenServer.start(__MODULE__, [token, share_token, self()], name: via(token)) + end + + def acknowledge_request(token) do + cast(token, {:request_acknowledged}) + end + + def close(request_token, share_token) do + Rook.Share.request_cancelled(share_token, request_token) + end + + def close(request_token) do + cast(request_token, {:share_cancelled}) + end + + def get(token) do + case Registry.lookup(Registry.Request, token) do + [{pid, _}] -> pid + _ -> nil + end + end + + def exists?(token) do + get(token) != nil + end + + ## Server + + def handle_cast({:request_acknowledged}, state) do + notify(state.token, "request_acknowledged", %{}) + {:noreply, state} + end + + def handle_cast({:share_cancelled}, state) do + notify(state.token, "share_cancelled", %{}) + {:stop, :shutdown, state} + end + + def handle_info({:EXIT, pid, reason}, state) do + if state.channel_pid == pid do + Rook.Request.close(state.token, state.share_token) + end + + {:stop, reason, state} + end + + ## Helpers + + defp via(name), do: {:via, Registry, {Registry.Request, name}} + defp cast(token, params), do: GenServer.cast(via(token), params) + + defp notify(token, event, params), + do: RookWeb.Endpoint.broadcast!("request:" <> token, event, params) +end diff --git a/lib/rook/share.ex b/lib/rook/share.ex index 17e680a..0d1d64c 100644 --- a/lib/rook/share.ex +++ b/lib/rook/share.ex @@ -27,13 +27,12 @@ defmodule Rook.Share do cast(share_token, {:new_request, request_token}) end - def cancel_request(share_token, request_token) do + def request_cancelled(share_token, request_token) do cast(share_token, {:request_cancelled, request_token}) end - def close(_requests) do - # TODO: Notify requestors - :ok + def close(requests) do + Enum.each(requests, &Rook.Request.close/1) end def get(token) do diff --git a/lib/rook_web/channels/request_channel.ex b/lib/rook_web/channels/request_channel.ex new file mode 100644 index 0000000..6290ae6 --- /dev/null +++ b/lib/rook_web/channels/request_channel.ex @@ -0,0 +1,20 @@ +defmodule RookWeb.RequestChannel do + use RookWeb, :channel + + def join("request:" <> token, %{"share" => share_token}, socket) do + if Rook.Token.match?(token, socket) do + if Rook.Share.exists?(share_token) do + Rook.Request.start(token, share_token) + {:ok, socket} + else + {:error, %{reason: "No such share exists."}} + end + else + {:error, %{reason: "Wrong token."}} + end + end + + def join("request:" <> _token, _params, _socket) do + {:error, %{reason: "No share given to request."}} + end +end diff --git a/lib/rook_web/channels/share_channel.ex b/lib/rook_web/channels/share_channel.ex index 2d99d87..0efb3ba 100644 --- a/lib/rook_web/channels/share_channel.ex +++ b/lib/rook_web/channels/share_channel.ex @@ -21,8 +21,8 @@ defmodule RookWeb.ShareChannel do {:error, %{reason: "No request given to accept."}} end - def handle_out("new_request", msg, socket) do - # TODO: Send ACK + def handle_out("new_request", %{request: request_token} = msg, socket) do + Rook.Request.acknowledge_request(request_token) push(socket, "new_request", msg) {:noreply, socket} end diff --git a/lib/rook_web/channels/user_socket.ex b/lib/rook_web/channels/user_socket.ex index ae82b6b..d6ce9c4 100644 --- a/lib/rook_web/channels/user_socket.ex +++ b/lib/rook_web/channels/user_socket.ex @@ -4,6 +4,7 @@ defmodule RookWeb.UserSocket do ## Channels channel "token", RookWeb.TokenChannel channel "share:*", RookWeb.ShareChannel + channel "request:*", RookWeb.RequestChannel # Socket params are passed from the client and can # be used to verify and authenticate a user. After diff --git a/lib/rook_web/controllers/app_controller.ex b/lib/rook_web/controllers/app_controller.ex index 9e36f3c..f252086 100644 --- a/lib/rook_web/controllers/app_controller.ex +++ b/lib/rook_web/controllers/app_controller.ex @@ -5,7 +5,7 @@ defmodule RookWeb.AppController do render(conn, "share.html") end - def request(conn, _params) do - render(conn, "request.html") + def request(conn, %{"token" => share_token}) do + render(conn, "request.html", share_token: share_token) end end diff --git a/lib/rook_web/templates/app/request.html.eex b/lib/rook_web/templates/app/request.html.eex index b7ff7bd..1e17e45 100644 --- a/lib/rook_web/templates/app/request.html.eex +++ b/lib/rook_web/templates/app/request.html.eex @@ -1 +1,7 @@ -<%= render_app(@conn, "request") %> +<%= if Rook.Share.exists?(@share_token) do %> + <%= render_app(@conn, "request") %> +<% else %> + <p> + The share you tried to request either expired or never existed. + </p> +<% end %> |
