Files
summercms/modules/wristband/example_test.go
Jakub Zych ddda59a12b feat(19.4-01): neutral wristband resource default and OIDC provider docs
- DefaultOptions().Resource is empty; comments name the host application,
  no consuming application (folded todo)
- Tests set an explicit neutral resource; TestDefaultOptionsResourceEmpty
- wristband README: new summary, two flavours, OIDC usage, API reference,
  OIDC defaults, dependencies, testing; root README row matches
- docs/services/oauth-server.md: OpenID Connect provider section;
  Resource described as required with an empty default
- ExampleNewOIDCServer and the newOIDCServer docs region
2026-10-19 18:32:03 +02:00

122 lines
4.1 KiB
Go

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 <nil>
// true true <nil>
}
// 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
}