Files
summercms/modules/wristband/oidc_subject.go
Jakub Zych 659b42aaa8 feat(19.4-01): OIDC flavour of wristband with an end-to-end tracer
- NewOIDCServer/SetOIDCBackend build a second Server on the same engine;
  Authorize and Token dispatch by flavour, Metadata/Register 404 on OIDC
- OIDCBackend/OIDCTx, KeyStore and OIDCHost seams; MCP Backend untouched
- Discovery (PHP field order), JWKS (stdlib JWK encoding), authorize with
  resume and one-shot consent token, token with an RS256 id_token signed
  through golang-jwt map claims, userinfo
- TestOIDCTracerSmoke verifies the id_token against the served JWKS
2026-10-19 18:18:05 +02:00

40 lines
1.0 KiB
Go

package wristband
import (
"context"
"errors"
"uuid"
)
// The subject types a client can have (D-15).
const (
// SubjectTypePublic gives a user the same sub at every public client.
SubjectTypePublic = "public"
// SubjectTypePairwise gives a user a different sub per sector.
SubjectTypePairwise = "pairwise"
)
// SubjectSector returns the subject sector of a client: "" for a public
// client.
func SubjectSector(c *OIDCClientRecord) (string, error) {
if c == nil {
return "", errors.New("wristband: no client")
}
switch c.SubjectType {
case "", SubjectTypePublic:
return "", nil
}
return "", errors.New("wristband: unknown subject type")
}
// subjectFor allocates (or reads) the subject of userID at client: a random
// UUIDv4 per (user, sector), never derived from an account attribute
// (T-19.4-13).
func subjectFor(ctx context.Context, tx OIDCTx, client *OIDCClientRecord, userID uint) (string, error) {
sector, err := SubjectSector(client)
if err != nil {
return "", err
}
return tx.SubjectFor(ctx, userID, sector, uuid.NewV4().String())
}