~ knotless Search/
↑↓ move↵ open⇧↵ all results
0
0
main
98 lines · 2.4 KB Raw History
package guestidentity

import (
	"cmp"
	"errors"
	"fmt"
	"strings"
	"time"

	"github.com/johnandersen777/socialweb-computer-kcp/internal/guestseed"
)

const (
	WIFSimpleNSID = "com.publicdomainrelay.temp.compute.config.wif.simple"

	WIFToIssue = "openbao-identity-oidc"

	WIFURLRoute = "/v1/identity/oidc/token"

	WIFSubjectTemplate = "actx:{actx}:plc:{did-plc-key}:role:{role}"
)

type BidConfig struct {
	Type string `json:"$type"`

	AcceptPath string `json:"accept_path"`

	IssuerURI string `json:"issuer_uri"`

	ToIssue string `json:"to_issue"`

	Actx string `json:"actx"`

	TokenPath string `json:"token_path"`

	URLPath string `json:"url_path"`

	URLRoute string `json:"url_route"`

	Subject string `json:"subject"`

	CreatedAt string `json:"createdAt"`
}

func SubjectFor(bidderDID, requesterDID, role string) (string, error) {
	team, err := didKey(bidderDID)
	if err != nil {
		return "", fmt.Errorf("guestidentity: bidder DID: %w", err)
	}
	requester, err := didKey(requesterDID)
	if err != nil {
		return "", fmt.Errorf("guestidentity: requester DID: %w", err)
	}
	if role == "" {
		return "", errors.New("guestidentity: the subject names no role")
	}
	return "actx:" + team + ":plc:" + requester + ":role:" + role, nil
}

func BidConfigFor(issuerURL, bidderDID, acceptPath, createdAt string) (BidConfig, error) {
	team, err := didKey(bidderDID)
	if err != nil {
		return BidConfig{}, fmt.Errorf("guestidentity: bidder DID: %w", err)
	}
	ingress, err := cleanIngressURL(issuerURL)
	if err != nil {
		return BidConfig{}, fmt.Errorf("guestidentity: the bid config's issuer: %w", err)
	}
	issuer := OIDCIssuer(ingress)
	acceptPath = cmp.Or(acceptPath, guestseed.AcceptPathVM)
	if createdAt == "" {
		createdAt = time.Now().UTC().Format(time.RFC3339)
	}
	return BidConfig{
		Type:       WIFSimpleNSID,
		AcceptPath: acceptPath,
		IssuerURI:  issuer,
		ToIssue:    WIFToIssue,
		Actx:       team,
		TokenPath:  guestseed.GuestLoginTokenPath,
		URLPath:    guestseed.OnNetworkBaseURLPath,
		URLRoute:   WIFURLRoute,
		Subject:    WIFSubjectTemplate,
		CreatedAt:  createdAt,
	}, nil
}

func didKey(did string) (string, error) {
	did = strings.TrimSpace(did)
	if !strings.HasPrefix(did, "did:") {
		return "", fmt.Errorf("%q is not a DID", did)
	}
	parts := strings.Split(did, ":")
	if len(parts) < 3 || parts[1] == "" || parts[len(parts)-1] == "" {
		return "", fmt.Errorf("%q names no identifier", did)
	}
	return parts[len(parts)-1], nil
}