This repository has been archived by the owner on Dec 26, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 43
/
ghapphandler.go
67 lines (60 loc) · 1.98 KB
/
ghapphandler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// Package ghapphandler provides a handler for the github app webhook endpoint.
package ghapphandler
import (
"errors"
"net/http"
"github.com/gorilla/mux"
"github.com/leg100/otf/internal"
"github.com/leg100/otf/internal/github"
"github.com/leg100/otf/internal/logr"
"github.com/leg100/otf/internal/vcs"
"github.com/leg100/otf/internal/vcsprovider"
)
type Handler struct {
logr.Logger
vcs.Publisher
VCSProviders *vcsprovider.Service
GithubApps *github.Service
}
func (h *Handler) AddHandlers(r *mux.Router) {
r.Handle(github.AppEventsPath, h)
}
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// permit handler to talk to services
ctx := internal.AddSubjectToContext(r.Context(), &internal.Superuser{Username: "github-app-event-handler"})
// retrieve github app config; if one hasn't been configured then return a
// 400
app, err := h.GithubApps.GetApp(ctx)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
h.V(2).Info("received vcs event", "github_app", app)
// use github-specific handler to unmarshal event
payload, err := github.HandleEvent(r, app.WebhookSecret)
// either ignore the event, return an error, or publish the event onwards
var ignore vcs.ErrIgnoreEvent
if errors.As(err, &ignore) {
h.V(2).Info("ignoring event: "+err.Error(), "github_app", app)
w.WriteHeader(http.StatusOK)
return
} else if err != nil {
h.Error(err, "handling vcs event", "github_app", app)
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// relay a copy of the event for each vcs provider configured with the
// github app install that triggered the event.
providers, err := h.VCSProviders.ListVCSProvidersByGithubAppInstall(ctx, *payload.GithubAppInstallID)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
for _, prov := range providers {
h.Publish(vcs.Event{
EventHeader: vcs.EventHeader{VCSProviderID: prov.ID},
EventPayload: *payload,
})
}
w.WriteHeader(http.StatusOK)
}