PluginProbe
ActivityPub / 2.1.1
ActivityPub v2.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-server.php

class-server.php in ActivityPub 2.1.1, at includes/rest/class-server.php

129 lines 3.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Activitypub\Rest;
3
4 use stdClass;
5 use WP_Error;
6 use WP_REST_Response;
7 use Activitypub\Signature;
8 use Activitypub\Model\Application_User;
9
10 /**
11 * ActivityPub Server REST-Class
12 *
13 * @author Django Doucet
14 *
15 * @see https://www.w3.org/TR/activitypub/#security-verification
16 */
17 class Server {
18 /**
19 * Initialize the class, registering WordPress hooks
20 */
21 public static function init() {
22 self::register_routes();
23
24 \add_filter( 'rest_request_before_callbacks', array( self::class, 'authorize_activitypub_requests' ), 10, 3 );
25 }
26
27 /**
28 * Register routes
29 */
30 public static function register_routes() {
31 \register_rest_route(
32 ACTIVITYPUB_REST_NAMESPACE,
33 '/application',
34 array(
35 array(
36 'methods' => \WP_REST_Server::READABLE,
37 'callback' => array( self::class, 'application_actor' ),
38 'permission_callback' => '__return_true',
39 ),
40 )
41 );
42 }
43
44 /**
45 * Render Application actor profile
46 *
47 * @return WP_REST_Response The JSON profile of the Application Actor.
48 */
49 public static function application_actor() {
50 $user = new Application_User();
51
52 $json = $user->to_array();
53
54 $rest_response = new WP_REST_Response( $json, 200 );
55 $rest_response->header( 'Content-Type', 'application/activity+json; charset=' . get_option( 'blog_charset' ) );
56
57 return $rest_response;
58 }
59
60 /**
61 * Callback function to authorize each api requests
62 *
63 * @see WP_REST_Request
64 *
65 * @param WP_REST_Response|WP_HTTP_Response|WP_Error|mixed $response Result to send to the client.
66 * Usually a WP_REST_Response or WP_Error.
67 * @param array $handler Route handler used for the request.
68 * @param WP_REST_Request $request Request used to generate the response.
69 *
70 * @return mixed|WP_Error The response, error, or modified response.
71 */
72 public static function authorize_activitypub_requests( $response, $handler, $request ) {
73 if ( 'HEAD' === $request->get_method() ) {
74 return $response;
75 }
76
77 $route = $request->get_route();
78
79 // check if it is an activitypub request and exclude webfinger and nodeinfo endpoints
80 if (
81 ! \str_starts_with( $route, '/' . ACTIVITYPUB_REST_NAMESPACE ) ||
82 \str_starts_with( $route, '/' . \trailingslashit( ACTIVITYPUB_REST_NAMESPACE ) . 'webfinger' ) ||
83 \str_starts_with( $route, '/' . \trailingslashit( ACTIVITYPUB_REST_NAMESPACE ) . 'nodeinfo' )
84 ) {
85 return $response;
86 }
87
88 /**
89 * Filter to defer signature verification
90 *
91 * Skip signature verification for debugging purposes or to reduce load for
92 * certain Activity-Types, like "Delete".
93 *
94 * @param bool $defer Whether to defer signature verification.
95 * @param WP_REST_Request $request The request used to generate the response.
96 *
97 * @return bool Whether to defer signature verification.
98 */
99 $defer = \apply_filters( 'activitypub_defer_signature_verification', false, $request );
100
101 if ( $defer ) {
102 return $response;
103 }
104
105 // POST-Requets are always signed
106 if ( 'GET' !== $request->get_method() ) {
107 $verified_request = Signature::verify_http_signature( $request );
108 if ( \is_wp_error( $verified_request ) ) {
109 return new WP_Error(
110 'activitypub_signature_verification',
111 $verified_request->get_error_message(),
112 array( 'status' => 401 )
113 );
114 }
115 } elseif ( 'GET' === $request->get_method() && ACTIVITYPUB_AUTHORIZED_FETCH ) { // GET-Requests are only signed in secure mode
116 $verified_request = Signature::verify_http_signature( $request );
117 if ( \is_wp_error( $verified_request ) ) {
118 return new WP_Error(
119 'activitypub_signature_verification',
120 $verified_request->get_error_message(),
121 array( 'status' => 401 )
122 );
123 }
124 }
125
126 return $response;
127 }
128 }
129