fix for forwarded reports
authorAlexander Strizhakov <alex.strizhakov@gmail.com>
Mon, 16 Nov 2020 16:22:32 +0000 (19:22 +0300)
committerAlexander Strizhakov <alex.strizhakov@gmail.com>
Thu, 19 Nov 2020 06:53:13 +0000 (09:53 +0300)
lib/pleroma/emails/admin_email.ex
lib/pleroma/web/activity_pub/activity_pub.ex
test/pleroma/web/activity_pub/activity_pub_controller_test.exs
test/pleroma/web/activity_pub/activity_pub_test.exs
test/support/factory.ex

index 02274554fe285414a4b63ac631a177d397296f7c..d5757c12a6403e6b7d16a8c08396a9643703f0bd 100644 (file)
@@ -48,6 +48,9 @@ defmodule Pleroma.Emails.AdminEmail do
               status_url = Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, id)
               "<li><a href=\"#{status_url}\">#{status_url}</li>"
 
+            %{"id" => id} when is_binary(id) ->
+              "<li><a href=\"#{id}\">#{id}</li>"
+
             id when is_binary(id) ->
               "<li><a href=\"#{id}\">#{id}</li>"
           end)
index 35f71b7ae3df78f247c05c1bc48bff49d232d4aa..8f3ce1343f1adef2ff64dc48277d93c81f6caf28 100644 (file)
@@ -332,15 +332,21 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
   end
 
   @spec flag(map()) :: {:ok, Activity.t()} | {:error, any()}
-  def flag(
-        %{
-          actor: actor,
-          context: _context,
-          account: account,
-          statuses: statuses,
-          content: content
-        } = params
-      ) do
+  def flag(params) do
+    with {:ok, result} <- Repo.transaction(fn -> do_flag(params) end) do
+      result
+    end
+  end
+
+  defp do_flag(
+         %{
+           actor: actor,
+           context: _context,
+           account: account,
+           statuses: statuses,
+           content: content
+         } = params
+       ) do
     # only accept false as false value
     local = !(params[:local] == false)
     forward = !(params[:forward] == false)
@@ -358,7 +364,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
          {:ok, activity} <- insert(flag_data, local),
          {:ok, stripped_activity} <- strip_report_status_data(activity),
          _ <- notify_and_stream(activity),
-         :ok <- maybe_federate(stripped_activity) do
+         :ok <-
+           maybe_federate(stripped_activity) do
       User.all_superusers()
       |> Enum.filter(fn user -> not is_nil(user.email) end)
       |> Enum.each(fn superuser ->
@@ -368,6 +375,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
       end)
 
       {:ok, activity}
+    else
+      {:error, error} -> Repo.rollback(error)
     end
   end
 
