debian-forge-composer/vendor/github.com/spiffe/go-spiffe/v2/spiffeid/id.go
Achilleas Koutsou 3fd7092db5 go.mod: update osbuild/images to v0.156.0
tag v0.155.0
Tagger: imagebuilder-bot <imagebuilder-bots+imagebuilder-bot@redhat.com>

Changes with 0.155.0

----------------
  * Fedora 43: add shadow-utils when LockRoot is enabled, update cloud-init service name (osbuild/images#1618)
    * Author: Achilleas Koutsou, Reviewers: Gianluca Zuccarelli, Michael Vogt
  * Update osbuild dependency commit ID to latest (osbuild/images#1609)
    * Author: SchutzBot, Reviewers: Achilleas Koutsou, Simon de Vlieger, Tomáš Hozza
  * Update snapshots to 20250626 (osbuild/images#1623)
    * Author: SchutzBot, Reviewers: Achilleas Koutsou, Simon de Vlieger
  * distro/rhel9: xz compress azure-cvm image type [HMS-8587] (osbuild/images#1620)
    * Author: Achilleas Koutsou, Reviewers: Simon de Vlieger, Tomáš Hozza
  * distro/rhel: introduce new image type: Azure SAP Apps [HMS-8738] (osbuild/images#1612)
    * Author: Achilleas Koutsou, Reviewers: Simon de Vlieger, Tomáš Hozza
  * distro/rhel: move ansible-core to sap_extras_pkgset (osbuild/images#1624)
    * Author: Achilleas Koutsou, Reviewers: Brian C. Lane, Tomáš Hozza
  * github/create-tag: allow passing the version when run manually (osbuild/images#1621)
    * Author: Achilleas Koutsou, Reviewers: Lukáš Zapletal, Tomáš Hozza
  * rhel9: move image-config into pure YAML (HMS-8593) (osbuild/images#1616)
    * Author: Michael Vogt, Reviewers: Achilleas Koutsou, Simon de Vlieger
  * test: split manifest checksums into separate files (osbuild/images#1625)
    * Author: Achilleas Koutsou, Reviewers: Simon de Vlieger, Tomáš Hozza

— Somewhere on the Internet, 2025-06-30

---

tag v0.156.0
Tagger: imagebuilder-bot <imagebuilder-bots+imagebuilder-bot@redhat.com>

Changes with 0.156.0

----------------
  * Many: delete repositories for EOL distributions (HMS-7044) (osbuild/images#1607)
    * Author: Tomáš Hozza, Reviewers: Michael Vogt, Simon de Vlieger
  * RHSM/facts: add 'image-builder CLI' API type (osbuild/images#1640)
    * Author: Tomáš Hozza, Reviewers: Brian C. Lane, Simon de Vlieger
  * Update dependencies 2025-06-29 (osbuild/images#1628)
    * Author: SchutzBot, Reviewers: Simon de Vlieger, Tomáš Hozza
  * Update osbuild dependency commit ID to latest (osbuild/images#1627)
    * Author: SchutzBot, Reviewers: Simon de Vlieger, Tomáš Hozza
  * [RFC] image: drop `InstallWeakDeps` from image.DiskImage (osbuild/images#1642)
    * Author: Michael Vogt, Reviewers: Brian C. Lane, Simon de Vlieger, Tomáš Hozza
  * build(deps): bump the go-deps group across 1 directory with 3 updates (osbuild/images#1632)
    * Author: dependabot[bot], Reviewers: SchutzBot, Tomáš Hozza
  * distro/rhel10: xz compress azure-cvm image type (osbuild/images#1638)
    * Author: Achilleas Koutsou, Reviewers: Brian C. Lane, Simon de Vlieger
  * distro: cleanup/refactor distro/{defs,generic} (HMS-8744) (osbuild/images#1570)
    * Author: Michael Vogt, Reviewers: Simon de Vlieger, Tomáš Hozza
  * distro: remove some hardcoded values from generic/images.go (osbuild/images#1636)
    * Author: Michael Vogt, Reviewers: Simon de Vlieger, Tomáš Hozza
  * distro: small tweaks for the YAML based imagetypes (osbuild/images#1622)
    * Author: Michael Vogt, Reviewers: Brian C. Lane, Simon de Vlieger
  * fedora/wsl: packages and locale (osbuild/images#1635)
    * Author: Simon de Vlieger, Reviewers: Michael Vogt, Tomáš Hozza
  * image/many: make compression more generic (osbuild/images#1634)
    * Author: Simon de Vlieger, Reviewers: Brian C. Lane, Michael Vogt
  * manifest: handle content template name with spaces (osbuild/images#1641)
    * Author: Bryttanie, Reviewers: Brian C. Lane, Michael Vogt, Tomáš Hozza
  * many: implement gzip (osbuild/images#1633)
    * Author: Simon de Vlieger, Reviewers: Michael Vogt, Tomáš Hozza
  * rhel/azure: set GRUB_TERMINAL based on architecture [RHEL-91383] (osbuild/images#1626)
    * Author: Achilleas Koutsou, Reviewers: Simon de Vlieger, Tomáš Hozza

— Somewhere on the Internet, 2025-07-07

---
2025-07-14 13:13:20 +02:00

258 lines
7.4 KiB
Go

package spiffeid
import (
"errors"
"fmt"
"net/url"
"strings"
)
const (
schemePrefix = "spiffe://"
schemePrefixLen = len(schemePrefix)
)
// FromPath returns a new SPIFFE ID in the given trust domain and with the
// given path. The supplied path must be a valid absolute path according to the
// SPIFFE specification.
// See https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE-ID.md#22-path
func FromPath(td TrustDomain, path string) (ID, error) {
if err := ValidatePath(path); err != nil {
return ID{}, err
}
return makeID(td, path)
}
// FromPathf returns a new SPIFFE ID from the formatted path in the given trust
// domain. The formatted path must be a valid absolute path according to the
// SPIFFE specification.
// See https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE-ID.md#22-path
func FromPathf(td TrustDomain, format string, args ...interface{}) (ID, error) {
path, err := FormatPath(format, args...)
if err != nil {
return ID{}, err
}
return makeID(td, path)
}
// FromSegments returns a new SPIFFE ID in the given trust domain with joined
// path segments. The path segments must be valid according to the SPIFFE
// specification and must not contain path separators.
// See https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE-ID.md#22-path
func FromSegments(td TrustDomain, segments ...string) (ID, error) {
path, err := JoinPathSegments(segments...)
if err != nil {
return ID{}, err
}
return makeID(td, path)
}
// FromString parses a SPIFFE ID from a string.
func FromString(id string) (ID, error) {
switch {
case id == "":
return ID{}, errEmpty
case !strings.HasPrefix(id, schemePrefix):
return ID{}, errWrongScheme
}
pathidx := schemePrefixLen
for ; pathidx < len(id); pathidx++ {
c := id[pathidx]
if c == '/' {
break
}
if !isValidTrustDomainChar(c) {
return ID{}, errBadTrustDomainChar
}
}
if pathidx == schemePrefixLen {
return ID{}, errMissingTrustDomain
}
if err := ValidatePath(id[pathidx:]); err != nil {
return ID{}, err
}
return ID{
id: id,
pathidx: pathidx,
}, nil
}
// FromStringf parses a SPIFFE ID from a formatted string.
func FromStringf(format string, args ...interface{}) (ID, error) {
return FromString(fmt.Sprintf(format, args...))
}
// FromURI parses a SPIFFE ID from a URI.
func FromURI(uri *url.URL) (ID, error) {
return FromString(uri.String())
}
// ID is a SPIFFE ID
type ID struct {
id string
// pathidx tracks the index to the beginning of the path inside of id. This
// is used when extracting the trust domain or path portions of the id.
pathidx int
}
// TrustDomain returns the trust domain of the SPIFFE ID.
func (id ID) TrustDomain() TrustDomain {
if id.IsZero() {
return TrustDomain{}
}
return TrustDomain{name: id.id[schemePrefixLen:id.pathidx]}
}
// MemberOf returns true if the SPIFFE ID is a member of the given trust domain.
func (id ID) MemberOf(td TrustDomain) bool {
return id.TrustDomain() == td
}
// Path returns the path of the SPIFFE ID inside the trust domain.
func (id ID) Path() string {
return id.id[id.pathidx:]
}
// String returns the string representation of the SPIFFE ID, e.g.,
// "spiffe://example.org/foo/bar".
func (id ID) String() string {
return id.id
}
// URL returns a URL for SPIFFE ID.
func (id ID) URL() *url.URL {
if id.IsZero() {
return &url.URL{}
}
return &url.URL{
Scheme: "spiffe",
Host: id.TrustDomain().String(),
Path: id.Path(),
}
}
// IsZero returns true if the SPIFFE ID is the zero value.
func (id ID) IsZero() bool {
return id.id == ""
}
// AppendPath returns an ID with the appended path. It will fail if called on a
// zero value. The path to append must be a valid absolute path according to
// the SPIFFE specification.
// See https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE-ID.md#22-path
func (id ID) AppendPath(path string) (ID, error) {
if id.IsZero() {
return ID{}, errors.New("cannot append path on a zero ID value")
}
if err := ValidatePath(path); err != nil {
return ID{}, err
}
id.id += path
return id, nil
}
// AppendPathf returns an ID with the appended formatted path. It will fail if
// called on a zero value. The formatted path must be a valid absolute path
// according to the SPIFFE specification.
// See https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE-ID.md#22-path
func (id ID) AppendPathf(format string, args ...interface{}) (ID, error) {
if id.IsZero() {
return ID{}, errors.New("cannot append path on a zero ID value")
}
path, err := FormatPath(format, args...)
if err != nil {
return ID{}, err
}
id.id += path
return id, nil
}
// AppendSegments returns an ID with the appended joined path segments. It
// will fail if called on a zero value. The path segments must be valid
// according to the SPIFFE specification and must not contain path separators.
// See https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE-ID.md#22-path
func (id ID) AppendSegments(segments ...string) (ID, error) {
if id.IsZero() {
return ID{}, errors.New("cannot append path segments on a zero ID value")
}
path, err := JoinPathSegments(segments...)
if err != nil {
return ID{}, err
}
id.id += path
return id, nil
}
// Replace path returns an ID with the given path in the same trust domain. It
// will fail if called on a zero value. The given path must be a valid absolute
// path according to the SPIFFE specification.
// See https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE-ID.md#22-path
func (id ID) ReplacePath(path string) (ID, error) {
if id.IsZero() {
return ID{}, errors.New("cannot replace path on a zero ID value")
}
return FromPath(id.TrustDomain(), path)
}
// ReplacePathf returns an ID with the formatted path in the same trust domain.
// It will fail if called on a zero value. The formatted path must be a valid
// absolute path according to the SPIFFE specification.
// See https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE-ID.md#22-path
func (id ID) ReplacePathf(format string, args ...interface{}) (ID, error) {
if id.IsZero() {
return ID{}, errors.New("cannot replace path on a zero ID value")
}
return FromPathf(id.TrustDomain(), format, args...)
}
// ReplaceSegments returns an ID with the joined path segments in the same
// trust domain. It will fail if called on a zero value. The path segments must
// be valid according to the SPIFFE specification and must not contain path
// separators.
// See https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE-ID.md#22-path
func (id ID) ReplaceSegments(segments ...string) (ID, error) {
if id.IsZero() {
return ID{}, errors.New("cannot replace path segments on a zero ID value")
}
return FromSegments(id.TrustDomain(), segments...)
}
// MarshalText returns a text representation of the ID. If the ID is the zero
// value, nil is returned.
func (id ID) MarshalText() ([]byte, error) {
if id.IsZero() {
return nil, nil
}
return []byte(id.String()), nil
}
// UnmarshalText decodes a text representation of the ID. If the text is empty,
// the ID is set to the zero value.
func (id *ID) UnmarshalText(text []byte) error {
if len(text) == 0 {
*id = ID{}
return nil
}
unmarshaled, err := FromString(string(text))
if err != nil {
return err
}
*id = unmarshaled
return nil
}
func makeID(td TrustDomain, path string) (ID, error) {
if td.IsZero() {
return ID{}, errors.New("trust domain is empty")
}
return ID{
id: schemePrefix + td.name + path,
pathidx: schemePrefixLen + len(td.name),
}, nil
}