first commit

This commit is contained in:
Beyhan Oğur
2026-04-26 21:52:23 +03:00
commit 880f412e2c
2662 changed files with 866266 additions and 0 deletions

View File

@@ -0,0 +1,93 @@
// Package handlers provides HTTP request handlers for the Bifrost HTTP transport.
// This file implements OAuth 2.0 metadata discovery endpoints per RFC 9728
// (Protected Resource Metadata) and RFC 8414 (Authorization Server Metadata).
// These endpoints enable MCP-spec-compliant clients (like Claude Code) to
// automatically discover Bifrost's OAuth configuration and authenticate.
package handlers
import (
"fmt"
"github.com/fasthttp/router"
"github.com/maximhq/bifrost/core/schemas"
"github.com/maximhq/bifrost/transports/bifrost-http/lib"
"github.com/valyala/fasthttp"
)
// OAuthMetadataHandler serves OAuth 2.0 discovery metadata endpoints.
// It provides the Protected Resource Metadata (RFC 9728) and Authorization
// Server Metadata (RFC 8414) that MCP clients use to discover how to
// authenticate with Bifrost's MCP server endpoint.
type OAuthMetadataHandler struct {
store *lib.Config
}
// NewOAuthMetadataHandler creates a new OAuth metadata handler instance.
func NewOAuthMetadataHandler(store *lib.Config) *OAuthMetadataHandler {
return &OAuthMetadataHandler{store: store}
}
// RegisterRoutes registers the well-known metadata discovery routes.
// These routes do NOT go through auth middleware since they must be
// accessible to unauthenticated clients during OAuth discovery.
func (h *OAuthMetadataHandler) RegisterRoutes(r *router.Router, middlewares ...schemas.BifrostHTTPMiddleware) {
// RFC 9728: Protected Resource Metadata
r.GET("/.well-known/oauth-protected-resource", lib.ChainMiddlewares(h.handleProtectedResourceMetadata, middlewares...))
// RFC 8414: Authorization Server Metadata
r.GET("/.well-known/oauth-authorization-server", lib.ChainMiddlewares(h.handleAuthorizationServerMetadata, middlewares...))
}
// handleProtectedResourceMetadata serves the Protected Resource Metadata
// document per RFC 9728. MCP clients fetch this after receiving a 401 response
// to discover which authorization server(s) protect the MCP resource.
//
// GET /.well-known/oauth-protected-resource
func (h *OAuthMetadataHandler) handleProtectedResourceMetadata(ctx *fasthttp.RequestCtx) {
if clients := h.store.GetPerUserOAuthMCPClients(); len(clients) == 0 {
sendStringError(ctx, fasthttp.StatusNotFound, "Not Found")
return
}
scheme := "http"
if ctx.IsTLS() || string(ctx.Request.Header.Peek("X-Forwarded-Proto")) == "https" {
scheme = "https"
}
host := string(ctx.Host())
baseURL := fmt.Sprintf("%s://%s", scheme, host)
SendJSON(ctx, map[string]interface{}{
"resource": baseURL + "/mcp",
"authorization_servers": []string{baseURL},
"scopes_supported": []string{"mcp:read", "mcp:write"},
"bearer_methods_supported": []string{"header"},
})
}
// handleAuthorizationServerMetadata serves the Authorization Server Metadata
// document per RFC 8414. MCP clients use this to discover Bifrost's OAuth
// endpoints (authorize, token, register) and supported capabilities.
//
// GET /.well-known/oauth-authorization-server
func (h *OAuthMetadataHandler) handleAuthorizationServerMetadata(ctx *fasthttp.RequestCtx) {
if clients := h.store.GetPerUserOAuthMCPClients(); len(clients) == 0 {
sendStringError(ctx, fasthttp.StatusNotFound, "Not Found")
return
}
scheme := "http"
if ctx.IsTLS() || string(ctx.Request.Header.Peek("X-Forwarded-Proto")) == "https" {
scheme = "https"
}
host := string(ctx.Host())
baseURL := fmt.Sprintf("%s://%s", scheme, host)
SendJSON(ctx, map[string]interface{}{
"issuer": baseURL,
"authorization_endpoint": baseURL + "/api/oauth/per-user/authorize",
"token_endpoint": baseURL + "/api/oauth/per-user/token",
"registration_endpoint": baseURL + "/api/oauth/per-user/register",
"response_types_supported": []string{"code"},
"grant_types_supported": []string{"authorization_code"},
"code_challenge_methods_supported": []string{"S256"},
"token_endpoint_auth_methods_supported": []string{"none"},
"scopes_supported": []string{"mcp:read", "mcp:write"},
})
}