PluginProbe
AI Builder – Generate pages, blocks, images & translate with AI / trunk
AI Builder – Generate pages, blocks, images & translate with AI vtrunk
2.7.10 2.7.9 2.7.8 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 2.3.10 All 122 releases
ai-builder / includes / class-agent-security-service.php

class-agent-security-service.php in AI Builder – Generate pages, blocks, images & translate with AI trunk, at includes/class-agent-security-service.php

368 lines 9.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Agent Security Service
4 *
5 * Manages the whitelist of API routes that the AI agent can access.
6 * Provides enable/disable functionality for each route.
7 *
8 * @package AI_Builder
9 */
10
11 if (!defined('ABSPATH')) {
12 exit;
13 }
14
15 class AIBUI_Agent_Security_Service
16 {
17 /**
18 * Option name for storing whitelist in database
19 */
20 const OPTION_WHITELIST = 'aibui_agent_route_whitelist';
21
22 /**
23 * Option name for storing route settings (custom configs)
24 */
25 const OPTION_ROUTE_SETTINGS = 'aibui_agent_route_settings';
26
27 /**
28 * Discovery service instance
29 *
30 * @var AIBUI_Agent_Discovery_Service
31 */
32 private $discovery;
33
34 /**
35 * Cached whitelist
36 *
37 * @var array|null
38 */
39 private $whitelist_cache = null;
40
41 /**
42 * Constructor
43 *
44 * @param AIBUI_Agent_Discovery_Service $discovery
45 */
46 public function __construct(AIBUI_Agent_Discovery_Service $discovery)
47 {
48 $this->discovery = $discovery;
49 }
50
51 /**
52 * Get the current whitelist of enabled routes
53 *
54 * @return array Array of route IDs that are enabled
55 */
56 public function get_whitelist()
57 {
58 if ($this->whitelist_cache !== null) {
59 return $this->whitelist_cache;
60 }
61
62 $whitelist = get_option(self::OPTION_WHITELIST, null);
63
64 // If no whitelist exists, initialize with defaults
65 if ($whitelist === null) {
66 $whitelist = $this->initialize_default_whitelist();
67 }
68
69 $this->whitelist_cache = $whitelist;
70 return $whitelist;
71 }
72
73 /**
74 * Initialize whitelist with default enabled routes
75 *
76 * @return array
77 */
78 private function initialize_default_whitelist()
79 {
80 $routes = $this->discovery->get_all_routes();
81 $whitelist = array();
82
83 foreach ($routes as $route) {
84 if ($route['is_default_enabled']) {
85 $whitelist[] = $route['unique_id'];
86 }
87 }
88
89 // Save the default whitelist
90 update_option(self::OPTION_WHITELIST, $whitelist, false);
91
92 return $whitelist;
93 }
94
95 /**
96 * Check if a route is whitelisted (enabled)
97 *
98 * @param string $route Route path
99 * @param string $method HTTP method
100 * @return bool
101 */
102 public function is_route_whitelisted($route, $method)
103 {
104 // First check if route is forbidden (security)
105 if ($this->discovery->is_forbidden_route($route, $method)) {
106 return false;
107 }
108
109 $route_id = $this->discovery->generate_route_id($route, $method);
110 $whitelist = $this->get_whitelist();
111
112 return in_array($route_id, $whitelist, true);
113 }
114
115 /**
116 * Enable a route
117 *
118 * @param string $route_id Unique route ID
119 * @return bool Success
120 */
121 public function enable_route($route_id)
122 {
123 // Verify the route exists and is not forbidden
124 if (!$this->is_valid_route_id($route_id)) {
125 return false;
126 }
127
128 $whitelist = $this->get_whitelist();
129
130 if (!in_array($route_id, $whitelist, true)) {
131 $whitelist[] = $route_id;
132 $this->save_whitelist($whitelist);
133 }
134
135 return true;
136 }
137
138 /**
139 * Disable a route
140 *
141 * @param string $route_id Unique route ID
142 * @return bool Success
143 */
144 public function disable_route($route_id)
145 {
146 $whitelist = $this->get_whitelist();
147 $key = array_search($route_id, $whitelist, true);
148
149 if ($key !== false) {
150 unset($whitelist[$key]);
151 $whitelist = array_values($whitelist); // Re-index
152 $this->save_whitelist($whitelist);
153 }
154
155 return true;
156 }
157
158 /**
159 * Update multiple routes at once
160 *
161 * @param array $enabled_routes Array of route IDs to enable
162 * @return bool Success
163 */
164 public function update_whitelist(array $enabled_routes)
165 {
166 // Validate all routes
167 $valid_routes = array();
168 foreach ($enabled_routes as $route_id) {
169 if ($this->is_valid_route_id($route_id)) {
170 $valid_routes[] = $route_id;
171 }
172 }
173
174 $this->save_whitelist($valid_routes);
175 return true;
176 }
177
178 /**
179 * Save whitelist to database
180 *
181 * @param array $whitelist
182 */
183 private function save_whitelist(array $whitelist)
184 {
185 update_option(self::OPTION_WHITELIST, $whitelist, false);
186 $this->whitelist_cache = $whitelist;
187 }
188
189 /**
190 * Check if a route ID is valid (exists and not forbidden)
191 *
192 * @param string $route_id
193 * @return bool
194 */
195 private function is_valid_route_id($route_id)
196 {
197 $routes = $this->discovery->get_all_routes();
198
199 foreach ($routes as $route) {
200 if ($route['unique_id'] === $route_id) {
201 return !$this->discovery->is_forbidden_route($route['route'], $route['method']);
202 }
203 }
204
205 return false;
206 }
207
208 /**
209 * Get all routes with their enabled status
210 *
211 * @return array
212 */
213 public function get_routes_with_status()
214 {
215 $routes = $this->discovery->get_routes_by_namespace();
216 $whitelist = $this->get_whitelist();
217 $result = array();
218
219 foreach ($routes as $namespace => $namespace_routes) {
220 $result[$namespace] = array();
221
222 foreach ($namespace_routes as $route) {
223 $route['is_enabled'] = in_array($route['unique_id'], $whitelist, true);
224 $route['can_toggle'] = !$this->discovery->is_forbidden_route($route['route'], $route['method']);
225 $result[$namespace][] = $route;
226 }
227 }
228
229 return $result;
230 }
231
232 /**
233 * Get only the whitelisted routes (for tool generation)
234 *
235 * @return array
236 */
237 public function get_enabled_routes()
238 {
239 $routes = $this->discovery->get_all_routes();
240 $whitelist = $this->get_whitelist();
241 $enabled = array();
242
243 foreach ($routes as $route) {
244 if (in_array($route['unique_id'], $whitelist, true)) {
245 $enabled[] = $route;
246 }
247 }
248
249 return $enabled;
250 }
251
252 /**
253 * Get tools for enabled routes only
254 *
255 * @return array Tools in JSON Schema format
256 */
257 public function get_enabled_tools()
258 {
259 $enabled_routes = $this->get_enabled_routes();
260 return $this->discovery->convert_to_tools_format($enabled_routes);
261 }
262
263 /**
264 * Reset whitelist to defaults
265 *
266 * @return bool
267 */
268 public function reset_to_defaults()
269 {
270 delete_option(self::OPTION_WHITELIST);
271 $this->whitelist_cache = null;
272 $this->get_whitelist(); // Re-initialize with defaults
273 return true;
274 }
275
276 /**
277 * Get route info by ID
278 *
279 * @param string $route_id
280 * @return array|null
281 */
282 public function get_route_by_id($route_id)
283 {
284 $routes = $this->discovery->get_all_routes();
285
286 foreach ($routes as $route) {
287 if ($route['unique_id'] === $route_id) {
288 return $route;
289 }
290 }
291
292 return null;
293 }
294
295 /**
296 * Find route by path and method
297 *
298 * @param string $path Route path
299 * @param string $method HTTP method
300 * @return array|null
301 */
302 public function find_route($path, $method)
303 {
304 $routes = $this->discovery->get_all_routes();
305
306 foreach ($routes as $route) {
307 if ($route['route'] === $path && $route['method'] === strtoupper($method)) {
308 return $route;
309 }
310 }
311
312 // Try pattern matching for parameterized routes
313 foreach ($routes as $route) {
314 if ($route['method'] !== strtoupper($method)) {
315 continue;
316 }
317
318 // Convert route pattern to regex
319 $pattern = '#^' . $route['route'] . '$#';
320 if (preg_match($pattern, $path)) {
321 return $route;
322 }
323 }
324
325 return null;
326 }
327
328 /**
329 * Validate that a tool name corresponds to a whitelisted route
330 *
331 * @param string $tool_name
332 * @return array|null Route info if valid, null otherwise
333 */
334 public function validate_tool($tool_name)
335 {
336 $enabled_tools = $this->get_enabled_tools();
337
338 foreach ($enabled_tools as $tool) {
339 if ($tool['name'] === $tool_name) {
340 return $tool['_meta'];
341 }
342 }
343
344 return null;
345 }
346
347 /**
348 * Get statistics about routes
349 *
350 * @return array
351 */
352 public function get_stats()
353 {
354 $all_routes = $this->discovery->get_all_routes();
355 $whitelist = $this->get_whitelist();
356 $by_namespace = $this->discovery->get_routes_by_namespace();
357
358 return array(
359 'total_routes' => count($all_routes),
360 'enabled_routes' => count($whitelist),
361 'disabled_routes' => count($all_routes) - count($whitelist),
362 'namespaces' => array_keys($by_namespace),
363 'namespace_count' => count($by_namespace),
364 );
365 }
366 }
367
368