PluginProbe
404 Solution / 4.2.0
404 Solution v4.2.0
4.3.5 4.3.4 4.3.3 4.3.2 4.3.1 4.3.0 4.2.0 4.1.19 4.1.18 4.1.17 4.1.16 4.1.15 4.1.13 4.1.12 4.1.11 4.1.10 4.1.9 4.1.8 4.1.7 4.1.6 4.1.5 4.1.4 4.1.3 trunk 2.30.0 All 109 releases
404-solution / includes / GscOAuthHandler.php

GscOAuthHandler.php in 404 Solution 4.2.0, at includes/GscOAuthHandler.php

112 lines 4.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if (!defined('ABSPATH')) {
4 exit;
5 }
6
7 /**
8 * Google Search Console OAuth callback and revocation handler.
9 *
10 * Supports both custom-credentials flow (code exchange) and centralized
11 * flow (Worker has already exchanged tokens).
12 */
13 class ABJ_404_Solution_GscOAuthHandler {
14
15 /**
16 * AJAX handler: OAuth callback from Google (custom mode) or from the
17 * centralized Worker (centralized mode).
18 *
19 * @return void
20 */
21 public static function handleCallback() {
22 if (!current_user_can('manage_options')) {
23 wp_die(__('Insufficient permissions.', '404-solution'), 403);
24 }
25
26 $logger = abj_service('logging');
27 $gsc = new ABJ_404_Solution_GoogleSearchConsole($logger);
28
29 $isCentralized = isset($_GET['abj404_gsc_centralized']) && $_GET['abj404_gsc_centralized'] === '1';
30
31 if ($isCentralized) {
32 self::handleCentralizedCallback($gsc);
33 return;
34 }
35
36 $code = isset($_GET['code']) ? sanitize_text_field((string)$_GET['code']) : '';
37 $state = isset($_GET['state']) ? sanitize_text_field((string)$_GET['state']) : '';
38
39 if (!wp_verify_nonce($state, 'abj404_gsc_oauth')) {
40 wp_die(__('Security check failed.', '404-solution'), 403);
41 }
42
43 if ($code === '') {
44 $gsc->setLastOAuthError(__('Authorization was denied or cancelled.', '404-solution'));
45 wp_safe_redirect(admin_url('options-general.php?page=' . ABJ404_PP . '&subpage=abj404_options'));
46 exit;
47 }
48
49 $error = $gsc->exchangeCodeForToken($code);
50
51 if ($error !== '') {
52 $gsc->setLastOAuthError($error);
53 }
54 wp_safe_redirect(admin_url('options-general.php?page=' . ABJ404_PP . '&subpage=abj404_options'));
55 exit;
56 }
57
58 /**
59 * Handle the centralized OAuth callback.
60 *
61 * @param ABJ_404_Solution_GoogleSearchConsole $gsc
62 * @return void
63 */
64 private static function handleCentralizedCallback(ABJ_404_Solution_GoogleSearchConsole $gsc): void {
65 $nonce = isset($_GET['nonce']) ? sanitize_text_field((string)$_GET['nonce']) : '';
66
67 if (!wp_verify_nonce($nonce, 'abj404_gsc_oauth')) {
68 wp_die(__('Security check failed.', '404-solution'), 403);
69 }
70
71 $error = isset($_GET['abj404_gsc_error']) ? sanitize_text_field((string)$_GET['abj404_gsc_error']) : '';
72 if ($error !== '') {
73 $gsc->setLastOAuthError($error);
74 wp_safe_redirect(admin_url('options-general.php?page=' . ABJ404_PP . '&subpage=abj404_options'));
75 exit;
76 }
77
78 $accessToken = isset($_GET['access_token']) ? sanitize_text_field((string)$_GET['access_token']) : '';
79 $refreshToken = isset($_GET['refresh_token']) ? sanitize_text_field((string)$_GET['refresh_token']) : '';
80 $expiresIn = isset($_GET['expires_in']) ? (int)$_GET['expires_in'] : 3600;
81
82 if ($accessToken === '') {
83 $gsc->setLastOAuthError(__('No access token received from authorization.', '404-solution'));
84 wp_safe_redirect(admin_url('options-general.php?page=' . ABJ404_PP . '&subpage=abj404_options'));
85 exit;
86 }
87
88 $gsc->storeCentralizedTokens($accessToken, $refreshToken, $expiresIn);
89
90 wp_safe_redirect(admin_url('options-general.php?page=' . ABJ404_PP . '&subpage=abj404_options'));
91 exit;
92 }
93
94 /**
95 * AJAX handler: revoke GSC authorization.
96 *
97 * @return void
98 */
99 public static function handleRevoke() {
100 if (!current_user_can('manage_options') || !check_admin_referer('abj404_gsc_revoke')) {
101 wp_die(__('Security check failed.', '404-solution'), 403);
102 }
103
104 $logger = abj_service('logging');
105 $gsc = new ABJ_404_Solution_GoogleSearchConsole($logger);
106 $gsc->revokeAuthorization();
107
108 wp_safe_redirect(admin_url('options-general.php?page=' . ABJ404_PP . '&subpage=abj404_options'));
109 exit;
110 }
111 }
112