Introduce relay

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel
2019-07-30 16:40:59 +02:00
parent 56467301a1
commit c51115bdbe
54 changed files with 3100 additions and 1038 deletions

View File

@@ -0,0 +1,34 @@
{
"type": "Accept",
"signature": {
"type": "RsaSignature2017",
"signatureValue": "rBzK4Kqhd4g7HDS8WE5oRbWQb2R+HF/6awbUuMWhgru/xCODT0SJWSri0qWqEO4fPcpoUyz2d25cw6o+iy9wiozQb3hQNnu69AR+H5Mytc06+g10KCHexbGhbAEAw/7IzmeXELHUbaqeduaDIbdt1zw4RkwLXdqgQcGXTJ6ND1wM3WMHXQCK1m0flasIXFoBxpliPAGiElV8s0+Ltuh562GvflG3kB3WO+j+NaR0ZfG5G9N88xMj9UQlCKit5gpAE5p6syUsCU2WGBHywTumv73i3OVTIFfq+P9AdMsRuzw1r7zoKEsthW4aOzLQDi01ZjvdBz8zH6JnjDU7SMN/Ig==",
"creator": "http://mastodon.example.org/users/admin#main-key",
"created": "2018-02-17T14:36:41Z"
},
"object": {
"type": "Follow",
"object": "http://mobilizon.test/@thomas0",
"actor": "http://mobilizon.test/@thomas1",
"id": "http://mobilizon.test/follows/fdfds"
},
"nickname": "lain",
"id": "\"id\": \"http://mobilizon.test/accepts/follows/fdfds",
"actor": "http://mobilizon.test/@thomas0",
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",
{
"toot": "http://joinmastodon.org/ns#",
"sensitive": "as:sensitive",
"ostatus": "http://ostatus.org#",
"movedTo": "as:movedTo",
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
"inReplyToAtomUri": "ostatus:inReplyToAtomUri",
"conversation": "ostatus:conversation",
"atomUri": "ostatus:atomUri",
"Hashtag": "as:Hashtag",
"Emoji": "toot:Emoji"
}
]
}

View File

@@ -10,14 +10,14 @@
"created": "2018-02-17T19:39:15Z"
},
"published": "2018-02-17T19:39:15Z",
"object": "https://social.tcit.fr/@tcit/101188891162897047",
"id": "https://social.tcit.fr/users/tcit/statuses/101188891162897047/activity",
"object": "https://framapiaf.org/users/Framasoft/statuses/102501959686438400",
"id": "https://framapiaf.org/users/Framasoft/statuses/102501959686438400/activity",
"cc": [
"https://social.tcit.fr/users/tcit",
"https://social.tcit.fr/users/tcit/followers"
"https://framapiaf.org/users/Framasoft",
"https://framapiaf.org/users/Framasoft/followers"
],
"atomUri": "https://social.tcit.fr/users/tcit/statuses/101188891162897047/activity",
"actor": "https://social.tcit.fr/users/tcit",
"atomUri": "https://framapiaf.org/users/Framasoft/statuses/102501959686438400/activity",
"actor": "https://framapiaf.org/users/Framasoft",
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",

View File

@@ -0,0 +1,34 @@
{
"type": "Reject",
"signature": {
"type": "RsaSignature2017",
"signatureValue": "rBzK4Kqhd4g7HDS8WE5oRbWQb2R+HF/6awbUuMWhgru/xCODT0SJWSri0qWqEO4fPcpoUyz2d25cw6o+iy9wiozQb3hQNnu69AR+H5Mytc06+g10KCHexbGhbAEAw/7IzmeXELHUbaqeduaDIbdt1zw4RkwLXdqgQcGXTJ6ND1wM3WMHXQCK1m0flasIXFoBxpliPAGiElV8s0+Ltuh562GvflG3kB3WO+j+NaR0ZfG5G9N88xMj9UQlCKit5gpAE5p6syUsCU2WGBHywTumv73i3OVTIFfq+P9AdMsRuzw1r7zoKEsthW4aOzLQDi01ZjvdBz8zH6JnjDU7SMN/Ig==",
"creator": "http://mastodon.example.org/users/admin#main-key",
"created": "2018-02-17T14:36:41Z"
},
"object": {
"type": "Follow",
"object": "http://mastodon.example.org/users/admin",
"id": "http://localtesting.pleroma.lol/users/lain#follows/4",
"actor": "http://localtesting.pleroma.lol/users/lain"
},
"nickname": "lain",
"id": "http://mastodon.example.org/users/admin#rejects/follows/4",
"actor": "http://mastodon.example.org/users/admin",
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",
{
"toot": "http://joinmastodon.org/ns#",
"sensitive": "as:sensitive",
"ostatus": "http://ostatus.org#",
"movedTo": "as:movedTo",
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
"inReplyToAtomUri": "ostatus:inReplyToAtomUri",
"conversation": "ostatus:conversation",
"atomUri": "ostatus:atomUri",
"Hashtag": "as:Hashtag",
"Emoji": "toot:Emoji"
}
]
}

