2
0

Add server-side support for handling posts with a quote policy allowing followers to quote (#36127)

This commit is contained in:
Claire
2025-09-15 17:03:44 +02:00
committed by GitHub
parent f5591346cc
commit e4bb0fc43a
5 changed files with 17 additions and 5 deletions

View File

@@ -88,6 +88,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
@status_parser = ActivityPub::Parser::StatusParser.new( @status_parser = ActivityPub::Parser::StatusParser.new(
@json, @json,
followers_collection: @account.followers_url, followers_collection: @account.followers_url,
following_collection: @account.following_url,
actor_uri: ActivityPub::TagManager.instance.uri_for(@account), actor_uri: ActivityPub::TagManager.instance.uri_for(@account),
object: @object object: @object
) )

View File

@@ -8,6 +8,7 @@ class ActivityPub::Parser::StatusParser
# @param [Hash] json # @param [Hash] json
# @param [Hash] options # @param [Hash] options
# @option options [String] :followers_collection # @option options [String] :followers_collection
# @option options [String] :following_collection
# @option options [String] :actor_uri # @option options [String] :actor_uri
# @option options [Hash] :object # @option options [Hash] :object
def initialize(json, **options) def initialize(json, **options)
@@ -146,8 +147,7 @@ class ActivityPub::Parser::StatusParser
flags |= Status::QUOTE_APPROVAL_POLICY_FLAGS[:public] if allowed_actors.delete('as:Public') || allowed_actors.delete('Public') || allowed_actors.delete('https://www.w3.org/ns/activitystreams#Public') flags |= Status::QUOTE_APPROVAL_POLICY_FLAGS[:public] if allowed_actors.delete('as:Public') || allowed_actors.delete('Public') || allowed_actors.delete('https://www.w3.org/ns/activitystreams#Public')
flags |= Status::QUOTE_APPROVAL_POLICY_FLAGS[:followers] if allowed_actors.delete(@options[:followers_collection]) flags |= Status::QUOTE_APPROVAL_POLICY_FLAGS[:followers] if allowed_actors.delete(@options[:followers_collection])
# TODO: we don't actually store that collection URI flags |= Status::QUOTE_APPROVAL_POLICY_FLAGS[:following] if allowed_actors.delete(@options[:following_collection])
# flags |= Status::QUOTE_APPROVAL_POLICY_FLAGS[:followed]
# Remove the special-meaning actor URI # Remove the special-meaning actor URI
allowed_actors.delete(@options[:actor_uri]) allowed_actors.delete(@options[:actor_uri])

View File

@@ -7,7 +7,7 @@ module Status::InteractionPolicyConcern
unsupported_policy: (1 << 0), unsupported_policy: (1 << 0),
public: (1 << 1), public: (1 << 1),
followers: (1 << 2), followers: (1 << 2),
followed: (1 << 3), following: (1 << 3),
}.freeze }.freeze
included do included do
@@ -30,6 +30,7 @@ module Status::InteractionPolicyConcern
return :denied if other_account.nil? || direct_visibility? return :denied if other_account.nil? || direct_visibility?
following_author = nil following_author = nil
followed_by_author = nil
# Post author is always allowed to quote themselves # Post author is always allowed to quote themselves
return :automatic if account_id == other_account.id return :automatic if account_id == other_account.id
@@ -44,6 +45,11 @@ module Status::InteractionPolicyConcern
return :automatic if following_author return :automatic if following_author
end end
if automatic_policy.anybits?(QUOTE_APPROVAL_POLICY_FLAGS[:following])
followed_by_author = account.following?(other_account) if followed_by_author.nil?
return :automatic if followed_by_author
end
# We don't know we are allowed by the automatic policy, considering the manual one # We don't know we are allowed by the automatic policy, considering the manual one
return :manual if manual_policy.anybits?(QUOTE_APPROVAL_POLICY_FLAGS[:public]) return :manual if manual_policy.anybits?(QUOTE_APPROVAL_POLICY_FLAGS[:public])
@@ -52,6 +58,11 @@ module Status::InteractionPolicyConcern
return :manual if following_author return :manual if following_author
end end
if manual_policy.anybits?(QUOTE_APPROVAL_POLICY_FLAGS[:following])
followed_by_author = account.following?(other_account) if followed_by_author.nil?
return :manual if followed_by_author
end
return :unknown if (automatic_policy | manual_policy).anybits?(QUOTE_APPROVAL_POLICY_FLAGS[:unsupported_policy]) return :unknown if (automatic_policy | manual_policy).anybits?(QUOTE_APPROVAL_POLICY_FLAGS[:unsupported_policy])
:denied :denied

View File

@@ -234,7 +234,7 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
policy = object.quote_approval_policy >> 16 policy = object.quote_approval_policy >> 16
approved_uris << ActivityPub::TagManager::COLLECTIONS[:public] if policy.anybits?(Status::QUOTE_APPROVAL_POLICY_FLAGS[:public]) approved_uris << ActivityPub::TagManager::COLLECTIONS[:public] if policy.anybits?(Status::QUOTE_APPROVAL_POLICY_FLAGS[:public])
approved_uris << ActivityPub::TagManager.instance.followers_uri_for(object.account) if policy.anybits?(Status::QUOTE_APPROVAL_POLICY_FLAGS[:followers]) approved_uris << ActivityPub::TagManager.instance.followers_uri_for(object.account) if policy.anybits?(Status::QUOTE_APPROVAL_POLICY_FLAGS[:followers])
approved_uris << ActivityPub::TagManager.instance.following_uri_for(object.account) if policy.anybits?(Status::QUOTE_APPROVAL_POLICY_FLAGS[:followed]) approved_uris << ActivityPub::TagManager.instance.following_uri_for(object.account) if policy.anybits?(Status::QUOTE_APPROVAL_POLICY_FLAGS[:following])
approved_uris << ActivityPub::TagManager.instance.uri_for(object.account) if approved_uris.empty? approved_uris << ActivityPub::TagManager.instance.uri_for(object.account) if approved_uris.empty?
{ {

View File

@@ -10,7 +10,7 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
@activity_json = activity_json @activity_json = activity_json
@json = object_json @json = object_json
@status_parser = ActivityPub::Parser::StatusParser.new(@json, followers_collection: status.account.followers_url, actor_uri: ActivityPub::TagManager.instance.uri_for(status.account)) @status_parser = ActivityPub::Parser::StatusParser.new(@json, followers_collection: status.account.followers_url, following_collection: status.account.following_url, actor_uri: ActivityPub::TagManager.instance.uri_for(status.account))
@uri = @status_parser.uri @uri = @status_parser.uri
@status = status @status = status
@account = status.account @account = status.account