-
Notifications
You must be signed in to change notification settings - Fork 800
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Connection: Add REST support for jsonAPI endpoints #39432
base: trunk
Are you sure you want to change the base?
Conversation
Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.
Interested in more tips and information?
|
Thank you for your PR! When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:
This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖 The e2e test report can be found here. Please note that it can take a few minutes after the e2e tests checks are complete for the report to be available. Follow this PR Review Process:
Still unsure? Reach out in #jetpack-developers for guidance! Jetpack plugin: The Jetpack plugin has different release cadences depending on the platform:
If you have any questions about the release process, please ask in the #jetpack-releases channel on Slack. |
1b9fbb2
to
a3cc273
Compare
9633b2c
to
bb92f7a
Compare
$user_id = get_current_user_id(); | ||
$allow_blog_token = $this->allow_fallback_to_jetpack_blog_token || $this->allow_jetpack_site_auth; | ||
|
||
if ( ( $allow_blog_token && Rest_Authentication::is_signed_with_blog_token() ) || ( $user_id && Rest_Authentication::is_signed_with_user_token() ) ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already have accepts_site_based_authentication
which essentially covers the cases of blog tokens used plus the endpoints accepting it. We don't need to check allow_fallback_to_jetpack_blog_token
, this is only used on WPCOM to determine if unauthorized requests can fall back to using a blog token.
That said, we already check accepts_site_based_authentication
as part of the capabilities check here but it only applies to endpoints extending Jetpack_JSON_API_Endpoint
🤔
Also do we really need to check Rest_Authentication::is_signed_with_user_token()
? Wouldn't it be enough to check if $user_id is not empty assuming the request is signed with a user token?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need to check
allow_fallback_to_jetpack_blog_token
Good point, removed in e97dd90
Also do we really need to check Rest_Authentication::is_signed_with_user_token()? Wouldn't it be enough to check if $user_id is not empty assuming the request is signed with a user token?
We don't really want to open those endpoints for requests coming from logged in users.
So we check if this actually is user token based auth.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, removed in e97dd90
I believe we can use $this->accepts_site_based_authentication
instead of $this->allow_jetpack_site_auth && Rest_Authentication::is_signed_with_blog_token()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good idea, but I'm not quite sure we should do that:
-
token_details
will haveblog_id
defined for both user and blog token, sois_jetpack_authorized_for_site()
will essentially useget_current_user_id()
to determine the type of token (blog/user).
is_signed_with_blog_token()
takes that information directly from token, so I find that more straightforward and reliable. -
We initialize JSON API in the callback. That means that
token_details
is empty during the REST endpoint permission callback, and I'd rather avoid that. -
I also don't feel confident about relying on
public_token
property because of this line:$api->token_details['user'] = $user_details;
$user_details
here comes from WPCOM directly, and trusted only because the request is signed. It's not something that comes from the token.
While it doesn't affect the blog token check in question directly, it's still something I'd rather stay away from.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, we should probably update accepts_site_based_authentication
then and re-use it everywhere, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a widely used method already, so editing it may have unintended side effects in such a sensitive component as JSON API.
So I wouldn't want to do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My point is, we're already doing some major changes here, so I'd prefer to minimize potential breaking points where we can.
So I'd rather avoid excessive refactoring, and revisit it separately later on.
Hi @fgiannar |
I believe we also need to copy the output logic from |
array_values( array( $this->path, $blog_id ) + $request->get_url_params() ) | ||
); | ||
|
||
if ( ! $callback_response && ! is_array( $callback_response ) ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need to use the output
method? Mostly asking because it seems to overcomplicate the approach..
I was testing this out and it seems to work fine if we simply return early in case of WP_Error
: if ( is_wp_error( $callback_response ) ) {
and leave the rest logic same as before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @fgiannar 👋
We use the output()
method here to wrap the response if http_envelope=1
is provided.
There was a bug though which didn't make it all work properly, fixed in bbb226a (don't mind the accidental $response = null;
, already reverted).
Here's what I get when I make $callback_response = null;
with http_envelope
:
HTTP/2 200
{"code":400,"headers":[{"name":"Content-Type","value":"application\/json"}],"body":{"error":"server_error","message":"The Jetpack site is inaccessible or returned an error: transport error - HTTP status code was not 200 (500) [-32300]"}}
And without http_envelope
:
HTTP/2 400
{"error":"server_error","message":"The Jetpack site is inaccessible or returned an error: transport error - HTTP status code was not 200 (500) [-32300]"}
} | ||
|
||
if ( $request->get_param( 'http_envelope' ) ) { | ||
$response = wp_json_encode( WPCOM_JSON_API::wrap_http_envelope( $status_code, $response, 'application/json' ) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we need to json encode the response independently of the http_envelope
param. Otherwise, we get a PHP Warning locally: PHP Warning: Array to string conversion in class.json-api-endpoints.php on line 2740
and a Fatal on WPCOM: Fatal error: Uncaught Error: Object of class stdClass could not be converted to string
Proposed changes:
Other information:
Jetpack product discussion
pf5801-18d-p2
Does this pull request change what data or activity we track or use?
No.
Testing instructions:
See D162401-code