-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathslack_util.go
68 lines (53 loc) · 1.76 KB
/
slack_util.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 main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"errors"
"gorm.io/gorm"
"io/ioutil"
"net/http"
"strconv"
"time"
)
var didWarnUnverifiedRequests = false
func verifyRequest(r *http.Request) ([]byte, error) {
requestBody, err := ioutil.ReadAll(r.Body)
if err != nil {
return nil, err
}
if SlackSigningSecret == "" {
if !didWarnUnverifiedRequests {
log.Warning("The BAGEL_SLACK_SIGNING_SECRET environment variable is empty; requests will not be verified")
didWarnUnverifiedRequests = true
}
return requestBody, nil
}
timestamp := r.Header.Get("X-Slack-Request-Timestamp")
timestampInt, err := strconv.ParseInt(timestamp, 10, 64)
if err != nil {
return nil, err
}
now := time.Now().Unix()
if timestampInt > now {
return nil, errors.New("request has a timestamp in the future")
}
var maxTimestampDifference int64 = 60
if now-timestampInt > maxTimestampDifference {
return nil, errors.New("request is more than " + strconv.FormatInt(maxTimestampDifference, 10) + " seconds in the past")
}
signatureBasestring := "v0:" + timestamp + ":" + string(requestBody)
h := hmac.New(sha256.New, []byte(SlackSigningSecret))
h.Write([]byte(signatureBasestring))
hexDigest := "v0=" + hex.EncodeToString(h.Sum(nil))
slackSignature := r.Header.Get("X-Slack-Signature")
if !hmac.Equal([]byte(hexDigest), []byte(slackSignature)) {
return nil, errors.New("computed signature and slack signature are not the same; possible malicious slack event")
}
return requestBody, nil
}
func SlackListenAndServe(db *gorm.DB, slack *Slack) {
http.Handle("/slack/action-event", SlackEventHandler{DB: db, Slack: slack})
http.Handle("/slack/interactive-endpoint", SlackInteractiveHandler{DB: db, Slack: slack})
log.Fatal(http.ListenAndServe(":29139", nil))
}