Compare commits

...

2 Commits

Author SHA1 Message Date
Mike DeAngelo
271f4d6f2f chore: refactor common code into helper function 2025-12-15 12:21:40 -05:00
Mike DeAngelo
881c3a1ac3 feat: serve /.well-known/... oauth metadata files 2025-12-15 12:21:40 -05:00
3 changed files with 42 additions and 0 deletions

View File

@@ -374,6 +374,8 @@ func NewCommand(opts ...Option) *Command {
flags.BoolVar(&cmd.cfg.DisableReload, "disable-reload", false, "Disables dynamic reloading of tools file.")
flags.BoolVar(&cmd.cfg.UI, "ui", false, "Launches the Toolbox UI web server.")
flags.StringSliceVar(&cmd.cfg.AllowedOrigins, "allowed-origins", []string{"*"}, "Specifies a list of origins permitted to access this server. Defaults to '*'.")
flags.StringVar(&cmd.cfg.OAuthProtectedResource, "oauth-protected-resource", "", "Specifies a yaml file that contains what should be returned from /.well-known/oauth-protected-resource")
flags.StringVar(&cmd.cfg.OAuthAuthorizationServer, "oauth-authorization-server", "", "Specifies a yaml file that contains what should be returned from /.well-known/oauth-authorization-server")
// wrap RunE command so that we have access to original Command object
cmd.RunE = func(*cobra.Command, []string) error { return run(cmd) }

View File

@@ -64,6 +64,10 @@ type ServerConfig struct {
UI bool
// Specifies a list of origins permitted to access this server.
AllowedOrigins []string
// source file for /.well-known/oauth-protected-resource.
OAuthProtectedResource string
// source file for /.well-known/oauth-authorization-server.
OAuthAuthorizationServer string
}
type logFormat string

View File

@@ -16,15 +16,19 @@ package server
import (
"context"
"encoding/json"
"fmt"
"io"
"net"
"net/http"
"os"
"slices"
"strconv"
"strings"
"time"
yaml "github.com/goccy/go-yaml"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"github.com/go-chi/cors"
@@ -379,9 +383,41 @@ func NewServer(ctx context.Context, cfg ServerConfig) (*Server, error) {
_, _ = w.Write([]byte("🧰 Hello, World! 🧰"))
})
if err := serveJsonFromYamlFile(r, cfg.OAuthProtectedResource, "/.well-known/oauth-protected-resource"); err != nil {
return nil, err
}
if err := serveJsonFromYamlFile(r, cfg.OAuthAuthorizationServer, "/.well-known/oauth-authorization-server"); err != nil {
return nil, err
}
return s, nil
}
// helper function to serve yaml files as json from fixed paths.
func serveJsonFromYamlFile(r *chi.Mux, filePath, endpointPath string) error {
if filePath == "" {
return nil
}
data, err := os.ReadFile(filePath)
if err != nil {
return fmt.Errorf("error reading yaml file %s: %w", filePath, err)
}
var metadata map[string]interface{}
if err := yaml.Unmarshal(data, &metadata); err != nil {
return fmt.Errorf("error unmarshalling yaml file %s: %w", filePath, err)
}
jsonData, err := json.MarshalIndent(metadata, "", " ")
if err != nil {
return fmt.Errorf("error marshalling yaml file %s as json: %w", filePath, err)
}
r.Get(endpointPath, func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write(jsonData)
})
return nil
}
// Listen starts a listener for the given Server instance.
func (s *Server) Listen(ctx context.Context) error {
ctx, cancel := context.WithCancel(ctx)