42 lines
1.3 KiB
Elixir
42 lines
1.3 KiB
Elixir
defmodule BirdyChatWeb.ServerChannel do
|
|
use BirdyChatWeb, :channel
|
|
|
|
@impl true
|
|
def join("server:" <> server_id, payload, socket) do
|
|
if authorised?(payload, server_id) do
|
|
{:ok, socket}
|
|
else
|
|
{:error, %{reason: "unauthorised"}}
|
|
end
|
|
end
|
|
|
|
@impl true
|
|
def handle_in("new_message", {:binary, message}, socket) do
|
|
result = :erlang.binary_to_term(message, [:safe])
|
|
|
|
# TODO: Add validation that this is the right server.
|
|
case BirdyChat.Message.validate(result) do
|
|
{:ok, changeset} ->
|
|
case BirdyChat.MessageWriter.write(changeset.changes) do
|
|
:ok ->
|
|
{:reply, {:ok, {:binary, message}}, socket}
|
|
end
|
|
end
|
|
end
|
|
|
|
# This is how we send messages
|
|
def broadcast!(peer, message) do
|
|
channel = "server:#{peer}"
|
|
encoded_message = :erlang.term_to_binary(message)
|
|
BirdyChatWeb.Endpoint.broadcast!(channel, "new_message", {:binary, encoded_message})
|
|
end
|
|
|
|
# Simple token-based authentication. Servers should use the same Phoenix secret key so they will
|
|
# have the basis for generating tokens.
|
|
defp authorised?(%{"token" => token}, server_id) do
|
|
case Phoenix.Token.verify(BirdyChatWeb.Endpoint, "serverAuth", token, max_age: 86400) do
|
|
{:ok, id} -> id == server_id
|
|
{:error, :invalid} -> false
|
|
end
|
|
end
|
|
end
|