File size: 1,428 Bytes
8da2481 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | defmodule Plausible.Shield.IPRuleCache do
@moduledoc """
Allows retrieving IP Rules by domain and IP
"""
alias Plausible.Shield.IPRule
import Ecto.Query
use Plausible.Cache
@cache_name :ip_blocklist_by_domain
@cached_schema_fields ~w(
id
inet
action
)a
@impl true
def name(), do: @cache_name
@impl true
def child_id(), do: :cache_ip_blocklist
@impl true
def count_all() do
Plausible.Repo.aggregate(IPRule, :count)
end
@impl true
def base_db_query() do
from rule in IPRule,
inner_join: s in assoc(rule, :site),
select: {
s.domain,
s.domain_changed_from,
%{struct(rule, ^@cached_schema_fields) | from_cache?: true}
}
end
@impl true
def get_from_source({domain, address}) do
query =
base_db_query()
|> where([rule, site], rule.inet == ^address and site.domain == ^domain)
case Plausible.Repo.one(query) do
{_, _, rule = %IPRule{}} -> %IPRule{rule | from_cache?: false}
_any -> nil
end
end
@impl true
def unwrap_cache_keys(items) do
Enum.reduce(items, [], fn
{domain, nil, object}, acc ->
[{{domain, to_string(object.inet)}, object} | acc]
{domain, domain_changed_from, object}, acc ->
[
{{domain, to_string(object.inet)}, object},
{{domain_changed_from, to_string(object.inet)}, object} | acc
]
end)
end
end
|