Monorepo for Tangled
tangled.org
1package rbac
2
3import (
4 "fmt"
5 "slices"
6 "strings"
7)
8
9func (e *Enforcer) getDomainsForUser(did string, keepFunc func(string) bool, stripFunc func(string) string) ([]string, error) {
10 domains, err := e.E.GetDomainsForUser(did)
11 if err != nil {
12 return nil, err
13 }
14
15 n := 0
16 for _, x := range domains {
17 if keepFunc(x) {
18 domains[n] = stripFunc(x)
19 n++
20 }
21 }
22 domains = domains[:n]
23
24 return domains, nil
25}
26
27func (e *Enforcer) addOwner(domain, owner string) error {
28 _, err := e.E.AddGroupingPolicy(owner, "server:owner", domain)
29 return err
30}
31
32func (e *Enforcer) removeOwner(domain, owner string) error {
33 _, err := e.E.RemoveGroupingPolicy(owner, "server:owner", domain)
34 return err
35}
36
37func (e *Enforcer) addMember(domain, member string) (bool, error) {
38 return e.E.AddGroupingPolicy(member, "server:member", domain)
39}
40
41func (e *Enforcer) removeMember(domain, member string) (bool, error) {
42 return e.E.RemoveGroupingPolicy(member, "server:member", domain)
43}
44
45func (e *Enforcer) isRole(user, role, domain string) (bool, error) {
46 roles, err := e.E.GetImplicitRolesForUser(user, domain)
47 if err != nil {
48 return false, err
49 }
50 if slices.Contains(roles, role) {
51 return true, nil
52 }
53 return false, nil
54}
55
56func (e *Enforcer) isInviteAllowed(user, domain string) (bool, error) {
57 return e.E.Enforce(user, domain, domain, "server:invite")
58}
59
60func (e *Enforcer) HasAnyPolicyForUser(user string) (bool, error) {
61 pPolicies, err := e.E.GetFilteredNamedPolicy("p", 0, user)
62 if err != nil {
63 return false, err
64 }
65 if len(pPolicies) > 0 {
66 return true, nil
67 }
68 gPolicies, err := e.E.GetFilteredNamedGroupingPolicy("g", 0, user)
69 if err != nil {
70 return false, err
71 }
72 return len(gPolicies) > 0, nil
73}
74
75func (e *Enforcer) wouldHaveAnyPolicyExcludingGrouping(user, role, domain string) (bool, error) {
76 pPolicies, err := e.E.GetFilteredNamedPolicy("p", 0, user)
77 if err != nil {
78 return false, err
79 }
80 if len(pPolicies) > 0 {
81 return true, nil
82 }
83 gPolicies, err := e.E.GetFilteredNamedGroupingPolicy("g", 0, user)
84 if err != nil {
85 return false, err
86 }
87 for _, gp := range gPolicies {
88 if len(gp) < 3 {
89 return true, nil
90 }
91 if gp[1] != role || gp[2] != domain {
92 return true, nil
93 }
94 }
95 return false, nil
96}
97
98func (e *Enforcer) WouldHaveAnyPolicyExcludingSpindleMember(user, domain string) (bool, error) {
99 return e.wouldHaveAnyPolicyExcludingGrouping(user, "server:member", intoSpindle(domain))
100}
101
102func checkRepoFormat(repo string) error {
103 // sanity check, repo must be of the form ownerDid/repo
104 if parts := strings.SplitN(repo, "/", 2); !strings.HasPrefix(parts[0], "did:") {
105 return fmt.Errorf("invalid repo: %s", repo)
106 }
107
108 return nil
109}
110
111const spindlePrefix = "spindle:"
112
113func intoSpindle(domain string) string {
114 if !isSpindle(domain) {
115 return spindlePrefix + domain
116 }
117 return domain
118}
119
120func unSpindle(domain string) string {
121 if !isSpindle(domain) {
122 return domain
123 }
124 return strings.TrimPrefix(domain, spindlePrefix)
125}
126
127func isSpindle(domain string) bool {
128 return strings.HasPrefix(domain, spindlePrefix)
129}
130
131func isNotSpindle(domain string) bool {
132 return !isSpindle(domain)
133}