PluginProbe
ActivityPub / trunk
ActivityPub vtrunk
9.3.1 9.3.0 9.2.2 9.2.1 9.2.0 9.1.0 9.0.2 9.0.1 9.0.0 8.3.0 8.2.1 8.2.0 8.1.1 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.2.0 1.3.0 2.0.0 2.0.1 2.1.0 2.1.1 All 160 releases
activitypub / includes / handler / class-accept.php

class-accept.php in ActivityPub trunk, at includes/handler/class-accept.php

111 lines 3.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Accept handler file.
4 *
5 * @package Activitypub
6 */
7
8 namespace Activitypub\Handler;
9
10 use Activitypub\Collection\Following;
11 use Activitypub\Collection\Outbox;
12 use Activitypub\Collection\Remote_Actors;
13
14 use function Activitypub\is_same_actor;
15 use function Activitypub\object_to_uri;
16
17 /**
18 * Handle Accept requests.
19 */
20 class Accept {
21 /**
22 * Initialize the class, registering WordPress hooks.
23 */
24 public static function init() {
25 \add_action( 'activitypub_inbox_accept', array( self::class, 'handle_accept' ), 10, 2 );
26 \add_filter( 'activitypub_validate_object', array( self::class, 'validate_object' ), 10, 3 );
27 }
28
29 /**
30 * Handles "Accept" requests.
31 *
32 * @param array $accept The activity-object.
33 * @param int|int[] $user_ids The id of the local blog-user.
34 */
35 public static function handle_accept( $accept, $user_ids ) {
36 // Validate that there is a Follow Activity.
37 $outbox_post = Outbox::get_by_guid( $accept['object']['id'] );
38
39 if (
40 \is_wp_error( $outbox_post ) ||
41 'Follow' !== \get_post_meta( $outbox_post->ID, '_activitypub_activity_type', true )
42 ) {
43 return;
44 }
45
46 /*
47 * For a Follow Accept, the sender must be the actor that was followed.
48 * Without this, a signed Accept from one actor could confirm a Follow that
49 * targeted another actor by referencing that pending Follow's outbox GUID.
50 */
51 if ( ! is_same_actor( $accept['actor'] ?? '', $accept['object']['object'] ?? '' ) ) {
52 return;
53 }
54
55 $actor_post = Remote_Actors::get_by_uri( object_to_uri( $accept['object']['object'] ?? '' ) );
56
57 if ( \is_wp_error( $actor_post ) ) {
58 return;
59 }
60
61 $user_id = \is_array( $user_ids ) ? \reset( $user_ids ) : $user_ids;
62 $result = Following::accept( $actor_post, $user_id );
63 $success = ! \is_wp_error( $result );
64
65 /**
66 * Fires after an ActivityPub Accept activity has been handled.
67 *
68 * @param array $accept The ActivityPub activity data.
69 * @param int[] $user_ids The local user IDs.
70 * @param bool $success True on success, false otherwise.
71 * @param \WP_Post|\WP_Error $result The remote actor post or error.
72 */
73 \do_action( 'activitypub_handled_accept', $accept, (array) $user_ids, $success, $result );
74 }
75
76 /**
77 * Validate the object.
78 *
79 * @param bool $valid The validation state.
80 * @param string $param The object parameter.
81 * @param \WP_REST_Request $request The request object.
82 *
83 * @return bool The validation state: true if valid, false if not.
84 */
85 public static function validate_object( $valid, $param, $request ) {
86 $activity = $request->get_json_params();
87
88 if ( empty( $activity['type'] ) ) {
89 return false;
90 }
91
92 if ( 'Accept' !== $activity['type'] ) {
93 return $valid;
94 }
95
96 if ( ! isset( $activity['actor'], $activity['object'] ) ) {
97 return false;
98 }
99
100 if ( ! \is_array( $activity['object'] ) ) {
101 return false;
102 }
103
104 if ( ! isset( $activity['object']['id'], $activity['object']['type'], $activity['object']['actor'], $activity['object']['object'] ) ) {
105 return false;
106 }
107
108 return $valid;
109 }
110 }
111