MM-56881 Validate and ensure valid CustomStatus is stored (#26287)
* don't allow invalid CustomStatus * allow empty emoji in custom status * lint fix * add english translation * update for review comments. * fix bad fix --------- Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
5740b43922
Коммит
30454f241d
@@ -9770,6 +9770,10 @@
|
||||
"id": "model.user.is_valid.id.app_error",
|
||||
"translation": "Invalid user id."
|
||||
},
|
||||
{
|
||||
"id": "model.user.is_valid.invalidProperty.app_error",
|
||||
"translation": "Invalid props (custom status)"
|
||||
},
|
||||
{
|
||||
"id": "model.user.is_valid.last_name.app_error",
|
||||
"translation": "Invalid last name."
|
||||
|
||||
@@ -35,10 +35,6 @@ type CustomStatus struct {
|
||||
}
|
||||
|
||||
func (cs *CustomStatus) PreSave() {
|
||||
if cs.Emoji == "" {
|
||||
cs.Emoji = DefaultCustomStatusEmoji
|
||||
}
|
||||
|
||||
if cs.Duration == "" && !cs.ExpiresAt.Before(time.Now()) {
|
||||
cs.Duration = "date_and_time"
|
||||
}
|
||||
|
||||
@@ -399,6 +399,13 @@ func (u *User) IsValid() *AppError {
|
||||
map[string]any{"Limit": UserRolesMaxLength}, "user_id="+u.Id+" roles_limit="+u.Roles, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
if u.Props != nil {
|
||||
if !u.ValidateCustomStatus() {
|
||||
return NewAppError("User.IsValid", "model.user.is_valid.invalidProperty.app_error",
|
||||
map[string]any{"Props": u.Props}, "user_id="+u.Id, http.StatusBadRequest)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -472,6 +479,12 @@ func (u *User) PreSave() {
|
||||
if u.Password != "" {
|
||||
u.Password = HashPassword(u.Password)
|
||||
}
|
||||
|
||||
cs := u.GetCustomStatus()
|
||||
if cs != nil {
|
||||
cs.PreSave()
|
||||
u.SetCustomStatus(cs)
|
||||
}
|
||||
}
|
||||
|
||||
// PreUpdate should be run before updating the user in the db.
|
||||
@@ -508,6 +521,14 @@ func (u *User) PreUpdate() {
|
||||
}
|
||||
u.NotifyProps[MentionKeysNotifyProp] = strings.Join(goodKeys, ",")
|
||||
}
|
||||
|
||||
if u.Props != nil {
|
||||
cs := u.GetCustomStatus()
|
||||
if cs != nil {
|
||||
cs.PreSave()
|
||||
u.SetCustomStatus(cs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (u *User) SetDefaultNotifications() {
|
||||
@@ -711,6 +732,17 @@ func (u *User) ClearCustomStatus() {
|
||||
u.Props[UserPropsKeyCustomStatus] = ""
|
||||
}
|
||||
|
||||
func (u *User) ValidateCustomStatus() bool {
|
||||
status, exists := u.Props[UserPropsKeyCustomStatus]
|
||||
if exists && status != "" {
|
||||
cs := u.GetCustomStatus()
|
||||
if cs == nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (u *User) GetFullName() string {
|
||||
if u.FirstName != "" && u.LastName != "" {
|
||||
return u.FirstName + " " + u.LastName
|
||||
|
||||
@@ -355,3 +355,24 @@ func TestUserSlice(t *testing.T) {
|
||||
assert.Len(t, nonBotUsers, 1)
|
||||
})
|
||||
}
|
||||
|
||||
func TestValidateCustomStatus(t *testing.T) {
|
||||
t.Run("ValidateCustomStatus", func(t *testing.T) {
|
||||
user0 := &User{Id: "user0", DeleteAt: 0, IsBot: true}
|
||||
|
||||
user0.Props = map[string]string{UserPropsKeyCustomStatus: ""}
|
||||
assert.True(t, user0.ValidateCustomStatus())
|
||||
|
||||
user0.Props[UserPropsKeyCustomStatus] = "hello"
|
||||
assert.False(t, user0.ValidateCustomStatus())
|
||||
|
||||
user0.Props[UserPropsKeyCustomStatus] = "{\"emoji\":{\"foo\":\"bar\"}}"
|
||||
assert.True(t, user0.ValidateCustomStatus())
|
||||
|
||||
user0.Props[UserPropsKeyCustomStatus] = "{\"text\": \"hello\"}"
|
||||
assert.True(t, user0.ValidateCustomStatus())
|
||||
|
||||
user0.Props[UserPropsKeyCustomStatus] = "{\"wrong\": \"hello\"}"
|
||||
assert.True(t, user0.ValidateCustomStatus())
|
||||
})
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user