778 lines
25 KiB
PHP
778 lines
25 KiB
PHP
<?php
|
|
/**
|
|
* Class Google\Site_Kit\Core\Permissions\Permissions
|
|
*
|
|
* @package Google\Site_Kit\Core\Permissions
|
|
* @copyright 2021 Google LLC
|
|
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
|
|
* @link https://sitekit.withgoogle.com
|
|
*/
|
|
|
|
namespace Google\Site_Kit\Core\Permissions;
|
|
|
|
use Exception;
|
|
use Google\Site_Kit\Context;
|
|
use Google\Site_Kit\Core\Authentication\Authentication;
|
|
use Google\Site_Kit\Core\Dismissals\Dismissed_Items;
|
|
use Google\Site_Kit\Core\Modules\Module_With_Owner;
|
|
use Google\Site_Kit\Core\Modules\Modules;
|
|
use Google\Site_Kit\Core\REST_API\REST_Route;
|
|
use Google\Site_Kit\Core\REST_API\REST_Routes;
|
|
use Google\Site_Kit\Core\Storage\User_Options;
|
|
use WP_REST_Response;
|
|
use WP_REST_Server;
|
|
use WP_User;
|
|
|
|
/**
|
|
* Class managing plugin permissions.
|
|
*
|
|
* @since 1.0.0
|
|
* @access private
|
|
* @ignore
|
|
*/
|
|
final class Permissions {
|
|
/*
|
|
* Custom base capabilities.
|
|
*/
|
|
const AUTHENTICATE = 'googlesitekit_authenticate';
|
|
const SETUP = 'googlesitekit_setup';
|
|
const VIEW_POSTS_INSIGHTS = 'googlesitekit_view_posts_insights';
|
|
const VIEW_DASHBOARD = 'googlesitekit_view_dashboard';
|
|
const VIEW_WP_DASHBOARD_WIDGET = 'googlesitekit_view_wp_dashboard_widget';
|
|
const VIEW_ADMIN_BAR_MENU = 'googlesitekit_view_admin_bar_menu';
|
|
const MANAGE_OPTIONS = 'googlesitekit_manage_options';
|
|
const UPDATE_PLUGINS = 'googlesitekit_update_plugins';
|
|
|
|
|
|
/*
|
|
* Custom meta capabilities.
|
|
*/
|
|
const VIEW_SPLASH = 'googlesitekit_view_splash';
|
|
const VIEW_SHARED_DASHBOARD = 'googlesitekit_view_shared_dashboard';
|
|
const VIEW_AUTHENTICATED_DASHBOARD = 'googlesitekit_view_authenticated_dashboard';
|
|
const VIEW_POST_INSIGHTS = 'googlesitekit_view_post_insights';
|
|
const READ_SHARED_MODULE_DATA = 'googlesitekit_read_shared_module_data';
|
|
const MANAGE_MODULE_SHARING_OPTIONS = 'googlesitekit_manage_module_sharing_options';
|
|
const DELEGATE_MODULE_SHARING_MANAGEMENT = 'googlesitekit_delegate_module_sharing_management';
|
|
|
|
/**
|
|
* Plugin context.
|
|
*
|
|
* @since 1.0.0
|
|
* @var Context
|
|
*/
|
|
private $context;
|
|
|
|
/**
|
|
* Authentication instance.
|
|
*
|
|
* @since 1.0.0
|
|
* @var Authentication
|
|
*/
|
|
protected $authentication;
|
|
|
|
/**
|
|
* Modules instance.
|
|
*
|
|
* @since 1.69.0
|
|
* @var Modules
|
|
*/
|
|
private $modules;
|
|
|
|
/**
|
|
* User_Options instance.
|
|
*
|
|
* @since 1.69.0
|
|
* @var User_Options
|
|
*/
|
|
private $user_options;
|
|
|
|
/**
|
|
* Dismissed_Items instance.
|
|
*
|
|
* @since 1.69.0
|
|
* @var Dismissed_Items
|
|
*/
|
|
private $dismissed_items;
|
|
|
|
/**
|
|
* Mappings for custom base capabilities to WordPress core built-in ones.
|
|
*
|
|
* @since 1.30.0
|
|
* @var array
|
|
*/
|
|
private $base_to_core = array();
|
|
|
|
/**
|
|
* Mappings for custom meta capabilities to WordPress core built-in ones.
|
|
*
|
|
* @since 1.0.0
|
|
* @var array
|
|
*/
|
|
private $meta_to_core = array();
|
|
|
|
/**
|
|
* Mappings for custom meta capabilities to custom base capabilities.
|
|
*
|
|
* @since 1.30.0
|
|
* @var array
|
|
*/
|
|
private $meta_to_base = array();
|
|
|
|
/**
|
|
* List of custom base capabilities that should require network access if the plugin is in network mode.
|
|
*
|
|
* @since 1.30.0
|
|
* @var array
|
|
*/
|
|
private $network_base = array();
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* Sets up the capability mappings.
|
|
*
|
|
* @since 1.0.0
|
|
*
|
|
* @param Context $context Plugin context.
|
|
* @param Authentication $authentication Authentication instance.
|
|
* @param Modules $modules Modules instance.
|
|
* @param User_Options $user_options User_Options instance.
|
|
* @param Dismissed_Items $dismissed_items Dismissed_Items instance.
|
|
*/
|
|
public function __construct( Context $context, Authentication $authentication, Modules $modules, User_Options $user_options, Dismissed_Items $dismissed_items ) {
|
|
$this->context = $context;
|
|
$this->authentication = $authentication;
|
|
$this->modules = $modules;
|
|
$this->user_options = $user_options;
|
|
$this->dismissed_items = $dismissed_items;
|
|
|
|
$this->base_to_core = array(
|
|
// By default, only allow administrators to authenticate.
|
|
self::AUTHENTICATE => 'manage_options',
|
|
|
|
// Allow contributors and up to view their own post's insights.
|
|
self::VIEW_POSTS_INSIGHTS => 'edit_posts',
|
|
|
|
// Allow editors and up to view the dashboard and module details.
|
|
self::VIEW_DASHBOARD => 'edit_posts',
|
|
self::VIEW_WP_DASHBOARD_WIDGET => 'edit_posts',
|
|
self::VIEW_ADMIN_BAR_MENU => 'edit_posts',
|
|
|
|
// Allow administrators and up to manage options and set up the plugin.
|
|
self::MANAGE_OPTIONS => 'manage_options',
|
|
self::SETUP => 'manage_options',
|
|
self::UPDATE_PLUGINS => 'update_plugins',
|
|
);
|
|
|
|
$this->meta_to_core = array(
|
|
// Allow users that can edit a post to view that post's insights.
|
|
self::VIEW_POST_INSIGHTS => 'edit_post',
|
|
);
|
|
|
|
$this->meta_to_base = array(
|
|
self::VIEW_SPLASH => self::VIEW_DASHBOARD,
|
|
self::VIEW_AUTHENTICATED_DASHBOARD => array( self::VIEW_DASHBOARD, self::AUTHENTICATE ),
|
|
// Allow users that can generally view posts insights to view a specific post's insights.
|
|
self::VIEW_POST_INSIGHTS => self::VIEW_POSTS_INSIGHTS,
|
|
// Allow users that can generally view dashboard to read shared module data.
|
|
self::READ_SHARED_MODULE_DATA => self::VIEW_DASHBOARD,
|
|
// Admins who can manage options for SK can generally manage module sharing options.
|
|
self::MANAGE_MODULE_SHARING_OPTIONS => self::MANAGE_OPTIONS,
|
|
self::DELEGATE_MODULE_SHARING_MANAGEMENT => self::MANAGE_OPTIONS,
|
|
self::VIEW_SHARED_DASHBOARD => self::VIEW_DASHBOARD,
|
|
);
|
|
|
|
$this->network_base = array(
|
|
// Require network admin access to view the dashboard and module details in network mode.
|
|
self::VIEW_DASHBOARD => 'manage_network',
|
|
self::VIEW_WP_DASHBOARD_WIDGET => 'manage_network',
|
|
self::VIEW_ADMIN_BAR_MENU => 'manage_network',
|
|
|
|
// Require network admin access to manage options and set up the plugin in network mode.
|
|
self::MANAGE_OPTIONS => 'manage_network_options',
|
|
self::SETUP => 'manage_network_options',
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Registers functionality through WordPress hooks.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
public function register() {
|
|
add_filter(
|
|
'map_meta_cap',
|
|
function ( array $caps, $cap, $user_id, $args ) {
|
|
return $this->map_meta_capabilities( $caps, $cap, $user_id, $args );
|
|
},
|
|
10,
|
|
4
|
|
);
|
|
|
|
add_filter(
|
|
'googlesitekit_rest_routes',
|
|
function ( $routes ) {
|
|
return array_merge( $routes, $this->get_rest_routes() );
|
|
}
|
|
);
|
|
|
|
add_filter(
|
|
'googlesitekit_apifetch_preload_paths',
|
|
function ( $paths ) {
|
|
return array_merge(
|
|
$paths,
|
|
array(
|
|
'/' . REST_Routes::REST_ROOT . '/core/user/data/permissions',
|
|
)
|
|
);
|
|
}
|
|
);
|
|
|
|
// This constant can be set if an alternative mechanism to grant these capabilities is in place.
|
|
if ( defined( 'GOOGLESITEKIT_DISABLE_DYNAMIC_CAPABILITIES' ) && GOOGLESITEKIT_DISABLE_DYNAMIC_CAPABILITIES ) {
|
|
return;
|
|
}
|
|
|
|
add_filter(
|
|
'user_has_cap',
|
|
function ( array $allcaps ) {
|
|
return $this->grant_additional_caps( $allcaps );
|
|
}
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Get dashboard sharing meta permissions for current user.
|
|
*
|
|
* @since 1.70.0
|
|
*
|
|
* @return array List meta capabilities as keys and current user permission as value.
|
|
*/
|
|
public function get_dashboard_sharing_meta_permissions() {
|
|
$dashboard_sharing_meta_capabilities = self::get_dashboard_sharing_meta_capabilities();
|
|
|
|
$shareable_modules = array_keys( $this->modules->get_shareable_modules() );
|
|
|
|
$dashboard_sharing_meta_permissions = array();
|
|
foreach ( $dashboard_sharing_meta_capabilities as $cap ) {
|
|
foreach ( $shareable_modules as $module ) {
|
|
$dashboard_sharing_meta_permissions[ "{$cap}::" . wp_json_encode( array( $module ) ) ] = current_user_can( $cap, $module );
|
|
}
|
|
}
|
|
|
|
return $dashboard_sharing_meta_permissions;
|
|
}
|
|
|
|
/**
|
|
* Check permissions for current user.
|
|
*
|
|
* @since 1.21.0
|
|
*
|
|
* @return array List of base capabilities and meta capabilities as keys and current user permission as value.
|
|
*/
|
|
public function check_all_for_current_user() {
|
|
$permissions = self::get_capabilities();
|
|
|
|
return array_merge(
|
|
array_combine(
|
|
$permissions,
|
|
array_map( 'current_user_can', $permissions )
|
|
),
|
|
self::get_dashboard_sharing_meta_permissions()
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Resolves meta capabilities to their base capabilities.
|
|
*
|
|
* This method first maps plugin meta capabilities to their base capabilities. In addition, if the meta
|
|
* capability should also map to a core meta capability, that mapping is taken care of as well.
|
|
*
|
|
* If in network mode and the custom base capability requires network access, it is checked that the user
|
|
* has that access, and if not, the method bails early causing in a result of false.
|
|
*
|
|
* It also prevents access to Site Kit's custom capabilities based on additional rules. These additional
|
|
* checks ideally could be done within the `user_has_cap` filter. However, the `user_has_cap` filter is
|
|
* applied after a check for multi-site admins which could potentially grant the capability without
|
|
* executing these additional checks.
|
|
*
|
|
* @see WP_User::has_cap() To see the order of execution mentioned above.
|
|
*
|
|
* @since 1.0.0
|
|
*
|
|
* @param array $caps List of resolved capabilities.
|
|
* @param string $cap Capability checked.
|
|
* @param int $user_id Current user ID.
|
|
* @param array $args Additional arguments passed to the capability check.
|
|
* @return array Filtered value of $caps.
|
|
*/
|
|
private function map_meta_capabilities( array $caps, $cap, $user_id, $args ) {
|
|
// Bail early under these circumstances as we already know for sure the check will result in false.
|
|
if ( isset( $this->network_base[ $cap ] ) && $this->context->is_network_mode() && ! is_super_admin( $user_id ) ) {
|
|
return array( 'do_not_allow' );
|
|
}
|
|
|
|
if ( isset( $this->meta_to_base[ $cap ] ) ) {
|
|
$caps = (array) $this->meta_to_base[ $cap ];
|
|
}
|
|
|
|
if ( isset( $this->meta_to_core[ $cap ] ) ) {
|
|
$required_core_caps = call_user_func_array(
|
|
'map_meta_cap',
|
|
array_merge(
|
|
array( $this->meta_to_core[ $cap ], $user_id ),
|
|
$args
|
|
)
|
|
);
|
|
|
|
$caps = array_merge( $caps, $required_core_caps );
|
|
}
|
|
|
|
// Special setup and authentication rules.
|
|
if ( ( isset( $this->base_to_core[ $cap ] ) || isset( $this->meta_to_core[ $cap ] ) ) ) {
|
|
// If setup has not yet been completed, require administrator capabilities for everything.
|
|
if ( self::SETUP !== $cap && ! $this->authentication->is_setup_completed() ) {
|
|
$caps[] = self::SETUP;
|
|
}
|
|
|
|
if ( ! in_array( $cap, array( self::AUTHENTICATE, self::SETUP, self::VIEW_DASHBOARD, self::VIEW_POSTS_INSIGHTS, self::VIEW_WP_DASHBOARD_WIDGET, self::VIEW_ADMIN_BAR_MENU ), true ) ) {
|
|
// For regular users, require being authenticated.
|
|
if ( ! $this->is_user_authenticated( $user_id ) ) {
|
|
return array_merge( $caps, array( 'do_not_allow' ) );
|
|
}
|
|
// For admin users, also require being verified.
|
|
if ( user_can( $user_id, self::SETUP ) && ! $this->is_user_verified( $user_id ) ) {
|
|
return array_merge( $caps, array( 'do_not_allow' ) );
|
|
}
|
|
|
|
// For all users, require setup to have been completed.
|
|
if ( ! $this->authentication->is_setup_completed() ) {
|
|
return array_merge( $caps, array( 'do_not_allow' ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( in_array( $cap, self::get_dashboard_sharing_capabilities(), true ) ) {
|
|
$caps = array_merge( $caps, $this->check_dashboard_sharing_capability( $cap, $user_id, $args ) );
|
|
}
|
|
|
|
switch ( $cap ) {
|
|
case self::VIEW_SPLASH:
|
|
$caps = array_merge( $caps, $this->check_view_splash_capability( $user_id ) );
|
|
break;
|
|
// Intentional fallthrough - viewing the dashboard widget and admin bar menu require
|
|
// a user to be authenticated.
|
|
case self::VIEW_AUTHENTICATED_DASHBOARD:
|
|
$caps = array_merge( $caps, $this->check_view_authenticated_dashboard_capability( $user_id ) );
|
|
break;
|
|
// Intentional fallthrough.
|
|
case self::VIEW_DASHBOARD:
|
|
case self::VIEW_POSTS_INSIGHTS:
|
|
$caps = array_merge( $caps, $this->check_view_dashboard_capability( $user_id ) );
|
|
break;
|
|
case self::VIEW_WP_DASHBOARD_WIDGET:
|
|
case self::VIEW_ADMIN_BAR_MENU:
|
|
$caps = array_merge( $caps, $this->check_view_wp_dashboard_widget_and_admin_bar_capability( $user_id ) );
|
|
break;
|
|
}
|
|
|
|
return $caps;
|
|
}
|
|
|
|
/**
|
|
* Checks a dashboard sharing capability based on rules of dashboard sharing.
|
|
*
|
|
* @since 1.69.0
|
|
*
|
|
* @param string $cap Capability to be checked.
|
|
* @param int $user_id User ID of the user the capability is checked for.
|
|
* @param array $args Additional arguments passed to check a meta capability.
|
|
* @return array Array with a 'do_not_allow' element if checks fail, empty array if checks pass.
|
|
*/
|
|
private function check_dashboard_sharing_capability( $cap, $user_id, $args ) {
|
|
if ( isset( $args[0] ) ) {
|
|
$module_slug = $args[0];
|
|
}
|
|
|
|
switch ( $cap ) {
|
|
case self::VIEW_SHARED_DASHBOARD:
|
|
return $this->check_view_shared_dashboard_capability( $user_id );
|
|
|
|
case self::READ_SHARED_MODULE_DATA:
|
|
return $this->check_read_shared_module_data_capability( $user_id, $module_slug );
|
|
|
|
case self::MANAGE_MODULE_SHARING_OPTIONS:
|
|
case self::DELEGATE_MODULE_SHARING_MANAGEMENT:
|
|
return $this->check_module_sharing_admin_capability( $cap, $user_id, $module_slug );
|
|
|
|
default:
|
|
return array();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Checks if the VIEW_SPLASH capability is allowed for the user.
|
|
*
|
|
* @since 1.73.0
|
|
*
|
|
* @param int $user_id User ID of the user the capability is checked for.
|
|
* @return array Array with a 'do_not_allow' element if checks fail, empty array if checks pass.
|
|
*/
|
|
private function check_view_splash_capability( $user_id ) {
|
|
if ( $this->is_shared_dashboard_splash_dismissed( $user_id ) ) {
|
|
return array( self::AUTHENTICATE );
|
|
}
|
|
|
|
if ( ! $this->user_has_shared_role( $user_id ) ) {
|
|
return array( self::AUTHENTICATE );
|
|
}
|
|
|
|
return array();
|
|
}
|
|
|
|
/**
|
|
* Checks if the VIEW_DASHBOARD capability is allowed for the user.
|
|
*
|
|
* Allows access to the VIEW_DASHBOARD capability if the user can view either
|
|
* the authenticated or shared dashboard.
|
|
*
|
|
* @since 1.73.0
|
|
*
|
|
* @param int $user_id User ID of the user the capability is checked for.
|
|
* @return array Array with a 'do_not_allow' element if checks fail, empty array if checks pass.
|
|
*/
|
|
private function check_view_dashboard_capability( $user_id ) {
|
|
$view_authenticated_dashboard = $this->check_view_authenticated_dashboard_capability( $user_id );
|
|
|
|
if ( in_array( 'do_not_allow', $view_authenticated_dashboard, true ) ) {
|
|
return $this->check_view_shared_dashboard_capability( $user_id );
|
|
}
|
|
|
|
return $view_authenticated_dashboard;
|
|
}
|
|
|
|
/**
|
|
* Checks if the VIEW_WP_DASHBOARD_WIDGET and VIEW_ADMIN_BAR_MENU capabilities are allowed for the user.
|
|
*
|
|
* Allows access to the VIEW_WP_DASHBOARD_WIDGET and VIEW_ADMIN_BAR_MENU capabilities if the user can view
|
|
* either the authenticated or shared dashboard and if the user has a shared role for either the Analytics
|
|
* or Search Console module.
|
|
*
|
|
* @since 1.120.0
|
|
*
|
|
* @param int $user_id User ID of the user the capability is checked for.
|
|
* @return array Array with a 'do_not_allow' element if checks fail, empty array if checks pass.
|
|
*/
|
|
private function check_view_wp_dashboard_widget_and_admin_bar_capability( $user_id ) {
|
|
$view_dashboard_capability = $this->check_view_dashboard_capability( $user_id );
|
|
|
|
if ( in_array( self::AUTHENTICATE, $view_dashboard_capability, true ) || in_array( 'do_not_allow', $view_dashboard_capability, true ) ) {
|
|
return $view_dashboard_capability;
|
|
}
|
|
|
|
if ( ! $this->user_has_shared_role_for_module( $user_id, 'analytics-4' ) &&
|
|
! $this->user_has_shared_role_for_module( $user_id, 'search-console' ) ) {
|
|
return array( 'do_not_allow' );
|
|
}
|
|
|
|
return array();
|
|
}
|
|
|
|
/**
|
|
* Checks if the VIEW_SHARED_DASHBOARD capability should be denied.
|
|
*
|
|
* Prevents access to the VIEW_SHARED_DASHBOARD capability if a user does not
|
|
* have any of the shared roles set for any shareable module or if they have
|
|
* not dismissed the dashboard sharing splash screen message.
|
|
*
|
|
* @since 1.69.0
|
|
*
|
|
* @param int $user_id User ID of the user the capability is checked for.
|
|
* @return array Array with a 'do_not_allow' element if checks fail, empty array if checks pass.
|
|
*/
|
|
private function check_view_shared_dashboard_capability( $user_id ) {
|
|
if ( ! $this->user_has_shared_role( $user_id ) ) {
|
|
return array( 'do_not_allow' );
|
|
}
|
|
|
|
if ( ! $this->is_shared_dashboard_splash_dismissed( $user_id ) ) {
|
|
return array( 'do_not_allow' );
|
|
}
|
|
|
|
return array();
|
|
}
|
|
|
|
/**
|
|
* Checks if the VIEW_AUTHENTICATED_DASHBOARD capability is allowed for the user.
|
|
*
|
|
* Allows access to the VIEW_AUTHENTICATED_DASHBOARD capability if the user is authenticated.
|
|
*
|
|
* @since 1.73.0
|
|
*
|
|
* @param int $user_id User ID of the user the capability is checked for.
|
|
* @return array Array with a 'do_not_allow' element if checks fail, otherise returns AUTHENTICATE capability.
|
|
*/
|
|
private function check_view_authenticated_dashboard_capability( $user_id ) {
|
|
if (
|
|
$this->is_user_authenticated( $user_id )
|
|
&& $this->is_user_verified( $user_id )
|
|
&& $this->authentication->is_setup_completed()
|
|
) {
|
|
return array( self::AUTHENTICATE );
|
|
}
|
|
return array( 'do_not_allow' );
|
|
}
|
|
|
|
/**
|
|
* Checks if the READ_SHARED_MODULE_DATA capability should be denied.
|
|
*
|
|
* Prevents access to the READ_SHARED_MODULE_DATA capability if a user does not
|
|
* have the shared roles set for the given module slug.
|
|
*
|
|
* @since 1.69.0
|
|
*
|
|
* @param int $user_id User ID of the user the capability is checked for.
|
|
* @param string $module_slug Module for which the meta capability is checked for.
|
|
* @return array Array with a 'do_not_allow' element if checks fail, empty array if checks pass.
|
|
*/
|
|
private function check_read_shared_module_data_capability( $user_id, $module_slug ) {
|
|
if ( ! $this->user_has_shared_role_for_module( $user_id, $module_slug ) ) {
|
|
return array( 'do_not_allow' );
|
|
}
|
|
|
|
return array();
|
|
}
|
|
|
|
/**
|
|
* Checks if the MANAGE_MODULE_SHARING_OPTIONS or the DELEGATE_MODULE_SHARING_MANAGEMENT
|
|
* capability should be denied.
|
|
*
|
|
* Prevents access to MANAGE_MODULE_SHARING_OPTIONS or the DELEGATE_MODULE_SHARING_MANAGEMENT
|
|
* capability if a user is not an authenticated admin.
|
|
*
|
|
* Furthermore, it prevents access for these capabilities if the user is not the owner
|
|
* of the given module slug. This check is skipped for MANAGE_MODULE_SHARING_OPTIONS if the
|
|
* module settings allow all admins to manage sharing options for that module.
|
|
*
|
|
* @since 1.69.0
|
|
*
|
|
* @param string $cap Capability to be checked.
|
|
* @param int $user_id User ID of the user the capability is checked for.
|
|
* @param string $module_slug Module for which the meta capability is checked for.
|
|
* @return array Array with a 'do_not_allow' element if checks fail, empty array if checks pass.
|
|
*/
|
|
private function check_module_sharing_admin_capability( $cap, $user_id, $module_slug ) {
|
|
$module_sharing_settings = $this->modules->get_module_sharing_settings();
|
|
$sharing_settings = $module_sharing_settings->get();
|
|
|
|
if ( ! $this->is_user_authenticated( $user_id ) ) {
|
|
return array( 'do_not_allow' );
|
|
}
|
|
|
|
if ( self::MANAGE_MODULE_SHARING_OPTIONS === $cap &&
|
|
isset( $sharing_settings[ $module_slug ]['management'] ) &&
|
|
'all_admins' === $sharing_settings[ $module_slug ]['management']
|
|
) {
|
|
return array();
|
|
}
|
|
|
|
try {
|
|
$module = $this->modules->get_module( $module_slug );
|
|
if ( ! ( $module instanceof Module_With_Owner ) ) {
|
|
return array( 'do_not_allow' );
|
|
}
|
|
if ( $module->get_owner_id() !== $user_id ) {
|
|
return array( 'do_not_allow' );
|
|
}
|
|
} catch ( Exception $e ) {
|
|
return array( 'do_not_allow' );
|
|
}
|
|
|
|
return array();
|
|
}
|
|
|
|
/**
|
|
* Checks if the given user has a role in the list of shared roles.
|
|
*
|
|
* @since 1.73.0
|
|
*
|
|
* @param int $user_id User ID.
|
|
* @param string[]|null $shared_roles Optional. List of shared role IDs to check against the user's. Defaults to all shared module roles.
|
|
* @return bool
|
|
*/
|
|
private function user_has_shared_role( $user_id, array $shared_roles = null ) {
|
|
if ( ! is_array( $shared_roles ) ) {
|
|
$shared_roles = $this->modules->get_module_sharing_settings()->get_all_shared_roles();
|
|
}
|
|
|
|
$shared_user_roles = array_intersect( $shared_roles, ( new WP_User( $user_id ) )->roles );
|
|
|
|
return ! empty( $shared_user_roles );
|
|
}
|
|
|
|
/**
|
|
* Checks if the given user has a role in the list of shared roles for the given module.
|
|
*
|
|
* @since 1.73.0
|
|
*
|
|
* @param int $user_id User ID.
|
|
* @param string $module Module slug.
|
|
* @return bool
|
|
*/
|
|
private function user_has_shared_role_for_module( $user_id, $module ) {
|
|
$settings = $this->modules->get_module_sharing_settings()->get();
|
|
|
|
if ( empty( $settings[ $module ]['sharedRoles'] ) ) {
|
|
return false;
|
|
}
|
|
|
|
return $this->user_has_shared_role( $user_id, $settings[ $module ]['sharedRoles'] );
|
|
}
|
|
|
|
/**
|
|
* Checks if a user is authenticated in Site Kit.
|
|
*
|
|
* @since 1.69.0
|
|
*
|
|
* @param int $user_id User ID of the user to be checked.
|
|
* @return bool True if the user is authenticated, false if not.
|
|
*/
|
|
public function is_user_authenticated( $user_id ) {
|
|
$restore_user = $this->user_options->switch_user( $user_id );
|
|
$is_user_authenticated = $this->authentication->is_authenticated();
|
|
$restore_user();
|
|
return $is_user_authenticated;
|
|
}
|
|
|
|
/**
|
|
* Checks if a user is verified in Site Kit.
|
|
*
|
|
* @since 1.69.0
|
|
*
|
|
* @param int $user_id User ID of the user to be checked.
|
|
* @return bool True if the user is verified, false if not.
|
|
*/
|
|
public function is_user_verified( $user_id ) {
|
|
$restore_user = $this->user_options->switch_user( $user_id );
|
|
$is_user_verified = $this->authentication->verification()->has();
|
|
$restore_user();
|
|
return $is_user_verified;
|
|
}
|
|
|
|
/**
|
|
* Checks if a user has dimissed the shared dashboard splash screen message.
|
|
*
|
|
* @since 1.69.0
|
|
*
|
|
* @param int $user_id User ID of the user to be checked.
|
|
* @return bool True if the user has dismissed the splash message, false if not.
|
|
*/
|
|
private function is_shared_dashboard_splash_dismissed( $user_id ) {
|
|
$restore_user = $this->user_options->switch_user( $user_id );
|
|
$is_splash_dismissed = $this->dismissed_items->is_dismissed( 'shared_dashboard_splash' );
|
|
$restore_user();
|
|
return $is_splash_dismissed;
|
|
}
|
|
|
|
/**
|
|
* Grants custom capabilities on-the-fly, based on core capabilities.
|
|
*
|
|
* If you want to instead set up your own custom role or mechanism to grant these capabilities, you can set a
|
|
* constant flag `GOOGLESITEKIT_DISABLE_DYNAMIC_CAPABILITIES` to ensure this function is not hooked in.
|
|
*
|
|
* @since 1.0.0
|
|
*
|
|
* @param array $allcaps Associative array of $capability => $grant pairs.
|
|
* @return array Filtered value of $allcaps.
|
|
*/
|
|
private function grant_additional_caps( array $allcaps ) {
|
|
foreach ( $this->base_to_core as $custom_cap => $core_cap ) {
|
|
if ( isset( $allcaps[ $core_cap ] ) ) {
|
|
$allcaps[ $custom_cap ] = $allcaps[ $core_cap ];
|
|
}
|
|
}
|
|
|
|
return $allcaps;
|
|
}
|
|
|
|
/**
|
|
* Gets related REST routes.
|
|
*
|
|
* @since 1.82.0
|
|
*
|
|
* @return array List of REST_Route objects.
|
|
*/
|
|
private function get_rest_routes() {
|
|
return array(
|
|
new REST_Route(
|
|
'core/user/data/permissions',
|
|
array(
|
|
array(
|
|
'methods' => WP_REST_Server::READABLE,
|
|
'callback' => function () {
|
|
return new WP_REST_Response( $this->check_all_for_current_user() );
|
|
},
|
|
'permission_callback' => function () {
|
|
return current_user_can( Permissions::VIEW_SPLASH ) || current_user_can( Permissions::VIEW_DASHBOARD );
|
|
},
|
|
),
|
|
)
|
|
),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Gets all the base capabilities used in Google Site Kit.
|
|
*
|
|
* @since 1.31.0
|
|
*
|
|
* @return array
|
|
*/
|
|
public static function get_capabilities() {
|
|
return array(
|
|
self::AUTHENTICATE,
|
|
self::SETUP,
|
|
self::VIEW_POSTS_INSIGHTS,
|
|
self::VIEW_DASHBOARD,
|
|
self::MANAGE_OPTIONS,
|
|
self::UPDATE_PLUGINS,
|
|
self::VIEW_SPLASH,
|
|
self::VIEW_AUTHENTICATED_DASHBOARD,
|
|
self::VIEW_WP_DASHBOARD_WIDGET,
|
|
self::VIEW_ADMIN_BAR_MENU,
|
|
self::VIEW_SHARED_DASHBOARD,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Gets all the capabilities specifically added for dashboard sharing.
|
|
*
|
|
* @since 1.69.0
|
|
*
|
|
* @return array List of capabilities specific to dashboard sharing.
|
|
*/
|
|
public static function get_dashboard_sharing_capabilities() {
|
|
return array(
|
|
self::VIEW_SHARED_DASHBOARD,
|
|
self::READ_SHARED_MODULE_DATA,
|
|
self::MANAGE_MODULE_SHARING_OPTIONS,
|
|
self::DELEGATE_MODULE_SHARING_MANAGEMENT,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Gets all the meta capabilities specifically added for dashboard sharing.
|
|
*
|
|
* @since 1.70.0
|
|
*
|
|
* @return array List of meta capabilities specific to dashboard sharing.
|
|
*/
|
|
public static function get_dashboard_sharing_meta_capabilities() {
|
|
return array(
|
|
self::READ_SHARED_MODULE_DATA,
|
|
self::MANAGE_MODULE_SHARING_OPTIONS,
|
|
self::DELEGATE_MODULE_SHARING_MANAGEMENT,
|
|
);
|
|
}
|
|
}
|