mirror of
https://github.com/bitechdev/ResolveSpec.git
synced 2026-10-02 03:22:09 +00:00
Guard() rejects unauthenticated callers (no guest/optional mode); Setup*/New* helpers take a SecurityList and have explicit *Unauthenticated variants. Model rules now reach the security hooks, create checks CanCreate (security.CheckModelCreateAllowed), create/update validate keys against the model's writable columns, update sets only given keys (NULL allowed), update and delete go through row security via a new BeforeScan hook, and the annotation tool is opt-in (Config.EnableAnnotations) and runs BeforeHandle.
53 lines
2.1 KiB
Go
53 lines
2.1 KiB
Go
package resolvemcp
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/bitechdev/ResolveSpec/pkg/logger"
|
|
"github.com/bitechdev/ResolveSpec/pkg/security"
|
|
)
|
|
|
|
// Guard returns middleware that requires an authenticated caller on every request.
|
|
//
|
|
// The security list's provider decides which credentials are accepted: build it from a
|
|
// security.ChainAuthenticator over an OAuth bearer token, a session token (header or cookie)
|
|
// and an API key authenticator. The authenticated security.UserContext is placed in the request
|
|
// context, which the MCP transports pass on to every tool call, so rules, row security and
|
|
// OnTxBegin apply to that caller.
|
|
//
|
|
// Unlike security.NewAuthMiddleware this guard has no guest or optional mode: it ignores
|
|
// security.SkipAuth / security.OptionalAuth markers on the request context, and fails closed
|
|
// (500) when no provider is configured.
|
|
func Guard(securityList *security.SecurityList) func(http.Handler) http.Handler {
|
|
return func(next http.Handler) http.Handler {
|
|
authed := security.NewAuthHandler(securityList, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if uc, ok := security.GetUserContext(r.Context()); !ok || uc == nil {
|
|
http.Error(w, "Authentication failed", http.StatusUnauthorized)
|
|
return
|
|
}
|
|
next.ServeHTTP(w, r)
|
|
}))
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if securityList == nil {
|
|
http.Error(w, "Security provider not configured", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
authed.ServeHTTP(w, r)
|
|
})
|
|
}
|
|
}
|
|
|
|
// requireGuard reports whether securityList can guard a route. Setup helpers use it to refuse
|
|
// to mount an endpoint rather than serve it unauthenticated by mistake.
|
|
func requireGuard(fn string, securityList *security.SecurityList) bool {
|
|
if securityList == nil || securityList.Provider() == nil {
|
|
logger.Error("resolvemcp.%s: no security provider configured; MCP endpoint NOT mounted", fn)
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func warnUnauthenticated(fn string) {
|
|
logger.Warn("resolvemcp.%s: serving the MCP endpoint WITHOUT authentication; every caller can read and write all registered models", fn)
|
|
}
|