-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Expand file tree
/
Copy pathallowlist.go
More file actions
80 lines (64 loc) · 2.22 KB
/
allowlist.go
File metadata and controls
80 lines (64 loc) · 2.22 KB
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
package codersdk
import (
"encoding/json"
"strings"
"github.com/google/uuid"
"golang.org/x/xerrors"
"github.com/coder/coder/v2/coderd/rbac/policy"
)
// APIAllowListTarget represents a single allow-list entry using the canonical
// string form "<resource_type>:<id>". The wildcard symbol "*" is treated as a
// permissive match for either side.
type APIAllowListTarget struct {
Type RBACResource `json:"type"`
ID string `json:"id"`
}
func AllowAllTarget() APIAllowListTarget {
return APIAllowListTarget{Type: ResourceWildcard, ID: policy.WildcardSymbol}
}
func AllowTypeTarget(r RBACResource) APIAllowListTarget {
return APIAllowListTarget{Type: r, ID: policy.WildcardSymbol}
}
func AllowResourceTarget(r RBACResource, id uuid.UUID) APIAllowListTarget {
return APIAllowListTarget{Type: r, ID: id.String()}
}
// String returns the canonical string representation "<type>:<id>" with "*" wildcards.
func (t APIAllowListTarget) String() string {
return string(t.Type) + ":" + t.ID
}
// MarshalJSON encodes as a JSON string: "<type>:<id>".
func (t APIAllowListTarget) MarshalJSON() ([]byte, error) {
return json.Marshal(t.String())
}
// UnmarshalJSON decodes from a JSON string: "<type>:<id>".
func (t *APIAllowListTarget) UnmarshalJSON(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return err
}
parts := strings.SplitN(strings.TrimSpace(s), ":", 2)
if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
return xerrors.Errorf("invalid allow_list entry %q: want <type>:<id>", s)
}
resource, id := RBACResource(parts[0]), parts[1]
// Type
if resource != ResourceWildcard {
if _, ok := policy.RBACPermissions[string(resource)]; !ok {
return xerrors.Errorf("unknown resource type %q", resource)
}
}
t.Type = resource
// ID
if id != policy.WildcardSymbol {
if _, err := uuid.Parse(id); err != nil {
return xerrors.Errorf("invalid %s ID (must be UUID): %q", resource, id)
}
}
t.ID = id
return nil
}
// Implement encoding.TextMarshaler/Unmarshaler for broader compatibility
func (t APIAllowListTarget) MarshalText() ([]byte, error) { return []byte(t.String()), nil }
func (t *APIAllowListTarget) UnmarshalText(b []byte) error {
return t.UnmarshalJSON([]byte("\"" + string(b) + "\""))
}