Merge branch 'support/issue_480' into 'develop'
[akkoma] / lib / pleroma / user.ex
index a38ead81af7d95bea5aff600bcaba39b461daf6d..41d6e9dc6a3c71449d6c8b7a8645fb96a2b6197b 100644 (file)
@@ -1,3 +1,7 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
 defmodule Pleroma.User do
   use Ecto.Schema
 
@@ -38,7 +42,20 @@ defmodule Pleroma.User do
     timestamps()
   end
 
-  def auth_active?(user), do: user.info && !user.info.confirmation_pending
+  def auth_active?(%User{} = user) do
+    (user.info && !user.info.confirmation_pending) ||
+      !Pleroma.Config.get([:instance, :account_activation_required])
+  end
+
+  def remote_or_auth_active?(%User{} = user), do: !user.local || auth_active?(user)
+
+  def visible_for?(%User{} = user, for_user \\ nil) do
+    User.remote_or_auth_active?(user) || (for_user && for_user.id == user.id) ||
+      User.superuser?(for_user)
+  end
+
+  def superuser?(nil), do: false
+  def superuser?(%User{} = user), do: user.info && User.Info.superuser?(user.info)
 
   def avatar_url(user) do
     case user.avatar do
@@ -80,6 +97,7 @@ defmodule Pleroma.User do
       note_count: user.info.note_count,
       follower_count: user.info.follower_count,
       locked: user.info.locked,
+      confirmation_pending: user.info.confirmation_pending,
       default_scope: user.info.default_scope
     }
   end
@@ -170,7 +188,16 @@ defmodule Pleroma.User do
     update_and_set_cache(password_update_changeset(user, data))
   end
 
-  def register_changeset(struct, params \\ %{}) do
+  def register_changeset(struct, params \\ %{}, opts \\ []) do
+    confirmation_status =
+      if opts[:confirmed] || !Pleroma.Config.get([:instance, :account_activation_required]) do
+        :confirmed
+      else
+        :unconfirmed
+      end
+
+    info_change = User.Info.confirmation_changeset(%User.Info{}, confirmation_status)
+
     changeset =
       struct
       |> cast(params, [:bio, :email, :name, :nickname, :password, :password_confirmation])
@@ -178,11 +205,12 @@ defmodule Pleroma.User do
       |> validate_confirmation(:password)
       |> unique_constraint(:email)
       |> unique_constraint(:nickname)
+      |> validate_exclusion(:nickname, Pleroma.Config.get([Pleroma.User, :restricted_nicknames]))
       |> validate_format(:nickname, local_nickname_regex())
       |> validate_format(:email, @email_regex)
       |> validate_length(:bio, max: 1000)
       |> validate_length(:name, min: 1, max: 100)
-      |> put_change(:info, %Pleroma.User.Info{})
+      |> put_change(:info, info_change)
 
     if changeset.valid? do
       hashed = Pbkdf2.hashpwsalt(changeset.changes[:password])
@@ -199,6 +227,25 @@ defmodule Pleroma.User do
     end
   end
 
+  @doc "Inserts provided changeset, performs post-registration actions (confirmation email sending etc.)"
+  def register(%Ecto.Changeset{} = changeset) do
+    with {:ok, user} <- Repo.insert(changeset),
+         {:ok, _} = try_send_confirmation_email(user) do
+      {:ok, user}
+    end
+  end
+
+  def try_send_confirmation_email(%User{} = user) do
+    if user.info.confirmation_pending &&
+         Pleroma.Config.get([:instance, :account_activation_required]) do
+      user
+      |> Pleroma.UserEmail.account_confirmation_email()
+      |> Pleroma.Mailer.deliver()
+    else
+      {:ok, :noop}
+    end
+  end
+
   def needs_update?(%User{local: true}), do: false
 
   def needs_update?(%User{local: false, last_refreshed_at: nil}), do: true
@@ -366,10 +413,6 @@ defmodule Pleroma.User do
     end
   end
 
-  def get_by_confirmation_token(token) do
-    Repo.one(from(u in User, where: fragment("? ->> 'confirmation_token' = ?", u.info, ^token)))
-  end
-
   def get_followers_query(%User{id: id, follower_address: follower_address}) do
     from(
       u in User,