PATH:
home
/
letacommog
/
letacommunication
/
wp-content
/
plugins
/
google-site-kit
/
includes
/
Core
/
Authentication
<?php /** * Class Google\Site_Kit\Core\Authentication\Google_Proxy * * @package Google\Site_Kit\Core\Authentication * @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\Authentication; use Google\Site_Kit\Context; use Google\Site_Kit\Core\Util\Feature_Flags; use WP_Error; use Exception; /** * Class for authentication service. * * @since 1.1.2 * @access private * @ignore */ class Google_Proxy { const BASE_URL = 'https://sitekit.withgoogle.com'; const OAUTH2_SITE_URI = '/o/oauth2/site/'; const OAUTH2_REVOKE_URI = '/o/oauth2/revoke/'; const OAUTH2_TOKEN_URI = '/o/oauth2/token/'; const OAUTH2_AUTH_URI = '/o/oauth2/auth/'; const OAUTH2_DELETE_SITE_URI = '/o/oauth2/delete-site/'; const SETUP_URI = '/site-management/setup/'; const PERMISSIONS_URI = '/site-management/permissions/'; const USER_INPUT_SETTINGS_URI = '/site-management/settings/'; const FEATURES_URI = '/site-management/features/'; const ACTION_SETUP = 'googlesitekit_proxy_setup'; const ACTION_PERMISSIONS = 'googlesitekit_proxy_permissions'; /** * Plugin context. * * @since 1.1.2 * @var Context */ private $context; /** * Google_Proxy constructor. * * @since 1.1.2 * * @param Context $context Plugin context. */ public function __construct( Context $context ) { $this->context = $context; } /** * Returns the application name: a combination of the namespace and version. * * @since 1.27.0 * * @return string The application name. */ public static function get_application_name() { return 'wordpress/google-site-kit/' . GOOGLESITEKIT_VERSION; } /** * Gets the list of features to declare support for when setting up with the proxy. * * @since 1.27.0 * * @return array Array of supported features. */ private function get_supports() { $supports = array( 'credentials_retrieval', 'short_verification_token', // Informs the proxy the user input feature is generally supported. 'user_input_flow', ); $home_path = wp_parse_url( $this->context->get_canonical_home_url(), PHP_URL_PATH ); if ( ! $home_path || '/' === $home_path ) { $supports[] = 'file_verification'; } // Informs the proxy the user input feature is already enabled locally. // TODO: Remove once the feature is fully rolled out. if ( Feature_Flags::enabled( 'userInput' ) ) { $supports[] = 'user_input_flow_feature'; } return $supports; } /** * Returns the setup URL to the authentication proxy. * * @since 1.27.0 * * @param Credentials $credentials Credentials instance. * @param array $query_params Optional. Additional query parameters. * @return string URL to the setup page on the authentication proxy. */ public function setup_url( Credentials $credentials, array $query_params = array() ) { $params = array_merge( $query_params, array( 'supports' => rawurlencode( implode( ' ', $this->get_supports() ) ), 'nonce' => rawurlencode( wp_create_nonce( self::ACTION_SETUP ) ), ) ); if ( $credentials->has() ) { $creds = $credentials->get(); $params['site_id'] = $creds['oauth2_client_id']; } /** * Filters parameters included in proxy setup URL. * * @since 1.27.0 */ $params = apply_filters( 'googlesitekit_proxy_setup_url_params', $params ); // If no site identification information is present, we need to provide details for a new site. if ( empty( $params['site_id'] ) && empty( $params['site_code'] ) ) { $site_fields = array_map( 'rawurlencode', $this->get_site_fields() ); $params = array_merge( $params, $site_fields ); } $user_fields = array_map( 'rawurlencode', $this->get_user_fields() ); $params = array_merge( $params, $user_fields ); $params['application_name'] = rawurlencode( self::get_application_name() ); $params['hl'] = get_user_locale(); return add_query_arg( $params, $this->url( self::SETUP_URI ) ); } /** * Returns the permissions URL to the authentication proxy. * * This only returns a URL if the user already has an access token set. * * @since 1.27.0 * * @param Credentials $credentials Credentials instance. * @param array $query_args Optional. Additional query parameters. * @return string URL to the permissions page on the authentication proxy on success, or an empty string on failure. */ public function permissions_url( Credentials $credentials, array $query_args = array() ) { if ( $credentials->has() ) { $creds = $credentials->get(); $query_args['site_id'] = $creds['oauth2_client_id']; } $query_args['application_name'] = rawurlencode( self::get_application_name() ); $query_args['hl'] = get_user_locale(); return add_query_arg( $query_args, $this->url( self::PERMISSIONS_URI ) ); } /** * Gets a URL to the proxy with optional path. * * @since 1.1.2 * * @param string $path Optional. Path to append to the base URL. * @return string Complete proxy URL. */ public function url( $path = '' ) { if ( defined( 'GOOGLESITEKIT_PROXY_URL' ) && GOOGLESITEKIT_PROXY_URL ) { $url = GOOGLESITEKIT_PROXY_URL; } else { $url = self::BASE_URL; } $url = untrailingslashit( $url ); if ( $path && is_string( $path ) ) { $url .= '/' . ltrim( $path, '/' ); } return $url; } /** * Sends a POST request to the Google Proxy server. * * @since 1.27.0 * * @param string $uri Endpoint to send the request to. * @param Credentials $credentials Credentials instance. * @param array $args Array of request arguments. * @return array|WP_Error The response as an associative array or WP_Error on failure. */ private function request( $uri, $credentials, array $args = array() ) { $request_args = array( 'headers' => ! empty( $args['headers'] ) && is_array( $args['headers'] ) ? $args['headers'] : array(), 'body' => ! empty( $args['body'] ) && is_array( $args['body'] ) ? $args['body'] : array(), ); if ( $credentials && $credentials instanceof Credentials ) { if ( ! $credentials->has() ) { return new WP_Error( 'oauth_credentials_not_exist', __( 'OAuth credentials haven\'t been found.', 'google-site-kit' ), array( 'status' => 401 ) ); } $creds = $credentials->get(); $request_args['body']['site_id'] = $creds['oauth2_client_id']; $request_args['body']['site_secret'] = $creds['oauth2_client_secret']; } if ( ! empty( $args['access_token'] ) && is_string( $args['access_token'] ) ) { $request_args['headers']['Authorization'] = 'Bearer ' . $args['access_token']; } if ( isset( $args['mode'] ) && 'async' === $args['mode'] ) { $request_args['timeout'] = 0.01; $request_args['blocking'] = false; } if ( ! empty( $args['json_request'] ) ) { $request_args['headers']['Content-Type'] = 'application/json'; $request_args['body'] = wp_json_encode( $request_args['body'] ); } $url = $this->url( $uri ); $response = wp_remote_post( $url, $request_args ); if ( is_wp_error( $response ) ) { return $response; } $code = wp_remote_retrieve_response_code( $response ); $body = wp_remote_retrieve_body( $response ); $body = json_decode( $body, true ); if ( $code < 200 || 299 < $code ) { $message = is_array( $body ) && ! empty( $body['error'] ) ? $body['error'] : ''; return new WP_Error( 'request_failed', $message, array( 'status' => $code ) ); } if ( is_null( $body ) ) { return new WP_Error( 'failed_to_parse_response', __( 'Failed to parse response.', 'google-site-kit' ), array( 'status' => 500 ) ); } return $body; } /** * Gets site fields. * * @since 1.5.0 * * @return array Associative array of $query_arg => $value pairs. */ public function get_site_fields() { return array( 'name' => wp_specialchars_decode( get_bloginfo( 'name' ) ), 'url' => $this->context->get_canonical_home_url(), 'redirect_uri' => add_query_arg( 'oauth2callback', 1, admin_url( 'index.php' ) ), 'action_uri' => admin_url( 'index.php' ), 'return_uri' => $this->context->admin_url( 'splash' ), 'analytics_redirect_uri' => add_query_arg( 'gatoscallback', 1, admin_url( 'index.php' ) ), ); } /** * Fetch site fields * * @since 1.22.0 * * @param Credentials $credentials Credentials instance. * @return array|WP_Error The response as an associative array or WP_Error on failure. */ public function fetch_site_fields( Credentials $credentials ) { return $this->request( self::OAUTH2_SITE_URI, $credentials ); } /** * Are site fields synced * * @since 1.22.0 * * @param Credentials $credentials Credentials instance. * * @return boolean|WP_Error Boolean do the site fields match or WP_Error on failure. */ public function are_site_fields_synced( Credentials $credentials ) { $site_fields = $this->fetch_site_fields( $credentials ); if ( is_wp_error( $site_fields ) ) { return $site_fields; } $get_site_fields = $this->get_site_fields(); foreach ( $get_site_fields as $key => $site_field ) { if ( ! array_key_exists( $key, $site_fields ) || $site_fields[ $key ] !== $site_field ) { return false; } } return true; } /** * Gets user fields. * * @since 1.10.0 * * @return array Associative array of $query_arg => $value pairs. */ public function get_user_fields() { $user_roles = wp_get_current_user()->roles; // If multisite, also consider network administrators. if ( is_multisite() && current_user_can( 'manage_network' ) ) { $user_roles[] = 'network_administrator'; } $user_roles = array_unique( $user_roles ); return array( 'user_roles' => implode( ',', $user_roles ), ); } /** * Unregisters the site on the proxy. * * @since 1.20.0 * * @param Credentials $credentials Credentials instance. * @return array|WP_Error Response data on success, otherwise WP_Error object. */ public function unregister_site( Credentials $credentials ) { return $this->request( self::OAUTH2_DELETE_SITE_URI, $credentials ); } /** * Synchronizes site fields with the proxy. * * @since 1.5.0 * * @param Credentials $credentials Credentials instance. * @param string $mode Sync mode. * @return array|WP_Error Response of the wp_remote_post request. */ public function sync_site_fields( Credentials $credentials, $mode = 'async' ) { return $this->request( self::OAUTH2_SITE_URI, $credentials, array( 'mode' => $mode, 'body' => $this->get_site_fields(), ) ); } /** * Synchronizes user input settings with the proxy. * * @since 1.27.0 * * @param Credentials $credentials Credentials instance. * @param string $access_token Access token. * @param array|null $settings Settings array. * @return array|WP_Error Response of the wp_remote_post request. */ public function sync_user_input_settings( Credentials $credentials, $access_token, $settings = null ) { $body = array(); if ( ! empty( $settings ) ) { $body = array( 'settings' => $settings, 'client_user_id' => (string) get_current_user_id(), ); } return $this->request( self::USER_INPUT_SETTINGS_URI, $credentials, array( 'json_request' => true, 'access_token' => $access_token, 'body' => $body, ) ); } /** * Exchanges a site code for client credentials from the proxy. * * @since 1.1.2 * * @param string $site_code Site code identifying the site. * @param string $undelegated_code Undelegated code identifying the undelegated token. * @return array|WP_Error Response data containing site_id and site_secret on success, WP_Error object on failure. */ public function exchange_site_code( $site_code, $undelegated_code ) { $response_data = $this->request( self::OAUTH2_SITE_URI, null, array( 'body' => array( 'code' => $undelegated_code, 'site_code' => $site_code, ), ) ); if ( is_wp_error( $response_data ) ) { return $response_data; } if ( ! isset( $response_data['site_id'], $response_data['site_secret'] ) ) { return new WP_Error( 'oauth_credentials_not_exist', __( 'OAuth credentials haven\'t been found.', 'google-site-kit' ), array( 'status' => 401 ) ); } return $response_data; } /** * Gets remote features. * * @since 1.27.0 * * @param Credentials $credentials Credentials instance. * @return array|WP_Error Response of the wp_remote_post request. */ public function get_features( Credentials $credentials ) { return $this->request( self::FEATURES_URI, $credentials, array( 'body' => array( 'platform' => 'wordpress/google-site-kit', 'version' => GOOGLESITEKIT_VERSION, ), ) ); } }
[+]
..
[-] Credentials.php
[edit]
[-] Profile.php
[edit]
[-] Verification.php
[edit]
[-] Verification_Meta.php
[edit]
[-] Initial_Version.php
[edit]
[-] Authentication.php
[edit]
[-] Has_Connected_Admins.php
[edit]
[+]
Clients
[-] Has_Multiple_Admins.php
[edit]
[-] Google_Proxy.php
[edit]
[-] Owner_ID.php
[edit]
[-] Verification_File.php
[edit]
[+]
Exception
[-] User_Input_State.php
[edit]
[-] Disconnected_Reason.php
[edit]
[-] Connected_Proxy_URL.php
[edit]