PluginProbe
Faust.js / 1.0.2
Faust.js v1.0.2
1.8.12 1.8.11 1.4.1 1.8.0 1.8.8 1.8.9 trunk 0.7.0 0.7.1 0.7.10 0.7.11 0.7.3 0.7.4 0.7.5 0.7.6 0.7.7 0.7.8 0.7.9 0.8.0 0.8.1 0.8.3 0.8.4 0.8.5 0.8.6 0.8.7 All 40 releases
faustwp / includes / rest / callbacks.php

callbacks.php in Faust.js 1.0.2, at includes/rest/callbacks.php

245 lines 7.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * REST related callbacks.
4 *
5 * @package FaustWP
6 */
7
8 namespace WPE\FaustWP\REST;
9
10 use function WPE\FaustWP\Auth\{
11 get_user_from_access_token,
12 get_user_from_refresh_token,
13 get_user_from_authorization_code,
14 generate_refresh_token,
15 generate_access_token
16 };
17 use function WPE\FaustWP\Settings\get_secret_key;
18
19 use function WPE\FaustWP\Telemetry\{
20 get_wp_version,
21 is_wpe,
22 get_anonymous_faustwp_data,
23 get_anonymous_wpgraphql_content_blocks_data,
24 };
25
26 if ( ! defined( 'ABSPATH' ) ) {
27 exit;
28 }
29
30 add_filter( 'determine_current_user', __NAMESPACE__ . '\\rest_determine_current_user', 20 );
31 /**
32 * Callback for WordPress 'determine_current_user' filter.
33 *
34 * Determine the current user based on authentication token from http header.
35 * Runs during GraphQL, REST and plain requests.
36 *
37 * @link https://developer.wordpress.org/reference/hooks/determine_current_user/
38 *
39 * @param int|bool $user_id User ID if one has been determined, false otherwise.
40 *
41 * @return int|bool User ID if one has been determined, false otherwise.
42 */
43 function rest_determine_current_user( $user_id ) {
44 if ( $user_id ) {
45 return $user_id;
46 }
47
48 if ( ! isset( $_SERVER['HTTP_AUTHORIZATION'] ) ) {
49 return $user_id;
50 }
51
52 $parts = explode( ' ', trim( $_SERVER['HTTP_AUTHORIZATION'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
53 if ( count( $parts ) < 2 ) {
54 return $user_id;
55 }
56
57 $wp_user = get_user_from_access_token( $parts[1] );
58 if ( $wp_user ) {
59 $user_id = $wp_user->ID;
60 }
61
62 return $user_id;
63 }
64
65 add_action( 'rest_api_init', __NAMESPACE__ . '\\register_rest_routes' );
66 /**
67 * Callback for WordPress 'rest_api_init' action.
68 *
69 * Register the GET /faustwp/v1/telemetry endpoint.
70 * Register the POST /faustwp/v1/authorize endpoint.
71 *
72 * @link https://developer.wordpress.org/reference/functions/register_rest_route/
73 * @link https://developer.wordpress.org/rest-api/extending-the-rest-api/routes-and-endpoints/
74 *
75 * @return void
76 */
77 function register_rest_routes() {
78 register_rest_route(
79 'faustwp/v1',
80 '/telemetry',
81 array(
82 'methods' => 'POST',
83 'callback' => __NAMESPACE__ . '\\handle_rest_telemetry_callback',
84 'permission_callback' => __NAMESPACE__ . '\\rest_telemetry_permission_callback',
85 )
86 );
87
88 register_rest_route(
89 'faustwp/v1',
90 '/authorize',
91 array(
92 'methods' => 'POST',
93 'callback' => __NAMESPACE__ . '\\handle_rest_authorize_callback',
94 'permission_callback' => __NAMESPACE__ . '\\rest_authorize_permission_callback',
95 )
96 );
97
98 /**
99 * Faust.js packages now use `faustwp/v1/authorize`.
100 *
101 * @deprecated
102 */
103 register_rest_route(
104 'wpac/v1',
105 '/authorize',
106 array(
107 'methods' => 'POST',
108 'callback' => __NAMESPACE__ . '\\handle_rest_authorize_callback',
109 'permission_callback' => __NAMESPACE__ . '\\wpac_authorize_permission_callback',
110 )
111 );
112 }
113
114 /**
115 * Callback for WordPress register_rest_route() 'callback' parameter.
116 *
117 * Handle GET /faustwp/v1/telemetry response.
118 *
119 * @link https://developer.wordpress.org/reference/functions/register_rest_route/
120 * @link https://developer.wordpress.org/rest-api/extending-the-rest-api/routes-and-endpoints/#endpoint-callback
121 *
122 * @param \WP_REST_Request $request Current WP_REST_Request object.
123 *
124 * @return mixed A WP_REST_Response, array, or WP_Error.
125 */
126 function handle_rest_telemetry_callback( \WP_REST_Request $request ) {
127 $data = array(
128 'faustwp' => get_anonymous_faustwp_data(),
129 'wpgraphql_content_blocks' => get_anonymous_wpgraphql_content_blocks_data(),
130 'is_wpe' => is_wpe(),
131 'multisite' => is_multisite(),
132 'php_version' => PHP_VERSION,
133 'wp_version' => get_wp_version(),
134 );
135
136 return new \WP_REST_Response( $data );
137 }
138
139 /**
140 * Callback to check permissions for requests to `faustwp/v1/telemetry`.
141 *
142 * Authorized if the 'secret_key' settings value and http header 'x-faustwp-secret' match.
143 *
144 * @param \WP_REST_Request $request The current WP_REST_Request object.
145 *
146 * @return bool True if current user can, false if else.
147 */
148 function rest_telemetry_permission_callback( \WP_REST_Request $request ) {
149 return rest_authorize_permission_callback( $request );
150 }
151
152 /**
153 * Callback for WordPress register_rest_route() 'callback' parameter.
154 *
155 * Handle POST /faustwp/v1/authorize response.
156 *
157 * Use the 'code' (authorization code) parameter to generate a new access token.
158 *
159 * @link https://developer.wordpress.org/reference/functions/register_rest_route/
160 * @link https://developer.wordpress.org/rest-api/extending-the-rest-api/routes-and-endpoints/#endpoint-callback
161 *
162 * @param \WP_REST_Request $request Current WP_REST_Request object.
163 *
164 * @return mixed A WP_REST_Response, array, or WP_Error.
165 */
166 function handle_rest_authorize_callback( \WP_REST_Request $request ) {
167 $code = trim( $request->get_param( 'code' ) );
168 $refresh_token = trim( $request->get_param( 'refreshToken' ) );
169
170 if ( ! $code && ! $refresh_token ) {
171 return new \WP_Error( 'invalid_request', 'Missing authorization code or refresh token.' );
172 }
173
174 if ( $refresh_token ) {
175 $user = get_user_from_refresh_token( $refresh_token );
176 } else {
177 $user = get_user_from_authorization_code( $code );
178 }
179
180 if ( ! $user ) {
181 return new \WP_Error( 'invalid_request', 'Invalid authorization code or refresh token.' );
182 }
183
184 $refresh_token_expiration = WEEK_IN_SECONDS * 2;
185 $access_token_expiration = MINUTE_IN_SECONDS * 5;
186
187 $access_token = generate_access_token( $user, $access_token_expiration );
188 $refresh_token = generate_refresh_token( $user, $refresh_token_expiration );
189
190 return array(
191 'accessToken' => $access_token,
192 'accessTokenExpiration' => ( time() + $access_token_expiration ),
193 'refreshToken' => $refresh_token,
194 'refreshTokenExpiration' => ( time() + $refresh_token_expiration ),
195 );
196 }
197
198 /**
199 * Callback to check permissions for requests to `faustwp/v1/authorize`.
200 *
201 * Authorized if the 'secret_key' settings value and http header 'x-faustwp-secret' match.
202 *
203 * @link https://developer.wordpress.org/reference/functions/register_rest_route/
204 * @link https://developer.wordpress.org/rest-api/extending-the-rest-api/routes-and-endpoints/#permissions-callback
205 *
206 * @param \WP_REST_Request $request The current WP_REST_Request object.
207 *
208 * @return bool True if current user can, false if else.
209 */
210 function rest_authorize_permission_callback( \WP_REST_Request $request ) {
211 $secret_key = get_secret_key();
212 $header_key = $request->get_header( 'x-faustwp-secret' );
213
214 if ( $secret_key && $header_key ) {
215 return $secret_key === $header_key;
216 }
217
218 return false;
219 }
220
221 /**
222 * Callback to check permissions for requests to `wpac/v1/authorize`.
223 *
224 * Authorized if the 'secret_key' settings value and http header 'x-wpe-headless-secret' match.
225 *
226 * @deprecated The `wpac/v1/authorize` route is deprecated. Use `faustwp/v1/authorize` instead.
227 *
228 * @link https://developer.wordpress.org/reference/functions/register_rest_route/
229 * @link https://developer.wordpress.org/rest-api/extending-the-rest-api/routes-and-endpoints/#permissions-callback
230 *
231 * @param \WP_REST_Request $request The current WP_REST_Request object.
232 *
233 * @return bool True if current user can, false if else.
234 */
235 function wpac_authorize_permission_callback( \WP_REST_Request $request ) {
236 $secret_key = get_secret_key();
237 $header_key = $request->get_header( 'x-wpe-headless-secret' );
238
239 if ( $secret_key && $header_key ) {
240 return $secret_key === $header_key;
241 }
242
243 return false;
244 }
245