package main import ( "context" "fmt" "strings" "time" "github.com/coreos/go-oidc/v3/oidc" ) type app struct { cfg config db *pgDatabase oidcVerifier *oidc.IDTokenVerifier notificationProvider notificationProvider stripeService stripeService billingCustomerEnsurer func(string, string) (Doc, error) stripeWebhookVerifier func([]byte, string) (stripeWebhookEvent, error) pageSlugInUse func(string, string) (bool, error) } func newApp(cfg config) (*app, error) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() db, err := openPostgres(ctx, cfg.DatabaseURL) if err != nil { return nil, fmt.Errorf("connect postgres: %w", err) } var verifier *oidc.IDTokenVerifier if !cfg.AuthDisabled { oidcCtx, oidcCancel := context.WithTimeout(context.Background(), 10*time.Second) defer oidcCancel() keySet := oidc.NewRemoteKeySet(oidcCtx, strings.TrimRight(cfg.KeycloakIssuerInternal, "/")+"/protocol/openid-connect/certs") verifier = oidc.NewVerifier(cfg.KeycloakIssuer, keySet, &oidc.Config{ // Keycloak access tokens commonly identify the requesting public client // through azp while aud contains resource servers. Verify issuer/signature/ // expiry here, then enforce the configured client/audience in middleware. SkipClientIDCheck: true, }) } return &app{ cfg: cfg, db: db, oidcVerifier: verifier, notificationProvider: newNotificationProvider(cfg), stripeService: newStripeService(cfg), }, nil } func (a *app) close() { if a.db != nil { a.db.Close() } }