[MM-25713] Adds props check to post import validator (#14728)

* [MM-25713] Adds props check to post import validator

* Fix linter

* Address review comments

Co-authored-by: mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
Miguel de la Cruz
2020-06-08 21:20:40 +02:00
коммит произвёл GitHub
родитель 6cd898fab7
Коммит 457903a12c
4 изменённых файлов: 132 добавлений и 94 удалений

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

@@ -1082,7 +1082,7 @@ func (a *App) importAttachment(data *AttachmentImportData, post *model.Post, tea
} }
fileInfo, appErr := a.DoUploadFile(timestamp, teamId, post.ChannelId, post.UserId, file.Name(), buf.Bytes()) fileInfo, appErr := a.DoUploadFile(timestamp, teamId, post.ChannelId, post.UserId, file.Name(), buf.Bytes())
if appErr != nil { if appErr != nil {
mlog.Error("Failed to upload file:", mlog.Err(err)) mlog.Error("Failed to upload file:", mlog.Err(appErr))
return nil, appErr return nil, appErr
} }

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

@@ -457,6 +457,10 @@ func validatePostImportData(data *PostImportData, maxPostSize int) *model.AppErr
} }
} }
if data.Props != nil && utf8.RuneCountInString(model.StringInterfaceToJson(*data.Props)) > model.POST_PROPS_MAX_RUNES {
return model.NewAppError("BulkImport", "app.import.validate_post_import_data.props_too_large.error", nil, "", http.StatusBadRequest)
}
return nil return nil
} }

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

