Remove unused custom domain code

This commit is contained in:
Uku Taht 2021-12-20 11:49:50 +02:00
parent 051294445a
commit 711cbdfca2
14 changed files with 1 additions and 331 deletions

View File

@ -97,12 +97,6 @@ cron_enabled =
|> get_var_from_path_or_env("CRON_ENABLED", "false")
|> String.to_existing_atom()
custom_domain_server_ip = get_var_from_path_or_env(config_dir, "CUSTOM_DOMAIN_SERVER_IP")
custom_domain_server_user = get_var_from_path_or_env(config_dir, "CUSTOM_DOMAIN_SERVER_USER")
custom_domain_server_password =
get_var_from_path_or_env(config_dir, "CUSTOM_DOMAIN_SERVER_PASSWORD")
geolite2_country_db =
get_var_from_path_or_env(
config_dir,
@ -271,11 +265,6 @@ case mailer_adapter do
raise "Unknown mailer_adapter; expected SMTPAdapter or PostmarkAdapter"
end
config :plausible, :custom_domain_server,
user: custom_domain_server_user,
password: custom_domain_server_password,
ip: custom_domain_server_ip
config :plausible, PlausibleWeb.Firewall,
blocklist:
get_var_from_path_or_env(config_dir, "IP_BLOCKLIST", "")
@ -307,8 +296,6 @@ if config_env() == :prod && !disable_cron do
{"0 14 * * *", Plausible.Workers.CheckUsage},
# Daily at 15
{"0 15 * * *", Plausible.Workers.NotifyAnnualRenewal},
# Every 10 minutes
{"*/10 * * * *", Plausible.Workers.ProvisionSslCertificates},
# Every midnight
{"0 0 * * *", Plausible.Workers.LockSites}
]

View File

@ -1,8 +1,5 @@
defmodule Plausible.Site.CustomDomain do
use Ecto.Schema
import Ecto.Changeset
@domain_name_regex ~r/(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]/
schema "custom_domains" do
field :domain, :string
@ -11,11 +8,4 @@ defmodule Plausible.Site.CustomDomain do
timestamps()
end
def changeset(custom_domain, attrs) do
custom_domain
|> cast(attrs, [:domain, :site_id])
|> validate_required([:domain, :site_id])
|> validate_format(:domain, @domain_name_regex, message: "please enter a valid domain name")
end
end

View File

@ -1,6 +1,6 @@
defmodule Plausible.Sites do
use Plausible.Repo
alias Plausible.Site.{CustomDomain, SharedLink}
alias Plausible.Site.SharedLink
def create(user, params) do
count = Enum.count(owned_by(user))
@ -149,12 +149,4 @@ defmodule Plausible.Sites do
Repo.delete!(site)
Plausible.ClickhouseRepo.clear_stats_for(site.domain)
end
def add_custom_domain(site, custom_domain) do
CustomDomain.changeset(%CustomDomain{}, %{
site_id: site.id,
domain: custom_domain
})
|> Repo.insert()
end
end

View File

@ -606,61 +606,6 @@ defmodule PlausibleWeb.SiteController do
redirect(conn, to: "/#{URI.encode_www_form(site.domain)}/settings/visibility")
end
def new_custom_domain(conn, _params) do
site = conn.assigns[:site]
changeset = Plausible.Site.CustomDomain.changeset(%Plausible.Site.CustomDomain{}, %{})
conn
|> assign(:skip_plausible_tracking, true)
|> render("new_custom_domain.html",
site: site,
changeset: changeset,
layout: {PlausibleWeb.LayoutView, "focus.html"}
)
end
def custom_domain_dns_setup(conn, _params) do
site = conn.assigns[:site] |> Repo.preload(:custom_domain)
conn
|> assign(:skip_plausible_tracking, true)
|> render("custom_domain_dns_setup.html",
site: site,
layout: {PlausibleWeb.LayoutView, "focus.html"}
)
end
def custom_domain_snippet(conn, _params) do
site =
conn.assigns[:site]
|> Repo.preload(:custom_domain)
conn
|> assign(:skip_plausible_tracking, true)
|> render("custom_domain_snippet.html",
site: site,
layout: {PlausibleWeb.LayoutView, "focus.html"}
)
end
def add_custom_domain(conn, %{"custom_domain" => domain}) do
site = conn.assigns[:site]
case Sites.add_custom_domain(site, domain["domain"]) do
{:ok, _custom_domain} ->
redirect(conn, to: "/sites/#{URI.encode_www_form(site.domain)}/custom-domains/dns-setup")
{:error, changeset} ->
conn
|> assign(:skip_plausible_tracking, true)
|> render("new_custom_domain.html",
site: site,
changeset: changeset,
layout: {PlausibleWeb.LayoutView, "focus.html"}
)
end
end
def delete_custom_domain(conn, _params) do
site =
conn.assigns[:site]

