Change: 単方向の承認だけでフレンドサーバーが有効になるようにする (#74)
* Test: テストを先に作成 * Fix: テスト不備 * Wip: フレンドサーバーのテストを修正 * Wip: エラーを修正 * 項目のラベリングを修正 * 新しい設定が変更できないのを修正 * Wip: 削除時の処理を修正 * フレンド自動承認設定を削除 * Fix: 申請を受けたドメインのINBOXが空になる問題 * Change: #75 フレンドでないサーバーからのローカル公開を未収載に変換 (#77)
This commit is contained in:
parent
521932c802
commit
1eb2d78b5d
24 changed files with 314 additions and 126 deletions
|
@ -118,5 +118,26 @@ RSpec.describe ActivityPub::Activity::Accept do
|
|||
subject.perform
|
||||
expect(friend.reload.i_am_accepted?).to be true
|
||||
end
|
||||
|
||||
it 'when the friend server is pending' do
|
||||
friend.update(passive_state: :pending)
|
||||
subject.perform
|
||||
expect(friend.reload.they_are_idle?).to be true
|
||||
expect(friend.i_am_accepted?).to be true
|
||||
end
|
||||
|
||||
it 'when the friend server is accepted' do
|
||||
friend.update(passive_state: :accepted)
|
||||
subject.perform
|
||||
expect(friend.reload.they_are_idle?).to be true
|
||||
expect(friend.i_am_accepted?).to be true
|
||||
end
|
||||
|
||||
it 'when my server is not pending' do
|
||||
friend.update(active_state: :idle)
|
||||
subject.perform
|
||||
expect(friend.reload.i_am_idle?).to be true
|
||||
expect(friend.they_are_idle?).to be true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -30,9 +30,11 @@ RSpec.describe ActivityPub::Activity::Create do
|
|||
|
||||
let(:sender_software) { 'mastodon' }
|
||||
let(:custom_before) { false }
|
||||
let(:active_friend) { false }
|
||||
|
||||
before do
|
||||
Fabricate(:instance_info, domain: 'example.com', software: sender_software)
|
||||
Fabricate(:friend_domain, domain: 'example.com', active_state: :accepted) if active_friend
|
||||
subject.perform unless custom_before
|
||||
end
|
||||
|
||||
|
@ -245,6 +247,26 @@ RSpec.describe ActivityPub::Activity::Create do
|
|||
}
|
||||
end
|
||||
|
||||
it 'creates status' do
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
expect(status.visibility).to eq 'unlisted'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when public_unlisted with LocalPublic from friend-server' do
|
||||
let(:object_json) do
|
||||
{
|
||||
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
|
||||
type: 'Note',
|
||||
content: 'Lorem ipsum',
|
||||
to: ['http://example.com/followers', 'LocalPublic'],
|
||||
cc: 'https://www.w3.org/ns/activitystreams#Public',
|
||||
}
|
||||
end
|
||||
let(:active_friend) { true }
|
||||
|
||||
it 'creates status' do
|
||||
status = sender.statuses.first
|
||||
|
||||
|
@ -433,6 +455,18 @@ RSpec.describe ActivityPub::Activity::Create do
|
|||
context 'with public_unlisted with LocalPublic' do
|
||||
let(:searchable_by) { ['http://example.com/followers', 'LocalPublic'] }
|
||||
|
||||
it 'create status' do
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
expect(status.searchability).to eq 'private'
|
||||
end
|
||||
end
|
||||
|
||||
context 'with public_unlisted with LocalPublic from friend-server' do
|
||||
let(:searchable_by) { ['http://example.com/followers', 'LocalPublic'] }
|
||||
let(:active_friend) { true }
|
||||
|
||||
it 'create status' do
|
||||
status = sender.statuses.first
|
||||
|
||||
|
@ -1506,11 +1540,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
|||
context 'when sender is in friend server' do
|
||||
subject { described_class.new(json, sender, delivery: true) }
|
||||
|
||||
before do
|
||||
Fabricate(:friend_domain, domain: sender.domain, active_state: :accepted, passive_state: :accepted)
|
||||
subject.perform
|
||||
end
|
||||
|
||||
let!(:friend) { Fabricate(:friend_domain, domain: sender.domain, active_state: :accepted) }
|
||||
let(:object_json) do
|
||||
{
|
||||
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
|
||||
|
@ -1520,11 +1550,20 @@ RSpec.describe ActivityPub::Activity::Create do
|
|||
end
|
||||
|
||||
it 'creates status' do
|
||||
subject.perform
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to_not be_nil
|
||||
expect(status.text).to eq 'Lorem ipsum'
|
||||
end
|
||||
|
||||
it 'whey no-relay not creates status' do
|
||||
friend.update(allow_all_posts: false)
|
||||
subject.perform
|
||||
status = sender.statuses.first
|
||||
|
||||
expect(status).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the sender has no relevance to local activity' do
|
||||
|
|
|
@ -339,6 +339,37 @@ RSpec.describe ActivityPub::Activity::Follow do
|
|||
expect(friend).to_not be_nil
|
||||
expect(friend.they_are_pending?).to be true
|
||||
expect(friend.passive_follow_activity_id).to eq 'foo'
|
||||
expect(friend.inbox_url).to eq 'https://abc.com/inbox'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when my server is pending' do
|
||||
before do
|
||||
friend.update(active_state: :pending)
|
||||
end
|
||||
|
||||
it 'marks me as idle' do
|
||||
subject.perform
|
||||
expect(friend.reload.they_are_pending?).to be true
|
||||
expect(friend.i_am_idle?).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'when my server is already accepted' do
|
||||
before do
|
||||
friend.update(active_state: :accepted)
|
||||
stub_request(:post, 'https://example.com/inbox')
|
||||
end
|
||||
|
||||
it 'marks me as idle and the friend as accepted' do
|
||||
subject.perform
|
||||
expect(friend.reload.they_are_accepted?).to be true
|
||||
expect(friend.i_am_idle?).to be true
|
||||
expect(a_request(:post, 'https://example.com/inbox').with(body: hash_including({
|
||||
id: 'foo#accepts/friends',
|
||||
type: 'Accept',
|
||||
object: 'foo',
|
||||
}))).to have_been_made.once
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -372,26 +403,6 @@ RSpec.describe ActivityPub::Activity::Follow do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when unlocked' do
|
||||
before do
|
||||
friend.update(unlocked: true)
|
||||
stub_request(:post, 'https://example.com/inbox')
|
||||
end
|
||||
|
||||
it 'marks the friend as accepted' do
|
||||
subject.perform
|
||||
|
||||
friend = FriendDomain.find_by(domain: 'abc.com')
|
||||
expect(friend).to_not be_nil
|
||||
expect(friend.they_are_accepted?).to be true
|
||||
expect(a_request(:post, 'https://example.com/inbox').with(body: hash_including({
|
||||
id: 'foo#accepts/friends',
|
||||
type: 'Accept',
|
||||
object: 'foo',
|
||||
}))).to have_been_made.once
|
||||
end
|
||||
end
|
||||
|
||||
context 'when unlocked on admin settings' do
|
||||
before do
|
||||
Form::AdminSettings.new(unlocked_friend: '1').save
|
||||
|
|
|
@ -192,5 +192,19 @@ RSpec.describe ActivityPub::Activity::Reject do
|
|||
subject.perform
|
||||
expect(friend.reload.i_am_rejected?).to be true
|
||||
end
|
||||
|
||||
it 'when the friend server is pending' do
|
||||
friend.update(passive_state: :pending)
|
||||
subject.perform
|
||||
expect(friend.reload.they_are_idle?).to be true
|
||||
expect(friend.i_am_rejected?).to be true
|
||||
end
|
||||
|
||||
it 'when the friend server is accepted' do
|
||||
friend.update(passive_state: :accepted)
|
||||
subject.perform
|
||||
expect(friend.reload.they_are_idle?).to be true
|
||||
expect(friend.i_am_rejected?).to be true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -149,7 +149,7 @@ RSpec.describe ActivityPub::Activity::Undo do
|
|||
friend = Fabricate(:friend_domain, domain: sender.domain, passive_state: :accepted)
|
||||
subject.perform
|
||||
expect(sender.following?(recipient)).to be false
|
||||
expect(friend.they_are_accepted?).to be true
|
||||
expect(friend.reload.they_are_accepted?).to be true
|
||||
end
|
||||
|
||||
context 'with only object uri' do
|
||||
|
@ -175,8 +175,19 @@ RSpec.describe ActivityPub::Activity::Undo do
|
|||
|
||||
it 'deletes follow from this server to friend' do
|
||||
subject.perform
|
||||
expect(friend.reload.they_are_idle?).to be true
|
||||
expect(friend.passive_follow_activity_id).to be_nil
|
||||
expect(FriendDomain.exists?(domain: 'abc.com')).to be false
|
||||
end
|
||||
|
||||
it 'when my server is pending' do
|
||||
friend.update(active_state: :pending)
|
||||
subject.perform
|
||||
expect(FriendDomain.exists?(domain: 'abc.com')).to be false
|
||||
end
|
||||
|
||||
it 'when my server is accepted' do
|
||||
friend.update(active_state: :accepted)
|
||||
subject.perform
|
||||
expect(FriendDomain.exists?(domain: 'abc.com')).to be false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -99,7 +99,7 @@ describe StatusReachFinder do
|
|||
let(:sender_software) { 'misskey' }
|
||||
let(:searchability) { :public }
|
||||
|
||||
before { Fabricate(:friend_domain, domain: 'foo.bar', inbox_url: 'https://foo.bar/inbox', available: true, active_state: :accepted, passive_state: :accepted, pseudo_relay: true) }
|
||||
before { Fabricate(:friend_domain, domain: 'foo.bar', inbox_url: 'https://foo.bar/inbox', available: true, active_state: :accepted, pseudo_relay: true) }
|
||||
|
||||
it 'send status without friend server' do
|
||||
expect(subject.inboxes).to_not include 'https://foo.bar/inbox'
|
||||
|
@ -114,7 +114,7 @@ describe StatusReachFinder do
|
|||
|
||||
context 'with follower' do
|
||||
before do
|
||||
Fabricate(:friend_domain, domain: 'foo.bar', active_state: :accepted)
|
||||
Fabricate(:friend_domain, domain: 'foo.bar', inbox_url: 'https://foo.bar/inbox', active_state: :accepted)
|
||||
bob.follow!(alice)
|
||||
end
|
||||
|
||||
|
@ -124,9 +124,21 @@ describe StatusReachFinder do
|
|||
end
|
||||
end
|
||||
|
||||
context 'with non-follower' do
|
||||
context 'with follower but not local-distributable' do
|
||||
before do
|
||||
Fabricate(:friend_domain, domain: 'foo.bar', active_state: :accepted)
|
||||
Fabricate(:friend_domain, domain: 'foo.bar', inbox_url: 'https://foo.bar/inbox', active_state: :accepted, delivery_local: false)
|
||||
bob.follow!(alice)
|
||||
end
|
||||
|
||||
it 'send status' do
|
||||
expect(subject.inboxes).to include 'https://foo.bar/inbox'
|
||||
expect(subject.inboxes_for_friend).to_not include 'https://foo.bar/inbox'
|
||||
end
|
||||
end
|
||||
|
||||
context 'with non-follower and non-relay' do
|
||||
before do
|
||||
Fabricate(:friend_domain, domain: 'foo.bar', inbox_url: 'https://foo.bar/inbox', active_state: :accepted)
|
||||
end
|
||||
|
||||
it 'send status' do
|
||||
|
@ -137,7 +149,7 @@ describe StatusReachFinder do
|
|||
|
||||
context 'with pending' do
|
||||
before do
|
||||
Fabricate(:friend_domain, domain: 'foo.bar', active_state: :pending)
|
||||
Fabricate(:friend_domain, domain: 'foo.bar', inbox_url: 'https://foo.bar/inbox', active_state: :pending)
|
||||
bob.follow!(alice)
|
||||
end
|
||||
|
||||
|
@ -147,21 +159,21 @@ describe StatusReachFinder do
|
|||
end
|
||||
end
|
||||
|
||||
context 'with idle' do
|
||||
context 'with unidirection from them' do
|
||||
before do
|
||||
Fabricate(:friend_domain, domain: 'foo.bar', active_state: :idle, passive_state: :accepted)
|
||||
Fabricate(:friend_domain, domain: 'foo.bar', inbox_url: 'https://foo.bar/inbox', active_state: :idle, passive_state: :accepted)
|
||||
bob.follow!(alice)
|
||||
end
|
||||
|
||||
it 'send status' do
|
||||
expect(subject.inboxes).to include 'https://foo.bar/inbox'
|
||||
expect(subject.inboxes_for_friend).to_not include 'https://foo.bar/inbox'
|
||||
expect(subject.inboxes).to_not include 'https://foo.bar/inbox'
|
||||
expect(subject.inboxes_for_friend).to include 'https://foo.bar/inbox'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when unavailable' do
|
||||
before do
|
||||
Fabricate(:friend_domain, domain: 'foo.bar', active_state: :accepted, available: false)
|
||||
Fabricate(:friend_domain, domain: 'foo.bar', inbox_url: 'https://foo.bar/inbox', active_state: :accepted, available: false)
|
||||
bob.follow!(alice)
|
||||
end
|
||||
|
||||
|
@ -173,7 +185,18 @@ describe StatusReachFinder do
|
|||
|
||||
context 'when distributable' do
|
||||
before do
|
||||
Fabricate(:friend_domain, domain: 'foo.bar', active_state: :accepted, passive_state: :accepted, pseudo_relay: true)
|
||||
Fabricate(:friend_domain, domain: 'foo.bar', inbox_url: 'https://foo.bar/inbox', passive_state: :accepted, pseudo_relay: true)
|
||||
end
|
||||
|
||||
it 'send status' do
|
||||
expect(subject.inboxes).to_not include 'https://foo.bar/inbox'
|
||||
expect(subject.inboxes_for_friend).to include 'https://foo.bar/inbox'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when distributable and following' do
|
||||
before do
|
||||
Fabricate(:friend_domain, domain: 'foo.bar', inbox_url: 'https://foo.bar/inbox', passive_state: :accepted, pseudo_relay: true)
|
||||
bob.follow!(alice)
|
||||
end
|
||||
|
||||
|
@ -183,9 +206,9 @@ describe StatusReachFinder do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when distributable and not following' do
|
||||
context 'when distributable reverse' do
|
||||
before do
|
||||
Fabricate(:friend_domain, domain: 'foo.bar', inbox_url: 'https://foo.bar/inbox', active_state: :accepted, passive_state: :accepted, pseudo_relay: true)
|
||||
Fabricate(:friend_domain, domain: 'foo.bar', inbox_url: 'https://foo.bar/inbox', active_state: :accepted, pseudo_relay: true)
|
||||
end
|
||||
|
||||
it 'send status' do
|
||||
|
@ -193,10 +216,35 @@ describe StatusReachFinder do
|
|||
expect(subject.inboxes_for_friend).to include 'https://foo.bar/inbox'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when distributable but not local distributable' do
|
||||
before do
|
||||
Fabricate(:friend_domain, domain: 'foo.bar', inbox_url: 'https://foo.bar/inbox', passive_state: :accepted, pseudo_relay: true, delivery_local: false)
|
||||
end
|
||||
|
||||
it 'send status' do
|
||||
expect(subject.inboxes).to include 'https://foo.bar/inbox'
|
||||
expect(subject.inboxes_for_friend).to_not include 'https://foo.bar/inbox'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when distributable and following but not local distributable' do
|
||||
before do
|
||||
Fabricate(:friend_domain, domain: 'foo.bar', passive_state: :accepted, pseudo_relay: true, delivery_local: false)
|
||||
bob.follow!(alice)
|
||||
end
|
||||
|
||||
it 'send status' do
|
||||
expect(subject.inboxes).to include 'https://foo.bar/inbox'
|
||||
expect(subject.inboxes_for_friend).to_not include 'https://foo.bar/inbox'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when it contains distributable friend server' do
|
||||
before { Fabricate(:friend_domain, domain: 'foo.bar', inbox_url: 'https://foo.bar/inbox', available: true, active_state: :accepted, passive_state: :accepted, pseudo_relay: true) }
|
||||
before do
|
||||
Fabricate(:friend_domain, domain: 'foo.bar', inbox_url: 'https://foo.bar/inbox', passive_state: :accepted, pseudo_relay: true)
|
||||
end
|
||||
|
||||
it 'includes the inbox of the mentioned account' do
|
||||
expect(subject.inboxes).to_not include 'https://foo.bar/inbox'
|
||||
|
@ -381,9 +429,11 @@ describe StatusReachFinder do
|
|||
Fabricate(:friend_domain, domain: 'def.com', inbox_url: 'https://def.com/inbox', active_state: :accepted, passive_state: :accepted, pseudo_relay: true, available: true)
|
||||
Fabricate(:friend_domain, domain: 'ghi.com', inbox_url: 'https://ghi.com/inbox', active_state: :accepted, passive_state: :accepted, pseudo_relay: true, available: false)
|
||||
Fabricate(:friend_domain, domain: 'jkl.com', inbox_url: 'https://jkl.com/inbox', active_state: :accepted, passive_state: :accepted, pseudo_relay: false, available: true)
|
||||
Fabricate(:friend_domain, domain: 'mno.com', inbox_url: 'https://mno.com/inbox', active_state: :accepted, passive_state: :pending, pseudo_relay: true, available: true)
|
||||
Fabricate(:friend_domain, domain: 'mno.com', inbox_url: 'https://mno.com/inbox', active_state: :accepted, passive_state: :idle, pseudo_relay: true, available: true)
|
||||
Fabricate(:friend_domain, domain: 'pqr.com', inbox_url: 'https://pqr.com/inbox', active_state: :accepted, passive_state: :accepted, pseudo_relay: true, available: true)
|
||||
Fabricate(:unavailable_domain, domain: 'pqr.com')
|
||||
Fabricate(:friend_domain, domain: 'stu.com', inbox_url: 'https://stu.com/inbox', active_state: :idle, passive_state: :accepted, pseudo_relay: true, available: true)
|
||||
Fabricate(:friend_domain, domain: 'vwx.com', inbox_url: 'https://vwx.com/inbox', active_state: :idle, passive_state: :accepted, pseudo_relay: true, available: true, delivery_local: false)
|
||||
end
|
||||
|
||||
it 'returns friend servers' do
|
||||
|
@ -399,8 +449,13 @@ describe StatusReachFinder do
|
|||
expect(subject).to_not include 'https://jkl.com/inbox'
|
||||
end
|
||||
|
||||
it 'not contains no-mutual friends' do
|
||||
expect(subject).to_not include 'https://mno.com/inbox'
|
||||
it 'contains no-mutual friends' do
|
||||
expect(subject).to include 'https://mno.com/inbox'
|
||||
expect(subject).to include 'https://stu.com/inbox'
|
||||
end
|
||||
|
||||
it 'not contains un local distable' do
|
||||
expect(subject).to_not include 'https://vwx.com/inbox'
|
||||
end
|
||||
|
||||
it 'not contains unavailable domain friends' do
|
||||
|
|
|
@ -11,9 +11,11 @@ describe FriendDomain do
|
|||
|
||||
describe '#follow!' do
|
||||
it 'call inbox' do
|
||||
friend.update(active_state: :accepted, passive_state: :accepted)
|
||||
friend.follow!
|
||||
expect(friend.active_follow_activity_id).to_not be_nil
|
||||
expect(friend.i_am_pending?).to be true
|
||||
expect(friend.they_are_idle?).to be true
|
||||
expect(a_request(:post, 'https://foo.bar/inbox').with(body: hash_including({
|
||||
id: friend.active_follow_activity_id,
|
||||
type: 'Follow',
|
||||
|
@ -25,10 +27,11 @@ describe FriendDomain do
|
|||
|
||||
describe '#unfollow!' do
|
||||
it 'call inbox' do
|
||||
friend.update(active_follow_activity_id: 'ohagi')
|
||||
friend.update(active_follow_activity_id: 'ohagi', active_state: :accepted, passive_state: :accepted)
|
||||
friend.unfollow!
|
||||
expect(friend.active_follow_activity_id).to be_nil
|
||||
expect(friend.i_am_idle?).to be true
|
||||
expect(friend.they_are_idle?).to be true
|
||||
expect(a_request(:post, 'https://foo.bar/inbox').with(body: hash_including({
|
||||
type: 'Undo',
|
||||
object: {
|
||||
|
@ -43,9 +46,10 @@ describe FriendDomain do
|
|||
|
||||
describe '#accept!' do
|
||||
it 'call inbox' do
|
||||
friend.update(passive_follow_activity_id: 'ohagi', passive_state: :pending)
|
||||
friend.update(passive_follow_activity_id: 'ohagi', active_state: :accepted, passive_state: :pending)
|
||||
friend.accept!
|
||||
expect(friend.they_are_accepted?).to be true
|
||||
expect(friend.i_am_idle?).to be true
|
||||
expect(a_request(:post, 'https://foo.bar/inbox').with(body: hash_including({
|
||||
id: 'ohagi#accepts/friends',
|
||||
type: 'Accept',
|
||||
|
@ -57,9 +61,10 @@ describe FriendDomain do
|
|||
|
||||
describe '#reject!' do
|
||||
it 'call inbox' do
|
||||
friend.update(passive_follow_activity_id: 'ohagi', passive_state: :pending)
|
||||
friend.update(passive_follow_activity_id: 'ohagi', active_state: :accepted, passive_state: :pending)
|
||||
friend.reject!
|
||||
expect(friend.they_are_rejected?).to be true
|
||||
expect(friend.i_am_idle?).to be true
|
||||
expect(a_request(:post, 'https://foo.bar/inbox').with(body: hash_including({
|
||||
id: 'ohagi#rejects/friends',
|
||||
type: 'Reject',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue