1package backend
2
3import (
4 "context"
5 "strings"
6
7 "github.com/charmbracelet/soft-serve/server/access"
8 "github.com/charmbracelet/soft-serve/server/db"
9 "github.com/charmbracelet/soft-serve/server/db/models"
10 "github.com/charmbracelet/soft-serve/server/utils"
11)
12
13// AddCollaborator adds a collaborator to a repository.
14//
15// It implements backend.Backend.
16func (d *Backend) AddCollaborator(ctx context.Context, repo string, username string, level access.AccessLevel) error {
17 username = strings.ToLower(username)
18 if err := utils.ValidateUsername(username); err != nil {
19 return err
20 }
21
22 repo = utils.SanitizeRepo(repo)
23 return db.WrapError(
24 d.db.TransactionContext(ctx, func(tx *db.Tx) error {
25 return d.store.AddCollabByUsernameAndRepo(ctx, tx, username, repo, level)
26 }),
27 )
28}
29
30// Collaborators returns a list of collaborators for a repository.
31//
32// It implements backend.Backend.
33func (d *Backend) Collaborators(ctx context.Context, repo string) ([]string, error) {
34 repo = utils.SanitizeRepo(repo)
35 var users []models.User
36 if err := d.db.TransactionContext(ctx, func(tx *db.Tx) error {
37 var err error
38 users, err = d.store.ListCollabsByRepoAsUsers(ctx, tx, repo)
39 return err
40 }); err != nil {
41 return nil, db.WrapError(err)
42 }
43
44 var usernames []string
45 for _, u := range users {
46 usernames = append(usernames, u.Username)
47 }
48
49 return usernames, nil
50}
51
52// IsCollaborator returns the access level and true if the user is a collaborator of the repository.
53//
54// It implements backend.Backend.
55func (d *Backend) IsCollaborator(ctx context.Context, repo string, username string) (access.AccessLevel, bool, error) {
56 if username == "" {
57 return -1, false, nil
58 }
59
60 repo = utils.SanitizeRepo(repo)
61 var m models.Collab
62 if err := d.db.TransactionContext(ctx, func(tx *db.Tx) error {
63 var err error
64 m, err = d.store.GetCollabByUsernameAndRepo(ctx, tx, username, repo)
65 return err
66 }); err != nil {
67 return -1, false, db.WrapError(err)
68 }
69
70 return m.AccessLevel, m.ID > 0, nil
71}
72
73// RemoveCollaborator removes a collaborator from a repository.
74//
75// It implements backend.Backend.
76func (d *Backend) RemoveCollaborator(ctx context.Context, repo string, username string) error {
77 repo = utils.SanitizeRepo(repo)
78 return db.WrapError(
79 d.db.TransactionContext(ctx, func(tx *db.Tx) error {
80 return d.store.RemoveCollabByUsernameAndRepo(ctx, tx, username, repo)
81 }),
82 )
83}