Something went wrong. Try again.
a pds written in elixir tempest.desertthunder.dev
Something went wrong. Try again.
3.4 kB · 101 lines
Elixir
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102defmodule TempestWeb.AdminController do use TempestWeb, :controller
alias Tempest.{Admin, AdminAuth} alias TempestWeb.XrpcErrorJSON
def status(conn, _params) do with_admin(conn, fn conn -> json(conn, Admin.status()) end) end
def dashboard(conn, _params) do with_admin(conn, fn conn -> render(conn, :dashboard, status: Admin.status()) end) end
def invites(conn, _params) do with_admin(conn, fn conn -> render(conn, :invites, status: Admin.status()) end) end
def repo(conn, _params) do with_admin(conn, fn conn -> render(conn, :repo, result: nil) end) end
def repo_action(conn, %{"op" => op} = params) do with_admin(conn, fn conn -> render(conn, :repo, result: run_repo_op(op, params)) end) end
def backups(conn, _params) do with_admin(conn, fn conn -> render(conn, :backups, result: nil) end) end
def backup_action(conn, %{"op" => op} = params) do with_admin(conn, fn conn -> render(conn, :backups, result: run_backup_op(op, params)) end) end
def storage(conn, _params) do with_admin(conn, fn conn -> render(conn, :storage, status: Admin.status()) end) end
def compatibility(conn, _params) do with_admin(conn, fn conn -> render(conn, :compatibility, status: Admin.compatibility_status()) end) end
defp with_admin(conn, fun) do cond do conn.assigns[:admin_auth] -> fun.(conn)
true -> case AdminAuth.verify_authorization_header(conn.req_headers) do :ok -> fun.(conn)
{:error, :missing_admin_token} -> reject(conn, 401, "AuthenticationRequired", "Admin bearer token is required")
{:error, :admin_token_not_configured} -> reject(conn, 503, "AdminAuthNotConfigured", "Admin token hash is not configured")
{:error, _reason} -> reject(conn, 401, "InvalidToken", "Admin bearer token is invalid") end end end
defp run_repo_op("verify", %{"did" => did}), do: Admin.RepoOps.verify(did) defp run_repo_op("export", %{"did" => did, "path" => path}), do: Admin.RepoOps.export(did, path) defp run_repo_op("import", %{"did" => did, "path" => path}), do: Admin.RepoOps.import(did, path) defp run_repo_op(_op, _params), do: {:error, :invalid_repo_operation}
defp run_backup_op("create", params) do opts = if blank?(params["path"]), do: [], else: [path: params["path"]] Admin.Backup.create(opts) end
defp run_backup_op("restore_dry_run", %{"path" => path} = params) do target = if blank?(params["target"]), do: Tempest.Config.load!().data_dir, else: params["target"] manifest = Path.join(path, "manifest.json")
cond do not File.dir?(path) -> {:error, :backup_not_found}
not File.exists?(manifest) -> {:error, :backup_manifest_missing}
File.exists?(Path.join(target, "account.sqlite")) or File.exists?(Path.join(target, "sequencer.sqlite")) -> {:ok, %{dry_run: true, refused: :target_not_empty, target: target}}
true -> {:ok, %{dry_run: true, would_restore: true, target: target}} end end
defp run_backup_op(_op, _params), do: {:error, :invalid_backup_operation}
defp blank?(value), do: is_nil(value) or String.trim(to_string(value)) == ""
defp reject(conn, status, error, message) do XrpcErrorJSON.render(conn, status, error, message) endend