philomena/lib/philomena/artist_links/automatic_verifier.ex

64 lines
2 KiB
Elixir

defmodule Philomena.ArtistLinks.AutomaticVerifier do
@moduledoc """
Artist link automatic verification.
Artist links contain a random code which is generated when the link is created. If the user
places the code on their linked page and this verifier finds it, this expedites the process
of verifying a link for the moderator, as they can simply use the presence of the code in a
field controlled by the artist to ascertain the validity of the artist link.
"""
alias Philomena.ArtistLinks.ArtistLink
alias Philomena.Repo
import Ecto.Query
@doc """
Check links pending verification to see if the user placed the appropriate code on the page.
Polls each artist link in unverified state and generates a changeset to either set it to
link verified, if the code was found on the page, or reset the next check time, if the code
was not found.
Returns a list of changesets with updated links.
"""
def generate_updates do
# Automatically retry in an hour if we don't manage to
# successfully verify any given link
now = DateTime.utc_now(:second)
recheck_time = DateTime.add(now, 3600, :second)
Enum.map(links_to_check(now), fn link ->
ArtistLink.automatic_verify_changeset(link, check_link(link, recheck_time))
end)
end
defp links_to_check(now) do
recheck_query =
from ul in ArtistLink,
where: ul.aasm_state == "unverified",
where: ul.next_check_at < ^now
Repo.all(recheck_query)
end
defp check_link(artist_link, recheck_time) do
artist_link.uri
|> PhilomenaProxy.Http.get()
|> contains_verification_code?(artist_link.verification_code)
|> case do
true ->
%{next_check_at: nil, aasm_state: "link_verified"}
false ->
%{next_check_at: recheck_time}
end
end
defp contains_verification_code?({:ok, %{body: body, status: 200}}, code) do
String.contains?(body, code)
end
defp contains_verification_code?(_response, _code) do
false
end
end