diff options
author | Jordan Bracco <href@random.sh> | 2022-12-20 02:47:33 +0000 |
---|---|---|
committer | Jordan Bracco <href@random.sh> | 2022-12-20 19:29:41 +0100 |
commit | 2127553ad058bfa688feb73097e604a8fb5a1899 (patch) | |
tree | 3246c31aef0f6c3a110376de21265a6f5d02c597 /lib/irc | |
parent | IRC.PubSub -> Nola.PubSub, refs T77 (diff) |
Rename IRC.Account to Nola.Account, refs T77
Diffstat (limited to 'lib/irc')
-rw-r--r-- | lib/irc/account.ex | 263 | ||||
-rw-r--r-- | lib/irc/connection.ex | 10 | ||||
-rw-r--r-- | lib/irc/membership.ex | 10 | ||||
-rw-r--r-- | lib/irc/nola_irc.ex | 2 | ||||
-rw-r--r-- | lib/irc/puppet_connection.ex | 18 | ||||
-rw-r--r-- | lib/irc/user_track.ex | 16 |
6 files changed, 28 insertions, 291 deletions
diff --git a/lib/irc/account.ex b/lib/irc/account.ex deleted file mode 100644 index a39733c..0000000 --- a/lib/irc/account.ex +++ /dev/null @@ -1,263 +0,0 @@ -defmodule IRC.Account do - alias IRC.UserTrack.User - - @moduledoc """ - Account registry.... - - Maps a network predicate: - * `{net, {:nick, nickname}}` - * `{net, {:account, account}}` - * `{net, {:mask, user@host}}` - to an unique identifier, that can be shared over multiple networks. - - If a predicate cannot be found for an existing account, a new account will be made in the database. - - To link two existing accounts from different network onto a different one, a merge operation is provided. - - """ - - # FIXME: Ensure uniqueness of name? - - @derive {Poison.Encoder, except: [:token]} - defstruct [:id, :name, :token] - @type t :: %__MODULE__{id: id(), name: String.t()} - @type id :: String.t() - - defimpl Inspect, for: __MODULE__ do - import Inspect.Algebra - - def inspect(%{id: id, name: name}, opts) do - concat(["#IRC.Account[", id, " ", name, "]"]) - end - end - - def file(base) do - to_charlist(Nola.data_path() <> "/account_#{base}.dets") - end - - defp from_struct(%__MODULE__{id: id, name: name, token: token}) do - {id, name, token} - end - - defp from_tuple({id, name, token}) do - %__MODULE__{id: id, name: name, token: token} - end - - def start_link() do - GenServer.start_link(__MODULE__, [], [name: __MODULE__]) - end - - def init(_) do - {:ok, accounts} = :dets.open_file(file("db"), []) - {:ok, meta} = :dets.open_file(file("meta"), []) - {:ok, predicates} = :dets.open_file(file("predicates"), [{:type, :set}]) - {:ok, %{accounts: accounts, meta: meta, predicates: predicates}} - end - - def get(id) do - case :dets.lookup(file("db"), id) do - [account] -> from_tuple(account) - _ -> nil - end - end - - def get_by_name(name) do - spec = [{{:_, :"$1", :_}, [{:==, :"$1", {:const, name}}], [:"$_"]}] - case :dets.select(file("db"), spec) do - [account] -> from_tuple(account) - _ -> nil - end - end - - def get_meta(%__MODULE__{id: id}, key, default \\ nil) do - case :dets.lookup(file("meta"), {id, key}) do - [{_, value}] -> (value || default) - _ -> default - end - end - - @spec find_meta_accounts(String.t()) :: [{account :: t(), value :: String.t()}, ...] - @doc "Find all accounts that have a meta of `key`." - def find_meta_accounts(key) do - spec = [{{{:"$1", :"$2"}, :"$3"}, [{:==, :"$2", {:const, key}}], [{{:"$1", :"$3"}}]}] - for {id, val} <- :dets.select(file("meta"), spec), do: {get(id), val} - end - - @doc "Find an account given a specific meta `key` and `value`." - @spec find_meta_account(String.t(), String.t()) :: t() | nil - def find_meta_account(key, value) do - #spec = [{{{:"$1", :"$2"}, :"$3"}, [:andalso, {:==, :"$2", {:const, key}}, {:==, :"$3", {:const, value}}], [:"$1"]}] - spec = [{{{:"$1", :"$2"}, :"$3"}, [{:andalso, {:==, :"$2", {:const, key}}, {:==, {:const, value}, :"$3"}}], [:"$1"]}] - case :dets.select(file("meta"), spec) do - [id] -> get(id) - _ -> nil - end - end - - def get_all_meta(%__MODULE__{id: id}) do - spec = [{{{:"$1", :"$2"}, :"$3"}, [{:==, :"$1", {:const, id}}], [{{:"$2", :"$3"}}]}] - :dets.select(file("meta"), spec) - end - - def put_user_meta(account = %__MODULE__{}, key, value) do - put_meta(account, "u:"<>key, value) - end - - def put_meta(%__MODULE__{id: id}, key, value) do - :dets.insert(file("meta"), {{id, key}, value}) - end - - def delete_meta(%__MODULE__{id: id}, key) do - :dets.delete(file("meta"), {id, key}) - end - - def all_accounts() do - :dets.traverse(file("db"), fn(obj) -> {:continue, from_tuple(obj)} end) - end - - def all_predicates() do - :dets.traverse(file("predicates"), fn(obj) -> {:continue, obj} end) - end - - def all_meta() do - :dets.traverse(file("meta"), fn(obj) -> {:continue, obj} end) - end - - def merge_account(old_id, new_id) do - if old_id != new_id do - spec = [{{:"$1", :"$2"}, [{:==, :"$2", {:const, old_id}}], [:"$1"]}] - predicates = :dets.select(file("predicates"), spec) - for pred <- predicates, do: :ok = :dets.insert(file("predicates"), {pred, new_id}) - spec = [{{{:"$1", :"$2"}, :"$3"}, [{:==, :"$1", {:const, old_id}}], [{{:"$2", :"$3"}}]}] - metas = :dets.select(file("meta"), spec) - for {k,v} <- metas do - :dets.delete(file("meta"), {{old_id, k}}) - :ok = :dets.insert(file("meta"), {{new_id, k}, v}) - end - :dets.delete(file("db"), old_id) - IRC.Membership.merge_account(old_id, new_id) - IRC.UserTrack.merge_account(old_id, new_id) - IRC.Connection.dispatch("account", {:account_change, old_id, new_id}) - IRC.Connection.dispatch("conn", {:account_change, old_id, new_id}) - end - :ok - end - - @doc "Find an account by a logged in user" - def find_by_nick(network, nick) do - do_lookup(%ExIRC.SenderInfo{nick: nick, network: network}, false) - end - - @doc "Always find an account by nickname, even if offline. Uses predicates and then account name." - def find_always_by_nick(network, chan, nick) do - with \ - nil <- find_by_nick(network, nick), - nil <- do_lookup(%User{network: network, nick: nick}, false), - nil <- get_by_name(nick) - do - nil - else - %__MODULE__{} = account -> - memberships = IRC.Membership.of_account(account) - if Enum.any?(memberships, fn({net, ch}) -> (net == network) or (chan && chan == ch) end) do - account - else - nil - end - end - end - - def find(something) do - do_lookup(something, false) - end - - def lookup(something, make_default \\ true) do - account = do_lookup(something, make_default) - if account && Map.get(something, :nick) do - IRC.Connection.dispatch("account", {:account_auth, Map.get(something, :nick), account.id}) - end - account - end - - def handle_info(_, state) do - {:noreply, state} - end - - def handle_cast(_, state) do - {:noreply, state} - end - - def handle_call(_, _, state) do - {:noreply, state} - end - - def terminate(_, state) do - for {_, dets} <- state do - :dets.sync(dets) - :dets.close(dets) - end - end - - defp do_lookup(message = %IRC.Message{account: account_id}, make_default) when is_binary(account_id) do - get(account_id) - end - - defp do_lookup(sender = %ExIRC.Who{}, make_default) do - if user = IRC.UserTrack.find_by_nick(sender) do - lookup(user, make_default) - else - #FIXME this will never work with continued lookup by other methods as Who isn't compatible - lookup_by_nick(sender, :dets.lookup(file("predicates"), {sender.network,{:nick, sender.nick}}), make_default) - end - end - - defp do_lookup(sender = %ExIRC.SenderInfo{}, make_default) do - lookup(IRC.UserTrack.find_by_nick(sender), make_default) - end - - defp do_lookup(user = %User{account: id}, make_default) when is_binary(id) do - get(id) - end - - defp do_lookup(user = %User{network: server, nick: nick}, make_default) do - lookup_by_nick(user, :dets.lookup(file("predicates"), {server,{:nick, nick}}), make_default) - end - - defp do_lookup(nil, _) do - nil - end - - defp lookup_by_nick(_, [{_, id}], _make_default) do - get(id) - end - - defp lookup_by_nick(user, _, make_default) do - #authenticate_by_host(user) - if make_default, do: new_account(user), else: nil - end - - def new_account(nick) do - id = EntropyString.large_id() - :dets.insert(file("db"), {id, nick, EntropyString.token()}) - get(id) - end - - def new_account(%{nick: nick, network: server}) do - id = EntropyString.large_id() - :dets.insert(file("db"), {id, nick, EntropyString.token()}) - :dets.insert(file("predicates"), {{server, {:nick, nick}}, id}) - get(id) - end - - def update_account_name(account = %__MODULE__{id: id}, name) do - account = %__MODULE__{account | name: name} - :dets.insert(file("db"), from_struct(account)) - get(id) - end - - def get_predicates(%__MODULE__{} = account) do - spec = [{{:"$1", :"$2"}, [{:==, :"$2", {:const, account.id}}], [:"$1"]}] - :dets.select(file("predicates"), spec) - end - -end diff --git a/lib/irc/connection.ex b/lib/irc/connection.ex index 4472466..49f5774 100644 --- a/lib/irc/connection.ex +++ b/lib/irc/connection.ex @@ -293,7 +293,7 @@ defmodule IRC.Connection do else if !Map.get(user.options, :puppet) do reply_fun = fn(text) -> irc_reply(state, {chan, sender}, text) end - account = IRC.Account.lookup(sender) + account = Nola.Account.lookup(sender) message = %IRC.Message{id: FlakeId.get(), transport: :irc, at: NaiveDateTime.utc_now(), text: text, network: state.network, account: account, sender: sender, channel: chan, replyfun: reply_fun, trigger: extract_trigger(text)} @@ -310,7 +310,7 @@ defmodule IRC.Connection do # Received a private message def handle_info({:received, text, sender}, state) do reply_fun = fn(text) -> irc_reply(state, {sender.nick, sender}, text) end - account = IRC.Account.lookup(sender) + account = Nola.Account.lookup(sender) message = %IRC.Message{id: FlakeId.get(), transport: :irc, text: text, network: state.network, at: NaiveDateTime.utc_now(), account: account, sender: sender, replyfun: reply_fun, trigger: extract_trigger(text)} message = case IRC.UserTrack.messaged(message) do @@ -322,7 +322,7 @@ defmodule IRC.Connection do end ## -- Broadcast - def handle_info({:broadcast, net, account = %IRC.Account{}, message}, state) do + def handle_info({:broadcast, net, account = %Nola.Account{}, message}, state) do if net == state.conn.network do user = IRC.UserTrack.find_by_account(net, account) if user do @@ -350,7 +350,7 @@ defmodule IRC.Connection do priv = if operator, do: [:operator], else: [] # Don't touch -- on WHO the bot joined, not the users. IRC.UserTrack.joined(channel, who, priv, false) - account = IRC.Account.lookup(who) + account = Nola.Account.lookup(who) if account do {:account, who.network, channel, who.nick, account.id} end @@ -367,7 +367,7 @@ defmodule IRC.Connection do def handle_info({:joined, channel, sender}, state) do IRC.UserTrack.joined(channel, sender, []) - account = IRC.Account.lookup(sender) + account = Nola.Account.lookup(sender) if account do dispatch("account", {:account, sender.network, channel, sender.nick, account.id}) end diff --git a/lib/irc/membership.ex b/lib/irc/membership.ex index b727dfd..25a0cfc 100644 --- a/lib/irc/membership.ex +++ b/lib/irc/membership.ex @@ -19,7 +19,7 @@ defmodule IRC.Membership do {:ok, dets} end - def of_account(%IRC.Account{id: id}) do + def of_account(%Nola.Account{id: id}) do spec = [{{{:"$1", :"$2", :"$3"}, :_}, [{:==, :"$1", {:const, id}}], [{{:"$2", :"$3"}}]}] :dets.select(dets(), spec) end @@ -33,11 +33,11 @@ defmodule IRC.Membership do end) end - def touch(%IRC.Account{id: id}, network, channel) do + def touch(%Nola.Account{id: id}, network, channel) do :dets.insert(dets(), {{id, network, channel}, NaiveDateTime.utc_now()}) end def touch(account_id, network, channel) do - if account = IRC.Account.get(account_id) do + if account = Nola.Account.get(account_id) do touch(account, network, channel) end end @@ -91,7 +91,7 @@ defmodule IRC.Membership do :dets.select(dets(), spec) end - def friends(account = %IRC.Account{id: id}) do + def friends(account = %Nola.Account{id: id}) do for({net, chan} <- of_account(account), do: members(net, chan)) |> List.flatten() |> Enum.uniq() @@ -116,7 +116,7 @@ defmodule IRC.Membership do defp expand(network, list) do for id <- list do - if account = IRC.Account.get(id) do + if account = Nola.Account.get(id) do user = IRC.UserTrack.find_by_account(network, account) nick = if(user, do: user.nick, else: account.name) {account, user, nick} diff --git a/lib/irc/nola_irc.ex b/lib/irc/nola_irc.ex index dde99af..2d355d3 100644 --- a/lib/irc/nola_irc.ex +++ b/lib/irc/nola_irc.ex @@ -13,7 +13,7 @@ defmodule Nola.IRC do [ worker(Registry, [[keys: :duplicate, name: IRC.ConnectionPubSub]], id: :registr_irc_conn), worker(IRC.Membership, []), - worker(IRC.Account, []), + worker(Nola.Account, []), worker(IRC.UserTrack.Storage, []), worker(Nola.Plugins.Account, []), supervisor(Nola.Plugins.Supervisor, [], [name: Nola.Plugins.Supervisor]), diff --git a/lib/irc/puppet_connection.ex b/lib/irc/puppet_connection.ex index 91a26b3..fd0a98e 100644 --- a/lib/irc/puppet_connection.ex +++ b/lib/irc/puppet_connection.ex @@ -12,7 +12,7 @@ defmodule IRC.PuppetConnection do DynamicSupervisor.start_link(__MODULE__, [], name: __MODULE__) end - def start_child(%IRC.Account{id: account_id}, %IRC.Connection{id: connection_id}) do + def start_child(%Nola.Account{id: account_id}, %IRC.Connection{id: connection_id}) do spec = %{id: {account_id, connection_id}, start: {IRC.PuppetConnection, :start_link, [account_id, connection_id]}, restart: :transient} DynamicSupervisor.start_child(__MODULE__, spec) end @@ -27,7 +27,7 @@ defmodule IRC.PuppetConnection do end end - def whereis(account = %IRC.Account{id: account_id}, connection = %IRC.Connection{id: connection_id}) do + def whereis(account = %Nola.Account{id: account_id}, connection = %IRC.Connection{id: connection_id}) do {:global, name} = name(account_id, connection_id) case :global.whereis_name(name) do :undefined -> nil @@ -35,11 +35,11 @@ defmodule IRC.PuppetConnection do end end - def send_message(account = %IRC.Account{id: account_id}, connection = %IRC.Connection{id: connection_id}, channel, text) do + def send_message(account = %Nola.Account{id: account_id}, connection = %IRC.Connection{id: connection_id}, channel, text) do GenServer.cast(name(account_id, connection_id), {:send_message, self(), channel, text}) end - def start_and_send_message(account = %IRC.Account{id: account_id}, connection = %IRC.Connection{id: connection_id}, channel, text) do + def start_and_send_message(account = %Nola.Account{id: account_id}, connection = %IRC.Connection{id: connection_id}, channel, text) do {:global, name} = name(account_id, connection_id) pid = whereis(account, connection) pid = if !pid do @@ -53,7 +53,7 @@ defmodule IRC.PuppetConnection do GenServer.cast(pid, {:send_message, self(), channel, text}) end - def start(account = %IRC.Account{}, connection = %IRC.Connection{}) do + def start(account = %Nola.Account{}, connection = %IRC.Connection{}) do IRC.PuppetConnection.Supervisor.start_child(account, connection) end @@ -66,7 +66,7 @@ defmodule IRC.PuppetConnection do end def init([account_id, connection_id]) do - account = %IRC.Account{} = IRC.Account.get(account_id) + account = %Nola.Account{} = Nola.Account.get(account_id) connection = %IRC.Connection{} = IRC.Connection.lookup(connection_id) Logger.metadata(puppet_conn: account.id <> "@" <> connection.id) backoff = :backoff.init(@min_backoff, @max_backoff) @@ -78,7 +78,7 @@ defmodule IRC.PuppetConnection do def handle_continue(:connect, state) do #ipv6 = if @env == :prod do # subnet = Nola.Subnet.assign(state.account_id) - # IRC.Account.put_meta(IRC.Account.get(state.account_id), "subnet", subnet) + # Nola.Account.put_meta(Nola.Account.get(state.account_id), "subnet", subnet) # ip = Pfx.host(subnet, 1) # {:ok, ipv6} = :inet_parse.ipv6_address(to_charlist(ip)) # System.cmd("add-ip6", [ip]) @@ -146,7 +146,7 @@ defmodule IRC.PuppetConnection do ExIRC.Client.msg(state.client, :privmsg, channel, text) meta = %{puppet: true, from: pid} - account = IRC.Account.get(state.account_id) + account = Nola.Account.get(state.account_id) nick = make_nick(state) sender = %ExIRC.SenderInfo{network: state.network, nick: suffix_nick(nick), user: nick, host: "puppet."} reply_fun = fn(text) -> @@ -219,7 +219,7 @@ defmodule IRC.PuppetConnection do end def make_nick(state) do - account = IRC.Account.get(state.account_id) + account = Nola.Account.get(state.account_id) user = IRC.UserTrack.find_by_account(state.network, account) base_nick = if(user, do: user.nick, else: account.name) clean_nick = case String.split(base_nick, ":", parts: 2) do diff --git a/lib/irc/user_track.ex b/lib/irc/user_track.ex index 1efa523..3f144d5 100644 --- a/lib/irc/user_track.ex +++ b/lib/irc/user_track.ex @@ -73,7 +73,7 @@ defmodule IRC.UserTrack do end end - def find_by_account(%IRC.Account{id: id}) do + def find_by_account(%Nola.Account{id: id}) do #iex(15)> :ets.fun2ms(fn(obj = {_, net, acct, _, _, _, _, _, _}) when net == network and acct == account -> obj end) spec = [ {{:_, :_, :"$2", :_, :_, :_, :_, :_, :_, :_, :_, :_}, @@ -90,7 +90,7 @@ defmodule IRC.UserTrack do nil end - def find_by_account(network, %IRC.Account{id: id}) do + def find_by_account(network, %Nola.Account{id: id}) do #iex(15)> :ets.fun2ms(fn(obj = {_, net, acct, _, _, _, _, _, _}) when net == network and acct == account -> obj end) spec = [ {{:_, :"$1", :"$2", :_, :_, :_, :_, :_, :_, :_, :_, :_}, @@ -178,7 +178,7 @@ defmodule IRC.UserTrack do # TODO def connected(network, nick, user, host, account_id, opts \\ %{}) do - if account = IRC.Account.get(account_id) do + if account = Nola.Account.get(account_id) do user = if user = find_by_nick(network, nick) do user else @@ -207,7 +207,7 @@ defmodule IRC.UserTrack do else user = %User{id: IRC.UserTrack.Id.large_id, network: sender.network, nick: nick, username: uname, host: host, privileges: %{channel => privileges}} - account = IRC.Account.lookup(user).id + account = Nola.Account.lookup(user).id user = %User{user | account: account} end user = touch_struct(user, channel) @@ -239,10 +239,10 @@ defmodule IRC.UserTrack do def messaged(%IRC.Message{network: network, account: account, channel: chan, sender: %{nick: nick}} = m) do {user, account} = if user = find_by_nick(network, nick) do - {touch_struct(user, chan), account || IRC.Account.lookup(user)} + {touch_struct(user, chan), account || Nola.Account.lookup(user)} else user = %User{network: network, nick: nick, privileges: %{}} - account = IRC.Account.lookup(user) + account = Nola.Account.lookup(user) {%User{user | account: account.id}, account} end Storage.insert(User.to_tuple(user)) @@ -256,9 +256,9 @@ defmodule IRC.UserTrack do def renamed(network, old_nick, new_nick) do if user = find_by_nick(network, old_nick) do - old_account = IRC.Account.lookup(user) + old_account = Nola.Account.lookup(user) user = %User{user | nick: new_nick, nicks: [old_nick|user.nicks]} - account = IRC.Account.lookup(user, false) || old_account + account = Nola.Account.lookup(user, false) || old_account user = %User{user | nick: new_nick, account: account.id, nicks: [old_nick|user.nicks]} Storage.insert(User.to_tuple(user)) channels = for {channel, _} <- user.privileges, do: channel |