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