Skip to content

Commit 71ccbb6

Browse files
committed
Mirror changes in the main folder structure
1 parent 0f25457 commit 71ccbb6

1 file changed

Lines changed: 103 additions & 10 deletions

File tree

src/ai-consent/application/consent-handler.php

Lines changed: 103 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,26 @@
22

33
namespace Yoast\WP\SEO\AI_Consent\Application;
44

5+
use Yoast\WP\SEO\AI_Authorization\Application\Token_Manager;
6+
use Yoast\WP\SEO\AI_HTTP_Request\Application\Request_Handler;
7+
use Yoast\WP\SEO\AI_HTTP_Request\Domain\Exceptions\Bad_Request_Exception;
8+
use Yoast\WP\SEO\AI_HTTP_Request\Domain\Exceptions\Forbidden_Exception;
9+
use Yoast\WP\SEO\AI_HTTP_Request\Domain\Exceptions\Internal_Server_Error_Exception;
10+
use Yoast\WP\SEO\AI_HTTP_Request\Domain\Exceptions\Not_Found_Exception;
11+
use Yoast\WP\SEO\AI_HTTP_Request\Domain\Exceptions\Payment_Required_Exception;
12+
use Yoast\WP\SEO\AI_HTTP_Request\Domain\Exceptions\Remote_Request_Exception;
13+
use Yoast\WP\SEO\AI_HTTP_Request\Domain\Exceptions\Request_Timeout_Exception;
14+
use Yoast\WP\SEO\AI_HTTP_Request\Domain\Exceptions\Service_Unavailable_Exception;
15+
use Yoast\WP\SEO\AI_HTTP_Request\Domain\Exceptions\Too_Many_Requests_Exception;
16+
use Yoast\WP\SEO\AI_HTTP_Request\Domain\Exceptions\Unauthorized_Exception;
17+
use Yoast\WP\SEO\AI_HTTP_Request\Domain\Exceptions\WP_Request_Exception;
18+
use Yoast\WP\SEO\AI_HTTP_Request\Domain\Request;
519
use Yoast\WP\SEO\Helpers\User_Helper;
20+
use Yoast\WP\SEO\Loggers\Logger;
621

722
/**
823
* Class Consent_Handler
9-
* Handles the consent given or revoked by the user.
24+
* Handles the consent given or revoked by the user, both locally (user meta) and remotely (Yoast AI service).
1025
*
1126
* @makePublic
1227
*/
@@ -19,34 +34,112 @@ class Consent_Handler implements Consent_Handler_Interface {
1934
*/
2035
private $user_helper;
2136

37+
/**
38+
* The token manager instance.
39+
*
40+
* @var Token_Manager
41+
*/
42+
private $token_manager;
43+
44+
/**
45+
* The request handler instance.
46+
*
47+
* @var Request_Handler
48+
*/
49+
private $request_handler;
50+
51+
/**
52+
* The logger instance.
53+
*
54+
* @var Logger
55+
*/
56+
private $logger;
57+
2258
/**
2359
* Class constructor.
2460
*
25-
* @param User_Helper $user_helper The user helper.
61+
* @param User_Helper $user_helper The user helper.
62+
* @param Token_Manager $token_manager The token manager, used to obtain a JWT for the consent endpoints.
63+
* @param Request_Handler $request_handler The request handler, used to call the AI service's consent endpoints.
64+
* @param Logger $logger The logger, used to record best-effort failures during revoke.
2665
*/
27-
public function __construct( User_Helper $user_helper ) {
28-
$this->user_helper = $user_helper;
66+
public function __construct(
67+
User_Helper $user_helper,
68+
Token_Manager $token_manager,
69+
Request_Handler $request_handler,
70+
Logger $logger
71+
) {
72+
$this->user_helper = $user_helper;
73+
$this->token_manager = $token_manager;
74+
$this->request_handler = $request_handler;
75+
$this->logger = $logger;
2976
}
3077

78+
// phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber -- PHPCS doesn't take into account exceptions thrown in called methods.
79+
3180
/**
32-
* Handles consent revoked by deleting the consent user metadata from the database.
81+
* Records the user's consent on the Yoast AI service and, on success, in the local user meta.
82+
*
83+
* Transactional: any HTTP-layer exception is propagated and the local meta is left untouched, so
84+
* the local and server state stay in sync.
3385
*
3486
* @param int $user_id The user ID.
3587
*
3688
* @return void
89+
*
90+
* @throws Bad_Request_Exception When the AI service responds with 400.
91+
* @throws Forbidden_Exception When the AI service responds with 403.
92+
* @throws Internal_Server_Error_Exception When the AI service responds with 500.
93+
* @throws Not_Found_Exception When the AI service responds with 404.
94+
* @throws Payment_Required_Exception When the AI service responds with 402.
95+
* @throws Request_Timeout_Exception When the AI service responds with 408.
96+
* @throws Service_Unavailable_Exception When the AI service responds with 503.
97+
* @throws Too_Many_Requests_Exception When the AI service responds with 429.
98+
* @throws Unauthorized_Exception When the AI service responds with 401.
99+
* @throws WP_Request_Exception When the underlying WordPress HTTP call fails.
37100
*/
38-
public function revoke_consent( int $user_id ) {
39-
$this->user_helper->delete_meta( $user_id, '_yoast_wpseo_ai_consent' );
101+
public function grant_consent( int $user_id ) {
102+
$user = \get_user_by( 'id', $user_id );
103+
$jwt = $this->token_manager->get_or_request_access_token( $user );
104+
105+
$this->request_handler->handle(
106+
new Request( '/user/consent', [], [ 'Authorization' => "Bearer $jwt" ], Request::METHOD_POST ),
107+
);
108+
109+
$this->user_helper->update_meta( $user_id, '_yoast_wpseo_ai_consent', true );
40110
}
41111

42112
/**
43-
* Handles consent granted by adding the consent user metadata to the database.
113+
* Revokes the user's consent on the Yoast AI service and clears the local user meta.
114+
*
115+
* Security-first: the local meta is always cleared, even if the remote DELETE fails. HTTP-layer
116+
* failures are logged as warnings and swallowed; programmer errors (non-`Remote_Request_Exception`
117+
* / non-`WP_Request_Exception`) are not caught and will propagate.
44118
*
45119
* @param int $user_id The user ID.
46120
*
47121
* @return void
48122
*/
49-
public function grant_consent( int $user_id ) {
50-
$this->user_helper->update_meta( $user_id, '_yoast_wpseo_ai_consent', true );
123+
public function revoke_consent( int $user_id ) {
124+
try {
125+
$user = \get_user_by( 'id', $user_id );
126+
$jwt = $this->token_manager->get_or_request_access_token( $user );
127+
128+
$this->request_handler->handle(
129+
new Request( '/user/consent', [], [ 'Authorization' => "Bearer $jwt" ], Request::METHOD_DELETE ),
130+
);
131+
} catch ( Remote_Request_Exception | WP_Request_Exception $e ) {
132+
$this->logger->warning(
133+
'Failed to revoke consent on the Yoast AI service; clearing local consent anyway.',
134+
[
135+
'user_id' => $user_id,
136+
'exception' => $e->getMessage(),
137+
],
138+
);
139+
}
140+
141+
$this->user_helper->delete_meta( $user_id, '_yoast_wpseo_ai_consent' );
51142
}
143+
144+
// phpcs:enable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
52145
}

0 commit comments

Comments
 (0)