[MM-46644] Auto respond message (#20900)

Automatic Merge
Этот коммит содержится в:
Vishal
2022-10-07 18:32:11 +05:30
коммит произвёл GitHub
родитель 56fd8bf5cc
Коммит 6e9b808efd
3 изменённых файлов: 75 добавлений и 1 удалений

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

@@ -34,8 +34,11 @@ const (
SYMBOLS = " !\"\\#$%&'()*+,-./:;<=>?@[]^_`|~" SYMBOLS = " !\"\\#$%&'()*+,-./:;<=>?@[]^_`|~"
BinaryParamKey = "MM_BINARY_PARAMETERS" BinaryParamKey = "MM_BINARY_PARAMETERS"
NoTranslation = "<untranslated>" NoTranslation = "<untranslated>"
maxPropSizeBytes = 1024 * 1024
) )
var ErrMaxPropSizeExceeded = fmt.Errorf("max prop size of %d exceeded", maxPropSizeBytes)
type StringInterface map[string]any type StringInterface map[string]any
type StringArray []string type StringArray []string
@@ -77,6 +80,14 @@ func (sa StringArray) Equals(input StringArray) bool {
// Value converts StringArray to database value // Value converts StringArray to database value
func (sa StringArray) Value() (driver.Value, error) { func (sa StringArray) Value() (driver.Value, error) {
sz := 0
for i := range sa {
sz += len(sa[i])
if sz > maxPropSizeBytes {
return nil, ErrMaxPropSizeExceeded
}
}
j, err := json.Marshal(sa) j, err := json.Marshal(sa)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -127,6 +138,15 @@ func (m *StringMap) Scan(value any) error {
func (m StringMap) Value() (driver.Value, error) { func (m StringMap) Value() (driver.Value, error) {
ok := m[BinaryParamKey] ok := m[BinaryParamKey]
delete(m, BinaryParamKey) delete(m, BinaryParamKey)
sz := 0
for k := range m {
sz += len(k) + len(m[k])
if sz > maxPropSizeBytes {
return nil, ErrMaxPropSizeExceeded
}
}
buf, err := json.Marshal(m) buf, err := json.Marshal(m)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -182,6 +202,11 @@ func (si StringInterface) Value() (driver.Value, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
if len(j) > maxPropSizeBytes {
return nil, ErrMaxPropSizeExceeded
}
// non utf8 characters are not supported https://mattermost.atlassian.net/browse/MM-41066 // non utf8 characters are not supported https://mattermost.atlassian.net/browse/MM-41066
return string(j), err return string(j), err
} }

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

@@ -10,6 +10,7 @@ import (
"fmt" "fmt"
"sort" "sort"
"strings" "strings"
"unicode/utf8"
sq "github.com/mattermost/squirrel" sq "github.com/mattermost/squirrel"
"github.com/pkg/errors" "github.com/pkg/errors"
@@ -17,6 +18,7 @@ import (
"github.com/mattermost/mattermost-server/v6/einterfaces" "github.com/mattermost/mattermost-server/v6/einterfaces"
"github.com/mattermost/mattermost-server/v6/model" "github.com/mattermost/mattermost-server/v6/model"
"github.com/mattermost/mattermost-server/v6/shared/mlog"
"github.com/mattermost/mattermost-server/v6/store" "github.com/mattermost/mattermost-server/v6/store"
) )
@@ -59,7 +61,24 @@ func newSqlUserStore(sqlStore *SqlStore, metrics einterfaces.MetricsInterface) s
return us return us
} }
func (us SqlUserStore) validateAutoResponderMessageSize(notifyProps model.StringMap) error {
if notifyProps != nil {
maxPostSize := us.Post().GetMaxPostSize()
msg := notifyProps[model.AutoResponderMessageNotifyProp]
msgSize := utf8.RuneCountInString(msg)
if msgSize > maxPostSize {
mlog.Warn("auto_responder_message has size restrictions", mlog.Int("max_characters", maxPostSize), mlog.Int("received_size", msgSize))
return errors.New("Auto responder message size can't be more than the allowed Post size")
}
}
return nil
}
func (us SqlUserStore) insert(user *model.User) (sql.Result, error) { func (us SqlUserStore) insert(user *model.User) (sql.Result, error) {
if err := us.validateAutoResponderMessageSize(user.NotifyProps); err != nil {
return nil, err
}
query := `INSERT INTO Users query := `INSERT INTO Users
(Id, CreateAt, UpdateAt, DeleteAt, Username, Password, AuthData, AuthService, (Id, CreateAt, UpdateAt, DeleteAt, Username, Password, AuthData, AuthService,
Email, EmailVerified, Nickname, FirstName, LastName, Position, Roles, AllowMarketing, Email, EmailVerified, Nickname, FirstName, LastName, Position, Roles, AllowMarketing,
@@ -150,6 +169,10 @@ func (us SqlUserStore) Update(user *model.User, trustedUpdateData bool) (*model.
return nil, err return nil, err
} }
if err := us.validateAutoResponderMessageSize(user.NotifyProps); err != nil {
return nil, err
}
oldUser := model.User{} oldUser := model.User{}
err := us.GetMasterX().Get(&oldUser, "SELECT * FROM Users WHERE Id=?", user.Id) err := us.GetMasterX().Get(&oldUser, "SELECT * FROM Users WHERE Id=?", user.Id)
if err != nil { if err != nil {
@@ -228,6 +251,10 @@ func (us SqlUserStore) Update(user *model.User, trustedUpdateData bool) (*model.
} }
func (us SqlUserStore) UpdateNotifyProps(userID string, props map[string]string) error { func (us SqlUserStore) UpdateNotifyProps(userID string, props map[string]string) error {
if err := us.validateAutoResponderMessageSize(props); err != nil {
return err
}
buf, err := json.Marshal(props) buf, err := json.Marshal(props)
if err != nil { if err != nil {
return errors.Wrap(err, "failed marshalling session props") return errors.Wrap(err, "failed marshalling session props")

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

@@ -130,7 +130,17 @@ func testUserStoreSave(t *testing.T, ss store.Store) {
u2.Username = "" u2.Username = ""
_, err = ss.User().Save(&u2) _, err = ss.User().Save(&u2)
require.Error(t, err, "should be unique username") require.Error(t, err, "should be non-empty username")
u3 := model.User{
Email: MakeEmail(),
Username: model.NewId(),
NotifyProps: make(map[string]string, 1),
}
maxPostSize := ss.Post().GetMaxPostSize()
u3.NotifyProps[model.AutoResponderMessageNotifyProp] = strings.Repeat("a", maxPostSize+1)
_, err = ss.User().Save(&u3)
require.Error(t, err, "auto responder message size should not be greater than maxPostSize")
for i := 0; i < 49; i++ { for i := 0; i < 49; i++ {
u := model.User{ u := model.User{
@@ -234,6 +244,18 @@ func testUserStoreUpdate(t *testing.T, ss store.Store) {
uNew, err := ss.User().Get(context.Background(), u1.Id) uNew, err := ss.User().Get(context.Background(), u1.Id)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, props, uNew.NotifyProps) assert.Equal(t, props, uNew.NotifyProps)
u4 := model.User{
Email: MakeEmail(),
Username: model.NewId(),
NotifyProps: make(map[string]string, 1),
}
maxPostSize := ss.Post().GetMaxPostSize()
u4.NotifyProps[model.AutoResponderMessageNotifyProp] = strings.Repeat("a", maxPostSize+1)
_, err = ss.User().Update(&u4, false)
require.Error(t, err, "auto responder message size should not be greater than maxPostSize")
err = ss.User().UpdateNotifyProps(u4.Id, u4.NotifyProps)
require.Error(t, err, "auto responder message size should not be greater than maxPostSize")
} }
func testUserStoreUpdateUpdateAt(t *testing.T, ss store.Store) { func testUserStoreUpdateUpdateAt(t *testing.T, ss store.Store) {