| @@ -7,14 +7,13 @@ | ||
| 7 | 7 | |
| 8 | 8 | namespace Activitypub\Handler; |
| 9 | 9 | |
| 10 | 10 | use Activitypub\Collection\Interactions; |
| 11 | +use Activitypub\Collection\Posts; | |
| 11 | 12 | use Activitypub\Collection\Remote_Actors; |
| 12 | -use Activitypub\Collection\Remote_Posts; | |
| 13 | -use Activitypub\Http; | |
| 14 | 13 | |
| 14 | +use function Activitypub\get_remote_metadata_by_actor; | |
| 15 | 15 | use function Activitypub\is_activity_reply; |
| 16 | -use function Activitypub\object_to_uri; | |
| 17 | 16 | |
| 18 | 17 | /** |
| 19 | 18 | * Handle Update requests. |
| 20 | 19 | */ |
| @@ -29,9 +28,9 @@ | ||
| 29 | 28 | /** |
| 30 | 29 | * Handle "Update" requests. |
| 31 | 30 | * |
| 32 | 31 | * @param array $activity The Activity object. |
| 33 | - * @param int[] $user_ids Local recipient user IDs (followers and addressed local actors); may be empty. | |
| 32 | + * @param int[] $user_ids The user IDs. Always null for Update activities. | |
| 34 | 33 | * @param \Activitypub\Activity\Activity $activity_object The activity object. Default null. |
| 35 | 34 | */ |
| 36 | 35 | public static function handle_update( $activity, $user_ids, $activity_object ) { |
| 37 | 36 | $object_type = $activity['object']['type'] ?? ''; |
| @@ -78,9 +77,9 @@ | ||
| 78 | 77 | /** |
| 79 | 78 | * Update an Object. |
| 80 | 79 | * |
| 81 | 80 | * @param array $activity The Activity object. |
| 82 | - * @param int[]|null $user_ids Local recipient user IDs (followers and addressed local actors); may be empty. | |
| 81 | + * @param int[]|null $user_ids The user IDs. Always null for Update activities. | |
| 83 | 82 | * @param \Activitypub\Activity\Activity $activity_object The activity object. Default null. |
| 84 | 83 | */ |
| 85 | 84 | public static function update_object( $activity, $user_ids, $activity_object ) { |
| 86 | 85 | $result = new \WP_Error( 'activitypub_update_failed', 'Update failed' ); |
| @@ -91,17 +90,13 @@ | ||
| 91 | 90 | $comment_data = Interactions::update_comment( $activity ); |
| 92 | 91 | |
| 93 | 92 | if ( false === $comment_data ) { |
| 94 | 93 | $updated = false; |
| 95 | - } elseif ( \is_wp_error( $comment_data ) ) { | |
| 96 | - // Handled but rejected (e.g. a foreign actor): keep the failure so the | |
| 97 | - // success flag stays false and the Create fallback is not triggered. | |
| 98 | - $result = $comment_data; | |
| 99 | 94 | } elseif ( ! empty( $comment_data['comment_ID'] ) ) { |
| 100 | 95 | $result = \get_comment( $comment_data['comment_ID'] ); |
| 101 | 96 | } |
| 102 | 97 | } elseif ( \get_option( 'activitypub_create_posts', false ) ) { |
| 103 | - $result = Remote_Posts::update( $activity, $user_ids ); | |
| 98 | + $result = Posts::update( $activity, $user_ids ); | |
| 104 | 99 | |
| 105 | 100 | if ( \is_wp_error( $result ) && 'activitypub_post_not_found' === $result->get_error_code() ) { |
| 106 | 101 | $updated = false; |
| 107 | 102 | } |
| @@ -128,43 +123,18 @@ | ||
| 128 | 123 | /** |
| 129 | 124 | * Update an Actor. |
| 130 | 125 | * |
| 131 | 126 | * @param array $activity The Activity object. |
| 132 | - * @param int[]|null $user_ids Local recipient user IDs (followers and addressed local actors); may be empty. | |
| 127 | + * @param int[]|null $user_ids The user IDs. Always null for Update activities. | |
| 133 | 128 | */ |
| 134 | 129 | public static function update_actor( $activity, $user_ids ) { |
| 135 | - /* | |
| 136 | - * Prefer the actor data embedded in the activity object, as it contains | |
| 137 | - * the fresh data sent by the remote server. | |
| 138 | - */ | |
| 139 | - $actor = $activity['object'] ?? null; | |
| 130 | + // Update cache. | |
| 131 | + $actor = get_remote_metadata_by_actor( $activity['actor'], false ); | |
| 140 | 132 | |
| 141 | - /* | |
| 142 | - * The object may be a string IRI instead of an embedded object, | |
| 143 | - * in which case we need to fetch the actor data remotely. | |
| 144 | - * We use Http::get_remote_object() directly instead of | |
| 145 | - * get_remote_metadata_by_actor() because the latter returns the | |
| 146 | - * stale locally cached copy via fetch_by_uri(). | |
| 147 | - */ | |
| 148 | - if ( ! \is_array( $actor ) || ! isset( $actor['id'] ) ) { | |
| 149 | - $object = Http::get_remote_object( $activity['actor'], false ); | |
| 150 | - | |
| 151 | - if ( ! \is_wp_error( $object ) && \is_array( $object ) ) { | |
| 152 | - $actor = $object; | |
| 153 | - } | |
| 154 | - } | |
| 155 | - | |
| 156 | - /* | |
| 157 | - * An actor may only update itself. Bind the updated object to the activity | |
| 158 | - * actor (the same constraint the Delete handler enforces) so a remote server | |
| 159 | - * cannot overwrite another host's cached actor by sending an Update whose | |
| 160 | - * object.id points at a victim actor. | |
| 161 | - */ | |
| 162 | - if ( \is_array( $actor ) && isset( $actor['id'] ) && object_to_uri( $actor ) === object_to_uri( $activity['actor'] ) ) { | |
| 133 | + if ( ! $actor || \is_wp_error( $actor ) || ! isset( $actor['id'] ) ) { | |
| 134 | + $state = new \WP_Error( 'activitypub_update_failed', 'Update failed: could not fetch actor data' ); | |
| 135 | + } else { | |
| 163 | 136 | $state = Remote_Actors::upsert( $actor ); |
| 164 | - } else { | |
| 165 | - $state = new \WP_Error( 'activitypub_update_failed', \__( 'Update failed: missing, invalid, or unauthorized actor object in Update activity.', 'activitypub' ) ); | |
| 166 | - $actor = array(); | |
| 167 | 137 | } |
| 168 | 138 | |
| 169 | 139 | /** |
| 170 | 140 | * Fires after an ActivityPub Update activity has been handled. |