PluginProbe
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF / trunk
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF vtrunk
2.3.4 2.3.3 2.3.2 2.3.1 2.3.0 2.2.9 2.2.8 trunk 1.10 1.3.3 1.3.4 1.3.5 1.3.5.1 1.3.5.2 1.3.6 1.3.6.1 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.5 All 103 releases
imagify / vendor / wp-media / mcp-oauth / inc / Auth / Discovery / Endpoints.php

Endpoints.php in Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF trunk, at vendor/wp-media/mcp-oauth/inc/Auth/Discovery/Endpoints.php

145 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 * OAuth 2.0 Discovery Endpoints.
4 *
5 * Registers the two RFC-mandated well-known documents so MCP clients can
6 * auto-discover the authorization server metadata without hard-coding URLs.
7 *
8 * Paths served:
9 * GET /.well-known/oauth-protected-resource (RFC 9728)
10 * GET /.well-known/oauth-authorization-server (RFC 8414)
11 */
12
13 declare(strict_types=1);
14
15 namespace WPMedia\MCP\OAuth\Auth\Discovery;
16
17 use WPMedia\MCP\OAuth\Auth\Http404Trait;
18 use WPMedia\MCP\OAuth\Context;
19 use WPMedia\MCP\OAuth\Logging\McpLogger;
20
21 class Endpoints {
22
23 use Http404Trait;
24
25 /**
26 * Query var name used to route discovery requests.
27 */
28 const QUERY_VAR = 'mcp_oauth_discovery';
29
30 /**
31 * OAuth server context.
32 *
33 * @var Context
34 */
35 private Context $context;
36
37 /**
38 * Constructor.
39 *
40 * @param Context $context OAuth server context.
41 */
42 public function __construct( Context $context ) {
43 $this->context = $context;
44 }
45
46 /**
47 * Register rewrite rules for the .well-known paths.
48 *
49 * Called on the 'init' action.
50 *
51 * @return void
52 */
53 public function add_rewrite_rules(): void {
54 if ( ! $this->context->is_enabled() ) {
55 return;
56 }
57
58 add_rewrite_rule(
59 '^\\.well-known/oauth-protected-resource$',
60 'index.php?' . self::QUERY_VAR . '=protected-resource',
61 'top'
62 );
63 add_rewrite_rule(
64 '^\\.well-known/oauth-authorization-server$',
65 'index.php?' . self::QUERY_VAR . '=authorization-server',
66 'top'
67 );
68 }
69
70 /**
71 * Add the OAuth query var to WordPress's list of recognised vars.
72 *
73 * @param string[] $vars Existing query vars.
74 * @return string[] Modified list.
75 */
76 public function add_query_vars( array $vars ): array {
77 $vars[] = self::QUERY_VAR;
78
79 return $vars;
80 }
81
82 /**
83 * Serve the discovery document if the request matches.
84 *
85 * @return void
86 */
87 public function handle_request(): void {
88 $discovery = (string) get_query_var( self::QUERY_VAR, '' );
89
90 if ( '' === $discovery ) {
91 return;
92 }
93
94 if ( ! $this->context->is_enabled() ) {
95 $this->force_404();
96 return;
97 }
98
99 // Every OAuth endpoint and both .well-known documents are served through
100 // rewrite rules, which resolve against home_url() (the Site Address) — the
101 // same base get_rest_url() uses for the resource/audience below. Advertising
102 // them under get_site_url() (the WordPress Address) would point clients at
103 // the wrong location on installs where WordPress lives in its own directory
104 // (siteurl !== home).
105 $base_url = home_url();
106
107 McpLogger::log(
108 'DISCOVERY',
109 'request received',
110 [
111 'document' => $discovery,
112 'remote_addr' => isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : '',
113 'user_agent' => isset( $_SERVER['HTTP_USER_AGENT'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) : '',
114 ]
115 );
116
117 if ( 'protected-resource' === $discovery ) {
118 $body = [
119 'resource' => get_rest_url( null, 'mcp/mcp-oauth-server' ),
120 'authorization_servers' => [ $base_url ],
121 'bearer_methods_supported' => [ 'header' ],
122 'scopes_supported' => [ 'mcp' ],
123 ];
124 McpLogger::log( 'DISCOVERY', 'serving protected-resource document', $body );
125 wp_send_json( $body );
126 } elseif ( 'authorization-server' === $discovery ) {
127 $body = [
128 'issuer' => $base_url,
129 'authorization_endpoint' => $base_url . '/oauth/authorize',
130 'token_endpoint' => $base_url . '/oauth/token',
131 'revocation_endpoint' => $base_url . '/oauth/revoke',
132 'response_types_supported' => [ 'code' ],
133 'grant_types_supported' => [ 'authorization_code', 'refresh_token' ],
134 'code_challenge_methods_supported' => [ 'S256' ],
135 'scopes_supported' => [ 'mcp' ],
136 'token_endpoint_auth_methods_supported' => [ 'none' ],
137 'client_id_metadata_document_supported' => true,
138 'authorization_response_iss_parameter_supported' => true,
139 ];
140 McpLogger::log( 'DISCOVERY', 'serving authorization-server document', $body );
141 wp_send_json( $body );
142 }
143 }
144 }
145