Skip to content

Commit

Permalink
[MM-46644] Auto respond message (#20900)
Browse files Browse the repository at this point in the history
Automatic Merge

(cherry picked from commit 6e9b808)
  • Loading branch information
vish9812 committed Oct 11, 2022
1 parent a57ed58 commit 64021bf
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 2 deletions.
25 changes: 25 additions & 0 deletions model/utils.go
Expand Up @@ -34,8 +34,11 @@ const (
NUMBERS = "0123456789"
SYMBOLS = " !\"\\#$%&'()*+,-./:;<=>?@[]^_`|~"
BinaryParamKey = "MM_BINARY_PARAMETERS"
maxPropSizeBytes = 1024 * 1024
)

var ErrMaxPropSizeExceeded = fmt.Errorf("max prop size of %d exceeded", maxPropSizeBytes)

type StringInterface map[string]any
type StringArray []string

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
}
Expand Down
27 changes: 27 additions & 0 deletions store/sqlstore/user_store.go
Expand Up @@ -10,13 +10,15 @@ import (
"fmt"
"sort"
"strings"
"unicode/utf8"

sq "github.com/mattermost/squirrel"
"github.com/pkg/errors"
"golang.org/x/sync/errgroup"

"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"
)

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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")
Expand Down
26 changes: 24 additions & 2 deletions store/storetest/user_store.go
Expand Up @@ -129,8 +129,18 @@ func testUserStoreSave(t *testing.T, ss store.Store) {
require.Error(t, err, "should be unique username")

u2.Username = ""
_, err = ss.User().Save(&u1)
require.Error(t, err, "should be unique username")
_, err = ss.User().Save(&u2)
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{
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 64021bf

Please sign in to comment.