philomena/lib/philomena_web/controllers/profile/alias_controller.ex
2020-01-10 23:20:19 -05:00

64 lines
1.8 KiB
Elixir

defmodule PhilomenaWeb.Profile.AliasController do
use PhilomenaWeb, :controller
alias Philomena.UserFingerprints.UserFingerprint
alias Philomena.UserIps.UserIp
alias Philomena.Users.User
alias Philomena.Repo
import Ecto.Query
plug PhilomenaWeb.CanaryMapPlug, index: :show_details
plug :load_and_authorize_resource,
model: User,
id_field: "slug",
id_name: "profile_id",
persisted: true
def index(conn, _params) do
user = conn.assigns.user
# N.B.: subquery runs faster and is easier to read
# than the equivalent join, but Ecto doesn't support
# that for some reason (and ActiveRecord does??)
ip_matches =
User
|> join(:inner, [u], _ in assoc(u, :user_ips))
|> join(:left, [u, ui1], ui2 in UserIp, on: ui1.ip == ui2.ip)
|> where([u, _ui1, ui2], u.id != ^user.id and ui2.user_id == ^user.id)
|> select([u, _ui1, _ui2], u)
|> preload(:bans)
|> Repo.all()
|> Map.new(&{&1.id, &1})
fp_matches =
User
|> join(:inner, [u], _ in assoc(u, :user_fingerprints))
|> join(:left, [u, uf1], uf2 in UserFingerprint, on: uf1.fingerprint == uf2.fingerprint)
|> where([u, _uf1, uf2], u.id != ^user.id and uf2.user_id == ^user.id)
|> select([u, _uf1, _uf2], u)
|> preload(:bans)
|> Repo.all()
|> Map.new(&{&1.id, &1})
both_matches = Map.take(ip_matches, Map.keys(fp_matches))
ip_matches = Map.drop(ip_matches, Map.keys(both_matches))
fp_matches = Map.drop(fp_matches, Map.keys(both_matches))
both_matches = Map.values(both_matches)
ip_matches = Map.values(ip_matches)
fp_matches = Map.values(fp_matches)
render(
conn,
"index.html",
title: "Potential Aliases for `#{user.name}'",
both_matches: both_matches,
ip_matches: ip_matches,
fp_matches: fp_matches
)
end
end