add basic floof handling

This commit is contained in:
Alain Zscheile 2022-11-26 18:08:04 +01:00
parent be957afe44
commit d4f5efca9d
4 changed files with 66 additions and 2 deletions

View file

@ -4,6 +4,7 @@ defmodule Chat.Application do
@moduledoc false
use Application
require Logger
@impl true
def start(_type, _args) do
@ -13,9 +14,17 @@ defmodule Chat.Application do
# Start the PubSub system
{Phoenix.PubSub, name: Chat.PubSub},
# Start the Endpoint (http/https)
ChatWeb.Endpoint
ChatWeb.Endpoint,
# Start a worker by calling: Chat.Worker.start_link(arg)
# {Chat.Worker, arg}
# Start the message handler
Chat.Floof,
# Start the relay
{Task, fn ->
Floof.Distributor.register(self())
relay_loop()
end}
]
# See https://hexdocs.pm/elixir/Supervisor.html
@ -31,4 +40,20 @@ defmodule Chat.Application do
ChatWeb.Endpoint.config_change(changed, removed)
:ok
end
defp relay_loop do
receive do
{:fwdxfer, {_, {:XferBlob, source, _, _, _, xfinner}}} ->
{:ok, dcdi} = :FloofProtocol.decode(:XferInner, xfinner)
{:XferInner, topic, attrs, _, data} = dcdi
if topic == [{:RelativeDistinguishedName, {0, 9, 2342, 19200300, 100, 1, 14}, "Chat"}] do
[{:RelativeDistinguishedName, {0, 9, 2342, 19200300, 100, 1, 4}, name}] = attrs
{:ok, source_encd} = :FloofProtocol.encode(:RDNSequence, source)
source_encd = Base.url_encode64(source_encd)
ChatWeb.Endpoint.broadcast!("room:lobby", "shout", %{name: source_encd <> " :: " <> name, message: data})
end
x -> Logger.error("unable to handle message #{inspect(x)}")
end
relay_loop()
end
end

37
lib/chat/floof.ex Normal file
View file

@ -0,0 +1,37 @@
defmodule Chat.Floof do
use Agent
require Logger
defstruct secret: "", source: []
def start_link do
Agent.start_link(fn ->
secret_file = Application.fetch_env!(:chat, :secret_file)
source = Application.fetch_env!(:chat, :source)
{:ok, secret} = File.read(secret_file)
%Chat.Floof{secret: secret, source: source}
end, name: __MODULE__)
end
def setup do
# generate and save a keypair
kp = :enacl.sign_keypair()
secret_file = Application.fetch_env!(:chat, :secret_file)
source = Application.fetch_env!(:chat, :source)
:ok = File.write(secret_file, kp.secret)
{:ok, pkname} = :FloofProtocol.encode(:RDNSequence, source)
pubkey_config = Application.fetch_env!(:floof, :pubkey_config)
:ok = File.write(pubkey_config.keydb <> "/" <> Base.url_encode64(pkname), kp.public)
end
def send_message(name, data) do
msg_topic = [{:RelativeDistinguishedName, {0, 9, 2342, 19200300, 100, 1, 14}, "Chat"}]
msg_attrs = [{:RelativeDistinguishedName, {0, 9, 2342, 19200300, 100, 1, 4}, name}]
msg_inner = Floof.Message.pack_inner(msg_topic, msg_attrs, :info, data)
Agent.cast(__MODULE__, fn state ->
msg_outer = Floof.Message.build_outer(state.source, 255, [], state.secret, msg_inner)
Floof.Message.emit(msg_outer)
state
end)
end
end

View file

@ -21,6 +21,7 @@ defmodule ChatWeb.RoomChannel do
# broadcast to everyone in the current topic (room:lobby).
@impl true
def handle_in("shout", payload, socket) do
Chat.Floof.send_message(payload.name, payload.message)
broadcast(socket, "shout", payload)
{:noreply, socket}
end

View file

@ -46,7 +46,8 @@ defmodule Chat.MixProject do
{:gettext, "~> 0.18"},
{:jason, "~> 1.2"},
{:plug_cowboy, "~> 2.5"},
{:floof, git: "https://git.exozy.me/zseri/floof.git"}
{:floof, git: "https://git.exozy.me/zseri/floof.git"},
{:enacl, "~> 1.0.0"}
]
end