Packages

Plugin-based heuristic spam scanner for free-text web form input. Elixir port of the Ruby despamilator gem.

Current section

Files

Jump to
despamilator_elixir lib despamilator allowlist.ex
Raw

lib/despamilator/allowlist.ex

defmodule Despamilator.Allowlist do
@moduledoc """
Allow-list of domains whose URLs should not be penalised by URL-aware filters.
Configure via:
config :despamilator_elixir_elixir,
url_allowlist: [
"pakwheels.com",
"google.com",
~r/\\.(gov|edu)\\b/
]
String entries match the host suffix (so `pakwheels.com` allows
`www.pakwheels.com` and `forums.pakwheels.com`). Regex entries match
anywhere in the lowercased host.
Filters that consult the allow-list:
* `Despamilator.Filter.URLs`
* `Despamilator.Filter.IPAddressURL`
* `Despamilator.Filter.VeryLongDomainName`
* `Despamilator.Filter.SpammyTLDs`
"""
@url_regex ~r{(https?://[^\s<>"']+)}i
@host_regex ~r{https?://([^\s/?#]+)}i
@doc "Returns the configured allow-list."
def entries do
Application.get_env(:despamilator_elixir, :url_allowlist, [])
end
@doc "True if `host` (e.g. `\"www.example.com\"`) is allow-listed."
def host_allowed?(host) when is_binary(host) do
h = String.downcase(host)
Enum.any?(entries(), &entry_matches?(&1, h))
end
@doc """
Returns `text` with every URL whose host is allow-listed replaced by a
single space. Used by URL-aware filters to skip trusted domains entirely.
"""
def strip(text) when is_binary(text) do
case entries() do
[] ->
text
_ ->
Regex.replace(@url_regex, text, fn url ->
if url_allowed?(url), do: " ", else: url
end)
end
end
defp url_allowed?(url) do
case Regex.run(@host_regex, url, capture: :all_but_first) do
[host] -> host_allowed?(host)
_ -> false
end
end
defp entry_matches?(entry, host) when is_binary(entry) do
e = String.downcase(entry)
host == e or String.ends_with?(host, "." <> e)
end
defp entry_matches?(%Regex{} = entry, host), do: Regex.match?(entry, host)
end