@@ -791,10 +800,10 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
       where:
         fragment(
           """
-          ?->>'type' != 'Create'     -- This isn't a Create      
+          ?->>'type' != 'Create'     -- This isn't a Create
           OR ?->>'inReplyTo' is null -- this isn't a reply
-          OR ? && array_remove(?, ?) -- The recipient is us or one of our friends, 
-                                     -- unless they are the author (because authors 
+          OR ? && array_remove(?, ?) -- The recipient is us or one of our friends,
+                                     -- unless they are the author (because authors
                                      -- are also part of the recipients). This leads
                                      -- to a bug that self-replies by friends won't
                                      -- show up.
index 31e48f87f6f9a49c3bb3826ebcbbcedc07f4f4d1..49eeaeaff000f74b35a88f38e8e5b6455893c138 100644 (file)
@@ -799,6 +799,82 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
 
       assert json_response(ret_conn, 200)
     end
+
+    test "forwarded report", %{conn: conn} do
+      admin = insert(:user, is_admin: true)
+      actor = insert(:user, local: false)
+      remote_domain = URI.parse(actor.ap_id).host
+      reported_user = insert(:user)
+
+      note = insert(:note_activity, user: reported_user)
+
+      data = %{
+        "@context" => [
+          "https://www.w3.org/ns/activitystreams",
+          "https://#{remote_domain}/schemas/litepub-0.1.jsonld",
+          %{
+            "@language" => "und"
+          }
+        ],
+        "actor" => actor.ap_id,
+        "cc" => [
+          reported_user.ap_id
+        ],
+        "content" => "test",
+        "context" => "context",
+        "id" => "http://#{remote_domain}/activities/02be56cf-35e3-46b4-b2c6-47ae08dfee9e",
+        "nickname" => reported_user.nickname,
+        "object" => [
+          reported_user.ap_id,
+          %{
+            "actor" => %{
+              "actor_type" => "Person",
+              "approval_pending" => false,
+              "avatar" => "",
+              "confirmation_pending" => false,
+              "deactivated" => false,
+              "display_name" => "test user",
+              "id" => reported_user.id,
+              "local" => false,
+              "nickname" => reported_user.nickname,
+              "registration_reason" => nil,
+              "roles" => %{
+                "admin" => false,
+                "moderator" => false
+              },
+              "tags" => [],
+              "url" => reported_user.ap_id
+            },
+            "content" => "",
+            "id" => note.data["id"],
+            "published" => note.data["published"],
+            "type" => "Note"
+          }
+        ],
+        "published" => note.data["published"],
+        "state" => "open",
+        "to" => [],
+        "type" => "Flag"
+      }
+
+      conn
+      |> assign(:valid_signature, true)
+      |> put_req_header("content-type", "application/activity+json")
+      |> post("/users/#{reported_user.nickname}/inbox", data)
+      |> json_response(200)
+
+      ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
+
+      assert Pleroma.Repo.aggregate(Activity, :count, :id) == 2
+
+      ObanHelpers.perform_all()
+
+      Swoosh.TestAssertions.assert_email_sent(
+        to: {admin.name, admin.email},
+        html_body: ~r/Reported Account:/i
+      )
+
+    end
   end
 
   describe "GET /users/:nickname/outbox" do
index 3eeb0f7358e9df94baf422a9bbc12ee09a2676fc..6cc25dd9e73a7561dca9e6df28e0be12db97cd72 100644 (file)
@@ -1298,6 +1298,31 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
 
       assert_called(Utils.maybe_federate(%{activity | data: new_data}))
     end
+
+    test_with_mock "reverts on error",
+                   %{
+                     reporter: reporter,
+                     context: context,
+                     target_account: target_account,
+                     reported_activity: reported_activity,
+                     content: content
+                   },
+                   Utils,
+                   [:passthrough],
+                   maybe_federate: fn _ -> {:error, :reverted} end do
+      assert {:error, :reverted} =
+               ActivityPub.flag(%{
+                 actor: reporter,
+                 context: context,
+                 account: target_account,
+                 statuses: [reported_activity],
+                 content: content
+               })
+
+      assert Repo.aggregate(Activity, :count, :id) == 1
+      assert Repo.aggregate(Object, :count, :id) == 2
+      assert Repo.aggregate(Notification, :count, :id) == 0
+    end
   end
 
   test "fetch_activities/2 returns activities addressed to a list " do
index 80b882ee413d5b4a6de7f7dcf3723428eacac4ec..8eb07dc3c19e4f54d24f5372a8a46a58147a29d3 100644 (file)
@@ -24,7 +24,7 @@ defmodule Pleroma.Factory do
     }
   end
 
-  def user_factory do
+  def user_factory(attrs \\ %{}) do
     user = %User{
       name: sequence(:name, &"Test ใƒ†ใ‚นใƒˆ User #{&1}"),
       email: sequence(:email, &"user#{&1}@example.com"),
@@ -39,13 +39,29 @@ defmodule Pleroma.Factory do
       ap_enabled: true
     }
 
-    %{
-      user
-      | ap_id: User.ap_id(user),
-        follower_address: User.ap_followers(user),
-        following_address: User.ap_following(user),
-        raw_bio: user.bio
-    }
+    urls =
+      if attrs[:local] == false do
+        base_domain = Enum.random(["domain1.com", "domain2.com", "domain3.com"])
+
+        ap_id = "https://#{base_domain}/users/#{user.nickname}"
+
+        %{
+          ap_id: ap_id,
+          follower_address: ap_id <> "/followers",
+          following_address: ap_id <> "/following"
+        }
+      else
+        %{
+          ap_id: User.ap_id(user),
+          follower_address: User.ap_followers(user),
+          following_address: User.ap_following(user)
+        }
+      end
+
+    user
+    |> Map.put(:raw_bio, user.bio)
+    |> Map.merge(urls)
+    |> merge_attributes(attrs)
   end
 
   def user_relationship_factory(attrs \\ %{}) do