@@ -34,8 +34,11 @@ const (
|
||||
SYMBOLS = " !\"\\#$%&'()*+,-./:;<=>?@[]^_`|~"
|
||||
BinaryParamKey = "MM_BINARY_PARAMETERS"
|
||||
NoTranslation = "<untranslated>"
|
||||
maxPropSizeBytes = 1024 * 1024
|
||||
)
|
||||
|
||||
var ErrMaxPropSizeExceeded = fmt.Errorf("max prop size of %d exceeded", maxPropSizeBytes)
|
||||
|
||||
type StringInterface map[string]any
|
||||
type StringArray []string
|
||||
|
||||
@@ -77,6 +80,14 @@ func (sa StringArray) Equals(input StringArray) bool {
|
||||
|
||||
// Value converts StringArray to database value
|
||||
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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -127,6 +138,15 @@ func (m *StringMap) Scan(value any) error {
|
||||
func (m StringMap) Value() (driver.Value, error) {
|
||||
ok := 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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -182,6 +202,11 @@ func (si StringInterface) Value() (driver.Value, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(j) > maxPropSizeBytes {
|
||||
return nil, ErrMaxPropSizeExceeded
|
||||
}
|
||||
|
||||
// non utf8 characters are not supported https://mattermost.atlassian.net/browse/MM-41066
|
||||
return string(j), err
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
sq "github.com/mattermost/squirrel"
|
||||
"github.com/pkg/errors"
|
||||
@@ -17,6 +18,7 @@ import (
|
||||
|
||||
"github.com/mattermost/mattermost-server/v6/einterfaces"
|
||||
"github.com/mattermost/mattermost-server/v6/model"
|
||||
"github.com/mattermost/mattermost-server/v6/shared/mlog"
|
||||
"github.com/mattermost/mattermost-server/v6/store"
|
||||
)
|
||||
|
||||
@@ -59,7 +61,24 @@ func newSqlUserStore(sqlStore *SqlStore, metrics einterfaces.MetricsInterface) s
|
||||
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) {
|
||||
if err := us.validateAutoResponderMessageSize(user.NotifyProps); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
query := `INSERT INTO Users
|
||||
(Id, CreateAt, UpdateAt, DeleteAt, Username, Password, AuthData, AuthService,
|
||||
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
|
||||
}
|
||||
|
||||
if err := us.validateAutoResponderMessageSize(user.NotifyProps); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
oldUser := model.User{}
|
||||
err := us.GetMasterX().Get(&oldUser, "SELECT * FROM Users WHERE Id=?", user.Id)
|
||||
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 {
|
||||
if err := us.validateAutoResponderMessageSize(props); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
buf, err := json.Marshal(props)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed marshalling session props")
|
||||
|
||||
@@ -130,7 +130,17 @@ func testUserStoreSave(t *testing.T, ss store.Store) {
|
||||
|
||||
u2.Username = ""
|
||||
_, 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++ {
|
||||
u := model.User{
|
||||
@@ -234,6 +244,18 @@ func testUserStoreUpdate(t *testing.T, ss store.Store) {
|
||||
uNew, err := ss.User().Get(context.Background(), u1.Id)
|
||||
require.NoError(t, err)
|
||||
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) {
|
||||
|
||||
Ссылка в новой задаче
Block a user