Файловый менеджер - Редактировать - /home/tuudkjt/globeasy/wp-includes/ID3/MCP.tar
Назад
Transport/WooCommerceRestTransport.php 0000777 00000013544 15252717507 0014274 0 ustar 00 <?php /** * WooCommerce MCP REST Transport with API validation. */ declare( strict_types=1 ); namespace Automattic\WooCommerce\Internal\MCP\Transport; use WP\MCP\Transport\HttpTransport; use WP\MCP\Transport\Infrastructure\McpTransportContext; use WP_REST_Request; use WP_Error; defined( 'ABSPATH' ) || exit; /** * WooCommerce MCP REST Transport class. * * Extends the base HttpTransport with standalone WooCommerce REST API key authentication. * Uses X-MCP-API-Key header with consumer_key:consumer_secret format. */ class WooCommerceRestTransport extends HttpTransport { /** * Current MCP user's API key permissions. * * @var string|null */ private static $current_mcp_permissions = null; /** * Constructor. * * @param McpTransportContext $context The transport context. */ public function __construct( McpTransportContext $context ) { parent::__construct( $context ); // This filter is documented in the check_ability_permission method. add_filter( 'woocommerce_check_rest_ability_permissions_for_method', array( $this, 'check_ability_permission' ), 10, 3 ); } /** * Validate request using WooCommerce REST API authentication. * * @param WP_REST_Request|null $request The REST request object. * @return bool|\WP_Error True if allowed, WP_Error if not. */ public function check_permission( $request = null ) { return $this->validate_request( $request ); } /** * Validate the MCP request using standalone authentication. * * @param \WP_REST_Request $request The REST request object. * @return bool|\WP_Error True if allowed, WP_Error if not. */ public function validate_request( \WP_REST_Request $request ) { // Require TLS by default; allow explicit opt-in for non-SSL (e.g., local dev). /** * Filter to allow insecure transport for MCP requests. * * @since 10.3.0 * @param bool $allowed Whether to allow insecure transport. * @param \WP_REST_Request $request The REST request object. */ if ( ! is_ssl() && ! apply_filters( 'woocommerce_mcp_allow_insecure_transport', false, $request ) ) { return new \WP_Error( 'insecure_transport', __( 'HTTPS is required for MCP requests.', 'woocommerce' ), array( 'status' => 403 ) ); } // Get X-MCP-API-Key header. $api_key = $request->get_header( 'X-MCP-API-Key' ); if ( empty( $api_key ) ) { return new \WP_Error( 'missing_api_key', __( 'X-MCP-API-Key header required. Format: consumer_key:consumer_secret', 'woocommerce' ), array( 'status' => 401 ) ); } if ( strpos( $api_key, ':' ) === false ) { return new \WP_Error( 'invalid_api_key', __( 'X-MCP-API-Key must be in format consumer_key:consumer_secret', 'woocommerce' ), array( 'status' => 401 ) ); } list( $consumer_key, $consumer_secret ) = explode( ':', $api_key, 2 ); // Use our standalone authentication method. $result = $this->authenticate( $consumer_key, $consumer_secret ); if ( is_wp_error( $result ) ) { return $result; } return true; } /** * Authenticate user using consumer key and secret. * * @param string $consumer_key Consumer key. * @param string $consumer_secret Consumer secret. * @return int|\WP_Error User ID on success, WP_Error on failure. */ private function authenticate( $consumer_key, $consumer_secret ) { global $wpdb; // Hash the consumer key as WooCommerce does. $hashed_consumer_key = wc_api_hash( trim( (string) $consumer_key ) ); // Query the WooCommerce API keys table directly. $user_data = $wpdb->get_row( $wpdb->prepare( "SELECT key_id, user_id, permissions, consumer_key, consumer_secret, nonces FROM {$wpdb->prefix}woocommerce_api_keys WHERE consumer_key = %s", $hashed_consumer_key ) ); // Check if user data was found. if ( empty( $user_data ) ) { return new \WP_Error( 'authentication_failed', __( 'Authentication failed.', 'woocommerce' ), array( 'status' => 401 ) ); } // Validate consumer secret using hash_equals for timing attack protection. if ( ! hash_equals( $user_data->consumer_secret, trim( (string) $consumer_secret ) ) ) { return new \WP_Error( 'authentication_failed', __( 'Authentication failed.', 'woocommerce' ), array( 'status' => 401 ) ); } // Store permissions for tool-level checking. self::$current_mcp_permissions = $user_data->permissions; // Ensure the user exists before switching context. $user = get_user_by( 'id', (int) $user_data->user_id ); if ( ! $user ) { return new \WP_Error( 'mcp_user_not_found', __( 'The user associated with this API key no longer exists.', 'woocommerce' ), array( 'status' => 401 ) ); } wp_set_current_user( $user->ID ); return $user->ID; } /** * Get the current MCP user's API key permissions. * * @return string|null The permissions (read, write, read_write) or null if no MCP context. */ public static function get_current_user_permissions(): ?string { return self::$current_mcp_permissions; } /** * Check REST ability permissions for HTTP method. * * @param bool $allowed Whether the operation is allowed. Default false. * @param string $method HTTP method (GET, POST, PUT, DELETE). * @param object $controller REST controller instance. * @return bool Whether permission is granted. */ public function check_ability_permission( $allowed, $method, $controller ) { // Only check permissions if we have MCP context. $permissions = self::get_current_user_permissions(); if ( null === $permissions ) { return $allowed; } // Check permissions based on method. switch ( $method ) { case 'HEAD': case 'GET': return ( 'read' === $permissions || 'read_write' === $permissions ); case 'POST': case 'PUT': case 'PATCH': case 'DELETE': return ( 'write' === $permissions || 'read_write' === $permissions ); case 'OPTIONS': return true; default: return false; } } } MCPAdapterProvider.php 0000777 00000014646 15252717507 0010745 0 ustar 00 <?php /** * MCP Adapter Provider class file. */ declare( strict_types=1 ); namespace Automattic\WooCommerce\Internal\MCP; use Automattic\WooCommerce\Utilities\FeaturesUtil; use Automattic\WooCommerce\Internal\Abilities\AbilitiesRegistry; use Automattic\WooCommerce\Internal\MCP\Transport\WooCommerceRestTransport; defined( 'ABSPATH' ) || exit; /** * MCP Adapter Provider class for WooCommerce. * * Manages MCP (Model Context Protocol) adapter initialization and server configuration. * Abilities should be registered separately using the WordPress Abilities API. */ class MCPAdapterProvider { /** * MCP server namespace. * * @var string */ const MCP_NAMESPACE = 'woocommerce'; /** * MCP server route. * * @var string */ const MCP_ROUTE = 'mcp'; /** * Whether MCP adapter is initialized. * * @var bool */ private bool $initialized = false; /** * Constructor. */ public function __construct() { /* * Hook into rest_api_init with priority 10 to initialize only on REST API requests. * MCP adapter registers on rest_api_init with priority 20000, so we initialize earlier. * This prevents unnecessary MCP initialization on favicon, cron, or admin requests. */ add_action( 'rest_api_init', array( $this, 'maybe_initialize' ), 10 ); } /** * Check feature flag and initialize MCP adapter if enabled. */ public function maybe_initialize(): void { // Check if MCP integration feature is enabled. if ( ! FeaturesUtil::feature_is_enabled( 'mcp_integration' ) ) { return; } // Prevent double initialization. if ( $this->initialized ) { return; } $this->initialize_mcp_adapter(); $this->register_hooks(); $this->initialized = true; } /** * Initialize the MCP adapter. */ private function initialize_mcp_adapter(): void { // Check if MCP adapter class exists (should be autoloaded by WooCommerce's composer). if ( ! class_exists( 'WP\MCP\Core\McpAdapter' ) ) { if ( function_exists( 'wc_get_logger' ) ) { wc_get_logger()->warning( 'MCP adapter class not found. Skipping MCP initialization.', array( 'source' => 'woocommerce-mcp' ) ); } return; } // Initialize the MCP adapter instance - this triggers the rest_api_init hook registration. \WP\MCP\Core\McpAdapter::instance(); } /** * Register WordPress hooks for MCP adapter. */ private function register_hooks(): void { // Initialize MCP server when MCP adapter is ready. add_action( 'mcp_adapter_init', array( $this, 'initialize_mcp_server' ) ); } /** * Initialize MCP server. * * @param object $adapter MCP adapter instance. */ public function initialize_mcp_server( $adapter ): void { // Get filtered abilities for MCP server. $abilities_ids = $this->get_woocommerce_mcp_abilities(); // Bail if no abilities are available. if ( empty( $abilities_ids ) ) { return; } /* * Temporarily disable MCP validation during server creation. * Workaround for validator bug with union types (e.g., ["integer", "null"]). * This will be removed once the mcp-adapter validator bug is fixed. * * @see https://github.com/WordPress/mcp-adapter/issues/47 */ add_filter( 'mcp_validation_enabled', array( __CLASS__, 'disable_mcp_validation' ), 999 ); try { // Create MCP server. $adapter->create_server( 'woocommerce-mcp', self::MCP_NAMESPACE, self::MCP_ROUTE, __( 'WooCommerce MCP Server', 'woocommerce' ), __( 'AI-accessible WooCommerce operations via MCP', 'woocommerce' ), '1.0.0', array( WooCommerceRestTransport::class ), \WP\MCP\Infrastructure\ErrorHandling\ErrorLogMcpErrorHandler::class, \WP\MCP\Infrastructure\Observability\NullMcpObservabilityHandler::class, $abilities_ids, ); } catch ( \Throwable $e ) { if ( function_exists( 'wc_get_logger' ) ) { wc_get_logger()->error( 'MCP server initialization failed: ' . $e->getMessage(), array( 'source' => 'woocommerce-mcp' ) ); } } finally { // Re-enable MCP validation immediately after server creation. remove_filter( 'mcp_validation_enabled', array( __CLASS__, 'disable_mcp_validation' ), 999 ); } } /** * Get WooCommerce abilities for MCP server. * * Filters abilities to include only those with 'woocommerce/' namespace by default, * with a filter to allow inclusion of abilities from other namespaces. * * @return array Array of ability IDs for MCP server. */ private function get_woocommerce_mcp_abilities(): array { // Get all abilities from the registry. $abilities_registry = wc_get_container()->get( AbilitiesRegistry::class ); $all_abilities_ids = $abilities_registry->get_abilities_ids(); // Filter abilities based on namespace and custom filter. $mcp_abilities = array_filter( $all_abilities_ids, function ( $ability_id ) { // Include WooCommerce abilities by default. $include = str_starts_with( $ability_id, 'woocommerce/' ); // Allow filter to override inclusion decision. /** * Filter to override MCP ability inclusion decision. * * @since 10.3.0 * @param bool $include Whether to include the ability. * @param string $ability_id The ability ID. */ return apply_filters( 'woocommerce_mcp_include_ability', $include, $ability_id ); } ); // Re-index array. return array_values( $mcp_abilities ); } /** * Temporarily disable MCP validation. * * Used as a callback for the mcp_validation_enabled filter to work around * validator bugs with union types. * * @return bool Always returns false to disable validation. */ public static function disable_mcp_validation(): bool { return false; } /** * Check if MCP adapter is initialized. * * @return bool Whether MCP adapter is initialized. */ public function is_initialized(): bool { return $this->initialized; } /** * Check if the current request is for the MCP endpoint. * * @return bool True if this is an MCP endpoint request. */ public static function is_mcp_request(): bool { // Check if this is a REST request. if ( ! defined( 'REST_REQUEST' ) || ! REST_REQUEST ) { return false; } // Get the request URI. $request_uri = isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : ''; // Build the MCP endpoint path dynamically from constants. $mcp_endpoint = '/' . self::MCP_NAMESPACE . '/' . self::MCP_ROUTE; // Check if the request is for the MCP endpoint. return false !== strpos( $request_uri, $mcp_endpoint ); } }
| ver. 1.6 |
Github
|
.
| PHP 8.1.34 | Генерация страницы: 0 |
proxy
|
phpinfo
|
Настройка