ostatus: we need to include the original author of a message as a mention
[akkoma] / lib / pleroma / user.ex
index 828370cabb43df0e61d206fddd87b292f9fdc8a2..856f27e1013a160701c0ef7a3991c4cd5e5b66fc 100644 (file)
@@ -197,6 +197,14 @@ defmodule Pleroma.User do
     end
   end
 
+  def maybe_follow(%User{} = follower, %User{info: info} = followed) do
+    if not following?(follower, followed) do
+      follow(follower, followed)
+    else
+      {:ok, follower}
+    end
+  end
+
   def follow(%User{} = follower, %User{info: info} = followed) do
     ap_followers = followed.follower_address
 
@@ -252,6 +260,10 @@ defmodule Pleroma.User do
     Enum.member?(follower.following, followed.follower_address)
   end
 
+  def locked?(%User{} = user) do
+    user.info["locked"] || false
+  end
+
   def get_by_ap_id(ap_id) do
     Repo.get_by(User, ap_id: ap_id)
   end
@@ -349,6 +361,40 @@ defmodule Pleroma.User do
     {:ok, Repo.all(q)}
   end
 
+  def get_follow_requests_query(%User{} = user) do
+    from(
+      a in Activity,
+      where:
+        fragment(
+          "? ->> 'type' = 'Follow'",
+          a.data
+        ),
+      where:
+        fragment(
+          "? ->> 'state' = 'pending'",
+          a.data
+        ),
+      where:
+        fragment(
+          "? @> ?",
+          a.data,
+          ^%{"object" => user.ap_id}
+        )
+    )
+  end
+
+  def get_follow_requests(%User{} = user) do
+    q = get_follow_requests_query(user)
+    reqs = Repo.all(q)
+
+    users =
+      Enum.map(reqs, fn req -> req.actor end)
+      |> Enum.uniq()
+      |> Enum.map(fn ap_id -> get_by_ap_id(ap_id) end)
+
+    {:ok, users}
+  end
+
   def increase_note_count(%User{} = user) do
     note_count = (user.info["note_count"] || 0) + 1
     new_info = Map.put(user.info, "note_count", note_count)
@@ -403,13 +449,29 @@ defmodule Pleroma.User do
     update_and_set_cache(cs)
   end
 
+  def get_notified_from_activity_query(to) do
+    from(
+      u in User,
+      where: u.ap_id in ^to,
+      where: u.local == true
+    )
+  end
+
+  def get_notified_from_activity(%Activity{recipients: to, data: %{"type" => "Announce"} = data}) do
+    object = Object.get_by_ap_id(data["object"])
+
+    # ensure that the actor who published the announced object appears only once
+    to =
+      (to ++ [object.data["actor"]])
+      |> Enum.uniq()
+
+    query = get_notified_from_activity_query(to)
+
+    Repo.all(query)
+  end
+
   def get_notified_from_activity(%Activity{recipients: to}) do
-    query =
-      from(
-        u in User,
-        where: u.ap_id in ^to,
-        where: u.local == true
-      )
+    query = get_notified_from_activity_query(to)
 
     Repo.all(query)
   end
@@ -479,7 +541,31 @@ defmodule Pleroma.User do
 
   def blocks?(user, %{ap_id: ap_id}) do
     blocks = user.info["blocks"] || []
-    Enum.member?(blocks, ap_id)
+    domain_blocks = user.info["domain_blocks"] || []
+    %{host: host} = URI.parse(ap_id)
+
+    Enum.member?(blocks, ap_id) ||
+      Enum.any?(domain_blocks, fn domain ->
+        host == domain
+      end)
+  end
+
+  def block_domain(user, domain) do
+    domain_blocks = user.info["domain_blocks"] || []
+    new_blocks = Enum.uniq([domain | domain_blocks])
+    new_info = Map.put(user.info, "domain_blocks", new_blocks)
+
+    cs = User.info_changeset(user, %{info: new_info})
+    update_and_set_cache(cs)
+  end
+
+  def unblock_domain(user, domain) do
+    blocks = user.info["domain_blocks"] || []
+    new_blocks = List.delete(blocks, domain)
+    new_info = Map.put(user.info, "domain_blocks", new_blocks)
+
+    cs = User.info_changeset(user, %{info: new_info})
+    update_and_set_cache(cs)
   end
 
   def local_user_query() do