Handle black name fields on incoming users.
[akkoma] / lib / pleroma / user.ex
index 47aefaebabc178f3621ddf90995d2938855a246f..ab29fe6f452f352a3a83d6a325cb4cf724d9aaff 100644 (file)
@@ -150,11 +150,12 @@ defmodule Pleroma.User do
 
   def follow(%User{} = follower, %User{info: info} = followed) do
     ap_followers = followed.follower_address
+
     if following?(follower, followed) or info["deactivated"] do
       {:error,
        "Could not follow user: #{followed.nickname} is already on your list."}
     else
-      if !followed.local && follower.local do
+      if !followed.local && follower.local && !ap_enabled?(followed) do
         Websub.subscribe(follower, followed)
       end
 
@@ -383,18 +384,48 @@ defmodule Pleroma.User do
     :ok
   end
 
+  def get_or_fetch_by_ap_id(ap_id) do
+    if user = get_by_ap_id(ap_id) do
+      user
+    else
+      with {:ok, user} <- ActivityPub.make_user_from_ap_id(ap_id) do
+        user
+      end
+    end
+  end
+
+  # AP style
+  def public_key_from_info(%{"source_data" => %{"publicKey" => %{"publicKeyPem" => public_key_pem}}}) do
+     key = :public_key.pem_decode(public_key_pem)
+     |> hd()
+     |> :public_key.pem_entry_decode()
+
+     {:ok, key}
+  end
+
+  # OStatus Magic Key
+  def public_key_from_info(%{"magic_key" => magic_key}) do
+    {:ok, Pleroma.Web.Salmon.decode_key(magic_key)}
+  end
+
   def get_public_key_for_ap_id(ap_id) do
-    with %User{} = user <- get_cached_by_ap_id(ap_id),
-         %{info: %{"magic_key" => magic_key}} <- user,
-         public_key <- Pleroma.Web.Salmon.decode_key(magic_key) do
+    with %User{} = user <- get_or_fetch_by_ap_id(ap_id),
+         {:ok, public_key} <- public_key_from_info(user.info) do
       {:ok, public_key}
     else
       _ -> :error
     end
   end
 
+  defp blank?(""), do: nil
+  defp blank?(n), do: n
+
   def insert_or_update_user(data) do
+    data = data
+    |> Map.put(:name, blank?(data[:name]) || data[:nickname])
     cs = User.remote_user_creation(data)
     Repo.insert(cs, on_conflict: :replace_all, conflict_target: :nickname)
   end
+
+  def ap_enabled?(%User{info: %{"ap_enabled" => ap}}), do: ap
 end