1package rbac2
2
3import (
4 "slices"
5 "strings"
6
7 "github.com/bluesky-social/indigo/atproto/syntax"
8 "tangled.org/core/api/tangled"
9)
10
11// AddRepo adds new repo with its owner to rbac enforcer
12func (e *Enforcer) AddRepo(repo syntax.ATURI) error {
13 if err := validateAtUri(repo, tangled.RepoNSID); err != nil {
14 return err
15 }
16 user := repo.Authority()
17
18 return e.setRoleForUser(user.String(), "repo:owner", repo.String())
19}
20
21// DeleteRepo deletes all policies related to the repo
22func (e *Enforcer) DeleteRepo(repo syntax.ATURI) error {
23 if err := validateAtUri(repo, tangled.RepoNSID); err != nil {
24 return err
25 }
26
27 _, err := e.e.DeleteDomains(repo.String())
28 return err
29}
30
31// AddRepoCollaborator adds new collaborator to the repo
32func (e *Enforcer) AddRepoCollaborator(user syntax.DID, repo syntax.ATURI) error {
33 if err := validateAtUri(repo, tangled.RepoNSID); err != nil {
34 return err
35 }
36
37 _, err := e.e.AddRoleForUser(user.String(), "repo:collaborator", repo.String())
38 return err
39}
40
41// RemoveRepoCollaborator removes the collaborator from the repo.
42// This won't remove inherited roles like repository owner.
43func (e *Enforcer) RemoveRepoCollaborator(user syntax.DID, repo syntax.ATURI) error {
44 if err := validateAtUri(repo, tangled.RepoNSID); err != nil {
45 return err
46 }
47
48 _, err := e.e.DeleteRoleForUser(user.String(), "repo:collaborator", repo.String())
49 return err
50}
51
52func (e *Enforcer) GetRepoCollaborators(repo syntax.ATURI) ([]syntax.DID, error) {
53 var collaborators []syntax.DID
54 members, err := e.e.GetImplicitUsersForRole("repo:collaborator", repo.String())
55 if err != nil {
56 return nil, err
57 }
58 for _, m := range members {
59 if !strings.HasPrefix(m, "did:") { // skip non-user subjects like 'repo:owner'
60 continue
61 }
62 collaborators = append(collaborators, syntax.DID(m))
63 }
64
65 slices.Sort(collaborators)
66 return slices.Compact(collaborators), nil
67}
68
69func (e *Enforcer) IsRepoOwner(user syntax.DID, repo syntax.ATURI) (bool, error) {
70 return e.e.HasRoleForUser(user.String(), "repo:owner", repo.String())
71}
72
73func (e *Enforcer) IsRepoCollaborator(user syntax.DID, repo syntax.ATURI) (bool, error) {
74 return e.hasImplicitRoleForUser(user.String(), "repo:collaborator", repo.String())
75}
76
77func (e *Enforcer) IsRepoWriteAllowed(user syntax.DID, repo syntax.ATURI) (bool, error) {
78 return e.e.Enforce(user.String(), repo.String(), "#/", "write")
79}
80
81func (e *Enforcer) IsRepoSettingsWriteAllowed(user syntax.DID, repo syntax.ATURI) (bool, error) {
82 return e.e.Enforce(user.String(), repo.String(), "#/settings", "write")
83}
84
85func (e *Enforcer) IsRepoCollaboratorInviteAllowed(user syntax.DID, repo syntax.ATURI) (bool, error) {
86 return e.e.Enforce(user.String(), repo.String(), "#/collaborator", "write")
87}
88
89func (e *Enforcer) IsRepoGitPushAllowed(user syntax.DID, repo syntax.ATURI) (bool, error) {
90 return e.e.Enforce(user.String(), repo.String(), "#/git", "write")
91}