Change user.confirmation_pending field to user.is_confirmed
[akkoma] / lib / pleroma / user.ex
index 6c1b77d9ffa0a353c0f6ad9cd2780b45c7daab97..04ce1768d0a707db8209b41d47646caa400871c0 100644 (file)
@@ -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.User do
@@ -110,7 +110,7 @@ defmodule Pleroma.User do
     field(:follower_count, :integer, default: 0)
     field(:following_count, :integer, default: 0)
     field(:is_locked, :boolean, default: false)
-    field(:confirmation_pending, :boolean, default: false)
+    field(:is_confirmed, :boolean, default: true)
     field(:password_reset_pending, :boolean, default: false)
     field(:approval_pending, :boolean, default: false)
     field(:registration_reason, :string, default: nil)
@@ -142,7 +142,7 @@ defmodule Pleroma.User do
     field(:allow_following_move, :boolean, default: true)
     field(:skip_thread_containment, :boolean, default: false)
     field(:actor_type, :string, default: "Person")
-    field(:also_known_as, {:array, :string}, default: [])
+    field(:also_known_as, {:array, ObjectValidators.ObjectID}, default: [])
     field(:inbox, :string)
     field(:shared_inbox, :string)
     field(:accepts_chat_messages, :boolean, default: nil)
@@ -290,7 +290,7 @@ defmodule Pleroma.User do
   def account_status(%User{password_reset_pending: true}), do: :password_reset_pending
   def account_status(%User{local: true, approval_pending: true}), do: :approval_pending
 
-  def account_status(%User{local: true, confirmation_pending: true}) do
+  def account_status(%User{local: true, is_confirmed: false}) do
     if Config.get([:instance, :account_activation_required]) do
       :confirmation_pending
     else
@@ -515,6 +515,7 @@ defmodule Pleroma.User do
         :hide_follows_count,
         :hide_favorites,
         :allow_following_move,
+        :also_known_as,
         :background,
         :show_role,
         :skip_thread_containment,
@@ -523,7 +524,6 @@ defmodule Pleroma.User do
         :pleroma_settings_store,
         :is_discoverable,
         :actor_type,
-        :also_known_as,
         :accepts_chat_messages
       ]
     )
@@ -808,18 +808,50 @@ defmodule Pleroma.User do
     end
   end
 
-  def post_register_action(%User{} = user) do
+  def post_register_action(%User{is_confirmed: false} = user) do
+    with {:ok, _} <- try_send_confirmation_email(user) do
+      {:ok, user}
+    end
+  end
+
+  def post_register_action(%User{approval_pending: true} = user) do
+    with {:ok, _} <- send_user_approval_email(user),
+         {:ok, _} <- send_admin_approval_emails(user) do
+      {:ok, user}
+    end
+  end
+
+  def post_register_action(%User{approval_pending: false, is_confirmed: true} = user) do
     with {:ok, user} <- autofollow_users(user),
          {:ok, _} <- autofollowing_users(user),
          {:ok, user} <- set_cache(user),
          {:ok, _} <- send_welcome_email(user),
          {:ok, _} <- send_welcome_message(user),
-         {:ok, _} <- send_welcome_chat_message(user),
-         {:ok, _} <- try_send_confirmation_email(user) do
+         {:ok, _} <- send_welcome_chat_message(user) do
       {:ok, user}
     end
   end
 
+  defp send_user_approval_email(user) do
+    user
+    |> Pleroma.Emails.UserEmail.approval_pending_email()
+    |> Pleroma.Emails.Mailer.deliver_async()
+
+    {:ok, :enqueued}
+  end
+
+  defp send_admin_approval_emails(user) do
+    all_superusers()
+    |> Enum.filter(fn user -> not is_nil(user.email) end)
+    |> Enum.each(fn superuser ->
+      superuser
+      |> Pleroma.Emails.AdminEmail.new_unapproved_registration(user)
+      |> Pleroma.Emails.Mailer.deliver_async()
+    end)
+
+    {:ok, :enqueued}
+  end
+
   def send_welcome_message(user) do
     if User.WelcomeMessage.enabled?() do
       User.WelcomeMessage.post_message(user)
@@ -850,7 +882,7 @@ defmodule Pleroma.User do
   def send_welcome_email(_), do: {:ok, :noop}
 
   @spec try_send_confirmation_email(User.t()) :: {:ok, :enqueued | :noop}
