PLT-2170 Send payload in application/json for outgoing webhooks (#3160)

* Send payload in application/json for outgoing webhooks

The Add outgoing webhook UI now has a 'Content-Type' field that allows
to choose between application/x-www-form-urlencoded and
application/json. All outgoing webhooks created before this change will
be considered as x-www-form-urlencoded. There's also a minor change in
the way the outgoing webhook summary is displayed: the 'Callback URLs'
label was missing.

* Fix JS formatting errors

* Increase ContentType field length to 128
Этот коммит содержится в:
Thomas Balthazar
2016-05-31 16:51:28 +02:00
коммит произвёл Christopher Speller
родитель 8f984771ae
Коммит c226cabc04
8 изменённых файлов: 250 добавлений и 109 удалений

Просмотреть файл

@@ -7,6 +7,8 @@ import (
"encoding/json"
"fmt"
"io"
"net/url"
"strconv"
)
type OutgoingWebhook struct {
@@ -22,6 +24,47 @@ type OutgoingWebhook struct {
CallbackURLs StringArray `json:"callback_urls"`
DisplayName string `json:"display_name"`
Description string `json:"description"`
ContentType string `json:"content_type"`
}
type OutgoingWebhookPayload struct {
Token string `json:"token"`
TeamId string `json:"team_id"`
TeamDomain string `json:"team_domain"`
ChannelId string `json:"channel_id"`
ChannelName string `json:"channel_name"`
Timestamp int64 `json:"timestamp"`
UserId string `json:"user_id"`
UserName string `json:"user_name"`
PostId string `json:"post_id"`
Text string `json:"text"`
TriggerWord string `json:"trigger_word"`
}
func (o *OutgoingWebhookPayload) ToJSON() string {
b, err := json.Marshal(o)
if err != nil {
return ""
} else {
return string(b)
}
}
func (o *OutgoingWebhookPayload) ToFormValues() string {
v := url.Values{}
v.Set("token", o.Token)
v.Set("team_id", o.TeamId)
v.Set("team_domain", o.TeamDomain)
v.Set("channel_id", o.ChannelId)
v.Set("channel_name", o.ChannelName)
v.Set("timestamp", strconv.FormatInt(o.Timestamp/1000, 10))
v.Set("user_id", o.UserId)
v.Set("user_name", o.UserName)
v.Set("post_id", o.PostId)
v.Set("text", o.Text)
v.Set("trigger_word", o.TriggerWord)
return v.Encode()
}
func (o *OutgoingWebhook) ToJson() string {
@@ -124,6 +167,10 @@ func (o *OutgoingWebhook) IsValid() *AppError {
return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.description.app_error", nil, "")
}
if len(o.ContentType) > 128 {
return NewLocAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.content_type.app_error", nil, "")
}
return nil
}

Просмотреть файл

@@ -4,6 +4,8 @@
package model
import (
"net/url"
"reflect"
"strings"
"testing"
)
@@ -107,8 +109,49 @@ func TestOutgoingWebhookIsValid(t *testing.T) {
o.Description = strings.Repeat("1", 128)
if err := o.IsValid(); err != nil {
t.Fatal("should be invalid")
}
o.ContentType = strings.Repeat("1", 129)
if err := o.IsValid(); err == nil {
t.Fatal(err)
}
o.ContentType = strings.Repeat("1", 128)
if err := o.IsValid(); err != nil {
t.Fatal(err)
}
}
func TestOutgoingWebhookPayloadToFormValues(t *testing.T) {
p := &OutgoingWebhookPayload{
Token: "Token",
TeamId: "TeamId",
TeamDomain: "TeamDomain",
ChannelId: "ChannelId",
ChannelName: "ChannelName",
Timestamp: 123000,
UserId: "UserId",
UserName: "UserName",
PostId: "PostId",
Text: "Text",
TriggerWord: "TriggerWord",
}
v := url.Values{}
v.Set("token", "Token")
v.Set("team_id", "TeamId")
v.Set("team_domain", "TeamDomain")
v.Set("channel_id", "ChannelId")
v.Set("channel_name", "ChannelName")
v.Set("timestamp", "123")
v.Set("user_id", "UserId")
v.Set("user_name", "UserName")
v.Set("post_id", "PostId")
v.Set("text", "Text")
v.Set("trigger_word", "TriggerWord")
if got, want := p.ToFormValues(), v.Encode(); !reflect.DeepEqual(got, want) {
t.Fatalf("Got %+v, wanted %+v", got, want)
}
}
func TestOutgoingWebhookPreSave(t *testing.T) {