package wristband_test import ( "encoding/json" "fmt" "net/http/httptest" "git.golem15.com/golem15/summercms/modules/wristband" ) // newServer builds the authorization server of an application served at // https://blog.example.com. The application sets Issuer and Resource for // its own deployment; the defaults cover everything else. func newServer() *wristband.Server { opts := wristband.DefaultOptions() opts.Issuer = "https://blog.example.com" opts.Resource = "https://blog.example.com/mcp" opts.ScopesSupported = []string{"read", "write", "offline_access"} return wristband.NewServer(opts) } func ExampleServer_Metadata() { srv := newServer() // srv.SetBackend(backend) attaches the application's stores; the // metadata document does not need them. rec := httptest.NewRecorder() srv.Metadata(rec, httptest.NewRequest("GET", "/.well-known/oauth-authorization-server", nil)) var doc map[string]any if err := json.Unmarshal(rec.Body.Bytes(), &doc); err != nil { fmt.Println(err) return } for _, key := range []string{ "issuer", "authorization_endpoint", "token_endpoint", "registration_endpoint", "scopes_supported", "grant_types_supported", "code_challenge_methods_supported", } { fmt.Println(key, doc[key]) } // Output: // issuer https://blog.example.com // authorization_endpoint https://blog.example.com/oauth/mcp/authorize // token_endpoint https://blog.example.com/oauth/mcp/token // registration_endpoint https://blog.example.com/oauth/mcp/register // scopes_supported [read write offline_access] // grant_types_supported [authorization_code refresh_token] // code_challenge_methods_supported [S256] } func ExampleRejectRedirectURI() { for _, uri := range []string{ "https://client.example.org/callback", "http://127.0.0.1:33418/callback", "http://client.example.org/callback", } { if reason := wristband.RejectRedirectURI(uri); reason != "" { fmt.Println("rejected:", reason) continue } fmt.Println("accepted:", uri) } // Output: // accepted: https://client.example.org/callback // accepted: http://127.0.0.1:33418/callback // rejected: Redirect URI must be https:// or loopback http://127.0.0.1 / http://localhost: http://client.example.org/callback } func ExampleIssueClientCredentials() { // A confidential client gets a secret, shown once; store only the hash. id, secret, hash, err := wristband.IssueClientCredentials("client_secret_post") fmt.Println(id != "", secret != "", hash != nil && *hash != secret, err) // A public client (PKCE only) gets no secret. _, secret, hash, err = wristband.IssueClientCredentials("none") fmt.Println(secret == "", hash == nil, err) // Output: // true true true // true true } // newOIDCServer builds the OpenID Connect provider of an application served // at https://id.example.com. The host application supplies storage, the // signing-key ring and its pages; SetOIDCBackend refuses a nil one. func newOIDCServer(backend wristband.OIDCBackend, keys wristband.KeyStore, host wristband.OIDCHost) (*wristband.Server, error) { opts := wristband.DefaultOptions() opts.Issuer = "https://id.example.com" oidc := wristband.DefaultOIDCOptions() oidc.LoginURL = "/account/login" oidc.RefreshEnabled = true // only clients with OfflineAccess get refresh tokens srv := wristband.NewOIDCServer(opts, oidc) if err := srv.SetOIDCBackend(backend, keys, host); err != nil { return nil, err } return srv, nil } func ExampleNewOIDCServer() { // Without storage, keys and a host the server refuses to start. _, err := newOIDCServer(nil, nil, nil) fmt.Println(err) // An OIDC server serves discovery instead of the MCP metadata document. srv := wristband.NewOIDCServer(wristband.DefaultOptions(), wristband.DefaultOIDCOptions()) rec := httptest.NewRecorder() srv.Metadata(rec, httptest.NewRequest("GET", "/.well-known/oauth-authorization-server", nil)) fmt.Println("metadata", rec.Code) defaults := wristband.DefaultOIDCOptions() fmt.Println(defaults.ScopesSupported, defaults.CodeTTL, defaults.RefreshEnabled) // Output: // wristband: OIDC backend is nil // metadata 404 // [openid profile email] 1m0s false }