-  def try_send_confirmation_email(%User{confirmation_pending: true, email: email} = user)
+  def try_send_confirmation_email(%User{is_confirmed: false, email: email} = user)
       when is_binary(email) do
     if Config.get([:instance, :account_activation_required]) do
       send_confirmation_email(user)
@@ -1091,7 +1123,7 @@ defmodule Pleroma.User do
   def get_cached_by_nickname(nickname) do
     key = "nickname:#{nickname}"
 
-    @cachex.fetch!(:user_cache, key, fn ->
+    @cachex.fetch!(:user_cache, key, fn ->
       case get_or_fetch_by_nickname(nickname) do
         {:ok, user} -> {:commit, user}
         {:error, _error} -> {:ignore, nil}
@@ -1592,11 +1624,34 @@ defmodule Pleroma.User do
     end)
   end
 
-  def approve(%User{} = user) do
-    change(user, approval_pending: false)
-    |> update_and_set_cache()
+  def approve(%User{approval_pending: true} = user) do
+    with chg <- change(user, approval_pending: false),
+         {:ok, user} <- update_and_set_cache(chg) do
+      post_register_action(user)
+      {:ok, user}
+    end
   end
 
+  def approve(%User{} = user), do: {:ok, user}
+
+  def confirm(users) when is_list(users) do
+    Repo.transaction(fn ->
+      Enum.map(users, fn user ->
+        with {:ok, user} <- confirm(user), do: user
+      end)
+    end)
+  end
+
+  def confirm(%User{is_confirmed: false} = user) do
+    with chg <- confirmation_changeset(user, need_confirmation: false),
+         {:ok, user} <- update_and_set_cache(chg) do
+      post_register_action(user)
+      {:ok, user}
+    end
+  end
+
+  def confirm(%User{} = user), do: {:ok, user}
+
   def update_notification_settings(%User{} = user, settings) do
     user
     |> cast(%{notification_settings: settings}, [])
@@ -1627,7 +1682,7 @@ defmodule Pleroma.User do
       follower_count: 0,
       following_count: 0,
       is_locked: false,
-      confirmation_pending: false,
+      is_confirmed: true,
       password_reset_pending: false,
       approval_pending: false,
       registration_reason: nil,
@@ -2083,18 +2138,6 @@ defmodule Pleroma.User do
     updated_user
   end
 
-  @spec toggle_confirmation(User.t()) :: {:ok, User.t()} | {:error, Changeset.t()}
-  def toggle_confirmation(%User{} = user) do
-    user
-    |> confirmation_changeset(need_confirmation: !user.confirmation_pending)
-    |> update_and_set_cache()
-  end
-
-  @spec toggle_confirmation([User.t()]) :: [{:ok, User.t()} | {:error, Changeset.t()}]
-  def toggle_confirmation(users) do
-    Enum.map(users, &toggle_confirmation/1)
-  end
-
   @spec need_confirmation(User.t(), boolean()) :: {:ok, User.t()} | {:error, Changeset.t()}
   def need_confirmation(%User{} = user, bool) do
     user
@@ -2144,7 +2187,7 @@ defmodule Pleroma.User do
   defp put_password_hash(
          %Ecto.Changeset{valid?: true, changes: %{password: password}} = changeset
        ) do
-    change(changeset, password_hash: Pbkdf2.hash_pwd_salt(password))
+    change(changeset, password_hash: Pleroma.Password.Pbkdf2.hash_pwd_salt(password))
   end
 
   defp put_password_hash(changeset), do: changeset
@@ -2270,17 +2313,17 @@ defmodule Pleroma.User do
     params =
       if need_confirmation? do
         %{
-          confirmation_pending: true,
+          is_confirmed: false,
           confirmation_token: :crypto.strong_rand_bytes(32) |> Base.url_encode64()
         }
       else
         %{
-          confirmation_pending: false,
+          is_confirmed: true,
           confirmation_token: nil
         }
       end
 
-    cast(user, params, [:confirmation_pending, :confirmation_token])
+    cast(user, params, [:is_confirmed, :confirmation_token])
   end
 
   @spec approval_changeset(User.t(), keyword()) :: Changeset.t()