StreamEntry model. Simply render Salmon slaps as they are neededmaster
@ -1,12 +1,37 @@ | |||
# frozen_string_literal: true | |||
class AuthorizeFollowService < BaseService | |||
include StreamEntryRenderer | |||
def call(source_account, target_account) | |||
follow_request = FollowRequest.find_by!(account: source_account, target_account: target_account) | |||
follow_request.authorize! | |||
NotificationWorker.perform_async(stream_entry_to_xml(follow_request.stream_entry), target_account.id, source_account.id) unless source_account.local? | |||
follow_request.stream_entry.destroy | |||
NotificationWorker.perform_async(build_xml(follow_request), target_account.id, source_account.id) unless source_account.local? | |||
end | |||
private | |||
def build_xml(follow_request) | |||
Nokogiri::XML::Builder.new do |xml| | |||
entry(xml, true) do | |||
author(xml) do | |||
include_author xml, follow_request.target_account | |||
end | |||
object_type xml, :activity | |||
verb xml, :authorize | |||
target(xml) do | |||
author(xml) do | |||
include_author xml, follow_request.account | |||
end | |||
object_type xml, :activity | |||
verb xml, :request_friend | |||
target(xml) do | |||
include_author xml, follow_request.target_account | |||
end | |||
end | |||
end | |||
end.to_xml | |||
end | |||
end |
@ -1,12 +1,37 @@ | |||
# frozen_string_literal: true | |||
class RejectFollowService < BaseService | |||
include StreamEntryRenderer | |||
def call(source_account, target_account) | |||
follow_request = FollowRequest.find_by!(account: source_account, target_account: target_account) | |||
follow_request.reject! | |||
NotificationWorker.perform_async(stream_entry_to_xml(follow_request.stream_entry), target_account.id, source_account.id) unless source_account.local? | |||
follow_request.stream_entry.destroy | |||
NotificationWorker.perform_async(build_xml(follow_request), target_account.id, source_account.id) unless source_account.local? | |||
end | |||
private | |||
def build_xml(follow_request) | |||
Nokogiri::XML::Builder.new do |xml| | |||
entry(xml, true) do | |||
author(xml) do | |||
include_author xml, follow_request.target_account | |||
end | |||
object_type xml, :activity | |||
verb xml, :reject | |||
target(xml) do | |||
author(xml) do | |||
include_author xml, follow_request.account | |||
end | |||
object_type xml, :activity | |||
verb xml, :request_friend | |||
target(xml) do | |||
include_author xml, follow_request.target_account | |||
end | |||
end | |||
end | |||
end.to_xml | |||
end | |||
end |
@ -1,12 +1,31 @@ | |||
# frozen_string_literal: true | |||
class UnblockService < BaseService | |||
include StreamEntryRenderer | |||
def call(account, target_account) | |||
return unless account.blocking?(target_account) | |||
unblock = account.unblock!(target_account) | |||
NotificationWorker.perform_async(stream_entry_to_xml(unblock.stream_entry), account.id, target_account.id) unless target_account.local? | |||
NotificationWorker.perform_async(build_xml(unblock), account.id, target_account.id) unless target_account.local? | |||
end | |||
private | |||
def build_xml(block) | |||
Nokogiri::XML::Builder.new do |xml| | |||
entry(xml, true) do | |||
title xml, "#{block.account.acct} no longer blocks #{block.target_account.acct}" | |||
author(xml) do | |||
include_author xml, block.account | |||
end | |||
object_type xml, :activity | |||
verb xml, :unblock | |||
target(xml) do | |||
include_author xml, block.target_account | |||
end | |||
end | |||
end.to_xml | |||
end | |||
end |
@ -1,16 +1,37 @@ | |||
# frozen_string_literal: true | |||
class UnfavouriteService < BaseService | |||
include StreamEntryRenderer | |||
def call(account, status) | |||
favourite = Favourite.find_by!(account: account, status: status) | |||
favourite.destroy! | |||
unless status.local? | |||
NotificationWorker.perform_async(stream_entry_to_xml(favourite.stream_entry), account.id, status.account_id) | |||
end | |||
NotificationWorker.perform_async(build_xml(favourite), account.id, status.account_id) unless status.local? | |||
favourite | |||
end | |||
private | |||
def build_xml(favourite) | |||
Nokogiri::XML::Builder.new do |xml| | |||
entry(xml, true) do | |||
title xml, "#{favourite.account.acct} no longer favourites a status by #{favourite.status.account.acct}" | |||
author(xml) do | |||
include_author xml, favourite.account | |||
end | |||
object_type xml, :activity | |||
verb xml, :unfavourite | |||
target(xml) do | |||
author(xml) do | |||
include_author xml, favourite.status.account | |||
end | |||
include_entry xml, favourite.status.stream_entry | |||
end | |||
end | |||
end.to_xml | |||
end | |||
end |
@ -1,14 +1,33 @@ | |||
# frozen_string_literal: true | |||
class UnfollowService < BaseService | |||
include StreamEntryRenderer | |||
# Unfollow and notify the remote user | |||
# @param [Account] source_account Where to unfollow from | |||
# @param [Account] target_account Which to unfollow | |||
def call(source_account, target_account) | |||
follow = source_account.unfollow!(target_account) | |||
NotificationWorker.perform_async(stream_entry_to_xml(follow.stream_entry), source_account.id, target_account.id) unless target_account.local? | |||
NotificationWorker.perform_async(build_xml(follow), source_account.id, target_account.id) unless target_account.local? | |||
UnmergeWorker.perform_async(target_account.id, source_account.id) | |||
end | |||
private | |||
def build_xml(follow) | |||
Nokogiri::XML::Builder.new do |xml| | |||
entry(xml, true) do | |||
title xml, "#{follow.account.acct} is no longer following #{follow.target_account.acct}" | |||
author(xml) do | |||
include_author xml, follow.account | |||
end | |||
object_type xml, :activity | |||
verb xml, :unfollow | |||
target(xml) do | |||
include_author xml, follow.target_account | |||
end | |||
end | |||
end.to_xml | |||
end | |||
end |
@ -1,5 +0,0 @@ | |||
.entry.entry-favourite | |||
.content.emojify | |||
%strong= favourite.account.acct | |||
= t('stream_entries.favourited') | |||
%strong= favourite.status.account.acct |
@ -1,5 +0,0 @@ | |||
.entry.entry-follow | |||
.content.emojify | |||
%strong= link_to follow.account.acct, account_path(follow.account) | |||
= t('stream_entries.is_now_following') | |||
%strong= link_to follow.target_account.acct, TagManager.instance.url_for(follow.target_account) |
@ -1,15 +1,93 @@ | |||
require 'rails_helper' | |||
RSpec.describe ProcessInteractionService do | |||
let(:receiver) { Fabricate(:user, email: 'alice@example.com', account: Fabricate(:account, username: 'alice')).account } | |||
let(:sender) { Fabricate(:user, email: 'bob@example.com', account: Fabricate(:account, username: 'bob')).account } | |||
subject { ProcessInteractionService.new } | |||
it 'creates account for new remote user' | |||
it 'updates account for existing remote user' | |||
it 'ignores envelopes that do not address the local user' | |||
it 'accepts a status that mentions the local user' | |||
it 'accepts a status that is a reply to the local user\'s' | |||
it 'accepts a favourite to a status by the local user' | |||
it 'accepts a reblog of a status of the local user' | |||
it 'accepts a follow of the local user' | |||
it 'accepts an unfollow of the local user' | |||
describe 'follow request slap' do | |||
before do | |||
receiver.update(locked: true) | |||
payload = <<XML | |||
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:activity="http://activitystrea.ms/spec/1.0/"> | |||
<author> | |||
<name>bob</name> | |||
<uri>https://cb6e6126.ngrok.io/users/bob</uri> | |||
</author> | |||
<id>someIdHere</id> | |||
<activity:verb>http://activitystrea.ms/schema/1.0/request-friend</activity:verb> | |||
</entry> | |||
XML | |||
envelope = OStatus2::Salmon.new.pack(payload, sender.keypair) | |||
subject.call(envelope, receiver) | |||
end | |||
it 'creates a record' do | |||
expect(FollowRequest.find_by(account: sender, target_account: receiver)).to_not be_nil | |||
end | |||
end | |||
describe 'follow request authorization slap' do | |||
before do | |||
receiver.update(locked: true) | |||
FollowRequest.create(account: sender, target_account: receiver) | |||
payload = <<XML | |||
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:activity="http://activitystrea.ms/spec/1.0/"> | |||
<author> | |||
<name>alice</name> | |||
<uri>https://cb6e6126.ngrok.io/users/alice</uri> | |||
</author> | |||
<id>someIdHere</id> | |||
<activity:verb>http://activitystrea.ms/schema/1.0/authorize</activity:verb> | |||
</entry> | |||
XML | |||
envelope = OStatus2::Salmon.new.pack(payload, receiver.keypair) | |||
subject.call(envelope, sender) | |||
end | |||
it 'creates a follow relationship' do | |||
expect(Follow.find_by(account: sender, target_account: receiver)).to_not be_nil | |||
end | |||
it 'removes the follow request' do | |||
expect(FollowRequest.find_by(account: sender, target_account: receiver)).to be_nil | |||
end | |||
end | |||
describe 'follow request rejection slap' do | |||
before do | |||
receiver.update(locked: true) | |||
FollowRequest.create(account: sender, target_account: receiver) | |||
payload = <<XML | |||
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:activity="http://activitystrea.ms/spec/1.0/"> | |||
<author> | |||
<name>alice</name> | |||
<uri>https://cb6e6126.ngrok.io/users/alice</uri> | |||
</author> | |||
<id>someIdHere</id> | |||
<activity:verb>http://activitystrea.ms/schema/1.0/reject</activity:verb> | |||
</entry> | |||
XML | |||
envelope = OStatus2::Salmon.new.pack(payload, receiver.keypair) | |||
subject.call(envelope, sender) | |||
end | |||
it 'does not create a follow relationship' do | |||
expect(Follow.find_by(account: sender, target_account: receiver)).to be_nil | |||
end | |||
it 'removes the follow request' do | |||
expect(FollowRequest.find_by(account: sender, target_account: receiver)).to be_nil | |||
end | |||
end | |||
end |