2017-08-08 21:52:15 +02:00
require 'rails_helper'
2018-05-02 18:58:48 +02:00
RSpec . describe ActivityPub :: ProcessCollectionService , type : :service do
2017-09-26 01:06:13 +02:00
let ( :actor ) { Fabricate ( :account , domain : 'example.com' , uri : 'http://example.com/account' ) }
2017-08-31 17:18:49 +02:00
let ( :payload ) do
{
'@context' : 'https://www.w3.org/ns/activitystreams' ,
id : 'foo' ,
type : 'Create' ,
actor : ActivityPub :: TagManager . instance . uri_for ( actor ) ,
object : {
id : 'bar' ,
type : 'Note' ,
content : 'Lorem ipsum' ,
} ,
}
end
let ( :json ) { Oj . dump ( payload ) }
2017-08-26 13:47:38 +02:00
subject { described_class . new }
2017-08-08 21:52:15 +02:00
describe '#call' do
2020-11-08 00:28:39 +01:00
context 'when actor is suspended' do
before do
actor . suspend! ( origin : :remote )
end
%w( Accept Add Announce Block Create Flag Follow Like Move Remove ) . each do | activity_type |
context " with #{ activity_type } activity " do
let ( :payload ) do
{
'@context' : 'https://www.w3.org/ns/activitystreams' ,
id : 'foo' ,
type : activity_type ,
actor : ActivityPub :: TagManager . instance . uri_for ( actor ) ,
}
end
it 'does not process payload' do
2023-02-20 02:33:27 +01:00
expect ( ActivityPub :: Activity ) . to_not receive ( :factory )
2020-11-08 00:28:39 +01:00
subject . call ( json , actor )
end
end
end
%w( Delete Reject Undo Update ) . each do | activity_type |
context " with #{ activity_type } activity " do
let ( :payload ) do
{
'@context' : 'https://www.w3.org/ns/activitystreams' ,
id : 'foo' ,
type : activity_type ,
actor : ActivityPub :: TagManager . instance . uri_for ( actor ) ,
}
end
it 'processes the payload' do
expect ( ActivityPub :: Activity ) . to receive ( :factory )
subject . call ( json , actor )
end
end
end
end
2017-08-31 17:18:49 +02:00
context 'when actor differs from sender' do
2017-09-26 01:06:13 +02:00
let ( :forwarder ) { Fabricate ( :account , domain : 'example.com' , uri : 'http://example.com/other_account' ) }
2017-08-31 17:18:49 +02:00
2018-12-30 09:48:59 +01:00
it 'does not process payload if no signature exists' do
2022-09-21 22:45:57 +02:00
expect_any_instance_of ( ActivityPub :: LinkedDataSignature ) . to receive ( :verify_actor! ) . and_return ( nil )
2023-02-20 02:33:27 +01:00
expect ( ActivityPub :: Activity ) . to_not receive ( :factory )
2017-08-31 17:18:49 +02:00
subject . call ( json , forwarder )
end
it 'processes payload with actor if valid signature exists' do
2018-10-04 12:36:53 +02:00
payload [ 'signature' ] = { 'type' = > 'RsaSignature2017' }
2017-08-31 17:18:49 +02:00
2022-09-21 22:45:57 +02:00
expect_any_instance_of ( ActivityPub :: LinkedDataSignature ) . to receive ( :verify_actor! ) . and_return ( actor )
2017-10-08 17:34:34 +02:00
expect ( ActivityPub :: Activity ) . to receive ( :factory ) . with ( instance_of ( Hash ) , actor , instance_of ( Hash ) )
2017-08-31 17:18:49 +02:00
subject . call ( json , forwarder )
end
it 'does not process payload if invalid signature exists' do
2018-10-04 12:36:53 +02:00
payload [ 'signature' ] = { 'type' = > 'RsaSignature2017' }
2017-08-31 17:18:49 +02:00
2022-09-21 22:45:57 +02:00
expect_any_instance_of ( ActivityPub :: LinkedDataSignature ) . to receive ( :verify_actor! ) . and_return ( nil )
2023-02-20 02:33:27 +01:00
expect ( ActivityPub :: Activity ) . to_not receive ( :factory )
2017-08-31 17:18:49 +02:00
subject . call ( json , forwarder )
end
2022-03-10 00:11:40 +01:00
context 'when receiving a fabricated status' do
let! ( :actor ) do
Fabricate ( :account ,
2023-02-17 22:56:20 +01:00
username : 'bob' ,
domain : 'example.com' ,
uri : 'https://example.com/users/bob' ,
public_key : " -----BEGIN PUBLIC KEY----- \n MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuuYyoyfsRkYnXRotMsId \n W3euBDDfiv9oVqOxUVC7bhel8KednIMrMCRWFAkgJhbrlzbIkjVr68o1MP9qLcn7 \n CmH/BXHp7yhuFTr4byjdJKpwB+/i2jNEsvDH5jR8WTAeTCe0x/QHg21V3F7dSI5m \n CCZ/1dSIyOXLRTWVlfDlm3rE4ntlCo+US3/7oSWbg/4/4qEnt1HC32kvklgScxua \n 4LR5ATdoXa5bFoopPWhul7MJ6NyWCyQyScUuGdlj8EN4kmKQJvphKHrI9fvhgOuG \n TvhTR1S5InA4azSSchY0tXEEw/VNxraeX0KPjbgr6DPcwhPd/m0nhVDq0zVyVBBD \n MwIDAQAB \n -----END PUBLIC KEY----- \n " ,
private_key : nil )
2022-03-10 00:11:40 +01:00
end
let ( :payload ) do
{
'@context' : [
'https://www.w3.org/ns/activitystreams' ,
nil ,
2023-02-18 22:54:30 +01:00
{ object : 'https://www.w3.org/ns/activitystreams#object' } ,
2022-03-10 00:11:40 +01:00
] ,
2023-02-18 03:23:49 +01:00
id : 'https://example.com/users/bob/fake-status/activity' ,
type : 'Create' ,
actor : 'https://example.com/users/bob' ,
published : '2022-01-22T15:00:00Z' ,
to : [
2023-02-18 22:54:30 +01:00
'https://www.w3.org/ns/activitystreams#Public' ,
2022-03-10 00:11:40 +01:00
] ,
2023-02-18 03:23:49 +01:00
cc : [
2023-02-18 22:54:30 +01:00
'https://example.com/users/bob/followers' ,
2022-03-10 00:11:40 +01:00
] ,
2023-02-18 03:23:49 +01:00
signature : {
type : 'RsaSignature2017' ,
creator : 'https://example.com/users/bob#main-key' ,
created : '2022-03-09T21:57:25Z' ,
2023-02-18 15:33:41 +01:00
signatureValue : 'WculK0LelTQ0MvGwU9TPoq5pFzFfGYRDCJqjZ232/Udj4CHqDTGOSw5UTDLShqBOyycCkbZGrQwXG+dpyDpQLSe1UVPZ5TPQtc/9XtI57WlS2nMNpdvRuxGnnb2btPdesXZ7n3pCxo0zjaXrJMe0mqQh5QJO22mahb4bDwwmfTHgbD3nmkD+fBfGi+UV2qWwqr+jlV4L4JqNkh0gWljF5KTePLRRZCuWiQ/FAt7c67636cdIPf7fR+usjuZltTQyLZKEGuK8VUn2Gkfsx5qns7Vcjvlz1JqlAjyO8HPBbzTTHzUG2nUOIgC3PojCSWv6mNTmRGoLZzOscCAYQA6cKw==' ,
2022-03-10 00:11:40 +01:00
} ,
'@id' : 'https://example.com/users/bob/statuses/107928807471117876/activity' ,
'@type' : 'https://www.w3.org/ns/activitystreams#Create' ,
'https://www.w3.org/ns/activitystreams#actor' : {
2023-02-18 15:33:41 +01:00
'@id' : 'https://example.com/users/bob' ,
2022-03-10 00:11:40 +01:00
} ,
'https://www.w3.org/ns/activitystreams#cc' : {
2023-02-18 15:33:41 +01:00
'@id' : 'https://example.com/users/bob/followers' ,
2022-03-10 00:11:40 +01:00
} ,
2023-02-18 03:23:49 +01:00
object : {
id : 'https://example.com/users/bob/fake-status' ,
type : 'Note' ,
published : '2022-01-22T15:00:00Z' ,
url : 'https://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=puck-was-here' ,
attributedTo : 'https://example.com/users/bob' ,
to : [
2023-02-18 22:54:30 +01:00
'https://www.w3.org/ns/activitystreams#Public' ,
2022-03-10 00:11:40 +01:00
] ,
2023-02-18 03:23:49 +01:00
cc : [
2023-02-18 22:54:30 +01:00
'https://example.com/users/bob/followers' ,
2022-03-10 00:11:40 +01:00
] ,
2023-02-18 03:23:49 +01:00
sensitive : false ,
atomUri : 'https://example.com/users/bob/fake-status' ,
conversation : 'tag:example.com,2022-03-09:objectId=15:objectType=Conversation' ,
content : '<p>puck was here</p>' ,
2022-03-10 00:11:40 +01:00
'@id' : 'https://example.com/users/bob/statuses/107928807471117876' ,
'@type' : 'https://www.w3.org/ns/activitystreams#Note' ,
'http://ostatus.org#atomUri' : 'https://example.com/users/bob/statuses/107928807471117876' ,
'http://ostatus.org#conversation' : 'tag:example.com,2022-03-09:objectId=15:objectType=Conversation' ,
'https://www.w3.org/ns/activitystreams#attachment' : [ ] ,
'https://www.w3.org/ns/activitystreams#attributedTo' : {
2023-02-18 15:33:41 +01:00
'@id' : 'https://example.com/users/bob' ,
2022-03-10 00:11:40 +01:00
} ,
'https://www.w3.org/ns/activitystreams#cc' : {
2023-02-18 15:33:41 +01:00
'@id' : 'https://example.com/users/bob/followers' ,
2022-03-10 00:11:40 +01:00
} ,
'https://www.w3.org/ns/activitystreams#content' : [
'<p>hello world</p>' ,
{
'@value' : '<p>hello world</p>' ,
2023-02-18 15:33:41 +01:00
'@language' : 'en' ,
2023-02-18 22:54:30 +01:00
} ,
2022-03-10 00:11:40 +01:00
] ,
'https://www.w3.org/ns/activitystreams#published' : {
'@type' : 'http://www.w3.org/2001/XMLSchema#dateTime' ,
2023-02-18 15:33:41 +01:00
'@value' : '2022-03-09T21:55:07Z' ,
2022-03-10 00:11:40 +01:00
} ,
'https://www.w3.org/ns/activitystreams#replies' : {
'@id' : 'https://example.com/users/bob/statuses/107928807471117876/replies' ,
'@type' : 'https://www.w3.org/ns/activitystreams#Collection' ,
'https://www.w3.org/ns/activitystreams#first' : {
'@type' : 'https://www.w3.org/ns/activitystreams#CollectionPage' ,
'https://www.w3.org/ns/activitystreams#items' : [ ] ,
'https://www.w3.org/ns/activitystreams#next' : {
2023-02-18 15:33:41 +01:00
'@id' : 'https://example.com/users/bob/statuses/107928807471117876/replies?only_other_accounts=true&page=true' ,
2022-03-10 00:11:40 +01:00
} ,
'https://www.w3.org/ns/activitystreams#partOf' : {
2023-02-18 15:33:41 +01:00
'@id' : 'https://example.com/users/bob/statuses/107928807471117876/replies' ,
} ,
} ,
2022-03-10 00:11:40 +01:00
} ,
'https://www.w3.org/ns/activitystreams#sensitive' : false ,
'https://www.w3.org/ns/activitystreams#tag' : [ ] ,
'https://www.w3.org/ns/activitystreams#to' : {
2023-02-18 15:33:41 +01:00
'@id' : 'https://www.w3.org/ns/activitystreams#Public' ,
2022-03-10 00:11:40 +01:00
} ,
'https://www.w3.org/ns/activitystreams#url' : {
2023-02-18 15:33:41 +01:00
'@id' : 'https://example.com/@bob/107928807471117876' ,
} ,
2022-03-10 00:11:40 +01:00
} ,
'https://www.w3.org/ns/activitystreams#published' : {
'@type' : 'http://www.w3.org/2001/XMLSchema#dateTime' ,
2023-02-18 15:33:41 +01:00
'@value' : '2022-03-09T21:55:07Z' ,
2022-03-10 00:11:40 +01:00
} ,
'https://www.w3.org/ns/activitystreams#to' : {
2023-02-18 15:33:41 +01:00
'@id' : 'https://www.w3.org/ns/activitystreams#Public' ,
} ,
2022-03-10 00:11:40 +01:00
}
end
it 'does not process forged payload' do
2023-02-20 02:33:27 +01:00
expect ( ActivityPub :: Activity ) . to_not receive ( :factory ) . with (
2022-03-10 00:11:40 +01:00
hash_including (
'object' = > hash_including (
'id' = > 'https://example.com/users/bob/fake-status'
)
) ,
2023-02-17 13:36:14 +01:00
anything ,
anything
2022-03-10 00:11:40 +01:00
)
2023-02-20 02:33:27 +01:00
expect ( ActivityPub :: Activity ) . to_not receive ( :factory ) . with (
2022-03-10 00:11:40 +01:00
hash_including (
'object' = > hash_including (
'content' = > '<p>puck was here</p>'
)
) ,
2023-02-17 13:36:14 +01:00
anything ,
anything
2022-03-10 00:11:40 +01:00
)
subject . call ( json , forwarder )
expect ( Status . where ( uri : 'https://example.com/users/bob/fake-status' ) . exists? ) . to be false
end
end
2017-08-31 17:18:49 +02:00
end
2017-08-08 21:52:15 +02:00
end
end