forked from keybase/managed-bots
-
Notifications
You must be signed in to change notification settings - Fork 0
/
http.go
123 lines (108 loc) · 2.97 KB
/
http.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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package gitlabbot
import (
"fmt"
"io/ioutil"
"net/http"
"strings"
"github.com/malware-unicorn/managed-bots/base/git"
"github.com/xanzy/go-gitlab"
"github.com/malware-unicorn/go-keybase-chat-bot/kbchat"
"github.com/malware-unicorn/managed-bots/base"
)
type HTTPSrv struct {
*base.HTTPSrv
kbc *kbchat.API
db *DB
handler *Handler
secret string
}
func NewHTTPSrv(stats *base.StatsRegistry, kbc *kbchat.API, debugConfig *base.ChatDebugOutputConfig,
db *DB, handler *Handler, secret string) *HTTPSrv {
h := &HTTPSrv{
kbc: kbc,
db: db,
handler: handler,
secret: secret,
}
h.HTTPSrv = base.NewHTTPSrv(stats, debugConfig)
http.HandleFunc("/gitlabbot", h.handleHealthCheck)
http.HandleFunc("/gitlabbot/webhook", h.handleWebhook)
return h
}
func (h *HTTPSrv) handleHealthCheck(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "beep boop! :)")
}
func (h *HTTPSrv) handleWebhook(w http.ResponseWriter, r *http.Request) {
payload, err := ioutil.ReadAll(r.Body)
if err != nil {
h.Errorf("Error reading payload: %s", err)
return
}
defer r.Body.Close()
event, err := gitlab.ParseWebhook(gitlab.WebhookEventType(r), payload)
if err != nil {
h.Errorf("could not parse webhook: type:%v %s\n", gitlab.WebhookEventType(r), err)
return
}
var message, repo string
switch event := event.(type) {
case *gitlab.IssueEvent:
message = git.FormatIssueMsg(
event.ObjectAttributes.Action,
event.User.Username,
event.Project.Name,
event.ObjectAttributes.IID,
event.ObjectAttributes.Title,
event.ObjectAttributes.URL,
)
repo = event.Project.PathWithNamespace
case *gitlab.MergeEvent:
message = git.FormatPullRequestMsg(
git.GITLAB,
event.ObjectAttributes.Action,
event.User.Username,
event.Project.PathWithNamespace,
event.ObjectAttributes.IID,
event.ObjectAttributes.Title,
event.ObjectAttributes.URL,
event.ObjectAttributes.TargetBranch,
)
repo = event.Project.PathWithNamespace
case *gitlab.PushEvent:
if len(event.Commits) == 0 {
break
}
branch := git.RefToName(event.Ref)
commitMsgs := getCommitMessages(event)
lastCommitDiffURL := event.Commits[len(event.Commits)-1].URL
message = git.FormatPushMsg(
event.UserUsername,
event.Project.Name,
branch,
len(event.Commits),
commitMsgs,
lastCommitDiffURL)
repo = event.Project.PathWithNamespace
case *gitlab.PipelineEvent:
repo = event.Project.PathWithNamespace
message = formatPipelineMsg(event, event.User.Username)
}
if message == "" || repo == "" {
return
}
repo = strings.ToLower(repo)
signature := r.Header.Get("X-Gitlab-Token")
convs, err := h.db.GetSubscribedConvs(repo)
if err != nil {
h.Errorf("Error getting subscriptions for repo: %s", err)
return
}
for _, convID := range convs {
var secretToken = base.MakeSecret(repo, convID, h.secret)
if signature != secretToken {
h.Debug("Error validating payload signature for conversation %s: %v", convID, err)
continue
}
h.ChatEcho(convID, message)
}
}