[MM-54730] Don't use old hardcoded rule for validating imported posts (#25823)

* don't use old hardcoded rule for validating imported posts

* fix http verb in doc

* Use client config

* Handle local mode

* E2E tests

* Enforce default if unable to use real limit

* Unit tests

* Fix tests

* Use model.PostMessageMaxRunesV2 as lower default

* Update direct post message length validation

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: streamer45 <cstcld91@gmail.com>
This commit is contained in:
Julien Tant 2024-04-19 10:45:32 -07:00 committed by GitHub
parent 389990ebe5
commit ffc08858cf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 404 additions and 16 deletions

View File

@ -21,6 +21,7 @@ func (api *API) InitConfigLocal() {
api.BaseRoutes.APIRoot.Handle("/config/patch", api.APILocal(localPatchConfig)).Methods("PUT") api.BaseRoutes.APIRoot.Handle("/config/patch", api.APILocal(localPatchConfig)).Methods("PUT")
api.BaseRoutes.APIRoot.Handle("/config/reload", api.APILocal(configReload)).Methods("POST") api.BaseRoutes.APIRoot.Handle("/config/reload", api.APILocal(configReload)).Methods("POST")
api.BaseRoutes.APIRoot.Handle("/config/migrate", api.APILocal(localMigrateConfig)).Methods("POST") api.BaseRoutes.APIRoot.Handle("/config/migrate", api.APILocal(localMigrateConfig)).Methods("POST")
api.BaseRoutes.APIRoot.Handle("/config/client", api.APILocal(localGetClientConfig)).Methods("GET")
} }
func localGetConfig(c *Context, w http.ResponseWriter, r *http.Request) { func localGetConfig(c *Context, w http.ResponseWriter, r *http.Request) {
@ -173,3 +174,24 @@ func localMigrateConfig(c *Context, w http.ResponseWriter, r *http.Request) {
auditRec.Success() auditRec.Success()
ReturnStatusOK(w) ReturnStatusOK(w)
} }
func localGetClientConfig(c *Context, w http.ResponseWriter, r *http.Request) {
auditRec := c.MakeAuditRecord("localGetClientConfig", audit.Fail)
defer c.LogAuditRec(auditRec)
format := r.URL.Query().Get("format")
if format == "" {
c.Err = model.NewAppError("getClientConfig", "api.config.client.old_format.app_error", nil, "", http.StatusNotImplemented)
return
}
if format != "old" {
c.SetInvalidParam("format")
return
}
auditRec.Success()
w.Write([]byte(model.MapToJSON(c.App.Srv().Platform().ClientConfigWithComputed())))
}

View File

@ -88,6 +88,7 @@ type Client interface {
MoveCommand(ctx context.Context, teamID string, commandID string) (*model.Response, error) MoveCommand(ctx context.Context, teamID string, commandID string) (*model.Response, error)
DeleteCommand(ctx context.Context, commandID string) (*model.Response, error) DeleteCommand(ctx context.Context, commandID string) (*model.Response, error)
GetConfig(ctx context.Context) (*model.Config, *model.Response, error) GetConfig(ctx context.Context) (*model.Config, *model.Response, error)
GetOldClientConfig(ctx context.Context, etag string) (map[string]string, *model.Response, error)
UpdateConfig(context.Context, *model.Config) (*model.Config, *model.Response, error) UpdateConfig(context.Context, *model.Config) (*model.Config, *model.Response, error)
PatchConfig(context.Context, *model.Config) (*model.Config, *model.Response, error) PatchConfig(context.Context, *model.Config) (*model.Config, *model.Response, error)
ReloadConfig(ctx context.Context) (*model.Response, error) ReloadConfig(ctx context.Context) (*model.Response, error)

View File

@ -95,7 +95,9 @@ var ImportValidateCmd = &cobra.Command{
Example: " import validate import_file.zip --team myteam --team myotherteam", Example: " import validate import_file.zip --team myteam --team myotherteam",
Short: "Validate an import file", Short: "Validate an import file",
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
RunE: importValidateCmdF, RunE: func(command *cobra.Command, args []string) error {
return importValidateCmdF(nil, command, args)
},
} }
func init() { func init() {
@ -382,7 +384,14 @@ type Statistics struct {
Attachments uint64 `json:"attachments"` Attachments uint64 `json:"attachments"`
} }
func importValidateCmdF(command *cobra.Command, args []string) error { type ImportValidationResult struct {
FileName string `json:"file_name"`
TotalLines uint64 `json:"total_lines"`
Elapsed time.Duration `json:"elapsed_time_ns"`
Errors []*importer.ImportValidationError `json:"errors"`
}
func importValidateCmdF(c client.Client, command *cobra.Command, args []string) error {
configurePrinter() configurePrinter()
defer printer.Print("Validation complete\n") defer printer.Print("Validation complete\n")
@ -391,9 +400,10 @@ func importValidateCmdF(command *cobra.Command, args []string) error {
serverChannels map[importer.ChannelTeam]*model.Channel serverChannels map[importer.ChannelTeam]*model.Channel
serverUsers map[string]*model.User serverUsers map[string]*model.User
serverEmails map[string]*model.User serverEmails map[string]*model.User
maxPostSize int
) )
err := withClient(func(c client.Client, cmd *cobra.Command, args []string) error { preRunWithClient := func(c client.Client, cmd *cobra.Command, args []string) error {
users, err := getPages(func(page, numPerPage int, etag string) ([]*model.User, *model.Response, error) { users, err := getPages(func(page, numPerPage int, etag string) ([]*model.User, *model.Response, error) {
return c.GetUsers(context.TODO(), page, numPerPage, etag) return c.GetUsers(context.TODO(), page, numPerPage, etag)
}, DefaultPageSize) }, DefaultPageSize)
@ -401,6 +411,16 @@ func importValidateCmdF(command *cobra.Command, args []string) error {
return err return err
} }
config, _, err := c.GetOldClientConfig(context.TODO(), "")
if err != nil {
return err
}
maxPostSize, err = strconv.Atoi(config["MaxPostSize"])
if err != nil {
return fmt.Errorf("failed to parse MaxPostSize: %w", err)
}
serverUsers = make(map[string]*model.User) serverUsers = make(map[string]*model.User)
serverEmails = make(map[string]*model.User) serverEmails = make(map[string]*model.User)
for _, user := range users { for _, user := range users {
@ -442,9 +462,16 @@ func importValidateCmdF(command *cobra.Command, args []string) error {
} }
return nil return nil
})(command, args) }
var err error
if c != nil {
err = preRunWithClient(c, command, args)
} else {
err = withClient(preRunWithClient)(command, args)
}
if err != nil { if err != nil {
printer.Print("could not initialize client, skipping online checks\n") printer.Print(fmt.Sprintf("could not initialize client (%s), skipping online checks\n", err.Error()))
} }
injectedTeams, err := command.Flags().GetStringArray("team") injectedTeams, err := command.Flags().GetStringArray("team")
@ -476,6 +503,10 @@ func importValidateCmdF(command *cobra.Command, args []string) error {
return err return err
} }
if maxPostSize == 0 {
maxPostSize = model.PostMessageMaxRunesV2
}
createMissingTeams := !checkMissingTeams && len(injectedTeams) == 0 createMissingTeams := !checkMissingTeams && len(injectedTeams) == 0
validator := importer.NewValidator( validator := importer.NewValidator(
args[0], // input file args[0], // input file
@ -486,11 +517,14 @@ func importValidateCmdF(command *cobra.Command, args []string) error {
serverChannels, // map of existing channels serverChannels, // map of existing channels
serverUsers, // map of users by name serverUsers, // map of users by name
serverEmails, // map of users by email serverEmails, // map of users by email
maxPostSize,
) )
var errors []*importer.ImportValidationError
templateError := template.Must(template.New("").Parse("{{ .Error }}\n")) templateError := template.Must(template.New("").Parse("{{ .Error }}\n"))
validator.OnError(func(ive *importer.ImportValidationError) error { validator.OnError(func(ive *importer.ImportValidationError) error {
printer.PrintPreparedT(templateError, ive) printer.PrintPreparedT(templateError, ive)
errors = append(errors, ive)
return nil return nil
}) })
@ -529,11 +563,7 @@ func importValidateCmdF(command *cobra.Command, args []string) error {
}{unusedAttachments}) }{unusedAttachments})
} }
printer.PrintT("It took {{ .Elapsed }} to validate {{ .TotalLines }} lines in {{ .FileName }}\n", struct { printer.PrintT("It took {{ .Elapsed }} to validate {{ .TotalLines }} lines in {{ .FileName }}\n", ImportValidationResult{args[0], validator.Lines(), validator.Duration(), errors})
FileName string `json:"file_name"`
TotalLines uint64 `json:"total_lines"`
Elapsed time.Duration `json:"elapsed_time_ns"`
}{args[0], validator.Lines(), validator.Duration()})
return nil return nil
} }