View File

@ -200,10 +200,6 @@ defmodule PlausibleWeb.Router do
put "/sites/:website/shared-links/:slug", SiteController, :update_shared_link
delete "/sites/:website/shared-links/:slug", SiteController, :delete_shared_link
get "/sites/:website/custom-domains/new", SiteController, :new_custom_domain
get "/sites/:website/custom-domains/dns-setup", SiteController, :custom_domain_dns_setup
get "/sites/:website/custom-domains/snippet", SiteController, :custom_domain_snippet
post "/sites/:website/custom-domains", SiteController, :add_custom_domain
delete "/sites/:website/custom-domains/:id", SiteController, :delete_custom_domain
get "/sites/:website/memberships/invite", Site.MembershipController, :invite_member_form

View File

@ -1,14 +0,0 @@
<div class="max-w-md w-full mx-auto bg-white dark:bg-gray-800 shadow-md rounded px-8 pt-6 pb-8 mb-4 mt-8">
<h2 class="text-xl font-black dark:text-gray-100">DNS for <%= @site.custom_domain.domain %></h2>
<ol class="list-disc pl-4 my-4">
<li class="dark:text-gray-100">Go to your DNS providers website</li>
<li class="mt-4 dark:text-gray-100">Create a new CNAME record for <code><%= @site.custom_domain.domain %></code></li>
<li class="mt-4 dark:text-gray-100">Point the record to <code>custom.<%= base_domain() %>.</code> (including the dot)</li>
<li class="mt-4 dark:text-gray-100">If you're using Cloudflare, make sure to disable the orange cloud proxy:</li>
<%= img_tag(Routes.static_path(@conn, "/images/cloudflare_orange_cloud.png"), class: "w-36 my-4 inline") %>
<span class="text-lg font-bold dark:text-gray-100">&rarr;</span>
<%= img_tag(Routes.static_path(@conn, "/images/cloudflare_gray_cloud.png"), class: "w-36 my-4 inline") %>
</ol>
<%= link("Done →", to: "/sites/#{URI.encode_www_form(@site.domain)}/custom-domains/snippet", class: "button w-full mt-6") %>
</div>

View File

@ -1,25 +0,0 @@
<%= form_for @conn, "/", [class: "max-w-md w-full mx-auto bg-white dark:bg-gray-800 shadow-md rounded px-8 pt-6 pb-8 mb-4 mt-8"], fn f -> %>
<h2 class="text-xl font-black dark:text-gray-100">Update javascript snippet</h2>
<div class="my-4">
<p class="dark:text-gray-100">
Allow up to 4 hours for DNS changes to propagate and for us to obtain an SSL certificate for <code><%= @site.custom_domain.domain %></code>
</p>
<p class="mt-4 dark:text-gray-100">
The setup is working when <a href="//<%= @site.custom_domain.domain %>/js/index.js" target="_blank" class="text-indigo-500"><%= @site.custom_domain.domain %>/js/index.js</a> loads the javascript tracker.
</p>
<p class="mt-4 dark:text-gray-100">
To finish your setup, please replace the tracking snippet on your site with the following.
</p>
<div class="relative">
<%= textarea f, :domain, id: "snippet_code", class: "transition overflow-hidden bg-gray-100 dark:bg-gray-900 outline-none appearance-none border border-transparent rounded w-full p-2 pr-6 text-gray-700 dark:text-gray-300 leading-normal appearance-none focus:outline-none focus:bg-white dark:focus:bg-gray-900 focus:border-gray-300 dark:focus:border-gray-500 text-xs mt-4 resize-none", value: snippet(@site), rows: 3, readonly: "readonly" %>
<a onclick="var textarea = document.getElementById('snippet_code'); textarea.focus(); textarea.select(); document.execCommand('copy');" href="javascript:void(0)" class="no-underline text-indigo-500 text-sm hover:underline">
<svg class="absolute text-indigo-500" style="top: 24px; right: 12px;" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>
</a>
</div>
</div>
<%= link("Back to settings →", class: "button mt-4 w-full", to: "/#{URI.encode_www_form(@site.domain)}/settings/custom-domain") %>
<p class="mt-4 text-gray-600 text-sm dark:text-gray-400">
Problems? <%= link("Get help via email", to: "mailto:support@plausible.io", class: "text-indigo-500 underline") %>
</p>
<% end %>

