mirror of
https://github.com/plausible/analytics.git
synced 2024-12-28 12:01:39 +03:00
99fe03701e
* Add Ecto.Network dependency * Migration: Add ip block list table * If Cachex errors out, mark the cache as not ready * Add IPRule schema * Seed IPRules * Add Shields context module * Implement IPRuleCache * Start IPRuleCache * Drop blocklisted IPs on ingestion * Cosmetic rename * Add settings sidebar item * Consider IPRuleCache readiness on health checks * Fix typo * Implement IP blocklist live view * Update moduledocs * Extend contextual module tests * Convert IPRules LiveView into LiveComponent * Keep live flashes on the tabs view * Update changelog * Format * Credo * Remove garbage * Update drop reason typespecs * Update typespecs for cache keys * Keep track of who added a rule and when * Test if adding via LV prefills the updated_by tooltip * Update ecto_network dependency * s/updated_by/added_by * s/drop_blocklist_ip/drop_shield_rule_ip * Add docs link * s/Updated/Added
107 lines
2.8 KiB
Elixir
107 lines
2.8 KiB
Elixir
defimpl FunWithFlags.Actor, for: BitString do
|
|
def id(str) do
|
|
str
|
|
end
|
|
end
|
|
|
|
defmodule PlausibleWeb.Api.ExternalController do
|
|
use PlausibleWeb, :controller
|
|
require Logger
|
|
|
|
alias Plausible.Ingestion
|
|
|
|
def event(conn, _params) do
|
|
with {:ok, request} <- Ingestion.Request.build(conn),
|
|
_ <- Sentry.Context.set_extra_context(%{request: request}) do
|
|
case Ingestion.Event.build_and_buffer(request) do
|
|
{:ok, %{dropped: [], buffered: _buffered}} ->
|
|
conn
|
|
|> put_status(202)
|
|
|> text("ok")
|
|
|
|
{:ok, %{dropped: dropped, buffered: _}} ->
|
|
first_invalid_changeset = find_first_invalid_changeset(dropped)
|
|
|
|
if first_invalid_changeset do
|
|
conn
|
|
|> put_resp_header("x-plausible-dropped", "#{Enum.count(dropped)}")
|
|
|> put_status(400)
|
|
|> json(%{errors: Plausible.ChangesetHelpers.traverse_errors(first_invalid_changeset)})
|
|
else
|
|
conn
|
|
|> put_resp_header("x-plausible-dropped", "#{Enum.count(dropped)}")
|
|
|> put_status(202)
|
|
|> text("ok")
|
|
end
|
|
end
|
|
else
|
|
{:error, %Ecto.Changeset{} = changeset} ->
|
|
conn
|
|
|> put_status(400)
|
|
|> json(%{errors: Plausible.ChangesetHelpers.traverse_errors(changeset)})
|
|
end
|
|
end
|
|
|
|
def error(conn, _params) do
|
|
Sentry.capture_message("JS snippet error")
|
|
send_resp(conn, 200, "")
|
|
end
|
|
|
|
def health(conn, _params) do
|
|
postgres_health =
|
|
case Ecto.Adapters.SQL.query(Plausible.Repo, "SELECT 1", []) do
|
|
{:ok, _} -> "ok"
|
|
e -> "error: #{inspect(e)}"
|
|
end
|
|
|
|
clickhouse_health =
|
|
case Ecto.Adapters.SQL.query(Plausible.ClickhouseRepo, "SELECT 1", []) do
|
|
{:ok, _} -> "ok"
|
|
e -> "error: #{inspect(e)}"
|
|
end
|
|
|
|
cache_health =
|
|
if postgres_health == "ok" and Plausible.Site.Cache.ready?() and
|
|
Plausible.Shield.IPRuleCache.ready?() do
|
|
"ok"
|
|
end
|
|
|
|
status =
|
|
case {postgres_health, clickhouse_health, cache_health} do
|
|
{"ok", "ok", "ok"} -> 200
|
|
_ -> 500
|
|
end
|
|
|
|
put_status(conn, status)
|
|
|> json(%{
|
|
postgres: postgres_health,
|
|
clickhouse: clickhouse_health,
|
|
sites_cache: cache_health
|
|
})
|
|
end
|
|
|
|
def info(conn, _params) do
|
|
build =
|
|
:plausible
|
|
|> Application.get_env(:runtime_metadata)
|
|
|> Keyword.take([:version, :commit, :created, :tags])
|
|
|> Map.new()
|
|
|
|
geo_database = Plausible.Geo.database_type() || "(not configured)"
|
|
|
|
json(conn, %{
|
|
geo_database: geo_database,
|
|
build: build
|
|
})
|
|
end
|
|
|
|
defp find_first_invalid_changeset(dropped) do
|
|
Enum.find_value(dropped, nil, fn dropped_event ->
|
|
case dropped_event.drop_reason do
|
|
{:error, %Ecto.Changeset{} = changeset} -> changeset
|
|
_ -> false
|
|
end
|
|
end)
|
|
end
|
|
end
|