View File

@@ -12,17 +12,17 @@
"http://www.w3.org/ns/activitystreams#Public"
],
"published": "2018-05-11T16:23:37Z",
"object": "http://mastodon.example.org/@admin/99541947525187367",
"id": "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity",
"object": "https://framapiaf.org/@Framasoft/statuses/102501959686438400",
"id": "https://framapiaf.org/users/Framasoft/statuses/102501959686438400/activity",
"cc": [
"http://mastodon.example.org/users/admin",
"http://mastodon.example.org/users/admin/followers"
"https://framapiaf.org/users/Framasoft/",
"https://framapiaf.org/users/Framasoft/followers"
],
"atomUri": "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity",
"actor": "http://mastodon.example.org/users/admin"
"atomUri": "https://framapiaf.org/users/Framasoft/statuses/102501959686438400/activity",
"actor": "https://framapiaf.org/users/Framasoft"
},
"id": "http://mastodon.example.org/users/admin#announces/100011594053806179/undo",
"actor": "http://mastodon.example.org/users/admin",
"id": "https://framapiaf.org/users/Framasoft#announces/100011594053806179/undo",
"actor": "https://framapiaf.org/users/Framasoft",
"@context": [
"http://www.w3.org/ns/activitystreams",
"http://w3id.org/security/v1",

View File

@@ -0,0 +1,57 @@
[
{
"request": {
"body": "",
"headers": {
"Accept": "application/activity+json"
},
"method": "get",
"options": {
"follow_redirect": "true"
},
"request_body": "",
"url": "http://localhost:8080/actor"
},
"response": {
"binary": false,
"body": "{\"@context\": \"https://www.w3.org/ns/activitystreams\", \"endpoints\": {\"sharedInbox\": \"http://localhost:8080/inbox\"}, \"followers\": \"http://localhost:8080/followers\", \"following\": \"http://localhost:8080/following\", \"inbox\": \"http://localhost:8080/inbox\", \"name\": \"ActivityRelay\", \"type\": \"Application\", \"id\": \"http://localhost:8080/actor\", \"publicKey\": {\"id\": \"http://localhost:8080/actor#main-key\", \"owner\": \"http://localhost:8080/actor\", \"publicKeyPem\": \"-----BEGIN PUBLIC KEY-----\\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvs6UuAo26Sb3BiOK7xay\\nsBzqvXI3xd55JAP0pAk2faF+Vl3r67/g9MoND96JqCVMuzSJZ9oSsqa6ilJCxG3p\\nXUUfQUvqAMGW49cCvga86DG17Ennjbc4C6WIQtoW3Wm5OdDciPY2Dx+pSXdTOajB\\nFX6RHUZcgqHENrsm3jPZI138e/2OJeqdxv4/5t2xdPXEpWdPGitX9AJhrqPY4lzg\\nzQ9Y9wS2eS1CVL9vZZRf9Z4RiZvAfVb0s1iS/IUxrf4TYERRFJxEoDLD2SZVrkq6\\nvhGldCfw2ZnfTftA1ToXguC9S6nSaz+li0ajNjpK/xjZjlKvn0I078UPPe5LUlsb\\nUcYZvBx5PC5rV8yKMLlgxnTY8PqC8LEVc453wO7Ai4M5TeB0SUyEycZHSyLfvQXV\\nThEN/07u1UaJViY3U5S/SihyoCQUfJXQ3jx2SjGgM32/aJ3IwxgveLaTsaZ0VVKM\\nbawEFw6iAcWYM06hZSB6j6dkL1xh+FYGEQTPMYMqUOJi2r1cD8yMLe8dTFOmwMLt\\nBnf7xxvnjKJcv3e9zGRWIdLkQbBQn3BEuRTCUMgljipxdjbeE5/JSP1kQLB94ncb\\nb9gvYgtemJKvT8m37+HOi9MI4BMIlDwpRWjqPZmkNvkegR/1KPjJSsyAnGdd89ne\\np442vUqPyXIq0tSCDmjmU+cCAwEAAQ==\\n-----END PUBLIC KEY-----\"}, \"summary\": \"ActivityRelay bot\", \"preferredUsername\": \"relay\", \"url\": \"http://localhost:8080/actor\"}",
"headers": {
"Content-Type": "application/json; charset=utf-8",
"Content-Length": "1368",
"Date": "Thu, 01 Aug 2019 14:44:38 GMT",
"Server": "Python/3.7 aiohttp/3.3.2"
},
"status_code": 200,
"type": "ok"
}
},
{
"request": {
"body": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://litepub.github.io/litepub/context.jsonld\",{\"Hashtag\":\"as:Hashtag\",\"category\":\"sc:category\",\"sc\":\"http://schema.org#\",\"uuid\":\"sc:identifier\"}],\"actor\":\"http://mobilizon.test/relay\",\"cc\":[\"https://www.w3.org/ns/activitystreams#Public\"],\"id\":\"http://mobilizon.test/follow/69/activity\",\"object\":\"http://localhost:8080/actor\",\"to\":[\"http://localhost:8080/actor\"],\"type\":\"Follow\"}",
"headers": {
"Content-Type": "application/activity+json",
"signature": "keyId=\"http://mobilizon.test/relay#main-key\",algorithm=\"rsa-sha256\",headers=\"(request-target) content-length date digest host\",signature=\"UADlb5eaeqmujO5zGfK1mWB3WZFXU6lkUgSvEf5YyQMOIkMaudDwTfNPIa4IYh2VMLwyYSjOOXxkcBdCw4f9UnMBQBhomPNRNkJ0QBzoxILPmyxddAojH9IzwwAUL/nHSGWaO116bkCux0OcEM5AVIrCT6dENep39lOjnOGPelBB5mKMS78AxH4pU/5tTGFKmNgiRL4Q06ezPUJHKauRrMwzcqZYdjUn+U9MDBDrYyfAzqQlgBPU/fMCjwusndxaICb9c+40YE3WaXzKewIivfrMoOBzWyw6ZsgAG8/NoOH+8z9Z+hBvdjCUXeG2bvAPPclNkSJillwIA2PnMOVgpw==\"",
"digest": "SHA-256=Ady0Dj2bEXe201P9bThLaj1Kw/7O1cfrjN9IifEfVBg=",
"date": "Thu, 01 Aug 2019 14:44:38 GMT"
},
"method": "post",
"options": {
"pool": "default"
},
"request_body": "",
"url": "http://localhost:8080/inbox"
},
"response": {
"binary": false,
"body": "signature check failed, signature did not match key",
"headers": {
"Content-Length": "51",
"Content-Type": "text/plain; charset=utf-8",
"Date": "Thu, 01 Aug 2019 14:44:38 GMT",
"Server": "Python/3.7 aiohttp/3.3.2"
},
"status_code": 401,
"type": "ok"
}
}
]

View File

@@ -0,0 +1,57 @@
[
{
"request": {
"body": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://litepub.github.io/litepub/context.jsonld\",{\"Hashtag\":\"as:Hashtag\",\"category\":\"sc:category\",\"sc\":\"http://schema.org#\",\"uuid\":\"sc:identifier\"}],\"actor\":\"http://mobilizon.test/relay\",\"cc\":[\"https://www.w3.org/ns/activitystreams#Public\"],\"id\":\"http://mobilizon.test/follow/68/activity\",\"object\":\"http://localhost:8080/actor\",\"to\":[\"http://localhost:8080/actor\"],\"type\":\"Follow\"}",
"headers": {
"Content-Type": "application/activity+json",
"signature": "keyId=\"http://mobilizon.test/relay#main-key\",algorithm=\"rsa-sha256\",headers=\"(request-target) content-length date digest host\",signature=\"WsxzipdObXsApVtY5l2yTonTOPV888XLKK2+AMQRyiNZm4RGMEux8kgBKgJIODaKmRx9EsX8dIzBtTmJdLyj5gqfjvGVyj8hVeR0ERNMZmjngh5EZ3W+ySbkdFYZeYDWhwpL1i+7dTFJ3zE/ASZVaTMeIgqEpFnzHNbamwPzBZVvcnzyraB1rrmwcbzzrk3UPlJ3tA+Xz67Njr2wOiNNsjZ53abArKZB3KGbife6OyrVrKldJ+UKZS+vokgUXFwvMBZxfdmH2GD+yXHPhCIu7bVu77ASdW7bl7tM3uIV/c/Wemy5qJtPOupwbDvpLZ9ETE5IRCoUPdQ7l75kvevNxQ==\"",
"digest": "SHA-256=qIEgTH6kBorFchTiX2kxd7onyZ7BHhvLgCODLs6RAVc=",
"date": "Thu, 01 Aug 2019 14:44:37 GMT"
},
"method": "post",
"options": {
"pool": "default"
},
"request_body": "",
"url": "http://localhost:8080/inbox"
},
"response": {
"binary": false,
"body": "signature check failed, signature did not match key",
"headers": {
"Content-Length": "51",
"Content-Type": "text/plain; charset=utf-8",
"Date": "Thu, 01 Aug 2019 14:44:37 GMT",
"Server": "Python/3.7 aiohttp/3.3.2"
},
"status_code": 401,
"type": "ok"
}
},
{
"request": {
"body": "",
"headers": {
"Accept": "application/activity+json"
},
"method": "get",
"options": {
"follow_redirect": "true"
},
"request_body": "",
"url": "http://localhost:8080/actor"
},
"response": {
"binary": false,
"body": "{\"@context\": \"https://www.w3.org/ns/activitystreams\", \"endpoints\": {\"sharedInbox\": \"http://localhost:8080/inbox\"}, \"followers\": \"http://localhost:8080/followers\", \"following\": \"http://localhost:8080/following\", \"inbox\": \"http://localhost:8080/inbox\", \"name\": \"ActivityRelay\", \"type\": \"Application\", \"id\": \"http://localhost:8080/actor\", \"publicKey\": {\"id\": \"http://localhost:8080/actor#main-key\", \"owner\": \"http://localhost:8080/actor\", \"publicKeyPem\": \"-----BEGIN PUBLIC KEY-----\\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvs6UuAo26Sb3BiOK7xay\\nsBzqvXI3xd55JAP0pAk2faF+Vl3r67/g9MoND96JqCVMuzSJZ9oSsqa6ilJCxG3p\\nXUUfQUvqAMGW49cCvga86DG17Ennjbc4C6WIQtoW3Wm5OdDciPY2Dx+pSXdTOajB\\nFX6RHUZcgqHENrsm3jPZI138e/2OJeqdxv4/5t2xdPXEpWdPGitX9AJhrqPY4lzg\\nzQ9Y9wS2eS1CVL9vZZRf9Z4RiZvAfVb0s1iS/IUxrf4TYERRFJxEoDLD2SZVrkq6\\nvhGldCfw2ZnfTftA1ToXguC9S6nSaz+li0ajNjpK/xjZjlKvn0I078UPPe5LUlsb\\nUcYZvBx5PC5rV8yKMLlgxnTY8PqC8LEVc453wO7Ai4M5TeB0SUyEycZHSyLfvQXV\\nThEN/07u1UaJViY3U5S/SihyoCQUfJXQ3jx2SjGgM32/aJ3IwxgveLaTsaZ0VVKM\\nbawEFw6iAcWYM06hZSB6j6dkL1xh+FYGEQTPMYMqUOJi2r1cD8yMLe8dTFOmwMLt\\nBnf7xxvnjKJcv3e9zGRWIdLkQbBQn3BEuRTCUMgljipxdjbeE5/JSP1kQLB94ncb\\nb9gvYgtemJKvT8m37+HOi9MI4BMIlDwpRWjqPZmkNvkegR/1KPjJSsyAnGdd89ne\\np442vUqPyXIq0tSCDmjmU+cCAwEAAQ==\\n-----END PUBLIC KEY-----\"}, \"summary\": \"ActivityRelay bot\", \"preferredUsername\": \"relay\", \"url\": \"http://localhost:8080/actor\"}",
"headers": {
"Content-Type": "application/json; charset=utf-8",
"Content-Length": "1368",
"Date": "Thu, 01 Aug 2019 14:44:36 GMT",
"Server": "Python/3.7 aiohttp/3.3.2"
},
"status_code": 200,
"type": "ok"
}
}
]

View File

@@ -479,9 +479,9 @@ defmodule Mobilizon.ActorsTest do
alias Mobilizon.Actors.Follower
alias Mobilizon.Actors.Actor
@valid_attrs %{approved: true, score: 42}
@update_attrs %{approved: false, score: 43}
@invalid_attrs %{approved: nil, score: nil}
@valid_attrs %{approved: true}
@update_attrs %{approved: false}
@invalid_attrs %{approved: nil}
setup do
actor = insert(:actor)
@@ -509,7 +509,6 @@ defmodule Mobilizon.ActorsTest do
assert {:ok, %Follower{} = follower} = Actors.create_follower(valid_attrs)
assert follower.approved == true
assert follower.score == 42
assert %{total: 1, elements: [target_actor]} = Actor.get_followings(actor)
assert %{total: 1, elements: [actor]} = Actor.get_followers(target_actor)
@@ -546,7 +545,6 @@ defmodule Mobilizon.ActorsTest do
assert {:ok, follower} = Actors.update_follower(follower, @update_attrs)
assert %Follower{} = follower
assert follower.approved == false
assert follower.score == 43
end
test "update_follower/2 with invalid data returns error changeset", context do
@@ -582,12 +580,12 @@ defmodule Mobilizon.ActorsTest do
assert actor.followings |> Enum.map(& &1.target_actor_id) == [target_actor.id]
# Test if actor is already following target actor
{:error, msg} = Actor.follow(target_actor, actor)
assert {:error, :already_following, msg} = Actor.follow(target_actor, actor)
assert msg =~ "already following"
# Test if target actor is suspended
target_actor = %{target_actor | suspended: true}
{:error, msg} = Actor.follow(target_actor, actor)
assert {:error, :suspended, msg} = Actor.follow(target_actor, actor)
assert msg =~ "suspended"
end
end

View File

@@ -11,7 +11,7 @@ defmodule Mobilizon.Service.ActivityPub.ActivityPubTest do
alias Mobilizon.Events
alias Mobilizon.Actors.Actor
alias Mobilizon.Actors
alias Mobilizon.Service.HTTPSignatures
alias Mobilizon.Service.HTTPSignatures.Signature
alias Mobilizon.Service.ActivityPub
use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney
@@ -24,12 +24,12 @@ defmodule Mobilizon.Service.ActivityPub.ActivityPubTest do
actor = insert(:actor)
signature =
HTTPSignatures.sign(actor, %{
Signature.sign(actor, %{
host: "example.com",
"content-length": 15,
digest: Jason.encode!(%{id: "my_id"}) |> HTTPSignatures.build_digest(),
"(request-target)": HTTPSignatures.generate_request_target("POST", "/inbox"),
date: HTTPSignatures.generate_date_header()
digest: Jason.encode!(%{id: "my_id"}) |> Signature.build_digest(),
"(request-target)": Signature.generate_request_target("POST", "/inbox"),
date: Signature.generate_date_header()
})
assert signature =~ "headers=\"(request-target) content-length date digest host\""
@@ -53,21 +53,21 @@ defmodule Mobilizon.Service.ActivityPub.ActivityPubTest do
end
describe "create activities" do
test "removes doubled 'to' recipients" do
actor = insert(:actor)
{:ok, activity, _} =
ActivityPub.create(%{
to: ["user1", "user1", "user2"],
actor: actor,
context: "",
object: %{}
})
assert activity.data["to"] == ["user1", "user2"]
assert activity.actor == actor.url
assert activity.recipients == ["user1", "user2"]
end
# test "removes doubled 'to' recipients" do
# actor = insert(:actor)
#
# {:ok, activity, _} =
# ActivityPub.create(%{
# to: ["user1", "user1", "user2"],
# actor: actor,
# context: "",
# object: %{}
# })
#
# assert activity.data["to"] == ["user1", "user2"]
# assert activity.actor == actor.url
# assert activity.recipients == ["user1", "user2"]
# end
end
describe "fetching an" do
@@ -110,6 +110,7 @@ defmodule Mobilizon.Service.ActivityPub.ActivityPubTest do
end
describe "deletion" do
# TODO: The delete activity it relayed and fetched once again (and then not found /o\)
test "it creates a delete activity and deletes the original event" do
event = insert(:event)
event = Events.get_event_full_by_url!(event.url)

View File

@@ -0,0 +1,15 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Mobilizon.Service.ActivityPub.RelayTest do
use Mobilizon.DataCase
alias Mobilizon.Service.ActivityPub.Relay
test "gets an actor for the relay" do
actor = Relay.get_actor()
assert actor.url =~ "/relay"
end
end

View File

@@ -13,6 +13,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
alias Mobilizon.Actors.Actor
alias Mobilizon.Events
alias Mobilizon.Events.{Comment, Event}
alias Mobilizon.Service.ActivityPub
alias Mobilizon.Service.ActivityPub.Utils
alias Mobilizon.Service.ActivityPub.Transmogrifier
use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney
@@ -151,7 +152,7 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
data = File.read!("test/fixtures/mastodon-post-activity-hashtag.json") |> Jason.decode!()
{:ok, %Activity{data: data, local: false}, _} = Transmogrifier.handle_incoming(data)
assert Enum.at(data["object"]["tag"], 2) == "moo"
assert Enum.at(data["object"]["tag"], 1)["name"] == "#moo"
end
# test "it works for incoming notices with contentMap" do
@@ -293,43 +294,41 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
# assert data["object"]["id"] == "http://mastodon.example.org/users/admin#likes/2"
# end
# test "it works for incoming announces" do
# data = File.read!("test/fixtures/mastodon-announce.json") |> Jason.decode!()
test "it works for incoming announces" do
data = File.read!("test/fixtures/mastodon-announce.json") |> Jason.decode!()
# {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
{:ok, %Activity{data: data, local: false}, _} = Transmogrifier.handle_incoming(data)
# assert data["actor"] == "https://social.tcit.fr/users/tcit"
# assert data["type"] == "Announce"
assert data["actor"] == "https://framapiaf.org/users/Framasoft"
assert data["type"] == "Announce"
# assert data["id"] ==
# "https://social.tcit.fr/users/tcit/statuses/101188891162897047/activity"
assert data["id"] ==
"https://framapiaf.org/users/Framasoft/statuses/102501959686438400/activity"
# assert data["object"] ==
# "https://social.tcit.fr/users/tcit/statuses/101188891162897047"
assert data["object"] ==
"https://framapiaf.org/users/Framasoft/statuses/102501959686438400"
# assert %Comment{} = Events.get_comment_from_url(data["object"])
# end
assert %Comment{} = Events.get_comment_from_url(data["object"])
end
# test "it works for incoming announces with an existing activity" do
# comment = insert(:comment)
test "it works for incoming announces with an existing activity" do
comment = insert(:comment)
# data =
# File.read!("test/fixtures/mastodon-announce.json")
# |> Jason.decode!()
# |> Map.put("object", comment.url)
data =
File.read!("test/fixtures/mastodon-announce.json")
|> Jason.decode!()
|> Map.put("object", comment.url)
# {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
{:ok, %Activity{data: data, local: false}, _} = Transmogrifier.handle_incoming(data)
# assert data["actor"] == "https://social.tcit.fr/users/tcit"
# assert data["type"] == "Announce"
assert data["actor"] == "https://framapiaf.org/users/Framasoft"
assert data["type"] == "Announce"
# assert data["id"] ==
# "https://social.tcit.fr/users/tcit/statuses/101188891162897047/activity"
assert data["id"] ==
"https://framapiaf.org/users/Framasoft/statuses/102501959686438400/activity"
# assert data["object"] == comment.url
# # assert Activity.get_create_activity_by_object_ap_id(data["object"]).id == activity.id
# end
assert data["object"] == comment.url
end
test "it works for incoming update activities" do
data = File.read!("test/fixtures/mastodon-post-activity.json") |> Jason.decode!()
@@ -423,32 +422,32 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
# assert Repo.get(Activity, activity.id)
# end
# test "it works for incoming unannounces with an existing notice" do
# comment = insert(:comment)
test "it works for incoming unannounces with an existing notice" do
comment = insert(:comment)
# announce_data =
# File.read!("test/fixtures/mastodon-announce.json")
# |> Jason.decode!()
# |> Map.put("object", comment.url)
announce_data =
File.read!("test/fixtures/mastodon-announce.json")
|> Jason.decode!()
|> Map.put("object", comment.url)
# {:ok, %Activity{data: announce_data, local: false}} =
# Transmogrifier.handle_incoming(announce_data)
{:ok, %Activity{data: announce_data, local: false}, _} =
Transmogrifier.handle_incoming(announce_data)
# data =
# File.read!("test/fixtures/mastodon-undo-announce.json")
# |> Jason.decode!()
# |> Map.put("object", announce_data)
# |> Map.put("actor", announce_data["actor"])
data =
File.read!("test/fixtures/mastodon-undo-announce.json")
|> Jason.decode!()
|> Map.put("object", announce_data)
|> Map.put("actor", announce_data["actor"])
# {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
{:ok, %Activity{data: data, local: false}, _} = Transmogrifier.handle_incoming(data)
# assert data["type"] == "Undo"
# assert data["object"]["type"] == "Announce"
# assert data["object"]["object"] == comment.url
assert data["type"] == "Undo"
assert data["object"]["type"] == "Announce"
assert data["object"]["object"] == comment.url
# assert data["object"]["id"] ==
# "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity"
# end
assert data["object"]["id"] ==
"https://framapiaf.org/users/Framasoft/statuses/102501959686438400/activity"
end
test "it works for incomming unfollows with an existing follow" do
actor = insert(:actor)
@@ -552,175 +551,127 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
# refute User.blocks?(blocker, user)
# end
# test "it works for incoming accepts which were pre-accepted" do
# follower = insert(:user)
# followed = insert(:user)
test "it works for incoming accepts which were pre-accepted" do
follower = insert(:actor)
followed = insert(:actor)
# {:ok, follower} = User.follow(follower, followed)
# assert User.following?(follower, followed) == true
refute Actor.following?(follower, followed)
# {:ok, follow_activity} = ActivityPub.follow(follower, followed)
{:ok, follow_activity, _} = ActivityPub.follow(follower, followed)
assert Actor.following?(follower, followed)
# accept_data =
# File.read!("test/fixtures/mastodon-accept-activity.json")
# |> Jason.decode!()
# |> Map.put("actor", followed.ap_id)
accept_data =
File.read!("test/fixtures/mastodon-accept-activity.json")
|> Jason.decode!()
|> Map.put("actor", followed.url)
# object =
# accept_data["object"]
# |> Map.put("actor", follower.ap_id)
# |> Map.put("id", follow_activity.data["id"])
object =
accept_data["object"]
|> Map.put("actor", follower.url)
|> Map.put("id", follow_activity.data["id"])
# accept_data = Map.put(accept_data, "object", object)
accept_data = Map.put(accept_data, "object", object)
# {:ok, activity} = Transmogrifier.handle_incoming(accept_data)
# refute activity.local
{:ok, activity, _} = Transmogrifier.handle_incoming(accept_data)
refute activity.local
# assert activity.data["object"] == follow_activity.data["id"]
assert activity.data["object"]["id"] == follow_activity.data["id"]
# follower = Repo.get(User, follower.id)
{:ok, follower} = Actors.get_actor_by_url(follower.url)
# assert User.following?(follower, followed) == true
# end
assert Actor.following?(follower, followed)
end
# test "it works for incoming accepts which were orphaned" do
# follower = insert(:user)
# followed = insert(:user, %{info: %{"locked" => true}})
test "it works for incoming accepts which are referenced by IRI only" do
follower = insert(:actor)
followed = insert(:actor)
# {:ok, follow_activity} = ActivityPub.follow(follower, followed)
{:ok, follow_activity, _} = ActivityPub.follow(follower, followed)
# accept_data =
# File.read!("test/fixtures/mastodon-accept-activity.json")
# |> Jason.decode!()
# |> Map.put("actor", followed.ap_id)
accept_data =
File.read!("test/fixtures/mastodon-accept-activity.json")
|> Jason.decode!()
|> Map.put("actor", followed.url)
|> Map.put("object", follow_activity.data["id"])
# accept_data =
# Map.put(accept_data, "object", Map.put(accept_data["object"], "actor", follower.ap_id))
{:ok, activity, _} = Transmogrifier.handle_incoming(accept_data)
assert activity.data["object"] == follow_activity.data["id"]
assert activity.data["object"] =~ "/follow/"
assert activity.data["id"] =~ "/accept/follow/"
# {:ok, activity} = Transmogrifier.handle_incoming(accept_data)
# assert activity.data["object"] == follow_activity.data["id"]
{:ok, follower} = Actors.get_actor_by_url(follower.url)
# follower = Repo.get(User, follower.id)
assert Actor.following?(follower, followed)
end
# assert User.following?(follower, followed) == true
# end
test "it fails for incoming accepts which cannot be correlated" do
follower = insert(:actor)
followed = insert(:actor)
# test "it works for incoming accepts which are referenced by IRI only" do
# follower = insert(:user)
# followed = insert(:user, %{info: %{"locked" => true}})
accept_data =
File.read!("test/fixtures/mastodon-accept-activity.json")
|> Jason.decode!()
|> Map.put("actor", followed.url)
# {:ok, follow_activity} = ActivityPub.follow(follower, followed)
accept_data =
Map.put(accept_data, "object", Map.put(accept_data["object"], "actor", follower.url))
# accept_data =
# File.read!("test/fixtures/mastodon-accept-activity.json")
# |> Jason.decode!()
# |> Map.put("actor", followed.ap_id)
# |> Map.put("object", follow_activity.data["id"])
:error = Transmogrifier.handle_incoming(accept_data)
# {:ok, activity} = Transmogrifier.handle_incoming(accept_data)
# assert activity.data["object"] == follow_activity.data["id"]
{:ok, follower} = Actors.get_actor_by_url(follower.url)
# follower = Repo.get(User, follower.id)
refute Actor.following?(follower, followed)
end
# assert User.following?(follower, followed) == true
# end
test "it fails for incoming rejects which cannot be correlated" do
follower = insert(:actor)
followed = insert(:actor)
# test "it fails for incoming accepts which cannot be correlated" do
# follower = insert(:user)
# followed = insert(:user, %{info: %{"locked" => true}})
accept_data =
File.read!("test/fixtures/mastodon-reject-activity.json")
|> Jason.decode!()
|> Map.put("actor", followed.url)
# accept_data =
# File.read!("test/fixtures/mastodon-accept-activity.json")
# |> Jason.decode!()
# |> Map.put("actor", followed.ap_id)
accept_data =
Map.put(accept_data, "object", Map.put(accept_data["object"], "actor", follower.url))
# accept_data =
# Map.put(accept_data, "object", Map.put(accept_data["object"], "actor", follower.ap_id))
:error = Transmogrifier.handle_incoming(accept_data)
# :error = Transmogrifier.handle_incoming(accept_data)
{:ok, follower} = Actors.get_actor_by_url(follower.url)
# follower = Repo.get(User, follower.id)
refute Actor.following?(follower, followed)
end
# refute User.following?(follower, followed) == true
# end
test "it works for incoming rejects which are referenced by IRI only" do
follower = insert(:actor)
followed = insert(:actor)
# test "it fails for incoming rejects which cannot be correlated" do
# follower = insert(:user)
# followed = insert(:user, %{info: %{"locked" => true}})
{:ok, follow_activity, _} = ActivityPub.follow(follower, followed)
# accept_data =
# File.read!("test/fixtures/mastodon-reject-activity.json")
# |> Jason.decode!()
# |> Map.put("actor", followed.ap_id)
assert Actor.following?(follower, followed)
# accept_data =
# Map.put(accept_data, "object", Map.put(accept_data["object"], "actor", follower.ap_id))
reject_data =
File.read!("test/fixtures/mastodon-reject-activity.json")
|> Jason.decode!()
|> Map.put("actor", followed.url)
|> Map.put("object", follow_activity.data["id"])
# :error = Transmogrifier.handle_incoming(accept_data)
{:ok, %Activity{data: _}, _} = Transmogrifier.handle_incoming(reject_data)
# follower = Repo.get(User, follower.id)
refute Actor.following?(follower, followed)
end
# refute User.following?(follower, followed) == true
# end
test "it rejects activities without a valid ID" do
actor = insert(:actor)
# test "it works for incoming rejects which are orphaned" do
# follower = insert(:user)
# followed = insert(:user, %{info: %{"locked" => true}})
data =
File.read!("test/fixtures/mastodon-follow-activity.json")
|> Jason.decode!()
|> Map.put("object", actor.url)
|> Map.put("id", "")
# {:ok, follower} = User.follow(follower, followed)
# {:ok, _follow_activity} = ActivityPub.follow(follower, followed)
# assert User.following?(follower, followed) == true
# reject_data =
# File.read!("test/fixtures/mastodon-reject-activity.json")
# |> Jason.decode!()
# |> Map.put("actor", followed.ap_id)
# reject_data =
# Map.put(reject_data, "object", Map.put(reject_data["object"], "actor", follower.ap_id))
# {:ok, activity} = Transmogrifier.handle_incoming(reject_data)
# refute activity.local
# follower = Repo.get(User, follower.id)
# assert User.following?(follower, followed) == false
# end
# test "it works for incoming rejects which are referenced by IRI only" do
# follower = insert(:user)
# followed = insert(:user, %{info: %{"locked" => true}})
# {:ok, follower} = User.follow(follower, followed)
# {:ok, follow_activity} = ActivityPub.follow(follower, followed)
# assert User.following?(follower, followed) == true
# reject_data =
# File.read!("test/fixtures/mastodon-reject-activity.json")
# |> Jason.decode!()
# |> Map.put("actor", followed.ap_id)
# |> Map.put("object", follow_activity.data["id"])
# {:ok, %Activity{data: _}} = Transmogrifier.handle_incoming(reject_data)
# follower = Repo.get(User, follower.id)
# assert User.following?(follower, followed) == false
# end
# test "it rejects activities without a valid ID" do
# user = insert(:user)
# data =
# File.read!("test/fixtures/mastodon-follow-activity.json")
# |> Jason.decode!()
# |> Map.put("object", user.ap_id)
# |> Map.put("id", "")
# :error = Transmogrifier.handle_incoming(data)
# end
:error = Transmogrifier.handle_incoming(data)
end
test "it accepts Flag activities" do
%Actor{url: reporter_url} = _reporter = insert(:actor)

View File

@@ -279,6 +279,28 @@ defmodule MobilizonWeb.ActivityPubControllerTest do
end
end
describe "/relay" do
test "with the relay active, it returns the relay user", %{conn: conn} do
res =
conn
|> get(activity_pub_path(conn, :relay))
|> json_response(200)
assert res["id"] =~ "/relay"
end
test "with the relay disabled, it returns 404", %{conn: conn} do
Mobilizon.CommonConfig.put([:instance, :allow_relay], false)
conn
|> get(activity_pub_path(conn, :relay))
|> json_response(404)
|> assert
Mobilizon.CommonConfig.put([:instance, :allow_relay], true)
end
end
#
# describe "/@:preferred_username/following" do
# test "it returns the following in a collection", %{conn: conn} do

View File

@@ -39,6 +39,7 @@ defmodule Mobilizon.Factory do
url: Actor.build_url(preferred_username, :page),
followers_url: Actor.build_url(preferred_username, :followers),
following_url: Actor.build_url(preferred_username, :following),
inbox_url: Actor.build_url(preferred_username, :inbox),
outbox_url: Actor.build_url(preferred_username, :outbox),
user: nil
}
@@ -54,9 +55,13 @@ defmodule Mobilizon.Factory do
end
def follower_factory do
uuid = Ecto.UUID.generate()
%Mobilizon.Actors.Follower{
target_actor: build(:actor),
actor: build(:actor)
actor: build(:actor),
id: uuid,
url: "#{MobilizonWeb.Endpoint.url()}/follows/#{uuid}"
}
end
@@ -118,6 +123,7 @@ defmodule Mobilizon.Factory do
visibility: :public,
tags: build_list(3, :tag),
url: Routes.page_url(Endpoint, :event, uuid),
picture: insert(:picture),
uuid: uuid
}
end

47
test/tasks/relay_test.exs Normal file
View File

@@ -0,0 +1,47 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Mix.Tasks.Mobilizon.RelayTest do
alias Mobilizon.Actors.{Actor, Follower}
alias Mobilizon.Actors
alias Mobilizon.Service.ActivityPub.Relay
use Mobilizon.DataCase
use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney
describe "running follow" do
test "relay is followed" do
use_cassette "relay/fetch_relay_follow" do
target_instance = "http://localhost:8080/actor"
Mix.Tasks.Mobilizon.Relay.run(["follow", target_instance])
local_actor = Relay.get_actor()
assert local_actor.url =~ "/relay"
{:ok, target_actor} = Actors.get_actor_by_url(target_instance)
refute is_nil(target_actor.domain)
assert Actor.following?(local_actor, target_actor)
end
end
end
describe "running unfollow" do
test "relay is unfollowed" do
use_cassette "relay/fetch_relay_unfollow" do
target_instance = "http://localhost:8080/actor"
Mix.Tasks.Mobilizon.Relay.run(["follow", target_instance])
%Actor{} = local_actor = Relay.get_actor()
{:ok, %Actor{} = target_actor} = Actors.get_actor_by_url(target_instance)
assert %Follower{} = Actor.following?(local_actor, target_actor)
Mix.Tasks.Mobilizon.Relay.run(["unfollow", target_instance])
refute Actor.following?(local_actor, target_actor)
end
end
end
end