diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/mix/tasks/pleroma/instance.ex | 11 | ||||
-rw-r--r-- | lib/pleroma/application.ex | 55 | ||||
-rw-r--r-- | lib/pleroma/application/environment.ex | 7 | ||||
-rw-r--r-- | lib/pleroma/config/loader.ex | 1 | ||||
-rw-r--r-- | lib/pleroma/emails/user_email.ex | 49 | ||||
-rw-r--r-- | lib/pleroma/helpers/config_helper.ex (renamed from lib/pleroma/config/helpers.ex) | 14 | ||||
-rw-r--r-- | lib/pleroma/helpers/server_ip_helper.ex | 63 | ||||
-rw-r--r-- | lib/pleroma/user.ex | 3 | ||||
-rw-r--r-- | lib/pleroma/user/welcome_email.ex | 7 | ||||
-rw-r--r-- | lib/pleroma/web/rich_media/helpers.ex | 2 |
10 files changed, 169 insertions, 43 deletions
diff --git a/lib/mix/tasks/pleroma/instance.ex b/lib/mix/tasks/pleroma/instance.ex index da27a99d0..cb6216474 100644 --- a/lib/mix/tasks/pleroma/instance.ex +++ b/lib/mix/tasks/pleroma/instance.ex @@ -86,9 +86,9 @@ defmodule Mix.Tasks.Pleroma.Instance do get_option( options, :indexable, - "Do you want search engines to index your site? (y/n)", - "y" - ) === "y" + "Do you want to deny Search Engine bots from crawling the site? (y/n)", + "n" + ) === "n" db_configurable? = get_option( @@ -275,7 +275,8 @@ defmodule Mix.Tasks.Pleroma.Instance do end end - defp write_robots_txt(static_dir, indexable, template_dir) do + @spec write_robots_txt(Path.t(), boolean(), Path.t()) :: :ok | no_return() + def write_robots_txt(static_dir, indexable, template_dir) do robots_txt = EEx.eval_file( template_dir <> "/robots_txt.eex", @@ -289,7 +290,7 @@ defmodule Mix.Tasks.Pleroma.Instance do shell_info("Backing up existing robots.txt to #{robots_txt_path}.bak") end - File.write(robots_txt_path, robots_txt) + :ok = File.write(robots_txt_path, robots_txt) shell_info("Writing #{robots_txt_path}.") end diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index afe605f01..c971be7e4 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -50,6 +50,7 @@ defmodule Pleroma.Application do end @doc """ + Checks that config file exists and starts application, otherwise starts web UI for configuration. Under main supervisor is started DynamicSupervisor, which later starts pleroma startup dependencies. Pleroma start is splitted into three `phases`: - running prestart requirements (runtime compilation, warnings, deprecations, monitoring, etc.) @@ -60,20 +61,68 @@ defmodule Pleroma.Application do def start(_type, _args) do children = [ {DynamicSupervisor, strategy: :one_for_one, name: @dynamic_supervisor}, - {Pleroma.Application.ConfigDependentDeps, [dynamic_supervisor: @dynamic_supervisor]}, - Pleroma.Repo + {Pleroma.Application.ConfigDependentDeps, [dynamic_supervisor: @dynamic_supervisor]} ] {:ok, main_supervisor} = Supervisor.start_link(children, strategy: :one_for_one, name: Pleroma.Supervisor) + if @mix_env == :test or File.exists?(Pleroma.Application.config_path()) do + :ok = start_pleroma() + else + DynamicSupervisor.start_child( + @dynamic_supervisor, + Pleroma.InstallerWeb.Endpoint + ) + + token = Ecto.UUID.generate() + + Pleroma.Config.put(:installer_token, token) + + installer_port = + Pleroma.InstallerWeb.Endpoint + |> Pleroma.Config.get() + |> get_in([:http, :port]) + + ip = + with {:ok, ip} <- Pleroma.Helpers.ServerIPHelper.real_ip() do + ip + else + _ -> "IP not found" + end + + Logger.warn("Access installer at http://#{ip}:#{installer_port}/?token=#{token}") + end + + {:ok, main_supervisor} + end + + defp start_pleroma do + {:ok, _} = DynamicSupervisor.start_child(@dynamic_supervisor, Pleroma.Repo) run_prestart_requirements() Pleroma.Application.Environment.load_from_db_and_update(pleroma_start: true) Pleroma.Application.StartUpDependencies.start_all(@mix_env) + end - {:ok, main_supervisor} + @spec stop_installer_and_start_pleroma() :: {:ok, pid()} + def stop_installer_and_start_pleroma do + Pleroma.Application.config_path() + |> Pleroma.Application.Environment.update() + + start_pleroma() + + Task.start(fn -> + Process.sleep(100) + + installer_endpoint = Process.whereis(Pleroma.InstallerWeb.Endpoint) + + DynamicSupervisor.terminate_child( + @dynamic_supervisor, + installer_endpoint + ) + end) end defp run_prestart_requirements do diff --git a/lib/pleroma/application/environment.ex b/lib/pleroma/application/environment.ex index 589be4726..9d792ee0a 100644 --- a/lib/pleroma/application/environment.ex +++ b/lib/pleroma/application/environment.ex @@ -20,6 +20,13 @@ defmodule Pleroma.Application.Environment do |> update(opts) end + @spec update(Path.t()) :: :ok + def update(config_path) when is_binary(config_path) do + config_path + |> Pleroma.Config.Loader.read!() + |> Application.put_all_env() + end + @spec update([Pleroma.ConfigDB.t()], keyword()) :: :ok def update(changes, opts \\ []) when is_list(changes) do if Pleroma.Config.get(:configurable_from_database) do diff --git a/lib/pleroma/config/loader.ex b/lib/pleroma/config/loader.ex index 69fd458c0..a6935d7d8 100644 --- a/lib/pleroma/config/loader.ex +++ b/lib/pleroma/config/loader.ex @@ -17,6 +17,7 @@ defmodule Pleroma.Config.Loader do @reject_keys [ Pleroma.Repo, Pleroma.Web.Endpoint, + Pleroma.InstallerWeb.Endpoint, :env, :configurable_from_database, :database, diff --git a/lib/pleroma/emails/user_email.ex b/lib/pleroma/emails/user_email.ex index 52f3d419d..1b15d06be 100644 --- a/lib/pleroma/emails/user_email.ex +++ b/lib/pleroma/emails/user_email.ex @@ -8,12 +8,11 @@ defmodule Pleroma.Emails.UserEmail do use Phoenix.Swoosh, view: Pleroma.Web.EmailView, layout: {Pleroma.Web.LayoutView, :email} alias Pleroma.Config + alias Pleroma.Helpers.ConfigHelper alias Pleroma.User alias Pleroma.Web.Endpoint alias Pleroma.Web.Router - import Pleroma.Config.Helpers, only: [instance_name: 0, sender: 0] - defp recipient(email, nil), do: email defp recipient(email, name), do: {name, email} defp recipient(%User{} = user), do: recipient(user.email, user.name) @@ -22,25 +21,25 @@ defmodule Pleroma.Emails.UserEmail do def welcome(user, opts \\ %{}) do new() |> to(recipient(user)) - |> from(Map.get(opts, :sender, sender())) - |> subject(Map.get(opts, :subject, "Welcome to #{instance_name()}!")) - |> html_body(Map.get(opts, :html, "Welcome to #{instance_name()}!")) - |> text_body(Map.get(opts, :text, "Welcome to #{instance_name()}!")) + |> from(Map.get(opts, :sender, ConfigHelper.sender())) + |> subject(Map.get(opts, :subject, "Welcome to #{ConfigHelper.instance_name()}!")) + |> html_body(Map.get(opts, :html, "Welcome to #{ConfigHelper.instance_name()}!")) + |> text_body(Map.get(opts, :text, "Welcome to #{ConfigHelper.instance_name()}!")) end def password_reset_email(user, token) when is_binary(token) do password_reset_url = Router.Helpers.reset_password_url(Endpoint, :reset, token) html_body = """ - <h3>Reset your password at #{instance_name()}</h3> - <p>Someone has requested password change for your account at #{instance_name()}.</p> + <h3>Reset your password at #{ConfigHelper.instance_name()}</h3> + <p>Someone has requested password change for your account at #{ConfigHelper.instance_name()}.</p> <p>If it was you, visit the following link to proceed: <a href="#{password_reset_url}">reset password</a>.</p> <p>If it was someone else, nothing to worry about: your data is secure and your password has not been changed.</p> """ new() |> to(recipient(user)) - |> from(sender()) + |> from(ConfigHelper.sender()) |> subject("Password reset") |> html_body(html_body) end @@ -59,15 +58,15 @@ defmodule Pleroma.Emails.UserEmail do ) html_body = """ - <h3>You are invited to #{instance_name()}</h3> - <p>#{user.name} invites you to join #{instance_name()}, an instance of Pleroma federated social networking platform.</p> + <h3>You are invited to #{ConfigHelper.instance_name()}</h3> + <p>#{user.name} invites you to join #{ConfigHelper.instance_name()}, an instance of Pleroma federated social networking platform.</p> <p>Click the following link to register: <a href="#{registration_url}">accept invitation</a>.</p> """ new() |> to(recipient(to_email, to_name)) - |> from(sender()) - |> subject("Invitation to #{instance_name()}") + |> from(ConfigHelper.sender()) + |> subject("Invitation to #{ConfigHelper.instance_name()}") |> html_body(html_body) end @@ -81,27 +80,27 @@ defmodule Pleroma.Emails.UserEmail do ) html_body = """ - <h3>Thank you for registering on #{instance_name()}</h3> + <h3>Thank you for registering on #{ConfigHelper.instance_name()}!</h3> <p>Email confirmation is required to activate the account.</p> <p>Please click the following link to <a href="#{confirmation_url}">activate your account</a>.</p> """ new() |> to(recipient(user)) - |> from(sender()) - |> subject("#{instance_name()} account confirmation") + |> from(ConfigHelper.sender()) + |> subject("#{ConfigHelper.instance_name()} account confirmation") |> html_body(html_body) end def approval_pending_email(user) do html_body = """ <h3>Awaiting Approval</h3> - <p>Your account at #{instance_name()} is being reviewed by staff. You will receive another email once your account is approved.</p> + <p>Your account at #{ConfigHelper.instance_name()} is being reviewed by staff. You will receive another email once your account is approved.</p> """ new() |> to(recipient(user)) - |> from(sender()) + |> from(ConfigHelper.sender()) |> subject("Your account is awaiting approval") |> html_body(html_body) end @@ -109,14 +108,14 @@ defmodule Pleroma.Emails.UserEmail do def successful_registration_email(user) do html_body = """ <h3>Hello @#{user.nickname},</h3> - <p>Your account at #{instance_name()} has been registered successfully.</p> + <p>Your account at #{ConfigHelper.instance_name()} has been registered successfully.</p> <p>No further action is required to activate your account.</p> """ new() |> to(recipient(user)) - |> from(sender()) - |> subject("Account registered on #{instance_name()}") + |> from(ConfigHelper.sender()) + |> subject("Account registered on #{ConfigHelper.instance_name()}") |> html_body(html_body) end @@ -168,7 +167,7 @@ defmodule Pleroma.Emails.UserEmail do logo = Config.get([__MODULE__, :logo]) html_data = %{ - instance: instance_name(), + instance: ConfigHelper.instance_name(), user: user, mentions: mentions, followers: followers, @@ -185,8 +184,8 @@ defmodule Pleroma.Emails.UserEmail do new() |> to(recipient(user)) - |> from(sender()) - |> subject("Your digest from #{instance_name()}") + |> from(ConfigHelper.sender()) + |> subject("Your digest from #{ConfigHelper.instance_name()}") |> put_layout(false) |> render_body("digest.html", html_data) |> attachment(Swoosh.Attachment.new(logo_path, filename: "logo.svg", type: :inline)) @@ -238,7 +237,7 @@ defmodule Pleroma.Emails.UserEmail do new() |> to(recipient(user)) - |> from(sender()) + |> from(ConfigHelper.sender()) |> subject("Your account archive is ready") |> html_body(html_body) end diff --git a/lib/pleroma/config/helpers.ex b/lib/pleroma/helpers/config_helper.ex index 9f26c3546..755918980 100644 --- a/lib/pleroma/config/helpers.ex +++ b/lib/pleroma/helpers/config_helper.ex @@ -2,16 +2,20 @@ # Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only -defmodule Pleroma.Config.Helpers do +defmodule Pleroma.Helpers.ConfigHelper do alias Pleroma.Config - def instance_name, do: Config.get([:instance, :name]) + require Logger - defp instance_notify_email do - Config.get([:instance, :notify_email]) || Config.get([:instance, :email]) - end + @spec instance_name() :: String.t() | nil + def instance_name, do: Config.get([:instance, :name]) + @spec sender() :: {String.t() | nil, String.t() | nil} def sender do {instance_name(), instance_notify_email()} end + + defp instance_notify_email do + Config.get([:instance, :notify_email]) || Config.get([:instance, :email]) + end end diff --git a/lib/pleroma/helpers/server_ip_helper.ex b/lib/pleroma/helpers/server_ip_helper.ex new file mode 100644 index 000000000..e6a1e1cf1 --- /dev/null +++ b/lib/pleroma/helpers/server_ip_helper.ex @@ -0,0 +1,63 @@ +defmodule Pleroma.Helpers.ServerIPHelper do + @moduledoc """ + Module tries to get server real ip address from system or makes request to the remote server. + """ + + # Taken from https://ipinfo.io/bogon + @bogon_ranges [ + "0.0.0.0/8", + "10.0.0.0/8", + "100.64.0.0/10", + "127.0.0.0/8", + "127.0.53.53/32", + "169.254.0.0/16", + "172.16.0.0/12", + "192.0.0.0/24", + "192.0.2.0/24", + "192.168.0.0/16", + "198.18.0.0/15", + "198.51.100.0/24", + "203.0.113.0/24", + "224.0.0.0/4", + "240.0.0.0/4", + "255.255.255.255/32" + ] + |> Enum.map(&InetCidr.parse/1) + + @spec real_ip() :: {:ok, String.t()} | {:error, term()} + def real_ip do + if Pleroma.Config.get(:env) == :prod do + from_system() || from_remote_server() + else + {:ok, "127.0.0.1"} + end + end + + defp from_system do + with {:ok, interfaces} <- :inet.getifaddrs(), + {_name, addresses} <- + Enum.find(interfaces, fn {_name, addresses} -> + addr = Keyword.get(addresses, :addr) + + Enum.all?([:up, :broadcast, :running], &(&1 in addresses[:flags])) and + not Enum.any?(@bogon_ranges, &InetCidr.contains?(&1, addr)) + end) do + ip = + addresses + |> Keyword.get(:addr) + |> :inet.ntoa() + |> to_string() + + {:ok, ip} + else + _ -> nil + end + end + + defp from_remote_server do + with {:ok, %{body: body}} <- Pleroma.HTTP.get("https://api.myip.com") do + %{"ip" => ip} = Jason.decode!(body) + {:ok, ip} + end + end +end diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index c1aa0f716..fb3fcf30f 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -2483,4 +2483,7 @@ defmodule Pleroma.User do |> where([u], u.local == true) |> Repo.aggregate(:count) end + + @spec email_regex() :: Regex.t() + def email_regex, do: @email_regex end diff --git a/lib/pleroma/user/welcome_email.ex b/lib/pleroma/user/welcome_email.ex index 295c1acc7..2ca6cb474 100644 --- a/lib/pleroma/user/welcome_email.ex +++ b/lib/pleroma/user/welcome_email.ex @@ -9,10 +9,9 @@ defmodule Pleroma.User.WelcomeEmail do alias Pleroma.Config alias Pleroma.Emails + alias Pleroma.Helpers.ConfigHelper alias Pleroma.User - import Pleroma.Config.Helpers, only: [instance_name: 0] - @spec enabled?() :: boolean() def enabled?, do: Config.get([:welcome, :email, :enabled], false) @@ -24,7 +23,7 @@ defmodule Pleroma.User.WelcomeEmail do end defp email_options(user) do - bindings = [user: user, instance_name: instance_name()] + bindings = [user: user, instance_name: ConfigHelper.instance_name()] %{} |> add_sender(Config.get([:welcome, :email, :sender], nil)) @@ -45,7 +44,7 @@ defmodule Pleroma.User.WelcomeEmail do end defp add_sender(opts, sender) when is_binary(sender) do - add_sender(opts, {instance_name(), sender}) + add_sender(opts, {ConfigHelper.instance_name(), sender}) end defp add_sender(opts, _), do: opts diff --git a/lib/pleroma/web/rich_media/helpers.ex b/lib/pleroma/web/rich_media/helpers.ex index 566fc8c8a..5d83a3f89 100644 --- a/lib/pleroma/web/rich_media/helpers.ex +++ b/lib/pleroma/web/rich_media/helpers.ex @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright _ 2017-2020 Pleroma Authors <https://pleroma.social/> +# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/> # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.RichMedia.Helpers do |