@@ -895,109 +895,139 @@ func TestImportValidateReplyImportData(t *testing.T) {
func TestImportValidatePostImportData(t *testing.T) { func TestImportValidatePostImportData(t *testing.T) {
maxPostSize := 10000 maxPostSize := 10000
// Test with minimum required valid properties. t.Run("Test with minimum required valid properties", func(t *testing.T) {
data := PostImportData{ data := PostImportData{
Team: ptrStr("teamname"), Team: ptrStr("teamname"),
Channel: ptrStr("channelname"), Channel: ptrStr("channelname"),
User: ptrStr("username"), User: ptrStr("username"),
Message: ptrStr("message"), Message: ptrStr("message"),
CreateAt: ptrInt64(model.GetMillis()), CreateAt: ptrInt64(model.GetMillis()),
} }
err := validatePostImportData(&data, maxPostSize) err := validatePostImportData(&data, maxPostSize)
require.Nil(t, err, "Validation failed but should have been valid.") require.Nil(t, err, "Validation failed but should have been valid.")
})
// Test with missing required properties. t.Run("Test with missing required properties", func(t *testing.T) {
data = PostImportData{ data := PostImportData{
Channel: ptrStr("channelname"), Channel: ptrStr("channelname"),
User: ptrStr("username"), User: ptrStr("username"),
Message: ptrStr("message"), Message: ptrStr("message"),
CreateAt: ptrInt64(model.GetMillis()), CreateAt: ptrInt64(model.GetMillis()),
} }
err = validatePostImportData(&data, maxPostSize) err := validatePostImportData(&data, maxPostSize)
require.NotNil(t, err, "Should have failed due to missing required property.") require.NotNil(t, err, "Should have failed due to missing required property.")
assert.Equal(t, err.Id, "app.import.validate_post_import_data.team_missing.error")
data = PostImportData{ data = PostImportData{
Team: ptrStr("teamname"), Team: ptrStr("teamname"),
User: ptrStr("username"), User: ptrStr("username"),
Message: ptrStr("message"), Message: ptrStr("message"),
CreateAt: ptrInt64(model.GetMillis()), CreateAt: ptrInt64(model.GetMillis()),
} }
err = validatePostImportData(&data, maxPostSize) err = validatePostImportData(&data, maxPostSize)
require.NotNil(t, err, "Should have failed due to missing required property.") require.NotNil(t, err, "Should have failed due to missing required property.")
assert.Equal(t, err.Id, "app.import.validate_post_import_data.channel_missing.error")
data = PostImportData{ data = PostImportData{
Team: ptrStr("teamname"), Team: ptrStr("teamname"),
Channel: ptrStr("channelname"), Channel: ptrStr("channelname"),
Message: ptrStr("message"), Message: ptrStr("message"),
CreateAt: ptrInt64(model.GetMillis()), CreateAt: ptrInt64(model.GetMillis()),
} }
err = validatePostImportData(&data, maxPostSize) err = validatePostImportData(&data, maxPostSize)
require.NotNil(t, err, "Should have failed due to missing required property.") require.NotNil(t, err, "Should have failed due to missing required property.")
assert.Equal(t, err.Id, "app.import.validate_post_import_data.user_missing.error")
data = PostImportData{ data = PostImportData{
Team: ptrStr("teamname"), Team: ptrStr("teamname"),
Channel: ptrStr("channelname"), Channel: ptrStr("channelname"),
User: ptrStr("username"), User: ptrStr("username"),
CreateAt: ptrInt64(model.GetMillis()), CreateAt: ptrInt64(model.GetMillis()),
} }
err = validatePostImportData(&data, maxPostSize) err = validatePostImportData(&data, maxPostSize)
require.NotNil(t, err, "Should have failed due to missing required property.") require.NotNil(t, err, "Should have failed due to missing required property.")
assert.Equal(t, err.Id, "app.import.validate_post_import_data.message_missing.error")
data = PostImportData{ data = PostImportData{
Team: ptrStr("teamname"), Team: ptrStr("teamname"),
Channel: ptrStr("channelname"), Channel: ptrStr("channelname"),
User: ptrStr("username"), User: ptrStr("username"),
Message: ptrStr("message"), Message: ptrStr("message"),
} }
err = validatePostImportData(&data, maxPostSize) err = validatePostImportData(&data, maxPostSize)
require.NotNil(t, err, "Should have failed due to missing required property.") require.NotNil(t, err, "Should have failed due to missing required property.")
assert.Equal(t, err.Id, "app.import.validate_post_import_data.create_at_missing.error")
})
// Test with invalid message. t.Run("Test with invalid message", func(t *testing.T) {
data = PostImportData{ data := PostImportData{
Team: ptrStr("teamname"), Team: ptrStr("teamname"),
Channel: ptrStr("channelname"), Channel: ptrStr("channelname"),
User: ptrStr("username"), User: ptrStr("username"),
Message: ptrStr(strings.Repeat("0", maxPostSize+1)), Message: ptrStr(strings.Repeat("0", maxPostSize+1)),
CreateAt: ptrInt64(model.GetMillis()), CreateAt: ptrInt64(model.GetMillis()),
} }
err = validatePostImportData(&data, maxPostSize) err := validatePostImportData(&data, maxPostSize)
require.NotNil(t, err, "Should have failed due to too long message.") require.NotNil(t, err, "Should have failed due to too long message.")
assert.Equal(t, err.Id, "app.import.validate_post_import_data.message_length.error")
})
// Test with invalid CreateAt t.Run("Test with invalid CreateAt", func(t *testing.T) {
data = PostImportData{ data := PostImportData{
Team: ptrStr("teamname"), Team: ptrStr("teamname"),
Channel: ptrStr("channelname"), Channel: ptrStr("channelname"),
User: ptrStr("username"), User: ptrStr("username"),
Message: ptrStr("message"), Message: ptrStr("message"),
CreateAt: ptrInt64(0), CreateAt: ptrInt64(0),
} }
err = validatePostImportData(&data, maxPostSize) err := validatePostImportData(&data, maxPostSize)
require.NotNil(t, err, "Should have failed due to 0 create-at value.") require.NotNil(t, err, "Should have failed due to 0 create-at value.")
assert.Equal(t, err.Id, "app.import.validate_post_import_data.create_at_zero.error")
})
// Test with valid all optional parameters. t.Run("Test with valid all optional parameters", func(t *testing.T) {
reactions := []ReactionImportData{{ reactions := []ReactionImportData{{
User: ptrStr("username"), User: ptrStr("username"),
EmojiName: ptrStr("emoji"), EmojiName: ptrStr("emoji"),
CreateAt: ptrInt64(model.GetMillis()), CreateAt: ptrInt64(model.GetMillis()),
}} }}
replies := []ReplyImportData{{ replies := []ReplyImportData{{
User: ptrStr("username"), User: ptrStr("username"),
Message: ptrStr("message"), Message: ptrStr("message"),
CreateAt: ptrInt64(model.GetMillis()), CreateAt: ptrInt64(model.GetMillis()),
}} }}
data = PostImportData{ data := PostImportData{
Team: ptrStr("teamname"), Team: ptrStr("teamname"),
Channel: ptrStr("channelname"), Channel: ptrStr("channelname"),
User: ptrStr("username"), User: ptrStr("username"),
Message: ptrStr("message"), Message: ptrStr("message"),
CreateAt: ptrInt64(model.GetMillis()), CreateAt: ptrInt64(model.GetMillis()),
Reactions: &reactions, Reactions: &reactions,
Replies: &replies, Replies: &replies,
} }
err = validatePostImportData(&data, maxPostSize) err := validatePostImportData(&data, maxPostSize)
require.Nil(t, err, "Should have succeeded.") require.Nil(t, err, "Should have succeeded.")
})
t.Run("Test with props too large", func(t *testing.T) {
props := model.StringInterface{
"attachment": strings.Repeat("a", model.POST_PROPS_MAX_RUNES),
}
data := PostImportData{
Team: ptrStr("teamname"),
Channel: ptrStr("channelname"),
User: ptrStr("username"),
Message: ptrStr("message"),
Props: &props,
CreateAt: ptrInt64(model.GetMillis()),
}
err := validatePostImportData(&data, maxPostSize)
require.NotNil(t, err, "Should have failed due to long props.")
assert.Equal(t, err.Id, "app.import.validate_post_import_data.props_too_large.error")
})
} }
func TestImportValidateDirectChannelImportData(t *testing.T) { func TestImportValidateDirectChannelImportData(t *testing.T) {

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

@@ -3370,6 +3370,10 @@
"id": "app.import.validate_post_import_data.message_missing.error", "id": "app.import.validate_post_import_data.message_missing.error",
"translation": "Missing required Post property: Message." "translation": "Missing required Post property: Message."
}, },
{
"id": "app.import.validate_post_import_data.props_too_large.error",
"translation": "Post Props are longer than the maximum permitted length."
},
{ {
"id": "app.import.validate_post_import_data.team_missing.error", "id": "app.import.validate_post_import_data.team_missing.error",
"translation": "Missing required Post property: Team." "translation": "Missing required Post property: Team."