Skip to content

Commit f23f672

Browse files
authored
Move the canFeature policy out of the Activity vocabulary layer (#3406)
1 parent dcbb961 commit f23f672

5 files changed

Lines changed: 127 additions & 39 deletions

File tree

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Significance: patch
2+
Type: fixed
3+
4+
Publish the Starter Kit consent policy only on your own blog and author profiles, no longer on system or third-party profiles.

includes/activity/class-actor.php

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -382,43 +382,4 @@ class Actor extends Base_Object {
382382
* @var boolean|null
383383
*/
384384
protected $invisible = null;
385-
386-
/**
387-
* Get the actor-level interaction policy.
388-
*
389-
* Overrides the magic property accessor on Base_Object so that we always
390-
* compute the policy from the current site setting rather than returning a
391-
* cached property value. Currently only emits `canFeature` (FEP-7aa9).
392-
* Driven by the site option `activitypub_default_feature_policy` and
393-
* defaults to denying all featured-collection requests, in line with
394-
* FEP-7aa9's "absence of policy = no consent" rule.
395-
*
396-
* @see https://w3id.org/fep/7aa9
397-
*
398-
* @since 9.0.0
399-
*
400-
* @return array
401-
*/
402-
public function get_interaction_policy() {
403-
return array_merge( (array) parent::get_interaction_policy(), array( 'canFeature' => $this->build_can_feature_policy() ) );
404-
}
405-
406-
/**
407-
* Build the `canFeature` policy array from the site option.
408-
*
409-
* @return array
410-
*/
411-
protected function build_can_feature_policy() {
412-
$policy = \get_option( 'activitypub_default_feature_policy', ACTIVITYPUB_INTERACTION_POLICY_ME );
413-
414-
switch ( $policy ) {
415-
case ACTIVITYPUB_INTERACTION_POLICY_ANYONE:
416-
return array( 'automaticApproval' => array( 'https://www.w3.org/ns/activitystreams#Public' ) );
417-
case ACTIVITYPUB_INTERACTION_POLICY_FOLLOWERS:
418-
return array( 'automaticApproval' => array( $this->get_followers() ) );
419-
case ACTIVITYPUB_INTERACTION_POLICY_ME:
420-
default:
421-
return array( 'automaticApproval' => array( $this->get_id() ) );
422-
}
423-
}
424385
}

includes/model/class-blog.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,4 +601,50 @@ public function get_moved_to() {
601601

602602
return $moved_to && $moved_to !== $this->get_id() ? $moved_to : null;
603603
}
604+
605+
/**
606+
* Get the actor-level interaction policy.
607+
*
608+
* Overrides the magic property accessor on Base_Object so that we always
609+
* compute the policy from the current site setting rather than returning a
610+
* cached property value. Currently only emits `canFeature` (FEP-7aa9).
611+
* Driven by the site option `activitypub_default_feature_policy` and
612+
* defaults to denying all featured-collection requests, in line with
613+
* FEP-7aa9's "absence of policy = no consent" rule.
614+
*
615+
* @see https://w3id.org/fep/7aa9
616+
*
617+
* @since 9.0.0
618+
*
619+
* @return array
620+
*/
621+
public function get_interaction_policy() {
622+
$policy = array( 'canFeature' => $this->build_can_feature_policy() );
623+
624+
// Merge with an explicitly set interaction policy, if any.
625+
if ( $this->interaction_policy ) {
626+
$policy = \array_merge( (array) $this->interaction_policy, $policy );
627+
}
628+
629+
return $policy;
630+
}
631+
632+
/**
633+
* Build the `canFeature` policy array from the site option.
634+
*
635+
* @return array
636+
*/
637+
protected function build_can_feature_policy() {
638+
$policy = \get_option( 'activitypub_default_feature_policy', ACTIVITYPUB_INTERACTION_POLICY_ME );
639+
640+
switch ( $policy ) {
641+
case ACTIVITYPUB_INTERACTION_POLICY_ANYONE:
642+
return array( 'automaticApproval' => array( 'https://www.w3.org/ns/activitystreams#Public' ) );
643+
case ACTIVITYPUB_INTERACTION_POLICY_FOLLOWERS:
644+
return array( 'automaticApproval' => array( $this->get_followers() ) );
645+
case ACTIVITYPUB_INTERACTION_POLICY_ME:
646+
default:
647+
return array( 'automaticApproval' => array( $this->get_id() ) );
648+
}
649+
}
604650
}