View File

@ -1,15 +0,0 @@
<%= form_for @changeset, "/sites/#{URI.encode_www_form(@site.domain)}/custom-domains", [class: "max-w-md w-full mx-auto bg-white dark:bg-gray-800 shadow-md rounded px-8 pt-6 pb-8 mb-4 mt-8"], fn f -> %>
<h2 class="text-xl font-black dark:text-gray-100">Setup custom domain</h2>
<div class="my-4 dark:text-gray-100">
We recommend using a subdomain of the website you're running Plausible on.
If your site is on <code>example.com</code> you can use <code>stats.example.com</code>.
<br /><br /> The name of the subdomain can be anything, it doesn't have to be <code>stats</code>.
</div>
<div class="my-4">
<%= label f, :domain, class: "block text-sm font-bold dark:text-gray-100" %>
<%= text_input f, :domain, class: "transition mt-3 bg-gray-100 dark:bg-gray-900 outline-none appearance-none border border-transparent rounded w-full p-2 text-gray-700 dark:text-gray-300 leading-normal focus:outline-none focus:bg-white dark:focus:bg-gray-800 focus:border-gray-300 dark:focus:border-gray-500", placeholder: "stats.[yourdomain].com" %>
<%= error_tag f, :domain %>
</div>
<%= submit "DNS setup →", class: "button mt-4 w-full dark:text-gray-100" %>
<% end %>

View File

@ -34,8 +34,6 @@
Configured domain: <b><%= @site.custom_domain.domain %></b>
</span>
<%= link("Remove custom domain", to: "/sites/#{URI.encode_www_form(@site.domain)}/custom-domains/#{@site.custom_domain.id}", class: "inline-block mt-4 px-4 py-2 border border-gray-300 dark:border-gray-500 text-sm leading-5 font-medium rounded-md text-red-700 bg-white dark:bg-gray-800 hover:text-red-500 dark:hover:text-red-400 focus:outline-none focus:border-blue-300 focus:ring active:text-red-800 active:bg-gray-50 transition ease-in-out duration-150", method: "delete") %>
<% else %>
<%= link("Add custom domain", to: "/sites/#{URI.encode_www_form(@site.domain)}/custom-domains/new", class: "button") %>
<% end %>
</div>
</div>

View File

