@@ -356,4 +356,14 @@ defmodule Pleroma.Activity do | |||
actor = user_actor(activity) | |||
activity.id in actor.pinned_activities | |||
end | |||
@spec get_by_object_ap_id_with_object(String.t()) :: t() | nil | |||
def get_by_object_ap_id_with_object(ap_id) when is_binary(ap_id) do | |||
ap_id | |||
|> Queries.by_object_id() | |||
|> with_preloaded_object() | |||
|> Repo.one() | |||
end | |||
def get_by_object_ap_id_with_object(_), do: nil | |||
end |
@@ -710,6 +710,22 @@ defmodule Pleroma.Web.ActivityPub.Utils do | |||
Enum.map(statuses || [], &build_flag_object/1) | |||
end | |||
defp build_flag_object(%Activity{} = activity) do | |||
activity_actor = User.get_by_ap_id(activity.object.data["actor"]) | |||
%{ | |||
"type" => "Note", | |||
"id" => activity.data["id"], | |||
"content" => activity.object.data["content"], | |||
"published" => activity.object.data["published"], | |||
"actor" => | |||
AccountView.render( | |||
"show.json", | |||
%{user: activity_actor, skip_visibility_check: true} | |||
) | |||
} | |||
end | |||
defp build_flag_object(act) when is_map(act) or is_binary(act) do | |||
id = | |||
case act do | |||
@@ -720,22 +736,14 @@ defmodule Pleroma.Web.ActivityPub.Utils do | |||
case Activity.get_by_ap_id_with_object(id) do | |||
%Activity{} = activity -> | |||
activity_actor = User.get_by_ap_id(activity.object.data["actor"]) | |||
%{ | |||
"type" => "Note", | |||
"id" => activity.data["id"], | |||
"content" => activity.object.data["content"], | |||
"published" => activity.object.data["published"], | |||
"actor" => | |||
AccountView.render( | |||
"show.json", | |||
%{user: activity_actor, skip_visibility_check: true} | |||
) | |||
} | |||
_ -> | |||
%{"id" => id, "deleted" => true} | |||
build_flag_object(activity) | |||
nil -> | |||
if activity = Activity.get_by_object_ap_id_with_object(id) do | |||
build_flag_object(activity) | |||
else | |||
%{"id" => id, "deleted" => true} | |||
end | |||
end | |||
end | |||
@@ -0,0 +1,67 @@ | |||
{ | |||
"@context": [ | |||
"https://www.w3.org/ns/activitystreams", | |||
"https://w3id.org/security/v1", | |||
{ | |||
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers", | |||
"toot": "http://joinmastodon.org/ns#", | |||
"featured": { | |||
"@id": "toot:featured", | |||
"@type": "@id" | |||
}, | |||
"alsoKnownAs": { | |||
"@id": "as:alsoKnownAs", | |||
"@type": "@id" | |||
}, | |||
"movedTo": { | |||
"@id": "as:movedTo", | |||
"@type": "@id" | |||
}, | |||
"schema": "http://schema.org#", | |||
"PropertyValue": "schema:PropertyValue", | |||
"value": "schema:value", | |||
"IdentityProof": "toot:IdentityProof", | |||
"discoverable": "toot:discoverable", | |||
"Device": "toot:Device", | |||
"Ed25519Signature": "toot:Ed25519Signature", | |||
"Ed25519Key": "toot:Ed25519Key", | |||
"Curve25519Key": "toot:Curve25519Key", | |||
"EncryptedMessage": "toot:EncryptedMessage", | |||
"publicKeyBase64": "toot:publicKeyBase64", | |||
"deviceId": "toot:deviceId", | |||
"claim": { | |||
"@type": "@id", | |||
"@id": "toot:claim" | |||
}, | |||
"fingerprintKey": { | |||
"@type": "@id", | |||
"@id": "toot:fingerprintKey" | |||
}, | |||
"identityKey": { | |||
"@type": "@id", | |||
"@id": "toot:identityKey" | |||
}, | |||
"devices": { | |||
"@type": "@id", | |||
"@id": "toot:devices" | |||
}, | |||
"messageFranking": "toot:messageFranking", | |||
"messageType": "toot:messageType", | |||
"cipherText": "toot:cipherText" | |||
} | |||
], | |||
"id": "https://{{DOMAIN}}/actor", | |||
"type": "Application", | |||
"inbox": "https://{{DOMAIN}}/actor/inbox", | |||
"preferredUsername": "{{DOMAIN}}", | |||
"url": "https://{{DOMAIN}}/about/more?instance_actor=true", | |||
"manuallyApprovesFollowers": true, | |||
"publicKey": { | |||
"id": "https://{{DOMAIN}}/actor#main-key", | |||
"owner": "https://{{DOMAIN}}/actor", | |||
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAA0CA08AMIIBCgKCAQEAyi2T2FFZJgRPY+96YQrn\n6J6eF2P60J+nz+/pRc/acv/Nx+NLxxPyXby0F2s60MV7uALRQbBBnf7oNKCd/T4S\nvbr7UXMCWTdaJBpYubMKWT9uBlaUUkUfqL+WTV+IQnlcKtssQ4+AwrAKAZXza8ws\nZypevOsLHzayyEzztmm1KQC9GCUOITCLf7Q6qEhy8z/HuqLBEC0Own0pD7QsbfcS\no1peuZY7g1E/jJ9HR9GqJccMaR0H28KmJ7tT1Yzlyf5uZMRIdPxsoMR9sGLjR2B8\noegSwaf9SogR3ScP395Tt/9Ud1VVzuhpoS8Uy7jKSs+3CuLJsEGoMrib8VyOwadS\n9wIDAQAB\n-----END PUBLIC KEY-----\n" | |||
}, | |||
"endpoints": { | |||
"sharedInbox": "https://{{DOMAIN}}/inbox" | |||
} | |||
} |
@@ -874,6 +874,65 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do | |||
html_body: ~r/Reported Account:/i | |||
) | |||
end | |||
test "forwarded report from mastodon", %{conn: conn} do | |||
admin = insert(:user, is_admin: true) | |||
actor = insert(:user, local: false) | |||
remote_domain = URI.parse(actor.ap_id).host | |||
remote_actor = "https://#{remote_domain}/actor" | |||
reported_user = insert(:user) | |||
note = insert(:note_activity, user: reported_user) | |||
mock_json_body = | |||
"test/fixtures/mastodon/application_actor.json" | |||
|> File.read!() | |||
|> String.replace("{{DOMAIN}}", remote_domain) | |||
Tesla.Mock.mock(fn %{url: ^remote_actor} -> | |||
%Tesla.Env{ | |||
status: 200, | |||
body: mock_json_body, | |||
headers: [{"content-type", "application/activity+json"}] | |||
} | |||
end) | |||
data = %{ | |||
"@context" => "https://www.w3.org/ns/activitystreams", | |||
"actor" => remote_actor, | |||
"content" => "test report", | |||
"id" => "https://#{remote_domain}/e3b12fd1-948c-446e-b93b-a5e67edbe1d8", | |||
"nickname" => reported_user.nickname, | |||
"object" => [ | |||
reported_user.ap_id, | |||
note.data["object"] | |||
], | |||
"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 | |||
flag_activity = "Flag" |> Pleroma.Activity.Queries.by_type() |> Pleroma.Repo.one() | |||
reported_user_ap_id = reported_user.ap_id | |||
[^reported_user_ap_id, flag_data] = flag_activity.data["object"] | |||
Enum.each(~w(actor content id published type), &Map.has_key?(flag_data, &1)) | |||
ObanHelpers.perform_all() | |||
Swoosh.TestAssertions.assert_email_sent( | |||
to: {admin.name, admin.email}, | |||
html_body: ~r/#{note.data["object"]}/i | |||
) | |||
end | |||
end | |||
describe "GET /users/:nickname/outbox" do | |||