Automattic /
jetpack
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | /** |
||
| 3 | * Sets up the Connection REST API endpoints. |
||
| 4 | * |
||
| 5 | * @package automattic/jetpack-connection |
||
| 6 | */ |
||
| 7 | |||
| 8 | namespace Automattic\Jetpack\Connection; |
||
| 9 | |||
| 10 | use Automattic\Jetpack\Status; |
||
| 11 | use Jetpack_XMLRPC_Server; |
||
| 12 | use WP_Error; |
||
| 13 | use WP_REST_Request; |
||
| 14 | use WP_REST_Response; |
||
| 15 | use WP_REST_Server; |
||
| 16 | |||
| 17 | /** |
||
| 18 | * Registers the REST routes for Connections. |
||
| 19 | */ |
||
| 20 | class REST_Connector { |
||
| 21 | /** |
||
| 22 | * The Connection Manager. |
||
| 23 | * |
||
| 24 | * @var Manager |
||
| 25 | */ |
||
| 26 | private $connection; |
||
| 27 | |||
| 28 | /** |
||
| 29 | * This property stores the localized "Insufficient Permissions" error message. |
||
| 30 | * |
||
| 31 | * @var string Generic error message when user is not allowed to perform an action. |
||
| 32 | */ |
||
| 33 | private static $user_permissions_error_msg; |
||
| 34 | |||
| 35 | /** |
||
| 36 | * Constructor. |
||
| 37 | * |
||
| 38 | * @param Manager $connection The Connection Manager. |
||
| 39 | */ |
||
| 40 | public function __construct( Manager $connection ) { |
||
| 41 | $this->connection = $connection; |
||
| 42 | |||
| 43 | self::$user_permissions_error_msg = esc_html__( |
||
| 44 | 'You do not have the correct user permissions to perform this action. |
||
| 45 | Please contact your site admin if you think this is a mistake.', |
||
| 46 | 'jetpack' |
||
| 47 | ); |
||
| 48 | |||
| 49 | if ( ! $this->connection->is_active() ) { |
||
| 50 | // Register a site. |
||
| 51 | register_rest_route( |
||
| 52 | 'jetpack/v4', |
||
| 53 | '/verify_registration', |
||
| 54 | array( |
||
| 55 | 'methods' => WP_REST_Server::EDITABLE, |
||
| 56 | 'callback' => array( $this, 'verify_registration' ), |
||
| 57 | 'permission_callback' => '__return_true', |
||
| 58 | ) |
||
| 59 | ); |
||
| 60 | } |
||
| 61 | |||
| 62 | // Authorize a remote user. |
||
| 63 | register_rest_route( |
||
| 64 | 'jetpack/v4', |
||
| 65 | '/remote_authorize', |
||
| 66 | array( |
||
| 67 | 'methods' => WP_REST_Server::EDITABLE, |
||
| 68 | 'callback' => __CLASS__ . '::remote_authorize', |
||
| 69 | 'permission_callback' => '__return_true', |
||
| 70 | ) |
||
| 71 | ); |
||
| 72 | |||
| 73 | // Get current connection status of Jetpack. |
||
| 74 | register_rest_route( |
||
| 75 | 'jetpack/v4', |
||
| 76 | '/connection', |
||
| 77 | array( |
||
| 78 | 'methods' => WP_REST_Server::READABLE, |
||
| 79 | 'callback' => __CLASS__ . '::connection_status', |
||
| 80 | 'permission_callback' => '__return_true', |
||
| 81 | ) |
||
| 82 | ); |
||
| 83 | |||
| 84 | // Get list of plugins that use the Jetpack connection. |
||
| 85 | register_rest_route( |
||
| 86 | 'jetpack/v4', |
||
| 87 | '/connection/plugins', |
||
| 88 | array( |
||
| 89 | 'methods' => WP_REST_Server::READABLE, |
||
| 90 | 'callback' => array( $this, 'get_connection_plugins' ), |
||
| 91 | 'permission_callback' => __CLASS__ . '::activate_plugins_permission_check', |
||
| 92 | ) |
||
| 93 | ); |
||
| 94 | |||
| 95 | // Full or partial reconnect in case of connection issues. |
||
| 96 | register_rest_route( |
||
| 97 | 'jetpack/v4', |
||
| 98 | '/connection/reconnect', |
||
| 99 | array( |
||
| 100 | 'methods' => WP_REST_Server::EDITABLE, |
||
| 101 | 'callback' => array( $this, 'connection_reconnect' ), |
||
| 102 | 'args' => array( |
||
| 103 | 'action' => array( |
||
| 104 | 'type' => 'string', |
||
| 105 | 'required' => true, |
||
| 106 | ), |
||
| 107 | ), |
||
| 108 | 'permission_callback' => __CLASS__ . '::jetpack_disconnect_permission_check', |
||
| 109 | ) |
||
| 110 | ); |
||
| 111 | } |
||
| 112 | |||
| 113 | /** |
||
| 114 | * Handles verification that a site is registered. |
||
| 115 | * |
||
| 116 | * @since 5.4.0 |
||
| 117 | * |
||
| 118 | * @param WP_REST_Request $request The request sent to the WP REST API. |
||
| 119 | * |
||
| 120 | * @return string|WP_Error |
||
| 121 | */ |
||
| 122 | public function verify_registration( WP_REST_Request $request ) { |
||
| 123 | $registration_data = array( $request['secret_1'], $request['state'] ); |
||
| 124 | |||
| 125 | return $this->connection->handle_registration( $registration_data ); |
||
| 126 | } |
||
| 127 | |||
| 128 | /** |
||
| 129 | * Handles verification that a site is registered |
||
| 130 | * |
||
| 131 | * @since 5.4.0 |
||
| 132 | * |
||
| 133 | * @param WP_REST_Request $request The request sent to the WP REST API. |
||
| 134 | * |
||
| 135 | * @return array|wp-error |
||
| 136 | */ |
||
| 137 | public static function remote_authorize( $request ) { |
||
| 138 | $xmlrpc_server = new Jetpack_XMLRPC_Server(); |
||
| 139 | $result = $xmlrpc_server->remote_authorize( $request ); |
||
| 140 | |||
| 141 | if ( is_a( $result, 'IXR_Error' ) ) { |
||
| 142 | $result = new WP_Error( $result->code, $result->message ); |
||
| 143 | } |
||
| 144 | |||
| 145 | return $result; |
||
| 146 | } |
||
| 147 | |||
| 148 | /** |
||
| 149 | * Get connection status for this Jetpack site. |
||
| 150 | * |
||
| 151 | * @since 4.3.0 |
||
| 152 | * |
||
| 153 | * @param bool $rest_response Should we return a rest response or a simple array. Default to rest response. |
||
| 154 | * |
||
| 155 | * @return WP_REST_Response|array Connection information. |
||
| 156 | */ |
||
| 157 | public static function connection_status( $rest_response = true ) { |
||
| 158 | $status = new Status(); |
||
| 159 | $connection = new Manager(); |
||
| 160 | |||
| 161 | $connection_status = array( |
||
| 162 | 'isActive' => $connection->is_active(), |
||
| 163 | 'isStaging' => $status->is_staging_site(), |
||
| 164 | 'isRegistered' => $connection->is_registered(), |
||
| 165 | 'offlineMode' => array( |
||
| 166 | 'isActive' => $status->is_offline_mode(), |
||
| 167 | 'constant' => defined( 'JETPACK_DEV_DEBUG' ) && JETPACK_DEV_DEBUG, |
||
| 168 | 'url' => $status->is_local_site(), |
||
| 169 | /** This filter is documented in packages/status/src/class-status.php */ |
||
| 170 | 'filter' => ( apply_filters( 'jetpack_development_mode', false ) || apply_filters( 'jetpack_offline_mode', false ) ), // jetpack_development_mode is deprecated. |
||
| 171 | 'wpLocalConstant' => defined( 'WP_LOCAL_DEV' ) && WP_LOCAL_DEV, |
||
| 172 | ), |
||
| 173 | 'isPublic' => '1' == get_option( 'blog_public' ), // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison |
||
| 174 | ); |
||
| 175 | |||
| 176 | if ( $rest_response ) { |
||
| 177 | return rest_ensure_response( |
||
| 178 | $connection_status |
||
| 179 | ); |
||
| 180 | } else { |
||
| 181 | return $connection_status; |
||
| 182 | } |
||
| 183 | } |
||
| 184 | |||
| 185 | |||
| 186 | /** |
||
| 187 | * Get plugins connected to the Jetpack. |
||
| 188 | * |
||
| 189 | * @since 8.6.0 |
||
| 190 | * |
||
| 191 | * @return WP_REST_Response|WP_Error Response or error object, depending on the request result. |
||
| 192 | */ |
||
| 193 | public function get_connection_plugins() { |
||
| 194 | $plugins = $this->connection->get_connected_plugins(); |
||
| 195 | |||
| 196 | if ( is_wp_error( $plugins ) ) { |
||
| 197 | return $plugins; |
||
| 198 | } |
||
| 199 | |||
| 200 | array_walk( |
||
| 201 | $plugins, |
||
| 202 | function( &$data, $slug ) { |
||
| 203 | $data['slug'] = $slug; |
||
| 204 | } |
||
| 205 | ); |
||
| 206 | |||
| 207 | return rest_ensure_response( array_values( $plugins ) ); |
||
| 208 | } |
||
| 209 | |||
| 210 | /** |
||
| 211 | * Verify that user can view Jetpack admin page and can activate plugins. |
||
| 212 | * |
||
| 213 | * @since 8.8.0 |
||
| 214 | * |
||
| 215 | * @return bool|WP_Error Whether user has the capability 'activate_plugins'. |
||
| 216 | */ |
||
| 217 | public static function activate_plugins_permission_check() { |
||
| 218 | if ( current_user_can( 'activate_plugins' ) ) { |
||
| 219 | return true; |
||
| 220 | } |
||
| 221 | |||
| 222 | return new WP_Error( 'invalid_user_permission_activate_plugins', self::get_user_permissions_error_msg(), array( 'status' => rest_authorization_required_code() ) ); |
||
| 223 | } |
||
| 224 | |||
| 225 | /** |
||
| 226 | * Verify that user is allowed to disconnect Jetpack. |
||
| 227 | * |
||
| 228 | * @since 8.8.0 |
||
| 229 | * |
||
| 230 | * @return bool|WP_Error Whether user has the capability 'jetpack_disconnect'. |
||
| 231 | */ |
||
| 232 | View Code Duplication | public static function jetpack_disconnect_permission_check() { |
|
| 233 | if ( current_user_can( 'jetpack_disconnect' ) ) { |
||
| 234 | return true; |
||
| 235 | } |
||
| 236 | |||
| 237 | return new WP_Error( 'invalid_user_permission_jetpack_disconnect', self::get_user_permissions_error_msg(), array( 'status' => rest_authorization_required_code() ) ); |
||
|
0 ignored issues
–
show
|
|||
| 238 | } |
||
| 239 | |||
| 240 | /** |
||
| 241 | * Returns generic error message when user is not allowed to perform an action. |
||
| 242 | * |
||
| 243 | * @return string The error message. |
||
| 244 | */ |
||
| 245 | public static function get_user_permissions_error_msg() { |
||
| 246 | return self::$user_permissions_error_msg; |
||
| 247 | } |
||
| 248 | |||
| 249 | /** |
||
| 250 | * The endpoint tried to partially or fully reconnect the website to WP.com. |
||
| 251 | * |
||
| 252 | * @since 8.8.0 |
||
| 253 | * |
||
| 254 | * @param WP_REST_Request $request The request sent to the WP REST API. |
||
| 255 | * |
||
| 256 | * @return \WP_REST_Response|WP_Error |
||
| 257 | */ |
||
| 258 | public function connection_reconnect( WP_REST_Request $request ) { |
||
| 259 | $params = $request->get_json_params(); |
||
| 260 | |||
| 261 | $response = array(); |
||
| 262 | |||
| 263 | switch ( $params['action'] ) { |
||
| 264 | case 'reconnect': |
||
| 265 | $result = $this->connection->reconnect(); |
||
| 266 | |||
| 267 | if ( true === $result ) { |
||
| 268 | $response['status'] = 'in_progress'; |
||
| 269 | $response['authorizeUrl'] = $this->connection->get_authorization_url(); |
||
| 270 | } elseif ( is_wp_error( $result ) ) { |
||
| 271 | $response = $result; |
||
| 272 | } |
||
| 273 | break; |
||
| 274 | default: |
||
| 275 | $response = new WP_Error( 'Unknown action' ); |
||
|
0 ignored issues
–
show
The call to
WP_Error::__construct() has too many arguments starting with 'Unknown action'.
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. In this case you can add the Loading history...
|
|||
| 276 | break; |
||
| 277 | } |
||
| 278 | |||
| 279 | return rest_ensure_response( $response ); |
||
| 280 | } |
||
| 281 | |||
| 282 | } |
||
| 283 |
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignorePhpDoc annotation to the duplicate definition and it will be ignored.