@ -1,64 +0,0 @@
defmodule Plausible.Workers.ProvisionSslCertificates do
use Plausible.Repo
use Oban.Worker, queue: :provision_ssl_certificates, max_attempts: 1
require Logger
@timeout 20_000
@impl Oban.Worker
def perform(_job, ssh \\ SSHEx) do
config = get_config()
{:ok, conn} =
ssh.connect(
ip: to_charlist(config[:ip]),
user: to_charlist(config[:user]),
password: to_charlist(config[:password])
)
recent_custom_domains =
Repo.all(
from cd in Plausible.Site.CustomDomain,
where: cd.updated_at > fragment("now() - '3 days'::interval"),
where: not cd.has_ssl_certificate
)
for domain <- recent_custom_domains do
res =
ssh.run(
conn,
'sudo certbot certonly --webroot -w /root/webroot -n -d \"#{domain.domain}\"',
channel_timeout: @timeout,
exec_timeout: @timeout
)
case res do
{:ok, msg, code} ->
report_result({msg, code}, domain)
e ->
Logger.warn("Error obtaining SSL certificate for #{domain.domain}: #{inspect(e)}")
end
end
:ok
end
defp report_result({_, 0}, domain) do
Ecto.Changeset.change(domain, has_ssl_certificate: true) |> Repo.update!()
Plausible.Slack.notify("Obtained SSL cert for #{domain.domain}")
:ok
end
defp report_result({error_msg, error_code}, domain) do
Logger.warn(
"Error obtaining SSL certificate for #{domain.domain}: #{error_msg} (code=#{error_code})"
)
# Failing to obtain is expected, not a failure for the job queue
:ok
end
defp get_config() do
Application.get_env(:plausible, :custom_domain_server)
end
end

View File

@ -82,7 +82,6 @@ defmodule Plausible.MixProject do
{:nanoid, "~> 2.0.2"},
{:siphash, "~> 3.2"},
{:oban, "~> 2.0"},
{:sshex, "2.2.1"},
{:geolix, "~> 1.0"},
{:clickhouse_ecto, git: "https://github.com/plausible/clickhouse_ecto.git"},
{:location, git: "https://github.com/plausible/location.git"},

View File

