File: trustdomain.go

package info (click to toggle)
golang-github-spiffe-go-spiffe 2.5.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,116 kB
  • sloc: makefile: 157
file content (127 lines) | stat: -rw-r--r-- 3,456 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package spiffeid

import (
	"net/url"
	"strings"
)

// TrustDomain represents the trust domain portion of a SPIFFE ID (e.g.
// example.org).
type TrustDomain struct {
	name string
}

// TrustDomainFromString returns a new TrustDomain from a string. The string
// can either be a trust domain name (e.g. example.org), or a valid SPIFFE ID
// URI (e.g. spiffe://example.org), otherwise an error is returned.
// See https://github.com/spiffe/spiffe/blob/main/standards/SPIFFE-ID.md#21-trust-domain.
func TrustDomainFromString(idOrName string) (TrustDomain, error) {
	switch {
	case idOrName == "":
		return TrustDomain{}, errMissingTrustDomain
	case strings.Contains(idOrName, ":/"):
		// The ID looks like it has something like a scheme separator, let's
		// try to parse as an ID. We use :/ instead of :// since the
		// diagnostics are better for a bad input like spiffe:/trustdomain.
		id, err := FromString(idOrName)
		if err != nil {
			return TrustDomain{}, err
		}
		return id.TrustDomain(), nil
	default:
		for i := 0; i < len(idOrName); i++ {
			if !isValidTrustDomainChar(idOrName[i]) {
				return TrustDomain{}, errBadTrustDomainChar
			}
		}
		return TrustDomain{name: idOrName}, nil
	}
}

// TrustDomainFromURI returns a new TrustDomain from a URI. The URI must be a
// valid SPIFFE ID (see FromURI) or an error is returned. The trust domain is
// extracted from the host field.
func TrustDomainFromURI(uri *url.URL) (TrustDomain, error) {
	id, err := FromURI(uri)
	if err != nil {
		return TrustDomain{}, err
	}

	return id.TrustDomain(), nil
}

// Name returns the trust domain name as a string, e.g. example.org.
func (td TrustDomain) Name() string {
	return td.name
}

// String returns the trust domain name as a string, e.g. example.org.
func (td TrustDomain) String() string {
	return td.name
}

// ID returns the SPIFFE ID of the trust domain.
func (td TrustDomain) ID() ID {
	if id, err := makeID(td, ""); err == nil {
		return id
	}
	return ID{}
}

// IDString returns a string representation of the the SPIFFE ID of the trust
// domain, e.g. "spiffe://example.org".
func (td TrustDomain) IDString() string {
	return td.ID().String()
}

// IsZero returns true if the trust domain is the zero value.
func (td TrustDomain) IsZero() bool {
	return td.name == ""
}

// Compare returns an integer comparing the trust domain to another
// lexicographically. The result will be 0 if td==other, -1 if td < other, and
// +1 if td > other.
func (td TrustDomain) Compare(other TrustDomain) int {
	return strings.Compare(td.name, other.name)
}

// MarshalText returns a text representation of the trust domain. If the trust
// domain is the zero value, nil is returned.
func (td TrustDomain) MarshalText() ([]byte, error) {
	if td.IsZero() {
		return nil, nil
	}
	return []byte(td.String()), nil
}

// UnmarshalText decodes a text representation of the trust domain. If the text
// is empty, the trust domain is set to the zero value.
func (td *TrustDomain) UnmarshalText(text []byte) error {
	if len(text) == 0 {
		*td = TrustDomain{}
		return nil
	}

	unmarshaled, err := TrustDomainFromString(string(text))
	if err != nil {
		return err
	}
	*td = unmarshaled
	return nil
}

func isValidTrustDomainChar(c uint8) bool {
	switch {
	case c >= 'a' && c <= 'z':
		return true
	case c >= '0' && c <= '9':
		return true
	case c == '-', c == '.', c == '_':
		return true
	case isBackcompatTrustDomainChar(c):
		return true
	default:
		return false
	}
}