includes/model/class-user.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,4 +483,50 @@ public function get_moved_to() {
483483

484484
return $moved_to && $moved_to !== $this->get_id() ? $moved_to : null;
485485
}
486+
487+
/**
488+
* Get the actor-level interaction policy.
489+
*
490+
* Overrides the magic property accessor on Base_Object so that we always
491+
* compute the policy from the current site setting rather than returning a
492+
* cached property value. Currently only emits `canFeature` (FEP-7aa9).
493+
* Driven by the site option `activitypub_default_feature_policy` and
494+
* defaults to denying all featured-collection requests, in line with
495+
* FEP-7aa9's "absence of policy = no consent" rule.
496+
*
497+
* @see https://w3id.org/fep/7aa9
498+
*
499+
* @since 9.0.0
500+
*
501+
* @return array
502+
*/
503+
public function get_interaction_policy() {
504+
$policy = array( 'canFeature' => $this->build_can_feature_policy() );
505+
506+
// Merge with an explicitly set interaction policy, if any.
507+
if ( $this->interaction_policy ) {
508+
$policy = \array_merge( (array) $this->interaction_policy, $policy );
509+
}
510+
511+
return $policy;
512+
}
513+
514+
/**
515+
* Build the `canFeature` policy array from the site option.
516+
*
517+
* @return array
518+
*/
519+
protected function build_can_feature_policy() {
520+
$policy = \get_option( 'activitypub_default_feature_policy', ACTIVITYPUB_INTERACTION_POLICY_ME );
521+
522+
switch ( $policy ) {
523+
case ACTIVITYPUB_INTERACTION_POLICY_ANYONE:
524+
return array( 'automaticApproval' => array( 'https://www.w3.org/ns/activitystreams#Public' ) );
525+
case ACTIVITYPUB_INTERACTION_POLICY_FOLLOWERS:
526+
return array( 'automaticApproval' => array( $this->get_followers() ) );
527+
case ACTIVITYPUB_INTERACTION_POLICY_ME:
528+
default:
529+
return array( 'automaticApproval' => array( $this->get_id() ) );
530+
}
531+
}
486532
}

tests/phpunit/tests/includes/model/class-test-interaction-policy.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,35 @@ public function test_blog_actor_emits_canfeature() {
9898
'Blog actor must default to explicit denial (its own id as the only approved target).'
9999
);
100100
}
101+
102+
/**
103+
* The generic Activity\Actor carries no application logic: it must not
104+
* compute a canFeature policy from the local site option, since it also
105+
* represents remote actors.
106+
*/
107+
public function test_generic_actor_does_not_emit_local_canfeature() {
108+
\update_option( 'activitypub_default_feature_policy', ACTIVITYPUB_INTERACTION_POLICY_ANYONE );
109+
110+
$actor = \Activitypub\Activity\Actor::init_from_array(
111+
array(
112+
'id' => 'https://remote.example/users/jane',
113+
'type' => 'Person',
114+
)
115+
);
116+
117+
$this->assertNull( $actor->get_interaction_policy(), 'A generic actor must not inherit the local canFeature policy.' );
118+
}
119+
120+
/**
121+
* The Application actor advertises no canFeature policy (absence of
122+
* policy means no consent per FEP-7aa9).
123+
*/
124+
public function test_application_actor_emits_no_interaction_policy() {
125+
\update_option( 'activitypub_default_feature_policy', ACTIVITYPUB_INTERACTION_POLICY_ANYONE );
126+
127+
$application = new \Activitypub\Model\Application();
128+
129+
$this->assertNull( $application->get_interaction_policy() );
130+
$this->assertArrayNotHasKey( 'interactionPolicy', $application->to_array( false ) );
131+
}
101132
}

0 commit comments

Comments
 (0)