PluginProbe
Extendify / 3.2.2
Extendify v3.2.2
3.2.2 3.2.1 3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 All 128 releases
extendify / app / Mcp / Confirmation.php

Confirmation.php in Extendify 3.2.2, at app/Mcp/Confirmation.php

84 lines 2.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * The token a preview hands out, and the check an execution makes of it.
5 */
6
7 namespace Extendify\Mcp;
8
9 defined('ABSPATH') || die('No direct access.');
10
11 /**
12 * Checking a token spends it, so a second execution and a changed set both
13 * send the model back to a preview.
14 */
15 class Confirmation
16 {
17 // phpcs:disable PSR12.Properties.ConstantVisibility.NotFound
18 const TTL = 10 * MINUTE_IN_SECONDS;
19
20 const PREFIX = 'extendify_mcp_confirm_';
21 // phpcs:enable PSR12.Properties.ConstantVisibility.NotFound
22
23 /**
24 * @param string $tool - The tool the preview ran for.
25 * @param array $set - The ids or slugs the preview reported.
26 * @return string
27 */
28 public static function issue($tool, array $set)
29 {
30 $token = \wp_generate_password(32, false);
31 \set_transient(self::key($token), self::digest($tool, $set), self::TTL);
32
33 return $token;
34 }
35
36 /**
37 * @param string $tool - The tool about to execute.
38 * @param array $set - The ids or slugs it matched now.
39 * @param mixed $token - The confirm_token the call carried.
40 * @return string|null - Why the execution may not go ahead, or null when it may.
41 */
42 public static function refusal($tool, array $set, $token)
43 {
44 if (!is_string($token) || $token === '') {
45 return 'Run with preview first, show the user the list, then pass back the confirm_token it returned.';
46 }
47
48 $held = \get_transient(self::key($token));
49 \delete_transient(self::key($token));
50 if (!is_string($held)) {
51 return 'This confirm_token has expired or was already used. Run with preview again.';
52 }
53
54 if (!hash_equals($held, self::digest($tool, $set))) {
55 return 'What matches has changed since that preview. Run with preview again and show the user the new'
56 . ' list.';
57 }
58
59 return null;
60 }
61
62 /**
63 * @param string $tool - The tool the token is for.
64 * @param array $set - The ids or slugs it covers.
65 * @return string
66 */
67 private static function digest($tool, array $set)
68 {
69 $set = array_map('strval', $set);
70 sort($set);
71
72 return hash('sha256', $tool . '|' . \get_current_user_id() . '|' . implode(',', $set));
73 }
74
75 /**
76 * @param string $token - The token as the client holds it.
77 * @return string
78 */
79 private static function key($token)
80 {
81 return self::PREFIX . hash('sha256', $token);
82 }
83 }
84