PluginProbe
ActivityPub / 4.1.1
ActivityPub v4.1.1
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 / rest / class-inbox.php

class-inbox.php in ActivityPub 4.1.1, at includes/rest/class-inbox.php

327 lines 8.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Inbox REST-Class file.
4 *
5 * @package Activitypub
6 */
7
8 namespace Activitypub\Rest;
9
10 use WP_REST_Server;
11 use WP_REST_Response;
12 use Activitypub\Activity\Activity;
13 use Activitypub\Collection\Users as User_Collection;
14
15 use function Activitypub\get_context;
16 use function Activitypub\url_to_authorid;
17 use function Activitypub\get_rest_url_by_path;
18 use function Activitypub\get_masked_wp_version;
19 use function Activitypub\extract_recipients_from_activity;
20
21 /**
22 * ActivityPub Inbox REST-Class.
23 *
24 * @author Matthias Pfefferle
25 *
26 * @see https://www.w3.org/TR/activitypub/#inbox
27 */
28 class Inbox {
29 /**
30 * Initialize the class, registering WordPress hooks.
31 */
32 public static function init() {
33 self::register_routes();
34 }
35
36 /**
37 * Register routes.
38 */
39 public static function register_routes() {
40 \register_rest_route(
41 ACTIVITYPUB_REST_NAMESPACE,
42 '/inbox',
43 array(
44 array(
45 'methods' => WP_REST_Server::CREATABLE,
46 'callback' => array( self::class, 'shared_inbox_post' ),
47 'args' => self::shared_inbox_post_parameters(),
48 'permission_callback' => '__return_true',
49 ),
50 )
51 );
52
53 \register_rest_route(
54 ACTIVITYPUB_REST_NAMESPACE,
55 '/(users|actors)/(?P<user_id>[\w\-\.]+)/inbox',
56 array(
57 array(
58 'methods' => WP_REST_Server::CREATABLE,
59 'callback' => array( self::class, 'user_inbox_post' ),
60 'args' => self::user_inbox_post_parameters(),
61 'permission_callback' => '__return_true',
62 ),
63 array(
64 'methods' => WP_REST_Server::READABLE,
65 'callback' => array( self::class, 'user_inbox_get' ),
66 'args' => self::user_inbox_get_parameters(),
67 'permission_callback' => '__return_true',
68 ),
69 )
70 );
71 }
72
73 /**
74 * Renders the user-inbox.
75 *
76 * @param \WP_REST_Request $request The request object.
77 * @return WP_REST_Response|\WP_Error The response object or WP_Error.
78 */
79 public static function user_inbox_get( $request ) {
80 $user_id = $request->get_param( 'user_id' );
81 $user = User_Collection::get_by_various( $user_id );
82
83 if ( is_wp_error( $user ) ) {
84 return $user;
85 }
86
87 /**
88 * Action triggered prior to the ActivityPub profile being created and sent to the client.
89 */
90 \do_action( 'activitypub_rest_inbox_pre' );
91
92 $json = new \stdClass();
93
94 // phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
95 $json->{'@context'} = get_context();
96 $json->id = get_rest_url_by_path( sprintf( 'actors/%d/inbox', $user->get__id() ) );
97 $json->generator = 'http://wordpress.org/?v=' . get_masked_wp_version();
98 $json->type = 'OrderedCollectionPage';
99 $json->partOf = get_rest_url_by_path( sprintf( 'actors/%d/inbox', $user->get__id() ) );
100 $json->totalItems = 0;
101 $json->orderedItems = array();
102 $json->first = $json->partOf;
103 // phpcs:enable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
104
105 /**
106 * Filter the ActivityPub inbox array.
107 *
108 * @param array $json The ActivityPub inbox array.
109 */
110 $json = \apply_filters( 'activitypub_rest_inbox_array', $json );
111
112 /**
113 * Action triggered after the ActivityPub profile has been created and sent to the client.
114 */
115 \do_action( 'activitypub_inbox_post' );
116
117 $rest_response = new WP_REST_Response( $json, 200 );
118 $rest_response->header( 'Content-Type', 'application/activity+json; charset=' . get_option( 'blog_charset' ) );
119
120 return $rest_response;
121 }
122
123 /**
124 * Handles user-inbox requests.
125 *
126 * @param \WP_REST_Request $request The request object.
127 *
128 * @return WP_REST_Response|\WP_Error The response object or WP_Error.
129 */
130 public static function user_inbox_post( $request ) {
131 $user_id = $request->get_param( 'user_id' );
132 $user = User_Collection::get_by_various( $user_id );
133
134 if ( is_wp_error( $user ) ) {
135 return $user;
136 }
137
138 $data = $request->get_json_params();
139 $activity = Activity::init_from_array( $data );
140 $type = $request->get_param( 'type' );
141 $type = \strtolower( $type );
142
143 /**
144 * ActivityPub inbox action.
145 *
146 * @param array $data The data array.
147 * @param int|null $user_id The user ID.
148 * @param string $type The type of the activity.
149 * @param Activity $activity The Activity object.
150 */
151 \do_action( 'activitypub_inbox', $data, $user->get__id(), $type, $activity );
152
153 /**
154 * ActivityPub inbox action for specific activity types.
155 *
156 * @param array $data The data array.
157 * @param int|null $user_id The user ID.
158 * @param Activity $activity The Activity object.
159 */
160 \do_action( "activitypub_inbox_{$type}", $data, $user->get__id(), $activity );
161
162 $rest_response = new WP_REST_Response( array(), 202 );
163 $rest_response->header( 'Content-Type', 'application/activity+json; charset=' . get_option( 'blog_charset' ) );
164
165 return $rest_response;
166 }
167
168 /**
169 * The shared inbox.
170 *
171 * @param \WP_REST_Request $request The request object.
172 *
173 * @return WP_REST_Response
174 */
175 public static function shared_inbox_post( $request ) {
176 $data = $request->get_json_params();
177 $activity = Activity::init_from_array( $data );
178 $type = $request->get_param( 'type' );
179 $type = \strtolower( $type );
180
181 /**
182 * ActivityPub inbox action.
183 *
184 * @param array $data The data array.
185 * @param int|null $user_id The user ID.
186 * @param string $type The type of the activity.
187 * @param Activity $activity The Activity object.
188 */
189 \do_action( 'activitypub_inbox', $data, null, $type, $activity );
190
191 /**
192 * ActivityPub inbox action for specific activity types.
193 *
194 * @param array $data The data array.
195 * @param int|null $user_id The user ID.
196 * @param Activity $activity The Activity object.
197 */
198 \do_action( "activitypub_inbox_{$type}", $data, null, $activity );
199
200 $rest_response = new WP_REST_Response( array(), 202 );
201 $rest_response->header( 'Content-Type', 'application/activity+json; charset=' . get_option( 'blog_charset' ) );
202
203 return $rest_response;
204 }
205
206 /**
207 * The supported parameters.
208 *
209 * @return array List of parameters.
210 */
211 public static function user_inbox_get_parameters() {
212 $params = array();
213
214 $params['page'] = array(
215 'type' => 'integer',
216 );
217
218 return $params;
219 }
220
221 /**
222 * The supported parameters.
223 *
224 * @return array List of parameters.
225 */
226 public static function user_inbox_post_parameters() {
227 $params = array();
228
229 $params['id'] = array(
230 'required' => true,
231 'sanitize_callback' => 'esc_url_raw',
232 );
233
234 $params['actor'] = array(
235 'required' => true,
236 'sanitize_callback' => '\Activitypub\object_to_uri',
237 );
238
239 $params['type'] = array(
240 'required' => true,
241 );
242
243 $params['object'] = array(
244 'required' => true,
245 'validate_callback' => function ( $param, $request, $key ) {
246 /**
247 * Filter the ActivityPub object validation.
248 *
249 * @param bool $validate The validation result.
250 * @param array $param The object data.
251 * @param object $request The request object.
252 * @param string $key The key.
253 */
254 return apply_filters( 'activitypub_validate_object', true, $param, $request, $key );
255 },
256 );
257
258 return $params;
259 }
260
261 /**
262 * The supported parameters.
263 *
264 * @return array List of parameters.
265 */
266 public static function shared_inbox_post_parameters() {
267 $params = self::user_inbox_post_parameters();
268
269 $params['to'] = array(
270 'required' => false,
271 'sanitize_callback' => function ( $param ) {
272 if ( \is_string( $param ) ) {
273 $param = array( $param );
274 }
275
276 return $param;
277 },
278 );
279
280 $params['cc'] = array(
281 'sanitize_callback' => function ( $param ) {
282 if ( \is_string( $param ) ) {
283 $param = array( $param );
284 }
285
286 return $param;
287 },
288 );
289
290 $params['bcc'] = array(
291 'sanitize_callback' => function ( $param ) {
292 if ( \is_string( $param ) ) {
293 $param = array( $param );
294 }
295
296 return $param;
297 },
298 );
299
300 return $params;
301 }
302
303 /**
304 * Get local user recipients.
305 *
306 * @param array $data The data array.
307 *
308 * @return array The list of local users.
309 */
310 public static function get_recipients( $data ) {
311 $recipients = extract_recipients_from_activity( $data );
312 $users = array();
313
314 foreach ( $recipients as $recipient ) {
315 $user_id = url_to_authorid( $recipient );
316
317 $user = get_user_by( 'id', $user_id );
318
319 if ( $user ) {
320 $users[] = $user;
321 }
322 }
323
324 return $users;
325 }
326 }
327