From 789afccf9b9fc9e2a9f43de98fdfbc3590b417c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?KMY=EF=BC=88=E9=9B=AA=E3=81=82=E3=81=99=E3=81=8B=EF=BC=89?= Date: Thu, 21 Dec 2023 11:21:33 +0900 Subject: [PATCH] =?UTF-8?q?Change:=20=E6=99=82=E9=99=90=E6=8A=95=E7=A8=BF?= =?UTF-8?q?=E3=81=AF=E3=83=95=E3=82=A9=E3=83=AD=E3=83=AF=E3=83=BC=E4=BB=A5?= =?UTF-8?q?=E5=A4=96=E3=81=AB=E3=81=AFActivity=E3=82=92=E7=99=BA=E8=A1=8C?= =?UTF-8?q?=E3=81=97=E3=81=AA=E3=81=84=20(#250)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Change: 時限投稿はフォロワー以外にはActivityを発行しない * Fix: ドメイン単位の認証になるように * Add test and fix * Fix lint * Fix test * Fix test * Revert "Fix test" This reverts commit 22f1114b7f54e8c1e2e424484cae7a9bd8996686. * Revert "Fix lint" This reverts commit a828efa9be3437ff15ff496258af3e1239571e6f. * Revert "Revert "Fix lint"" This reverts commit 6a2d68f28a868d170f7ae4334046f21e704b14c8. * Revert "Revert "Fix test"" This reverts commit a21c0b9d3e0f3aff66992fccb41dd43fe4c0fc6b. --- app/controllers/statuses_controller.rb | 4 +- app/models/concerns/account/interactions.rb | 9 +++++ app/models/status.rb | 4 ++ app/policies/status_policy.rb | 13 +++++++ .../concerns/account/interactions_spec.rb | 37 +++++++++++++++++++ 5 files changed, 66 insertions(+), 1 deletion(-) diff --git a/app/controllers/statuses_controller.rb b/app/controllers/statuses_controller.rb index f5397c3b82..1e7a8f406c 100644 --- a/app/controllers/statuses_controller.rb +++ b/app/controllers/statuses_controller.rb @@ -29,7 +29,7 @@ class StatusesController < ApplicationController end format.json do - expires_in 3.minutes, public: true if @status.distributable? && public_fetch_mode? && !misskey_software? + expires_in 3.minutes, public: true if @status.distributable? && public_fetch_mode? && !misskey_software? && !@status.expires? render_with_cache json: @status, content_type: 'application/activity+json', serializer: status_activity_serializer, adapter: ActivityPub::Adapter, cancel_cache: misskey_software? end end @@ -64,6 +64,8 @@ class StatusesController < ApplicationController if request.authorization.present? && request.authorization.match(/^Bearer /i) raise Mastodon::NotPermittedError unless @status.capability_tokens.find_by(token: request.authorization.gsub(/^Bearer /i, '')) + elsif request.format == :json && @status.expires? + raise Mastodon::NotPermittedError unless StatusPolicy.new(signed_request_account, @status).show_activity? else authorize @status, :show? end diff --git a/app/models/concerns/account/interactions.rb b/app/models/concerns/account/interactions.rb index 93d40a24c0..ede0084b47 100644 --- a/app/models/concerns/account/interactions.rb +++ b/app/models/concerns/account/interactions.rb @@ -198,6 +198,15 @@ module Account::Interactions other_account.following?(self) end + def followed_by_domain?(other_domain, since = nil) + return true if other_domain.blank? + return false unless local? + + scope = followers + scope = scope.where('follows.created_at < ?', since) if since.present? + scope.exists?(domain: other_domain) + end + def mutual?(other_account) following?(other_account) && followed_by?(other_account) end diff --git a/app/models/status.rb b/app/models/status.rb index 5dea348ca7..389478db5d 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -253,6 +253,10 @@ class Status < ApplicationRecord !quote_of_id.nil? && !quote.nil? end + def expires? + scheduled_expiration_status.present? + end + def within_realtime_window? created_at >= REAL_TIME_WINDOW.ago end diff --git a/app/policies/status_policy.rb b/app/policies/status_policy.rb index 2251179247..fb88ace740 100644 --- a/app/policies/status_policy.rb +++ b/app/policies/status_policy.rb @@ -28,6 +28,13 @@ class StatusPolicy < ApplicationPolicy record.limited_visibility? ? owned_conversation? : owned? end + def show_activity? + return false unless show? + return true unless record.expires? + + following_author_domain? + end + def reblog? !requires_mention? && (!private? || owned?) && show? && !blocking_author? end @@ -115,6 +122,12 @@ class StatusPolicy < ApplicationPolicy @preloaded_relations[:following] ? @preloaded_relations[:following][author.id] : current_account.following?(author) end + def following_author_domain? + return false if current_account.nil? + + author.followed_by_domain?(current_account.domain, record.created_at) + end + def author record.account end diff --git a/spec/models/concerns/account/interactions_spec.rb b/spec/models/concerns/account/interactions_spec.rb index e1d7a187b7..48b78c4bf9 100644 --- a/spec/models/concerns/account/interactions_spec.rb +++ b/spec/models/concerns/account/interactions_spec.rb @@ -381,6 +381,43 @@ describe Account::Interactions do end end + describe '#followed_by_domain?' do + subject { account.followed_by_domain?('example.com') } + + let(:target_account) { Fabricate(:account, domain: 'example.com', uri: 'https://example.com/actor') } + + context 'when followed by target_account' do + it 'returns true' do + account.passive_relationships.create(account: target_account) + expect(subject).to be true + end + end + + context 'when not followed by target_account' do + it 'returns false' do + expect(subject).to be false + end + end + + context 'with status' do + subject { account.followed_by_domain?('example.com', '2022/12/24 10:00:00') } + + context 'when followed by target_account since the time' do + it 'returns true' do + account.passive_relationships.create(account: target_account, created_at: '2022/12/22 10:00:00') + expect(subject).to be true + end + end + + context 'when followed by target_account after the time' do + it 'returns false' do + account.passive_relationships.create(account: target_account, created_at: '2022/12/26 10:00:00') + expect(subject).to be false + end + end + end + end + describe '#blocking?' do subject { account.blocking?(target_account) }