View File

@ -21,6 +21,8 @@ func (s *MmctlE2ETestSuite) TestImportUploadCmdF() {
serverPath := os.Getenv("MM_SERVER_PATH") serverPath := os.Getenv("MM_SERVER_PATH")
importName := "import_test.zip" importName := "import_test.zip"
importFilePath := filepath.Join(serverPath, "tests", importName) importFilePath := filepath.Join(serverPath, "tests", importName)
info, err := os.Stat(importFilePath)
s.Require().NoError(err)
s.Run("no permissions", func() { s.Run("no permissions", func() {
printer.Clean() printer.Clean()
@ -70,7 +72,7 @@ func (s *MmctlE2ETestSuite) TestImportUploadCmdF() {
us, _, err := c.CreateUpload(context.TODO(), &model.UploadSession{ us, _, err := c.CreateUpload(context.TODO(), &model.UploadSession{
Filename: importName, Filename: importName,
FileSize: 276051, FileSize: info.Size(),
Type: model.UploadTypeImport, Type: model.UploadTypeImport,
UserId: userID, UserId: userID,
}) })
@ -366,3 +368,68 @@ func (s *MmctlE2ETestSuite) TestImportJobListCmdF() {
s.Require().Equal(job2, printer.GetLines()[1].(*model.Job)) s.Require().Equal(job2, printer.GetLines()[1].(*model.Job))
}) })
} }
func (s *MmctlE2ETestSuite) TestImportValidateCmdF() {
s.SetupTestHelper().InitBasic()
serverPath := os.Getenv("MM_SERVER_PATH")
importName := "import_test.zip"
importFilePath := filepath.Join(serverPath, "tests", importName)
s.RunForSystemAdminAndLocal("defaults", func(c client.Client) {
printer.Clean()
cmd := &cobra.Command{}
cmd.Flags().StringArray("team", nil, "")
cmd.Flags().Bool("check-missing-teams", false, "")
cmd.Flags().Bool("ignore-attachments", false, "")
cmd.Flags().Bool("check-server-duplicates", true, "")
err := importValidateCmdF(c, cmd, []string{importFilePath})
s.Require().Nil(err)
s.Require().Empty(printer.GetErrorLines())
s.Require().Equal(Statistics{
Teams: 2,
Channels: 24,
Users: 16,
Posts: 2001,
DirectChannels: 79,
DirectPosts: 901,
Attachments: 2,
}, printer.GetLines()[0].(Statistics))
s.Require().Equal(struct {
UnusedAttachments []string `json:"unused_attachments"`
}{
UnusedAttachments: []string{"data/test2.png"},
}, printer.GetLines()[1].(struct {
UnusedAttachments []string `json:"unused_attachments"`
}))
s.Require().Equal("Validation complete\n", printer.GetLines()[3])
})
s.RunForSystemAdminAndLocal("ignore attachments", func(c client.Client) {
printer.Clean()
cmd := &cobra.Command{}
cmd.Flags().StringArray("team", nil, "")
cmd.Flags().Bool("check-missing-teams", false, "")
cmd.Flags().Bool("ignore-attachments", true, "")
cmd.Flags().Bool("check-server-duplicates", true, "")
err := importValidateCmdF(c, cmd, []string{importFilePath})
s.Require().Nil(err)
s.Require().Empty(printer.GetErrorLines())
s.Require().Equal(Statistics{
Teams: 2,
Channels: 24,
Users: 16,
Posts: 2001,
DirectChannels: 79,
DirectPosts: 901,
Attachments: 0,
}, printer.GetLines()[0].(Statistics))
s.Require().Equal("Validation complete\n", printer.GetLines()[2])
})
}

View File

@ -4,8 +4,13 @@
package commands package commands
import ( import (
"archive/zip"
"context" "context"
"fmt"
"net/http" "net/http"
"os"
"path/filepath"
"strings"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -229,3 +234,245 @@ func (s *MmctlUnitTestSuite) TestImportProcessCmdF() {
s.Empty(printer.GetErrorLines()) s.Empty(printer.GetErrorLines())
s.Equal(mockJob, printer.GetLines()[0].(*model.Job)) s.Equal(mockJob, printer.GetLines()[0].(*model.Job))
} }
func (s *MmctlUnitTestSuite) TestImportValidateCmdF() {
importFilePath := filepath.Join(os.TempDir(), "import.zip")
importBase := `{"type":"version","version":1}
{"type":"team","team":{"name":"reiciendis-0","display_name":"minus","type":"O","description":"doloremque dignissimos velit eum quae non omnis. dolores rerum cupiditate porro quia aperiam necessitatibus natus aut. velit eveniet porro explicabo tempora voluptas beatae. eum saepe a aut. perferendis aut ab ipsum! molestias animi ut porro dolores vel. ","allow_open_invite":false}}
{"type":"team","team":{"name":"ad-1","display_name":"eligendi","type":"O","description":"et iste illum reprehenderit aliquid in rem itaque in maxime eius.","allow_open_invite":false}}
{"type":"channel","channel":{"team":"ad-1","name":"iusto-9","display_name":"incidunt","type":"P","header":"officia accusamus aut aliquid dolor qui. quia magni pariatur numquam nesciunt. maxime dolorum sit neque commodi dolorum qui dicta sit. labore laudantium quisquam voluptatem commodi magnam. est aliquid perspiciatis sequi adipisci modi sit nam. totam iste quidem sed mollitia earum. vel voluptates labore cumque eaque qui!","purpose":"sit et accusamus repudiandae id. ut et officiis eos quod. sit soluta aliquid pariatur consectetur nostrum aut magni. numquam quas aspernatur et voluptatum et ipsam animi."}}
{"type":"user","user":{"username":"ashley.berry","email":"user-12@sample.mattermost.com","auth_service":null,"nickname":"","first_name":"Ashley","last_name":"Berry","position":"Registered Nurse","roles":"system_user","locale":"en","delete_at":0,"teams":[{"name":"reiciendis-0","roles":"team_admin team_user","channels":[{"name":"town-square","roles":"channel_user","notify_props":{"desktop":"default","mobile":"default","mark_unread":"all"},"favorite":false},{"name":"doloremque-0","roles":"channel_user","notify_props":{"desktop":"default","mobile":"default","mark_unread":"all"},"favorite":false},{"name":"voluptas-9","roles":"channel_user","notify_props":{"desktop":"default","mobile":"default","mark_unread":"all"},"favorite":false},{"name":"minus-8","roles":"channel_user","notify_props":{"desktop":"default","mobile":"default","mark_unread":"all"},"favorite":false},{"name":"rem-7","roles":"channel_user","notify_props":{"desktop":"default","mobile":"default","mark_unread":"all"},"favorite":false},{"name":"odit-3","roles":"channel_user","notify_props":{"desktop":"default","mobile":"default","mark_unread":"all"},"favorite":true}]},{"name":"ad-1","roles":"team_user","channels":[{"name":"iusto-9","roles":"channel_user","notify_props":{"desktop":"default","mobile":"default","mark_unread":"all"},"favorite":false},{"name":"amet-0","roles":"channel_admin channel_user","notify_props":{"desktop":"default","mobile":"default","mark_unread":"all"},"favorite":false},{"name":"minus-6","roles":"channel_user","notify_props":{"desktop":"default","mobile":"default","mark_unread":"all"},"favorite":false},{"name":"autem-2","roles":"channel_user","notify_props":{"desktop":"default","mobile":"default","mark_unread":"all"},"favorite":false},{"name":"town-square","roles":"channel_user","notify_props":{"desktop":"default","mobile":"default","mark_unread":"all"},"favorite":false},{"name":"aut-8","roles":"channel_admin channel_user","notify_props":{"desktop":"default","mobile":"default","mark_unread":"all"},"favorite":false}]}],"military_time":"false","link_previews":"true","message_display":"compact","channel_display_mode":"full","tutorial_step":"2","notify_props":{"desktop":"mention","desktop_sound":"true","email":"true","mobile":"mention","mobile_push_status":"away","channel":"true","comments":"never","mention_keys":""}}}
{"type":"direct_channel","direct_channel":{"members":["ashley.berry","ashley.berry"],"favorited_by":null,"header":""}}`
s.Run("empty file", func() {
file, err := os.Create(importFilePath)
s.Require().NoError(err)
zipWr := zip.NewWriter(file)
wr, err := zipWr.Create("import.jsonl")
s.Require().NoError(err)
_, err = wr.Write([]byte(``))
s.Require().NoError(err)
err = zipWr.Close()
s.Require().NoError(err)
err = file.Close()
s.Require().NoError(err)
printer.Clean()
err = importValidateCmdF(nil, ImportValidateCmd, []string{importFilePath})
s.Require().Nil(err)
s.Len(printer.GetLines(), 5)
s.Empty(printer.GetErrorLines())
s.Equal(Statistics{}, printer.GetLines()[2].(Statistics))
s.Equal("Validation complete\n", printer.GetLines()[4])
})
s.Run("post size under default limit", func() {
file, err := os.Create(importFilePath)
s.Require().NoError(err)
zipWr := zip.NewWriter(file)
wr, err := zipWr.Create("import.jsonl")
s.Require().NoError(err)
msg := strings.Repeat("t", model.PostMessageMaxRunesV2)
_, err = wr.Write([]byte(importBase))
s.Require().NoError(err)
_, err = wr.Write([]byte(fmt.Sprintf(`
{"type":"post","post":{"team":"ad-1","channel":"iusto-9","user":"ashley.berry","message":"%s","props":{},"create_at":1603398068740,"reactions":null,"replies":null}}`, msg)))
s.Require().NoError(err)
err = zipWr.Close()
s.Require().NoError(err)
err = file.Close()
s.Require().NoError(err)
printer.Clean()
err = importValidateCmdF(nil, ImportValidateCmd, []string{importFilePath})
s.Require().Nil(err)
s.Empty(printer.GetErrorLines())
s.Equal(Statistics{
Teams: 2,
Channels: 1,
DirectChannels: 1,
Users: 1,
Posts: 1,
}, printer.GetLines()[0].(Statistics))
res := printer.GetLines()[1].(ImportValidationResult)
s.Require().Empty(res.Errors)
s.Equal("Validation complete\n", printer.GetLines()[2])
})
s.Run("post size above default limit", func() {
file, err := os.Create(importFilePath)
s.Require().NoError(err)
zipWr := zip.NewWriter(file)
wr, err := zipWr.Create("import.jsonl")
s.Require().NoError(err)
msg := strings.Repeat("t", model.PostMessageMaxRunesV2+1)
_, err = wr.Write([]byte(importBase))
s.Require().NoError(err)
_, err = wr.Write([]byte(fmt.Sprintf(`
{"type":"post","post":{"team":"ad-1","channel":"iusto-9","user":"ashley.berry","message":"%s","props":{},"create_at":1603398068740,"reactions":null,"replies":null}}`, msg)))
s.Require().NoError(err)
err = zipWr.Close()
s.Require().NoError(err)
err = file.Close()
s.Require().NoError(err)
printer.Clean()
err = importValidateCmdF(nil, ImportValidateCmd, []string{importFilePath})
s.Require().Nil(err)
s.Empty(printer.GetErrorLines())
s.Equal(Statistics{
Teams: 2,
Channels: 1,
DirectChannels: 1,
Users: 1,
Posts: 1,
}, printer.GetLines()[0].(Statistics))
res := printer.GetLines()[1].(ImportValidationResult)
s.Require().Len(res.Errors, 1)
s.Require().Equal("app.import.validate_post_import_data.message_length.error", res.Errors[0].Err.(*model.AppError).Id)
s.Equal("Validation complete\n", printer.GetLines()[2])
})
s.Run("post size below config limit", func() {
file, err := os.Create(importFilePath)
s.Require().NoError(err)
zipWr := zip.NewWriter(file)
wr, err := zipWr.Create("import.jsonl")
s.Require().NoError(err)
msg := strings.Repeat("t", model.PostMessageMaxRunesV2*2)
_, err = wr.Write([]byte(importBase))
s.Require().NoError(err)
_, err = wr.Write([]byte(fmt.Sprintf(`
{"type":"post","post":{"team":"ad-1","channel":"iusto-9","user":"ashley.berry","message":"%s","props":{},"create_at":1603398068740,"reactions":null,"replies":null}}`, msg)))
s.Require().NoError(err)
err = zipWr.Close()
s.Require().NoError(err)
err = file.Close()
s.Require().NoError(err)
printer.Clean()
s.client.
EXPECT().
GetUsers(context.TODO(), 0, 200, "").
Return(nil, &model.Response{}, nil).
Times(1)
s.client.
EXPECT().
GetAllTeams(context.TODO(), "", 0, 200).
Return(nil, &model.Response{}, nil).
Times(1)
s.client.
EXPECT().
GetOldClientConfig(context.TODO(), "").
Return(map[string]string{
"MaxPostSize": fmt.Sprintf("%d", model.PostMessageMaxRunesV2*2),
}, &model.Response{}, nil).
Times(1)
err = importValidateCmdF(s.client, ImportValidateCmd, []string{importFilePath})
s.Require().Nil(err)
s.Empty(printer.GetErrorLines())
s.Equal(Statistics{
Teams: 2,
Channels: 1,
DirectChannels: 1,
Users: 1,
Posts: 1,
}, printer.GetLines()[0].(Statistics))
res := printer.GetLines()[1].(ImportValidationResult)
s.Require().Empty(res.Errors)
s.Equal("Validation complete\n", printer.GetLines()[2])
})
s.Run("direct post size below config limit", func() {
file, err := os.Create(importFilePath)
s.Require().NoError(err)
zipWr := zip.NewWriter(file)
wr, err := zipWr.Create("import.jsonl")
s.Require().NoError(err)
msg := strings.Repeat("t", model.PostMessageMaxRunesV2*2)
_, err = wr.Write([]byte(importBase))
s.Require().NoError(err)
_, err = wr.Write([]byte(fmt.Sprintf(`
{"type":"direct_post","direct_post":{"channel_members":["ashley.berry","ashley.berry"],"user":"ashley.berry","message":"%s","props":{},"create_at":1603398112372,"flagged_by":null,"reactions":null,"replies":null,"attachments":null}}`, msg)))
s.Require().NoError(err)
err = zipWr.Close()
s.Require().NoError(err)
err = file.Close()
s.Require().NoError(err)
printer.Clean()
s.client.
EXPECT().
GetUsers(context.TODO(), 0, 200, "").
Return(nil, &model.Response{}, nil).
Times(1)
s.client.
EXPECT().
GetAllTeams(context.TODO(), "", 0, 200).
Return(nil, &model.Response{}, nil).
Times(1)
s.client.
EXPECT().
GetOldClientConfig(context.TODO(), "").
Return(map[string]string{
"MaxPostSize": fmt.Sprintf("%d", model.PostMessageMaxRunesV2*2),
}, &model.Response{}, nil).
Times(1)
err = importValidateCmdF(s.client, ImportValidateCmd, []string{importFilePath})
s.Require().Nil(err)
s.Empty(printer.GetErrorLines())
s.Equal(Statistics{
Teams: 2,
Channels: 1,
Users: 1,
DirectChannels: 1,
DirectPosts: 1,
}, printer.GetLines()[0].(Statistics))
res := printer.GetLines()[1].(ImportValidationResult)
s.Require().Empty(res.Errors)
s.Equal("Validation complete\n", printer.GetLines()[2])
})
}

View File

@ -68,6 +68,8 @@ type Validator struct { //nolint:govet
directPosts uint64 directPosts uint64
emojis map[string]ImportFileInfo emojis map[string]ImportFileInfo
maxPostSize int
start time.Time start time.Time
end time.Time end time.Time
@ -96,6 +98,7 @@ func NewValidator(
serverChannels map[ChannelTeam]*model.Channel, serverChannels map[ChannelTeam]*model.Channel,
serverUsers map[string]*model.User, serverUsers map[string]*model.User,
serverEmails map[string]*model.User, serverEmails map[string]*model.User,
maxPostSize int,
) *Validator { ) *Validator {
v := &Validator{ v := &Validator{
archiveName: name, archiveName: name,
@ -118,6 +121,8 @@ func NewValidator(
channels: map[ChannelTeam]ImportFileInfo{}, channels: map[ChannelTeam]ImportFileInfo{},
users: map[string]ImportFileInfo{}, users: map[string]ImportFileInfo{},
emojis: map[string]ImportFileInfo{}, emojis: map[string]ImportFileInfo{},
maxPostSize: maxPostSize,
} }
v.loadFromServer() v.loadFromServer()
@ -722,7 +727,7 @@ func (v *Validator) validateUser(info ImportFileInfo, line imports.LineImportDat
func (v *Validator) validatePost(info ImportFileInfo, line imports.LineImportData) (err error) { func (v *Validator) validatePost(info ImportFileInfo, line imports.LineImportData) (err error) {
ivErr := validateNotNil(info, "post", line.Post, func(data imports.PostImportData) *ImportValidationError { ivErr := validateNotNil(info, "post", line.Post, func(data imports.PostImportData) *ImportValidationError {
appErr := imports.ValidatePostImportData(&data, model.PostMessageMaxRunesV1) appErr := imports.ValidatePostImportData(&data, v.maxPostSize)
if appErr != nil { if appErr != nil {
return &ImportValidationError{ return &ImportValidationError{
ImportFileInfo: info, ImportFileInfo: info,
@ -854,7 +859,7 @@ func (v *Validator) validateDirectChannel(info ImportFileInfo, line imports.Line
func (v *Validator) validateDirectPost(info ImportFileInfo, line imports.LineImportData) (err error) { func (v *Validator) validateDirectPost(info ImportFileInfo, line imports.LineImportData) (err error) {
ivErr := validateNotNil(info, "direct_post", line.DirectPost, func(data imports.DirectPostImportData) *ImportValidationError { ivErr := validateNotNil(info, "direct_post", line.DirectPost, func(data imports.DirectPostImportData) *ImportValidationError {
appErr := imports.ValidateDirectPostImportData(&data, model.PostMessageMaxRunesV1) appErr := imports.ValidateDirectPostImportData(&data, v.maxPostSize)
if appErr != nil { if appErr != nil {
return &ImportValidationError{ return &ImportValidationError{
ImportFileInfo: info, ImportFileInfo: info,

View File

@ -958,6 +958,22 @@ func (mr *MockClientMockRecorder) GetOAuthApps(arg0, arg1, arg2 interface{}) *go
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOAuthApps", reflect.TypeOf((*MockClient)(nil).GetOAuthApps), arg0, arg1, arg2) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOAuthApps", reflect.TypeOf((*MockClient)(nil).GetOAuthApps), arg0, arg1, arg2)
} }
// GetOldClientConfig mocks base method.
func (m *MockClient) GetOldClientConfig(arg0 context.Context, arg1 string) (map[string]string, *model.Response, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetOldClientConfig", arg0, arg1)
ret0, _ := ret[0].(map[string]string)
ret1, _ := ret[1].(*model.Response)
ret2, _ := ret[2].(error)
return ret0, ret1, ret2
}
// GetOldClientConfig indicates an expected call of GetOldClientConfig.
func (mr *MockClientMockRecorder) GetOldClientConfig(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOldClientConfig", reflect.TypeOf((*MockClient)(nil).GetOldClientConfig), arg0, arg1)
}
// GetOutgoingWebhook mocks base method. // GetOutgoingWebhook mocks base method.
func (m *MockClient) GetOutgoingWebhook(arg0 context.Context, arg1 string) (*model.OutgoingWebhook, *model.Response, error) { func (m *MockClient) GetOutgoingWebhook(arg0 context.Context, arg1 string) (*model.OutgoingWebhook, *model.Response, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()

Binary file not shown.