@@ -2,59 +2,18 @@ package middleware
22
33import (
44 "bytes"
5- "context"
65 "encoding/json"
76 "fmt"
87 "io"
98 "net/http"
109 "strings"
11- "time"
1210
1311 ghcontext "github.com/github/github-mcp-server/pkg/context"
1412 "github.com/github/github-mcp-server/pkg/http/oauth"
1513 "github.com/github/github-mcp-server/pkg/scopes"
1614 "github.com/github/github-mcp-server/pkg/utils"
1715)
1816
19- // FetchScopesFromGitHubAPI fetches the OAuth scopes from the GitHub API by making
20- // a HEAD request and reading the X-OAuth-Scopes header. This is used as a fallback
21- // when scopes are not provided in the token info header.
22- func FetchScopesFromGitHubAPI (ctx context.Context , token string , apiHost utils.APIHostResolver ) ([]string , error ) {
23- baseURL , err := apiHost .BaseRESTURL (ctx )
24- if err != nil {
25- return nil , err
26- }
27-
28- req , err := http .NewRequestWithContext (ctx , http .MethodHead , strings .TrimSuffix (baseURL .String (), "/" )+ "/user" , http .NoBody )
29- if err != nil {
30- return nil , err
31- }
32- req .Header .Set ("Authorization" , "Bearer " + token )
33-
34- client := & http.Client {Timeout : 10 * time .Second }
35- resp , err := client .Do (req )
36- if err != nil {
37- return nil , err
38- }
39- defer resp .Body .Close ()
40-
41- scopeHeader := resp .Header .Get ("X-OAuth-Scopes" )
42- if scopeHeader == "" {
43- return []string {}, nil
44- }
45-
46- // Parse comma-separated scopes and trim whitespace
47- rawScopes := strings .Split (scopeHeader , "," )
48- parsedScopes := make ([]string , 0 , len (rawScopes ))
49- for _ , s := range rawScopes {
50- trimmed := strings .TrimSpace (s )
51- if trimmed != "" {
52- parsedScopes = append (parsedScopes , trimmed )
53- }
54- }
55- return parsedScopes , nil
56- }
57-
5817// WithScopeChallenge creates a new middleware that determines if an OAuth request contains sufficient scopes to
5918// complete the request and returns a scope challenge if not.
6019func WithScopeChallenge (oauthCfg * oauth.Config , scopeFetcher scopes.FetcherInterface ) func (http.Handler ) http.Handler {
@@ -142,6 +101,9 @@ func WithScopeChallenge(oauthCfg *oauth.Config, scopeFetcher scopes.FetcherInter
142101 return
143102 }
144103
104+ // Store active scopes in context for downstream use
105+ ghcontext .SetTokenScopes (ctx , activeScopes )
106+
145107 // Check if user has the required scopes
146108 if toolScopeInfo .HasAcceptedScope (activeScopes ... ) {
147109 next .ServeHTTP (w , r )
0 commit comments