collaborator.go

 1package webhook
 2
 3import (
 4	"context"
 5	"fmt"
 6
 7	"github.com/charmbracelet/soft-serve/pkg/access"
 8	"github.com/charmbracelet/soft-serve/pkg/db"
 9	"github.com/charmbracelet/soft-serve/pkg/proto"
10	"github.com/charmbracelet/soft-serve/pkg/store"
11)
12
13// CollaboratorEvent is a collaborator event.
14type CollaboratorEvent struct {
15	Common
16
17	// Action is the collaborator event action.
18	Action CollaboratorEventAction `json:"action" url:"action"`
19	// AccessLevel is the collaborator access level.
20	AccessLevel access.AccessLevel `json:"access_level" url:"access_level"`
21	// Collaborator is the collaborator.
22	Collaborator User `json:"collaborator" url:"collaborator"`
23}
24
25// CollaboratorEventAction is a collaborator event action.
26type CollaboratorEventAction string
27
28const (
29	// CollaboratorEventAdded is a collaborator added event.
30	CollaboratorEventAdded CollaboratorEventAction = "added"
31	// CollaboratorEventRemoved is a collaborator removed event.
32	CollaboratorEventRemoved CollaboratorEventAction = "removed"
33)
34
35// NewCollaboratorEvent sends a collaborator event.
36func NewCollaboratorEvent(ctx context.Context, user proto.User, repo proto.Repository, collabUsername string, action CollaboratorEventAction) (CollaboratorEvent, error) {
37	event := EventCollaborator
38
39	payload := CollaboratorEvent{
40		Action: action,
41		Common: Common{
42			EventType: event,
43			Repository: Repository{
44				ID:          repo.ID(),
45				Name:        repo.Name(),
46				Description: repo.Description(),
47				ProjectName: repo.ProjectName(),
48				Private:     repo.IsPrivate(),
49				CreatedAt:   repo.CreatedAt(),
50				UpdatedAt:   repo.UpdatedAt(),
51			},
52			Sender: User{
53				ID:       user.ID(),
54				Username: user.Username(),
55			},
56		},
57	}
58
59	// Find repo owner.
60	dbx := db.FromContext(ctx)
61	datastore := store.FromContext(ctx)
62	owner, err := datastore.GetUserByID(ctx, dbx, repo.UserID())
63	if err != nil {
64		return CollaboratorEvent{}, db.WrapError(err)
65	}
66
67	handle, err := datastore.GetHandleByUserID(ctx, dbx, owner.ID)
68	if err != nil {
69		return CollaboratorEvent{}, db.WrapError(err)
70	}
71
72	payload.Repository.Owner.ID = owner.ID
73	payload.Repository.Owner.Username = handle.Handle
74	payload.Repository.DefaultBranch, err = proto.RepositoryDefaultBranch(repo)
75	if err != nil {
76		return CollaboratorEvent{}, err
77	}
78
79	collab, err := datastore.GetCollabByUsernameAndRepo(ctx, dbx, collabUsername, repo.Name())
80	if err != nil {
81		return CollaboratorEvent{}, err
82	}
83
84	payload.AccessLevel = collab.AccessLevel
85	if !collab.UserID.Valid {
86		return CollaboratorEvent{}, fmt.Errorf("collaborator user ID is invalid")
87	}
88
89	payload.Collaborator.ID = collab.UserID.Int64
90	payload.Collaborator.Username = collabUsername
91
92	return payload, nil
93}