-
Notifications
You must be signed in to change notification settings - Fork 2
/
payload.go
89 lines (76 loc) · 2.45 KB
/
payload.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
package slackcmd
import (
"errors"
"net/url"
"github.com/spf13/viper"
)
// Payload contains all information that Slack post to server
type Payload struct {
Token string
TeamID string
TeamDomain string
ChannelID string
ChannelName string
UserID string
UserName string
Command string
Text string
}
// IsPrivateGroup return true if command comes from a private group
func (p *Payload) IsPrivateGroup() bool {
return p.ChannelName == "privategroup"
}
// IsValid return true if payload is valid, otherwise return false;
// Required fields: Token, Command, ChannelName, ChannelID.
func (p *Payload) IsValid() bool {
return p.Token != "" &&
p.ChannelName != "" &&
p.ChannelID != "" &&
p.Command != ""
}
// newPayloadByForm create payload from post/get form from request
func newPayloadByForm(form url.Values) *Payload {
return &Payload{
Token: form.Get("token"),
TeamID: form.Get("team_id"),
TeamDomain: form.Get("team_domain"),
ChannelID: form.Get("channel_id"),
ChannelName: form.Get("channel_name"),
UserID: form.Get("user_id"),
UserName: form.Get("user_name"),
Command: form.Get("command"),
Text: form.Get("text"),
}
}
// PayloadValidator define interface which will be used to verify payload
type PayloadValidator interface {
// Validate payload return nil if payload is valid, otherwise return an error
Validate(payload *Payload) error
}
// NewTokenValidator return an implement of PayloadValidator,
// TokenValidator will check if token sent by Slack Commands are match with token that in configuration.
//
// Token in configuration will be load by Viper (github.com/spf13/viper) at key `slackcmd.tokens`,
// that key should be a map of comand and token, check `config.yml.dist` in package example.
//
// If token was not configured, then the payload is always valid with any token.
func NewTokenValidator() PayloadValidator {
return &tokenValidator{}
}
var (
// ErrTokenInvalid return when validate token failed
ErrTokenInvalid = errors.New("token is invalid")
)
// tokenValidator used to validate token of Slack payload
type tokenValidator struct{}
// Validate token of Slack payload with configured token in app
func (t *tokenValidator) Validate(payload *Payload) error {
tokens := viper.GetStringMapString("slackcmd.tokens")
command := payload.Command[1:]
if token, found := tokens[command]; found {
if token != payload.Token {
return ErrTokenInvalid
}
}
return nil
}