@ -91,7 +91,6 @@
"sentry": {:hex, :sentry, "8.0.6", "c8de1bf0523bc120ec37d596c55260901029ecb0994e7075b0973328779ceef7", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.6", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, "~> 2.3", [hex: :plug_cowboy, repo: "hexpm", optional: true]}], "hexpm", "051a2d0472162f3137787c7c9d6e6e4ef239de9329c8c45b1f1bf1e9379e1883"},
"siphash": {:hex, :siphash, "3.2.0", "ec03fd4066259218c85e2a4b8eec4bb9663bc02b127ea8a0836db376ba73f2ed", [:make, :mix], [], "hexpm", "ba3810701c6e95637a745e186e8a4899087c3b079ba88fb8f33df054c3b0b7c3"},
"sleeplocks": {:hex, :sleeplocks, "1.1.1", "3d462a0639a6ef36cc75d6038b7393ae537ab394641beb59830a1b8271faeed3", [:rebar3], [], "hexpm", "84ee37aeff4d0d92b290fff986d6a95ac5eedf9b383fadfd1d88e9b84a1c02e1"},
"sshex": {:hex, :sshex, "2.2.1", "e1270b8345ea2a66a11c2bb7aed22c93e3bc7bc813486f4ffd0a980e4a898160", [:mix], [], "hexpm", "45b2caa5011dc850e70a2d77e3b62678a3e8bcb903eab6f3e7afb2ea897b13db"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
"telemetry": {:hex, :telemetry, "1.0.0", "0f453a102cdf13d506b7c0ab158324c337c41f1cc7548f0bc0e130bbf0ae9452", [:rebar3], [], "hexpm", "73bc09fa59b4a0284efb4624335583c528e07ec9ae76aca96ea0673850aec57a"},
"telemetry_registry": {:hex, :telemetry_registry, "0.3.0", "6768f151ea53fc0fbca70dbff5b20a8d663ee4e0c0b2ae589590e08658e76f1e", [:mix, :rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "492e2adbc609f3e79ece7f29fec363a97a2c484ac78a83098535d6564781e917"},

View File

@ -707,61 +707,6 @@ defmodule PlausibleWeb.SiteControllerTest do
end
end
describe "GET /sites/:website/custom-domains/new" do
setup [:create_user, :log_in, :create_site]
test "shows form for new custom domain", %{conn: conn, site: site} do
conn = get(conn, "/sites/#{site.domain}/custom-domains/new")
assert html_response(conn, 200) =~ "Setup custom domain"
end
end
describe "POST /sites/:website/custom-domains" do
setup [:create_user, :log_in, :create_site]
test "creates a custom domain", %{conn: conn, site: site} do
conn =
post(conn, "/sites/#{site.domain}/custom-domains", %{
"custom_domain" => %{"domain" => "plausible.example.com"}
})
domain = Repo.one(Plausible.Site.CustomDomain)
assert redirected_to(conn, 302) =~ "/sites/#{site.domain}/custom-domains/dns-setup"
assert domain.domain == "plausible.example.com"
end
test "validates presence of domain name", %{conn: conn, site: site} do
conn =
post(conn, "/sites/#{site.domain}/custom-domains", %{"custom_domain" => %{"domain" => ""}})
refute Repo.one(Plausible.Site.CustomDomain)
assert html_response(conn, 200) =~ "Setup custom domain"
end
test "validates format of domain name", %{conn: conn, site: site} do
conn =
post(conn, "/sites/#{site.domain}/custom-domains", %{
"custom_domain" => %{"domain" => "ASD?/not-domain"}
})
refute Repo.one(Plausible.Site.CustomDomain)
assert html_response(conn, 200) =~ "Setup custom domain"
end
end
describe "GET /sites/:website/custom-domains/dns-setup" do
setup [:create_user, :log_in, :create_site]
test "shows instructions to set up dns", %{conn: conn, site: site} do
domain = insert(:custom_domain, site: site)
conn = get(conn, "/sites/#{site.domain}/custom-domains/dns-setup")
assert html_response(conn, 200) =~ "DNS for #{domain.domain}"
end
end
describe "DELETE sites/:website/custom-domains/:id" do
setup [:create_user, :log_in, :create_site]

View File

@ -1,63 +0,0 @@
defmodule Plausible.Workers.SslCertificatesTest do
use Plausible.DataCase
alias Plausible.Workers.ProvisionSslCertificates
import Double
test "makes ssh call to certbot" do
site = insert(:site)
insert(:custom_domain, site: site, domain: "custom-site.com")
ssh_stub =
stub(SSHEx, :connect, fn _cmd -> {:ok, nil} end)
|> stub(:run, fn _conn, _cmd, _opts -> {:ok, "", 0} end)
ProvisionSslCertificates.perform(nil, ssh_stub)
assert_receive(
{SSHEx, :run,
[nil, 'sudo certbot certonly --webroot -w /root/webroot -n -d "custom-site.com"', _]}
)
end
test "sets has_ssl_certficate=true if the ssh command is succesful" do
site = insert(:site)
insert(:custom_domain, site: site, domain: "custom-site.com")
ssh_stub =
stub(SSHEx, :connect, fn _cmd -> {:ok, nil} end)
|> stub(:run, fn _conn, _cmd, _opts -> {:ok, "", 0} end)
ProvisionSslCertificates.perform(nil, ssh_stub)
domain = Repo.get_by(Plausible.Site.CustomDomain, site_id: site.id)
assert domain.has_ssl_certificate
end
test "does not set has_ssl_certficate=true if the ssh command fails" do
site = insert(:site)
insert(:custom_domain, site: site, domain: "custom-site.com")
ssh_stub =
stub(SSHEx, :connect, fn _cmd -> {:ok, nil} end)
|> stub(:run, fn _conn, _cmd, _opts -> {:ok, "", 1} end)
ProvisionSslCertificates.perform(nil, ssh_stub)
domain = Repo.get_by(Plausible.Site.CustomDomain, site_id: site.id)
refute domain.has_ssl_certificate
end
test "does not set has_ssl_certficate=true if the ssh command errors completely" do
site = insert(:site)
insert(:custom_domain, site: site, domain: "custom-site.com")
ssh_stub =
stub(SSHEx, :connect, fn _cmd -> {:ok, nil} end)
|> stub(:run, fn _conn, _cmd, _opts -> {:error, "msg"} end)
ProvisionSslCertificates.perform(nil, ssh_stub)
domain = Repo.get_by(Plausible.Site.CustomDomain, site_id: site.id)
refute domain.has_ssl_certificate
end
end