@@ -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) {
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user