@@ -3,142 +3,24 @@ package oauth
33import (
44 "context"
55 "fmt"
6- "os"
76
8- "github.com/docker/mcp-gateway/pkg/catalog"
97 "github.com/docker/mcp-gateway/pkg/desktop"
10- "github.com/docker/mcp-gateway/pkg/oauth"
118)
129
1310func Authorize (ctx context.Context , app string , scopes string ) error {
1411 client := desktop .NewAuthClient ()
15- // Check if DCR client exists
16- dcrClient , err := client .GetDCRClient (ctx , app )
17- if err != nil {
18- // Not a DCR provider - handle traditional OAuth flow for built-in providers
19- authResponse , err := client .PostOAuthApp (ctx , app , scopes , false )
20- if err != nil {
21- return err
22- }
23-
24- // Check if the response contains a valid browser URL
25- if authResponse .BrowserURL == "" {
26- return fmt .Errorf ("OAuth provider does not exist" )
27- }
28-
29- fmt .Printf ("Opening your browser for authentication. If it doesn't open automatically, please visit: %s\n " , authResponse .BrowserURL )
30- return nil
31- }
32-
33- // This is a DCR provider - check if it needs setup (atomic DCR)
34- fmt .Fprintf (os .Stderr , "[MCP-DCR] Found DCR client for %s, state: %s\n " , app , dcrClient .State )
35- if dcrClient .State == "unregistered" {
36- // Unregistered DCR provider - needs atomic discovery + DCR + auth
37- fmt .Printf ("first-time oauth setup for %s\n " , app )
38- return performAtomicDCRAndAuthorize (ctx , app , scopes )
39- }
40-
41- // DCR client exists and is ready - proceed with normal authorization
42- return authorizeRemoteMCPServer (ctx , app , scopes , dcrClient )
43- }
44-
45- // performAtomicDCRAndAuthorize performs discovery, DCR, and authorization atomically
46- func performAtomicDCRAndAuthorize (ctx context.Context , serverName string , scopes string ) error {
47- // Get catalog to find server configuration
48- cat , err := catalog .GetWithOptions (ctx , true , nil )
49- if err != nil {
50- return fmt .Errorf ("failed to get catalog: %w" , err )
51- }
52-
53- server , found := cat .Servers [serverName ]
54- if ! found {
55- return fmt .Errorf ("server %s not found in catalog" , serverName )
56- }
57-
58- // Get server URL
59- serverURL := server .Remote .URL
60- if serverURL == "" {
61- serverURL = server .SSEEndpoint
62- if serverURL == "" {
63- return fmt .Errorf ("server %s has no remote URL configured" , serverName )
64- }
65- }
66-
67- fmt .Fprintf (os .Stderr , "[MCP-DCR] Starting OAuth discovery for server: %s\n " , serverName )
68- fmt .Printf ("discovering oauth requirements for %s\n " , serverName )
69-
70- // STEP 1: OAuth Discovery (catalog-based, bypass 401 probe)
71- discovery , err := oauth .DiscoverOAuthRequirements (ctx , serverURL )
72- if err != nil {
73- return fmt .Errorf ("OAuth discovery failed: %w" , err )
74- }
75-
76- // STEP 2: Dynamic Client Registration
77- fmt .Fprintf (os .Stderr , "[MCP-DCR] Starting DCR registration for server: %s\n " , serverName )
78- fmt .Printf ("registering oauth client for %s\n " , serverName )
79- credentials , err := oauth .PerformDCR (ctx , discovery , serverName )
80- if err != nil {
81- return fmt .Errorf ("DCR registration failed: %w" , err )
82- }
83-
84- // Extract provider name from OAuth config
85- var providerName string
86- if server .OAuth != nil && len (server .OAuth .Providers ) > 0 {
87- providerName = server .OAuth .Providers [0 ].Provider // Use first provider
88- } else {
89- return fmt .Errorf ("no OAuth providers configured for server %s" , serverName )
90- }
91-
92- // STEP 3: Store DCR client in Docker Desktop (updates the pending provider)
93- client := desktop .NewAuthClient ()
94- dcrRequest := desktop.RegisterDCRRequest {
95- ClientID : credentials .ClientID ,
96- ProviderName : providerName ,
97- AuthorizationEndpoint : credentials .AuthorizationEndpoint ,
98- TokenEndpoint : credentials .TokenEndpoint ,
99- ResourceURL : credentials .ServerURL ,
100- }
101-
102- if err := client .RegisterDCRClient (ctx , serverName , dcrRequest ); err != nil {
103- return fmt .Errorf ("failed to store DCR client: %w" , err )
104- }
105-
106- fmt .Fprintf (os .Stderr , "[MCP-DCR] DCR registration successful, clientID: %s, authEndpoint: %s\n " , credentials .ClientID , credentials .AuthorizationEndpoint )
107- fmt .Printf ("oauth client registered successfully\n " )
108- fmt .Printf (" Client ID: %s\n " , credentials .ClientID )
109-
110- // STEP 4: Continue with authorization
111- dcrClient := & desktop.DCRClient {
112- ServerName : serverName ,
113- ProviderName : providerName ,
114- ClientID : credentials .ClientID ,
115- AuthorizationEndpoint : credentials .AuthorizationEndpoint ,
116- TokenEndpoint : credentials .TokenEndpoint ,
117- }
118-
119- return authorizeRemoteMCPServer (ctx , serverName , scopes , dcrClient )
120- }
121-
122- func authorizeRemoteMCPServer (ctx context.Context , serverName string , scopes string , dcrClient * desktop.DCRClient ) error {
123- client := desktop .NewAuthClient ()
124-
125- fmt .Printf ("starting oauth authorization for %s\n " , serverName )
126- fmt .Printf (" Using client: %s\n " , dcrClient .ClientID )
12712
128- // Start OAuth flow via Docker Desktop (handles PKCE generation and browser opening)
129- fmt .Printf ("starting oauth authorization flow\n " )
130- authResponse , err := client .PostOAuthApp (ctx , serverName , scopes , false )
13+ // Start OAuth flow - Docker Desktop handles DCR automatically if needed
14+ authResponse , err := client .PostOAuthApp (ctx , app , scopes , false )
13115 if err != nil {
132- return fmt . Errorf ( "failed to start OAuth flow: %w" , err )
16+ return err
13317 }
13418
135- // Provide user feedback based on auth response
136- if authResponse .BrowserURL != "" {
137- fmt .Printf ("browser opened for oauth authentication\n " )
138- fmt .Printf ("If the browser doesn't open, visit: %s\n " , authResponse .BrowserURL )
139- } else {
140- fmt .Printf ("oauth flow started successfully\n " )
19+ // Check if the response contains a valid browser URL
20+ if authResponse .BrowserURL == "" {
21+ return fmt .Errorf ("OAuth provider does not exist" )
14122 }
14223
24+ fmt .Printf ("Opening your browser for authentication. If it doesn't open automatically, please visit: %s\n " , authResponse .BrowserURL )
14325 return nil
14426}
0 commit comments