Skip to content

Commit

Permalink
Social | Add site context for publicize endpoints (#40914)
Browse files Browse the repository at this point in the history
* Allow requests as blog in base controller

* Add filters for connections controller

* Add changelog

* Update baseline.php

* Rename the 'include' param to 'scope' for clarity

* Return shared connections by default

* Remove scope parameter in favour of request context

* Only pass test_connections to WPCOM

* Update baseline.php
  • Loading branch information
manzoorwanijk authored Jan 9, 2025
1 parent 42a62f9 commit 27b255e
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 15 deletions.
6 changes: 5 additions & 1 deletion projects/packages/publicize/.phan/baseline.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
// PhanPossiblyUndeclaredVariable : 2 occurrences
// PhanTypeMismatchReturnProbablyReal : 2 occurrences
// PhanTypeMissingReturn : 2 occurrences
// PhanUndeclaredClassMethod : 2 occurrences
// PhanImpossibleCondition : 1 occurrence
// PhanNoopNew : 1 occurrence
// PhanParamSignatureMismatch : 1 occurrence
Expand All @@ -28,6 +29,8 @@
// PhanTypeMismatchDefault : 1 occurrence
// PhanTypeMismatchDimFetch : 1 occurrence
// PhanTypeMismatchReturn : 1 occurrence
// PhanUndeclaredFunction : 1 occurrence
// PhanUndeclaredMethod : 1 occurrence

// Currently, file_suppressions and directory_suppressions are the only supported suppressions
'file_suppressions' => [
Expand All @@ -38,7 +41,8 @@
'src/class-publicize-ui.php' => ['PhanPluginDuplicateExpressionAssignmentOperation', 'PhanTypeMismatchReturnProbablyReal'],
'src/class-publicize.php' => ['PhanParamSignatureMismatch', 'PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgument', 'PhanTypeMissingReturn'],
'src/class-rest-controller.php' => ['PhanPluginDuplicateConditionalNullCoalescing', 'PhanTypeMismatchReturnProbablyReal'],
'src/rest-api/class-connections-controller.php' => ['PhanPluginMixedKeyNoKey'],
'src/rest-api/class-base-controller.php' => ['PhanUndeclaredClassMethod', 'PhanUndeclaredFunction'],
'src/rest-api/class-connections-controller.php' => ['PhanPluginMixedKeyNoKey', 'PhanUndeclaredMethod'],
'src/social-image-generator/class-post-settings.php' => ['PhanPluginDuplicateConditionalNullCoalescing'],
'src/social-image-generator/class-rest-settings-controller.php' => ['PhanPluginMixedKeyNoKey'],
'src/social-image-generator/class-settings.php' => ['PhanPluginDuplicateConditionalNullCoalescing'],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: added

Publicize: Allow filtering of connections in publicize rest endpoint
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@
*/
abstract class Base_Controller extends WP_REST_Controller {

/**
* Whether to allow requests as blog.
*
* @var bool
*/
protected $allow_requests_as_blog = false;

/**
* Constructor.
*/
Expand All @@ -34,6 +41,22 @@ public static function is_wpcom() {
return ( new Host() )->is_wpcom_simple();
}

/**
* Check if the request is authorized for the blog.
*
* @return bool
*/
protected static function is_authorized_blog_request() {
if ( self::is_wpcom() && is_jetpack_site( get_current_blog_id() ) ) {

$jp_auth_endpoint = new \WPCOM_REST_API_V2_Endpoint_Jetpack_Auth();

return $jp_auth_endpoint->is_jetpack_authorized_for_site() === true;
}

return false;
}

/**
* Filters out data based on ?_fields= request parameter
*
Expand All @@ -59,9 +82,11 @@ public function prepare_item_for_response( $item, $request ) {
/**
* Verify that user can access Publicize data
*
* @param WP_REST_Request $request Full details about the request.
* @return true|WP_Error
*/
public function get_items_permission_check() {
public function get_items_permissions_check( $request ) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable

global $publicize;

if ( ! $publicize ) {
Expand All @@ -72,6 +97,10 @@ public function get_items_permission_check() {
);
}

if ( $this->allow_requests_as_blog && self::is_authorized_blog_request() ) {
return true;
}

if ( $publicize->current_user_can_access_publicize_data() ) {
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public function __construct() {
$this->namespace = 'wpcom/v2';
$this->rest_base = 'publicize/connections';

$this->allow_requests_as_blog = true;

add_action( 'rest_api_init', array( $this, 'register_routes' ) );
}

Expand All @@ -41,7 +43,7 @@ public function register_routes() {
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_items' ),
'permission_callback' => array( $this, 'get_items_permission_check' ),
'permission_callback' => array( $this, 'get_items_permissions_check' ),
'args' => array(
'test_connections' => array(
'type' => 'boolean',
Expand Down Expand Up @@ -165,23 +167,32 @@ public function get_item_schema() {
/**
* Get all connections. Meant to be called directly only on WPCOM.
*
* @param bool $run_tests Whether to run tests on the connections.
* @param array $args Arguments
* - 'test_connections': bool Whether to run connection tests.
* - 'scope': enum('site', 'user') Which connections to include.
*
* @return array
*/
protected static function get_all_connections( $run_tests = false ) {
protected static function get_all_connections( $args = array() ) {
/**
* Publicize instance.
*
* @var \Automattic\Jetpack\Publicize\Publicize $publicize
*/
global $publicize;

$items = array();

$run_tests = $args['test_connections'] ?? false;

$test_results = $run_tests ? self::get_connections_test_status() : array();

foreach ( (array) $publicize->get_services( 'connected' ) as $service_name => $connections ) {
// If a (Jetpack) blog request, return all the connections for that site.
if ( self::is_authorized_blog_request() ) {
$service_connections = $publicize->get_all_connections_for_blog_id( get_current_blog_id() );
} else {
$service_connections = (array) $publicize->get_services( 'connected' );
}

foreach ( $service_connections as $service_name => $connections ) {
foreach ( $connections as $connection ) {

$connection_id = $publicize->get_connection_id( $connection );
Expand Down Expand Up @@ -219,13 +230,15 @@ protected static function get_all_connections( $run_tests = false ) {
/**
* Get a list of publicize connections.
*
* @param bool $run_tests Whether to run tests on the connections.
* @param array $args Arguments.
*
* @see Automattic\Jetpack\Publicize\REST_API\Connections_Controller::get_all_connections()
*
* @return array
*/
public static function get_connections( $run_tests = false ) {
public static function get_connections( $args = array() ) {
if ( self::is_wpcom() ) {
return self::get_all_connections( $run_tests );
return self::get_all_connections( $args );
}

$site_id = Manager::get_site_id( true );
Expand All @@ -234,11 +247,17 @@ public static function get_connections( $run_tests = false ) {
}

$path = add_query_arg(
array( 'test_connections' => $run_tests ),
array(
'test_connections' => $args['test_connections'] ?? false,
),
sprintf( '/sites/%d/publicize/connections', $site_id )
);

$response = Client::wpcom_json_api_request_as_user( $path, 'v2', array( 'method' => 'GET' ) );
$blog_or_user = ( $args['scope'] ?? '' ) === 'site' ? 'blog' : 'user';

$callback = array( Client::class, "wpcom_json_api_request_as_{$blog_or_user}" );

$response = call_user_func( $callback, $path, 'v2', array( 'method' => 'GET' ), null, 'wpcom' );

if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
// TODO log error.
Expand All @@ -262,9 +281,12 @@ public static function get_connections( $run_tests = false ) {
public function get_items( $request ) {
$items = array();

$run_tests = $request->get_param( 'test_connections' );
// On Jetpack, we don't want to pass the 'scope' param to get_connections().
$args = array(
'test_connections' => $request->get_param( 'test_connections' ),
);

foreach ( self::get_connections( $run_tests ) as $item ) {
foreach ( self::get_connections( $args ) as $item ) {
$data = $this->prepare_item_for_response( $item, $request );

$items[] = $this->prepare_response_for_collection( $data );
Expand Down

0 comments on commit 27b255e

Please sign in to comment.