PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 28.2
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v28.2
28.5 28.4 28.3 28.2 28.1 28.0 27.9 27.8 27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 19.0 All 129 releases
wordpress-seo / src / config / wincher-client.php

wincher-client.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI 28.2, at src/config/wincher-client.php

129 lines 3.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Yoast\WP\SEO\Config;
4
5 use WPSEO_Utils;
6 use Yoast\WP\SEO\Exceptions\OAuth\Authentication_Failed_Exception;
7 use Yoast\WP\SEO\Exceptions\OAuth\Tokens\Empty_Property_Exception;
8 use Yoast\WP\SEO\Exceptions\OAuth\Tokens\Empty_Token_Exception;
9 use Yoast\WP\SEO\Helpers\Options_Helper;
10 use Yoast\WP\SEO\Values\OAuth\OAuth_Token;
11 use Yoast\WP\SEO\Wrappers\WP_Remote_Handler;
12 use YoastSEO_Vendor\GuzzleHttp\Client;
13 use YoastSEO_Vendor\League\OAuth2\Client\Provider\Exception\IdentityProviderException;
14
15 /**
16 * Class Wincher_Client
17 */
18 class Wincher_Client extends OAuth_Client {
19
20 /**
21 * The option's key.
22 */
23 public const TOKEN_OPTION = 'wincher_tokens';
24
25 /**
26 * Name of the temporary PKCE cookie.
27 */
28 public const PKCE_TRANSIENT_NAME = 'yoast_wincher_pkce';
29
30 /**
31 * The WP_Remote_Handler instance.
32 *
33 * @var WP_Remote_Handler
34 */
35 protected $wp_remote_handler;
36
37 /**
38 * Wincher_Client constructor.
39 *
40 * @param Options_Helper $options_helper The Options_Helper instance.
41 * @param WP_Remote_Handler $wp_remote_handler The request handler.
42 *
43 * @throws Empty_Property_Exception Exception thrown if a token property is empty.
44 */
45 public function __construct( Options_Helper $options_helper, WP_Remote_Handler $wp_remote_handler ) {
46 $provider = new Wincher_PKCE_Provider(
47 [
48 'clientId' => 'yoast',
49 'redirectUri' => 'https://auth.wincher.com/yoast/setup',
50 'urlAuthorize' => 'https://auth.wincher.com/connect/authorize',
51 'urlAccessToken' => 'https://auth.wincher.com/connect/token',
52 'urlResourceOwnerDetails' => 'https://api.wincher.com/beta/user',
53 'scopes' => [ 'profile', 'account', 'websites:read', 'websites:write', 'offline_access' ],
54 'scopeSeparator' => ' ',
55 'pkceMethod' => 'S256',
56 ],
57 [
58 'httpClient' => new Client( [ 'handler' => $wp_remote_handler ] ),
59 ],
60 );
61
62 parent::__construct(
63 self::TOKEN_OPTION,
64 $provider,
65 $options_helper,
66 );
67 }
68
69 /**
70 * Return the authorization URL.
71 *
72 * @return string The authentication URL.
73 */
74 public function get_authorization_url() {
75 $parsed_site_url = \wp_parse_url( \get_site_url() );
76
77 $url = $this->provider->getAuthorizationUrl(
78 [
79 'state' => WPSEO_Utils::format_json_encode( [ 'domain' => $parsed_site_url['host'] ] ),
80 ],
81 );
82
83 $pkce_code = $this->provider->getPkceCode();
84
85 // Store a transient value with the PKCE code that we need in order to
86 // exchange the returned code for a token after authorization.
87 \set_transient( self::PKCE_TRANSIENT_NAME, $pkce_code, \DAY_IN_SECONDS );
88
89 return $url;
90 }
91
92 /**
93 * Requests the access token and refresh token based on the passed code.
94 *
95 * @param string $code The code to send.
96 *
97 * @return OAuth_Token The requested tokens.
98 *
99 * @throws Authentication_Failed_Exception Exception thrown if authentication has failed.
100 */
101 public function request_tokens( $code ) {
102 $pkce_code = \get_transient( self::PKCE_TRANSIENT_NAME );
103 if ( $pkce_code ) {
104 $this->provider->setPkceCode( $pkce_code );
105 }
106 return parent::request_tokens( $code );
107 }
108
109 /**
110 * Performs the specified request.
111 *
112 * @codeCoverageIgnore
113 *
114 * @param string $method The HTTP method to use.
115 * @param string $url The URL to send the request to.
116 * @param array $options The options to pass along to the request.
117 *
118 * @return mixed The parsed API response.
119 *
120 * @throws IdentityProviderException Exception thrown if there's something wrong with the identifying data.
121 * @throws Authentication_Failed_Exception Exception thrown if authentication has failed.
122 * @throws Empty_Token_Exception Exception thrown if the token is empty.
123 */
124 protected function do_request( $method, $url, array $options ) {
125 $options['headers'] = [ 'Content-Type' => 'application/json' ];
126 return parent::do_request( $method, $url, $options );
127 }
128 }
129