Merge remote-tracking branch 'origin/master' into advanced-permissions-phase-1
Этот коммит содержится в:
@@ -141,7 +141,7 @@ func New(options ...Option) (outApp *App, outErr error) {
|
||||
|
||||
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CONFIG_CHANGED, "", "", "", nil)
|
||||
|
||||
message.Add("config", app.ClientConfigWithNoAccounts())
|
||||
message.Add("config", app.ClientConfigWithComputed())
|
||||
app.Go(func() {
|
||||
app.Publish(message)
|
||||
})
|
||||
|
||||
@@ -273,15 +273,17 @@ func (a *App) GetSiteURL() string {
|
||||
return a.siteURL
|
||||
}
|
||||
|
||||
// ClientConfigWithNoAccounts gets the configuration in a format suitable for sending to the client.
|
||||
func (a *App) ClientConfigWithNoAccounts() map[string]string {
|
||||
// ClientConfigWithComputed gets the configuration in a format suitable for sending to the client.
|
||||
func (a *App) ClientConfigWithComputed() map[string]string {
|
||||
respCfg := map[string]string{}
|
||||
for k, v := range a.ClientConfig() {
|
||||
respCfg[k] = v
|
||||
}
|
||||
|
||||
// NoAccounts is not actually part of the configuration, but is expected by the client.
|
||||
// These properties are not configurable, but nevertheless represent configuration expected
|
||||
// by the client.
|
||||
respCfg["NoAccounts"] = strconv.FormatBool(a.IsFirstUserAccount())
|
||||
respCfg["MaxPostSize"] = strconv.Itoa(a.MaxPostSize())
|
||||
|
||||
return respCfg
|
||||
}
|
||||
|
||||
@@ -64,12 +64,15 @@ func TestAsymmetricSigningKey(t *testing.T) {
|
||||
assert.NotEmpty(t, th.App.ClientConfig()["AsymmetricSigningPublicKey"])
|
||||
}
|
||||
|
||||
func TestClientConfigWithNoAccounts(t *testing.T) {
|
||||
func TestClientConfigWithComputed(t *testing.T) {
|
||||
th := Setup().InitBasic()
|
||||
defer th.TearDown()
|
||||
|
||||
config := th.App.ClientConfigWithNoAccounts()
|
||||
config := th.App.ClientConfigWithComputed()
|
||||
if _, ok := config["NoAccounts"]; !ok {
|
||||
t.Fatal("expected NoAccounts in returned config")
|
||||
}
|
||||
if _, ok := config["MaxPostSize"]; !ok {
|
||||
t.Fatal("expected MaxPostSize in returned config")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1086,7 +1086,7 @@ func (a *App) ImportReaction(data *ReactionImportData, post *model.Post, dryRun
|
||||
}
|
||||
|
||||
func (a *App) ImportReply(data *ReplyImportData, post *model.Post, dryRun bool) *model.AppError {
|
||||
if err := validateReplyImportData(data, post.CreateAt); err != nil {
|
||||
if err := validateReplyImportData(data, post.CreateAt, a.MaxPostSize()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1136,7 +1136,7 @@ func (a *App) ImportReply(data *ReplyImportData, post *model.Post, dryRun bool)
|
||||
}
|
||||
|
||||
func (a *App) ImportPost(data *PostImportData, dryRun bool) *model.AppError {
|
||||
if err := validatePostImportData(data); err != nil {
|
||||
if err := validatePostImportData(data, a.MaxPostSize()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1271,14 +1271,14 @@ func validateReactionImportData(data *ReactionImportData, parentCreateAt int64)
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateReplyImportData(data *ReplyImportData, parentCreateAt int64) *model.AppError {
|
||||
func validateReplyImportData(data *ReplyImportData, parentCreateAt int64, maxPostSize int) *model.AppError {
|
||||
if data.User == nil {
|
||||
return model.NewAppError("BulkImport", "app.import.validate_reply_import_data.user_missing.error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if data.Message == nil {
|
||||
return model.NewAppError("BulkImport", "app.import.validate_reply_import_data.message_missing.error", nil, "", http.StatusBadRequest)
|
||||
} else if utf8.RuneCountInString(*data.Message) > model.POST_MESSAGE_MAX_RUNES {
|
||||
} else if utf8.RuneCountInString(*data.Message) > maxPostSize {
|
||||
return model.NewAppError("BulkImport", "app.import.validate_reply_import_data.message_length.error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
@@ -1293,7 +1293,7 @@ func validateReplyImportData(data *ReplyImportData, parentCreateAt int64) *model
|
||||
return nil
|
||||
}
|
||||
|
||||
func validatePostImportData(data *PostImportData) *model.AppError {
|
||||
func validatePostImportData(data *PostImportData, maxPostSize int) *model.AppError {
|
||||
if data.Team == nil {
|
||||
return model.NewAppError("BulkImport", "app.import.validate_post_import_data.team_missing.error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
@@ -1308,7 +1308,7 @@ func validatePostImportData(data *PostImportData) *model.AppError {
|
||||
|
||||
if data.Message == nil {
|
||||
return model.NewAppError("BulkImport", "app.import.validate_post_import_data.message_missing.error", nil, "", http.StatusBadRequest)
|
||||
} else if utf8.RuneCountInString(*data.Message) > model.POST_MESSAGE_MAX_RUNES {
|
||||
} else if utf8.RuneCountInString(*data.Message) > maxPostSize {
|
||||
return model.NewAppError("BulkImport", "app.import.validate_post_import_data.message_length.error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
@@ -1326,7 +1326,7 @@ func validatePostImportData(data *PostImportData) *model.AppError {
|
||||
|
||||
if data.Replies != nil {
|
||||
for _, reply := range *data.Replies {
|
||||
validateReplyImportData(&reply, *data.CreateAt)
|
||||
validateReplyImportData(&reply, *data.CreateAt, maxPostSize)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1446,7 +1446,7 @@ func validateDirectChannelImportData(data *DirectChannelImportData) *model.AppEr
|
||||
}
|
||||
|
||||
func (a *App) ImportDirectPost(data *DirectPostImportData, dryRun bool) *model.AppError {
|
||||
if err := validateDirectPostImportData(data); err != nil {
|
||||
if err := validateDirectPostImportData(data, a.MaxPostSize()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1572,7 +1572,7 @@ func (a *App) ImportDirectPost(data *DirectPostImportData, dryRun bool) *model.A
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateDirectPostImportData(data *DirectPostImportData) *model.AppError {
|
||||
func validateDirectPostImportData(data *DirectPostImportData, maxPostSize int) *model.AppError {
|
||||
if data.ChannelMembers == nil {
|
||||
return model.NewAppError("BulkImport", "app.import.validate_direct_post_import_data.channel_members_required.error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
@@ -1591,7 +1591,7 @@ func validateDirectPostImportData(data *DirectPostImportData) *model.AppError {
|
||||
|
||||
if data.Message == nil {
|
||||
return model.NewAppError("BulkImport", "app.import.validate_direct_post_import_data.message_missing.error", nil, "", http.StatusBadRequest)
|
||||
} else if utf8.RuneCountInString(*data.Message) > model.POST_MESSAGE_MAX_RUNES {
|
||||
} else if utf8.RuneCountInString(*data.Message) > maxPostSize {
|
||||
return model.NewAppError("BulkImport", "app.import.validate_direct_post_import_data.message_length.error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
@@ -1624,7 +1624,7 @@ func validateDirectPostImportData(data *DirectPostImportData) *model.AppError {
|
||||
|
||||
if data.Replies != nil {
|
||||
for _, reply := range *data.Replies {
|
||||
validateReplyImportData(&reply, *data.CreateAt)
|
||||
validateReplyImportData(&reply, *data.CreateAt, maxPostSize)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1640,12 +1640,13 @@ func validateDirectPostImportData(data *DirectPostImportData) *model.AppError {
|
||||
func (a *App) OldImportPost(post *model.Post) {
|
||||
// Workaround for empty messages, which may be the case if they are webhook posts.
|
||||
firstIteration := true
|
||||
maxPostSize := a.MaxPostSize()
|
||||
for messageRuneCount := utf8.RuneCountInString(post.Message); messageRuneCount > 0 || firstIteration; messageRuneCount = utf8.RuneCountInString(post.Message) {
|
||||
firstIteration = false
|
||||
var remainder string
|
||||
if messageRuneCount > model.POST_MESSAGE_MAX_RUNES {
|
||||
remainder = string(([]rune(post.Message))[model.POST_MESSAGE_MAX_RUNES:])
|
||||
post.Message = truncateRunes(post.Message, model.POST_MESSAGE_MAX_RUNES)
|
||||
if messageRuneCount > maxPostSize {
|
||||
remainder = string(([]rune(post.Message))[maxPostSize:])
|
||||
post.Message = truncateRunes(post.Message, maxPostSize)
|
||||
} else {
|
||||
remainder = ""
|
||||
}
|
||||
|
||||
@@ -628,12 +628,13 @@ func TestImportValidateReactionImportData(t *testing.T) {
|
||||
func TestImportValidateReplyImportData(t *testing.T) {
|
||||
// Test with minimum required valid properties.
|
||||
parentCreateAt := model.GetMillis() - 100
|
||||
maxPostSize := 10000
|
||||
data := ReplyImportData{
|
||||
User: ptrStr("username"),
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validateReplyImportData(&data, parentCreateAt); err != nil {
|
||||
if err := validateReplyImportData(&data, parentCreateAt, maxPostSize); err != nil {
|
||||
t.Fatal("Validation failed but should have been valid.")
|
||||
}
|
||||
|
||||
@@ -642,7 +643,7 @@ func TestImportValidateReplyImportData(t *testing.T) {
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validateReplyImportData(&data, parentCreateAt); err == nil {
|
||||
if err := validateReplyImportData(&data, parentCreateAt, maxPostSize); err == nil {
|
||||
t.Fatal("Should have failed due to missing required property.")
|
||||
}
|
||||
|
||||
@@ -650,7 +651,7 @@ func TestImportValidateReplyImportData(t *testing.T) {
|
||||
User: ptrStr("username"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validateReplyImportData(&data, parentCreateAt); err == nil {
|
||||
if err := validateReplyImportData(&data, parentCreateAt, maxPostSize); err == nil {
|
||||
t.Fatal("Should have failed due to missing required property.")
|
||||
}
|
||||
|
||||
@@ -658,17 +659,17 @@ func TestImportValidateReplyImportData(t *testing.T) {
|
||||
User: ptrStr("username"),
|
||||
Message: ptrStr("message"),
|
||||
}
|
||||
if err := validateReplyImportData(&data, parentCreateAt); err == nil {
|
||||
if err := validateReplyImportData(&data, parentCreateAt, maxPostSize); err == nil {
|
||||
t.Fatal("Should have failed due to missing required property.")
|
||||
}
|
||||
|
||||
// Test with invalid message.
|
||||
data = ReplyImportData{
|
||||
User: ptrStr("username"),
|
||||
Message: ptrStr(strings.Repeat("1234567890", 500)),
|
||||
Message: ptrStr(strings.Repeat("0", maxPostSize+1)),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validateReplyImportData(&data, parentCreateAt); err == nil {
|
||||
if err := validateReplyImportData(&data, parentCreateAt, maxPostSize); err == nil {
|
||||
t.Fatal("Should have failed due to too long message.")
|
||||
}
|
||||
|
||||
@@ -678,7 +679,7 @@ func TestImportValidateReplyImportData(t *testing.T) {
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(0),
|
||||
}
|
||||
if err := validateReplyImportData(&data, parentCreateAt); err == nil {
|
||||
if err := validateReplyImportData(&data, parentCreateAt, maxPostSize); err == nil {
|
||||
t.Fatal("Should have failed due to 0 create-at value.")
|
||||
}
|
||||
|
||||
@@ -687,12 +688,13 @@ func TestImportValidateReplyImportData(t *testing.T) {
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(parentCreateAt - 100),
|
||||
}
|
||||
if err := validateReplyImportData(&data, parentCreateAt); err == nil {
|
||||
if err := validateReplyImportData(&data, parentCreateAt, maxPostSize); err == nil {
|
||||
t.Fatal("Should have failed due parent with newer create-at value.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestImportValidatePostImportData(t *testing.T) {
|
||||
maxPostSize := 10000
|
||||
|
||||
// Test with minimum required valid properties.
|
||||
data := PostImportData{
|
||||
@@ -702,7 +704,7 @@ func TestImportValidatePostImportData(t *testing.T) {
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validatePostImportData(&data); err != nil {
|
||||
if err := validatePostImportData(&data, maxPostSize); err != nil {
|
||||
t.Fatal("Validation failed but should have been valid.")
|
||||
}
|
||||
|
||||
@@ -713,7 +715,7 @@ func TestImportValidatePostImportData(t *testing.T) {
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validatePostImportData(&data); err == nil {
|
||||
if err := validatePostImportData(&data, maxPostSize); err == nil {
|
||||
t.Fatal("Should have failed due to missing required property.")
|
||||
}
|
||||
|
||||
@@ -723,7 +725,7 @@ func TestImportValidatePostImportData(t *testing.T) {
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validatePostImportData(&data); err == nil {
|
||||
if err := validatePostImportData(&data, maxPostSize); err == nil {
|
||||
t.Fatal("Should have failed due to missing required property.")
|
||||
}
|
||||
|
||||
@@ -733,7 +735,7 @@ func TestImportValidatePostImportData(t *testing.T) {
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validatePostImportData(&data); err == nil {
|
||||
if err := validatePostImportData(&data, maxPostSize); err == nil {
|
||||
t.Fatal("Should have failed due to missing required property.")
|
||||
}
|
||||
|
||||
@@ -743,7 +745,7 @@ func TestImportValidatePostImportData(t *testing.T) {
|
||||
User: ptrStr("username"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validatePostImportData(&data); err == nil {
|
||||
if err := validatePostImportData(&data, maxPostSize); err == nil {
|
||||
t.Fatal("Should have failed due to missing required property.")
|
||||
}
|
||||
|
||||
@@ -753,7 +755,7 @@ func TestImportValidatePostImportData(t *testing.T) {
|
||||
User: ptrStr("username"),
|
||||
Message: ptrStr("message"),
|
||||
}
|
||||
if err := validatePostImportData(&data); err == nil {
|
||||
if err := validatePostImportData(&data, maxPostSize); err == nil {
|
||||
t.Fatal("Should have failed due to missing required property.")
|
||||
}
|
||||
|
||||
@@ -762,10 +764,10 @@ func TestImportValidatePostImportData(t *testing.T) {
|
||||
Team: ptrStr("teamname"),
|
||||
Channel: ptrStr("channelname"),
|
||||
User: ptrStr("username"),
|
||||
Message: ptrStr(strings.Repeat("1234567890", 500)),
|
||||
Message: ptrStr(strings.Repeat("0", maxPostSize+1)),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validatePostImportData(&data); err == nil {
|
||||
if err := validatePostImportData(&data, maxPostSize); err == nil {
|
||||
t.Fatal("Should have failed due to too long message.")
|
||||
}
|
||||
|
||||
@@ -777,7 +779,7 @@ func TestImportValidatePostImportData(t *testing.T) {
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(0),
|
||||
}
|
||||
if err := validatePostImportData(&data); err == nil {
|
||||
if err := validatePostImportData(&data, maxPostSize); err == nil {
|
||||
t.Fatal("Should have failed due to 0 create-at value.")
|
||||
}
|
||||
|
||||
@@ -801,7 +803,7 @@ func TestImportValidatePostImportData(t *testing.T) {
|
||||
Reactions: &reactions,
|
||||
Replies: &replies,
|
||||
}
|
||||
if err := validatePostImportData(&data); err != nil {
|
||||
if err := validatePostImportData(&data, maxPostSize); err != nil {
|
||||
t.Fatal("Should have succeeded.")
|
||||
}
|
||||
}
|
||||
@@ -917,6 +919,7 @@ func TestImportValidateDirectChannelImportData(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestImportValidateDirectPostImportData(t *testing.T) {
|
||||
maxPostSize := 10000
|
||||
|
||||
// Test with minimum required valid properties.
|
||||
data := DirectPostImportData{
|
||||
@@ -928,7 +931,7 @@ func TestImportValidateDirectPostImportData(t *testing.T) {
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validateDirectPostImportData(&data); err != nil {
|
||||
if err := validateDirectPostImportData(&data, maxPostSize); err != nil {
|
||||
t.Fatal("Validation failed but should have been valid.")
|
||||
}
|
||||
|
||||
@@ -938,7 +941,7 @@ func TestImportValidateDirectPostImportData(t *testing.T) {
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validateDirectPostImportData(&data); err == nil {
|
||||
if err := validateDirectPostImportData(&data, maxPostSize); err == nil {
|
||||
t.Fatal("Should have failed due to missing required property.")
|
||||
}
|
||||
|
||||
@@ -950,7 +953,7 @@ func TestImportValidateDirectPostImportData(t *testing.T) {
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validateDirectPostImportData(&data); err == nil {
|
||||
if err := validateDirectPostImportData(&data, maxPostSize); err == nil {
|
||||
t.Fatal("Should have failed due to missing required property.")
|
||||
}
|
||||
|
||||
@@ -962,7 +965,7 @@ func TestImportValidateDirectPostImportData(t *testing.T) {
|
||||
User: ptrStr("username"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validateDirectPostImportData(&data); err == nil {
|
||||
if err := validateDirectPostImportData(&data, maxPostSize); err == nil {
|
||||
t.Fatal("Should have failed due to missing required property.")
|
||||
}
|
||||
|
||||
@@ -974,7 +977,7 @@ func TestImportValidateDirectPostImportData(t *testing.T) {
|
||||
User: ptrStr("username"),
|
||||
Message: ptrStr("message"),
|
||||
}
|
||||
if err := validateDirectPostImportData(&data); err == nil {
|
||||
if err := validateDirectPostImportData(&data, maxPostSize); err == nil {
|
||||
t.Fatal("Should have failed due to missing required property.")
|
||||
}
|
||||
|
||||
@@ -985,7 +988,7 @@ func TestImportValidateDirectPostImportData(t *testing.T) {
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validateDirectPostImportData(&data); err == nil {
|
||||
if err := validateDirectPostImportData(&data, maxPostSize); err == nil {
|
||||
t.Fatal("Should have failed due to unsuitable number of members.")
|
||||
}
|
||||
|
||||
@@ -997,7 +1000,7 @@ func TestImportValidateDirectPostImportData(t *testing.T) {
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validateDirectPostImportData(&data); err == nil {
|
||||
if err := validateDirectPostImportData(&data, maxPostSize); err == nil {
|
||||
t.Fatal("Should have failed due to unsuitable number of members.")
|
||||
}
|
||||
|
||||
@@ -1018,7 +1021,7 @@ func TestImportValidateDirectPostImportData(t *testing.T) {
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validateDirectPostImportData(&data); err == nil {
|
||||
if err := validateDirectPostImportData(&data, maxPostSize); err == nil {
|
||||
t.Fatal("Should have failed due to unsuitable number of members.")
|
||||
}
|
||||
|
||||
@@ -1033,7 +1036,7 @@ func TestImportValidateDirectPostImportData(t *testing.T) {
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validateDirectPostImportData(&data); err != nil {
|
||||
if err := validateDirectPostImportData(&data, maxPostSize); err != nil {
|
||||
t.Fatal("Validation failed but should have been valid.")
|
||||
}
|
||||
|
||||
@@ -1044,10 +1047,10 @@ func TestImportValidateDirectPostImportData(t *testing.T) {
|
||||
model.NewId(),
|
||||
},
|
||||
User: ptrStr("username"),
|
||||
Message: ptrStr(strings.Repeat("1234567890", 500)),
|
||||
Message: ptrStr(strings.Repeat("0", maxPostSize+1)),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validateDirectPostImportData(&data); err == nil {
|
||||
if err := validateDirectPostImportData(&data, maxPostSize); err == nil {
|
||||
t.Fatal("Should have failed due to too long message.")
|
||||
}
|
||||
|
||||
@@ -1061,7 +1064,7 @@ func TestImportValidateDirectPostImportData(t *testing.T) {
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(0),
|
||||
}
|
||||
if err := validateDirectPostImportData(&data); err == nil {
|
||||
if err := validateDirectPostImportData(&data, maxPostSize); err == nil {
|
||||
t.Fatal("Should have failed due to 0 create-at value.")
|
||||
}
|
||||
|
||||
@@ -1081,7 +1084,7 @@ func TestImportValidateDirectPostImportData(t *testing.T) {
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validateDirectPostImportData(&data); err == nil {
|
||||
if err := validateDirectPostImportData(&data, maxPostSize); err == nil {
|
||||
t.Fatal("Validation should have failed due to non-member flagged.")
|
||||
}
|
||||
|
||||
@@ -1099,7 +1102,7 @@ func TestImportValidateDirectPostImportData(t *testing.T) {
|
||||
Message: ptrStr("message"),
|
||||
CreateAt: ptrInt64(model.GetMillis()),
|
||||
}
|
||||
if err := validateDirectPostImportData(&data); err != nil {
|
||||
if err := validateDirectPostImportData(&data, maxPostSize); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -1130,7 +1133,7 @@ func TestImportValidateDirectPostImportData(t *testing.T) {
|
||||
Replies: &replies,
|
||||
}
|
||||
|
||||
if err := validateDirectPostImportData(&data); err != nil {
|
||||
if err := validateDirectPostImportData(&data, maxPostSize); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
11
app/post.go
11
app/post.go
@@ -958,3 +958,14 @@ func (a *App) ImageProxyRemover() (f func(string) string) {
|
||||
return url
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) MaxPostSize() int {
|
||||
maxPostSize := model.POST_MESSAGE_MAX_RUNES_V1
|
||||
if result := <-a.Srv.Store.Post().GetMaxPostSize(); result.Err != nil {
|
||||
l4g.Error(result.Err)
|
||||
} else {
|
||||
maxPostSize = result.Data.(int)
|
||||
}
|
||||
|
||||
return maxPostSize
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -17,6 +18,8 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/mattermost/mattermost-server/model"
|
||||
"github.com/mattermost/mattermost-server/store"
|
||||
"github.com/mattermost/mattermost-server/store/storetest"
|
||||
)
|
||||
|
||||
func TestUpdatePostEditAt(t *testing.T) {
|
||||
@@ -383,3 +386,59 @@ func TestMakeOpenGraphURLsAbsolute(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMaxPostSize(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := []struct {
|
||||
Description string
|
||||
StoreMaxPostSize int
|
||||
ExpectedMaxPostSize int
|
||||
ExpectedError *model.AppError
|
||||
}{
|
||||
{
|
||||
"error fetching max post size",
|
||||
0,
|
||||
model.POST_MESSAGE_MAX_RUNES_V1,
|
||||
model.NewAppError("TestMaxPostSize", "this is an error", nil, "", http.StatusBadRequest),
|
||||
},
|
||||
{
|
||||
"4000 rune limit",
|
||||
4000,
|
||||
4000,
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"16383 rune limit",
|
||||
16383,
|
||||
16383,
|
||||
nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run(testCase.Description, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
mockStore := &storetest.Store{}
|
||||
defer mockStore.AssertExpectations(t)
|
||||
|
||||
mockStore.PostStore.On("GetMaxPostSize").Return(
|
||||
storetest.NewStoreChannel(store.StoreResult{
|
||||
Data: testCase.StoreMaxPostSize,
|
||||
Err: testCase.ExpectedError,
|
||||
}),
|
||||
)
|
||||
|
||||
app := App{
|
||||
Srv: &Server{
|
||||
Store: mockStore,
|
||||
},
|
||||
config: atomic.Value{},
|
||||
}
|
||||
|
||||
assert.Equal(t, testCase.ExpectedMaxPostSize, app.MaxPostSize())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ package app
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
@@ -149,8 +150,10 @@ func (a *App) StartServer() error {
|
||||
}
|
||||
|
||||
if *a.Config().ServiceSettings.Forward80To443 {
|
||||
if host, _, err := net.SplitHostPort(addr); err != nil {
|
||||
if host, port, err := net.SplitHostPort(addr); err != nil {
|
||||
l4g.Error("Unable to setup forwarding: " + err.Error())
|
||||
} else if port != "443" {
|
||||
return fmt.Errorf(utils.T("api.server.start_server.forward80to443.enabled_but_listening_on_wrong_port"), port)
|
||||
} else {
|
||||
httpListenAddress := net.JoinHostPort(host, "http")
|
||||
|
||||
@@ -169,6 +172,8 @@ func (a *App) StartServer() error {
|
||||
}()
|
||||
}
|
||||
}
|
||||
} else if *a.Config().ServiceSettings.UseLetsEncrypt {
|
||||
return errors.New(utils.T("api.server.start_server.forward80to443.disabled_while_using_lets_encrypt"))
|
||||
}
|
||||
|
||||
a.Srv.didFinishListen = make(chan struct{})
|
||||
|
||||
@@ -940,6 +940,8 @@ func (a *App) UpdateActive(user *model.User, active bool) (*model.User, *model.A
|
||||
}
|
||||
}
|
||||
|
||||
a.sendUpdatedUserEvent(*ruser, false)
|
||||
|
||||
return ruser, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ func (a *App) TriggerWebhook(payload *model.OutgoingWebhookPayload, hook *model.
|
||||
}
|
||||
}
|
||||
|
||||
func SplitWebhookPost(post *model.Post) ([]*model.Post, *model.AppError) {
|
||||
func SplitWebhookPost(post *model.Post, maxPostSize int) ([]*model.Post, *model.AppError) {
|
||||
splits := make([]*model.Post, 0)
|
||||
remainingText := post.Message
|
||||
|
||||
@@ -159,12 +159,12 @@ func SplitWebhookPost(post *model.Post) ([]*model.Post, *model.AppError) {
|
||||
return nil, model.NewAppError("SplitWebhookPost", "web.incoming_webhook.split_props_length.app_error", map[string]interface{}{"Max": model.POST_PROPS_MAX_USER_RUNES}, "", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
for utf8.RuneCountInString(remainingText) > model.POST_MESSAGE_MAX_RUNES {
|
||||
for utf8.RuneCountInString(remainingText) > maxPostSize {
|
||||
split := base
|
||||
x := 0
|
||||
for index := range remainingText {
|
||||
x++
|
||||
if x > model.POST_MESSAGE_MAX_RUNES {
|
||||
if x > maxPostSize {
|
||||
split.Message = remainingText[:index]
|
||||
remainingText = remainingText[index:]
|
||||
break
|
||||
@@ -266,7 +266,7 @@ func (a *App) CreateWebhookPost(userId string, channel *model.Channel, text, ove
|
||||
}
|
||||
}
|
||||
|
||||
splits, err := SplitWebhookPost(post)
|
||||
splits, err := SplitWebhookPost(post, a.MaxPostSize())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -383,23 +383,25 @@ func TestSplitWebhookPost(t *testing.T) {
|
||||
Expected []*model.Post
|
||||
}
|
||||
|
||||
maxPostSize := 10000
|
||||
|
||||
for name, tc := range map[string]TestCase{
|
||||
"LongPost": {
|
||||
Post: &model.Post{
|
||||
Message: strings.Repeat("本", model.POST_MESSAGE_MAX_RUNES*3/2),
|
||||
Message: strings.Repeat("本", maxPostSize*3/2),
|
||||
},
|
||||
Expected: []*model.Post{
|
||||
{
|
||||
Message: strings.Repeat("本", model.POST_MESSAGE_MAX_RUNES),
|
||||
Message: strings.Repeat("本", maxPostSize),
|
||||
},
|
||||
{
|
||||
Message: strings.Repeat("本", model.POST_MESSAGE_MAX_RUNES/2),
|
||||
Message: strings.Repeat("本", maxPostSize/2),
|
||||
},
|
||||
},
|
||||
},
|
||||
"LongPostAndMultipleAttachments": {
|
||||
Post: &model.Post{
|
||||
Message: strings.Repeat("本", model.POST_MESSAGE_MAX_RUNES*3/2),
|
||||
Message: strings.Repeat("本", maxPostSize*3/2),
|
||||
Props: map[string]interface{}{
|
||||
"attachments": []*model.SlackAttachment{
|
||||
&model.SlackAttachment{
|
||||
@@ -416,10 +418,10 @@ func TestSplitWebhookPost(t *testing.T) {
|
||||
},
|
||||
Expected: []*model.Post{
|
||||
{
|
||||
Message: strings.Repeat("本", model.POST_MESSAGE_MAX_RUNES),
|
||||
Message: strings.Repeat("本", maxPostSize),
|
||||
},
|
||||
{
|
||||
Message: strings.Repeat("本", model.POST_MESSAGE_MAX_RUNES/2),
|
||||
Message: strings.Repeat("本", maxPostSize/2),
|
||||
Props: map[string]interface{}{
|
||||
"attachments": []*model.SlackAttachment{
|
||||
&model.SlackAttachment{
|
||||
@@ -452,7 +454,7 @@ func TestSplitWebhookPost(t *testing.T) {
|
||||
},
|
||||
} {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
splits, err := SplitWebhookPost(tc.Post)
|
||||
splits, err := SplitWebhookPost(tc.Post, maxPostSize)
|
||||
if tc.Expected == nil {
|
||||
require.NotNil(t, err)
|
||||
} else {
|
||||
|
||||
Ссылка в новой задаче
Block a user