1package entitlements
2
3import "github.com/pkg/errors"
4
5type Entitlement string
6
7const (
8	EntitlementSecurityConfined   Entitlement = "security.confined"
9	EntitlementSecurityUnconfined Entitlement = "security.unconfined" // unimplemented
10	EntitlementNetworkHost        Entitlement = "network.host"
11	EntitlementNetworkNone        Entitlement = "network.none"
12)
13
14var all = map[Entitlement]struct{}{
15	EntitlementSecurityConfined:   {},
16	EntitlementSecurityUnconfined: {},
17	EntitlementNetworkHost:        {},
18	EntitlementNetworkNone:        {},
19}
20
21var defaults = map[Entitlement]struct{}{
22	EntitlementSecurityConfined: {},
23	EntitlementNetworkNone:      {},
24}
25
26func Parse(s string) (Entitlement, error) {
27	_, ok := all[Entitlement(s)]
28	if !ok {
29		return "", errors.Errorf("unknown entitlement %s", s)
30	}
31	return Entitlement(s), nil
32}
33
34func WhiteList(allowed, supported []Entitlement) (Set, error) {
35	m := map[Entitlement]struct{}{}
36
37	var supm Set
38	if supported != nil {
39		var err error
40		supm, err = WhiteList(supported, nil)
41		if err != nil { // should not happen
42			return nil, err
43		}
44	}
45
46	for _, e := range allowed {
47		e, err := Parse(string(e))
48		if err != nil {
49			return nil, err
50		}
51		if supported != nil {
52			if !supm.Allowed(e) {
53				return nil, errors.Errorf("entitlement %s is not allowed", e)
54			}
55		}
56		m[e] = struct{}{}
57	}
58
59	for e := range defaults {
60		m[e] = struct{}{}
61	}
62	return Set(m), nil
63}
64
65type Set map[Entitlement]struct{}
66
67func (s Set) Allowed(e Entitlement) bool {
68	_, ok := s[e]
69	return ok
70}
71