Skip to content

Commit

Permalink
MM 55199 Limit User Preferences (#25579) (#26341)
Browse files Browse the repository at this point in the history
Automatic Merge
  • Loading branch information
mattermost-build committed Feb 29, 2024
1 parent e82a8af commit 362b7d2
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 4 deletions.
4 changes: 4 additions & 0 deletions api/v4/source/preferences.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@
type: array
items:
$ref: '#/components/schemas/Preference'
minItems: 1
maxItems: 100
responses:
"200":
description: User preferences saved successful
Expand Down Expand Up @@ -102,6 +104,8 @@
type: array
items:
$ref: '#/components/schemas/Preference'
minItems: 1
maxItems: 100
responses:
"200":
description: User preferences saved successful
Expand Down
18 changes: 14 additions & 4 deletions server/channels/api4/preference.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
"github.com/mattermost/mattermost/server/v8/channels/audit"
)

const maxUpdatePreferences = 100

func (api *API) InitPreference() {
api.BaseRoutes.Preferences.Handle("", api.APISessionRequired(getPreferences)).Methods("GET")
api.BaseRoutes.Preferences.Handle("", api.APISessionRequired(updatePreferences)).Methods("PUT")
Expand Down Expand Up @@ -101,8 +103,12 @@ func updatePreferences(c *Context, w http.ResponseWriter, r *http.Request) {
}

var preferences model.Preferences
if jsonErr := json.NewDecoder(r.Body).Decode(&preferences); jsonErr != nil {
c.SetInvalidParamWithErr("preferences", jsonErr)
err := model.StructFromJSONLimited(r.Body, *c.App.Config().ServiceSettings.MaximumPayloadSizeBytes, &preferences)
if err != nil {
c.SetInvalidParamWithErr("preferences", err)
return
} else if len(preferences) == 0 || len(preferences) > maxUpdatePreferences {
c.SetInvalidParam("preferences")
return
}

Expand Down Expand Up @@ -149,8 +155,12 @@ func deletePreferences(c *Context, w http.ResponseWriter, r *http.Request) {
}

var preferences model.Preferences
if jsonErr := json.NewDecoder(r.Body).Decode(&preferences); jsonErr != nil {
c.SetInvalidParamWithErr("preferences", jsonErr)
err := model.StructFromJSONLimited(r.Body, *c.App.Config().ServiceSettings.MaximumPayloadSizeBytes, &preferences)
if err != nil {
c.SetInvalidParamWithErr("preferences", err)
return
} else if len(preferences) == 0 || len(preferences) > maxUpdatePreferences {
c.SetInvalidParam("preferences")
return
}

Expand Down
72 changes: 72 additions & 0 deletions server/channels/api4/preference_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,42 @@ func TestUpdatePreferences(t *testing.T) {
CheckUnauthorizedStatus(t, resp)
}

func TestUpdatePreferencesOverload(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
client := th.Client

th.LoginBasic()
user1 := th.BasicUser

t.Run("No preferences", func(t *testing.T) {
preferences1 := model.Preferences{}
// should error if no preferences
resp, err := client.UpdatePreferences(context.Background(), user1.Id, preferences1)
require.Error(t, err)
CheckErrorID(t, err, "api.context.invalid_body_param.app_error")
CheckBadRequestStatus(t, resp)
})

t.Run("Too many preferences", func(t *testing.T) {
preferences1 := model.Preferences{}
category := model.NewId()
// should error if too many preferences
for i := 0; i <= 100; i++ {
preferences1 = append(preferences1, model.Preference{
UserId: user1.Id,
Category: category,
Name: model.NewId(),
Value: model.NewId(),
})
}
resp, err := client.UpdatePreferences(context.Background(), user1.Id, preferences1)
require.Error(t, err)
CheckErrorID(t, err, "api.context.invalid_body_param.app_error")
CheckBadRequestStatus(t, resp)
})
}

func TestUpdatePreferencesWebsocket(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
Expand Down Expand Up @@ -590,6 +626,42 @@ func TestDeletePreferences(t *testing.T) {
CheckUnauthorizedStatus(t, resp)
}

func TestDeletePreferencesOverload(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
client := th.Client

th.LoginBasic()
user1 := th.BasicUser

t.Run("No preferences", func(t *testing.T) {
preferences1 := model.Preferences{}
// should error if no preferences
resp, err := client.DeletePreferences(context.Background(), user1.Id, preferences1)
require.Error(t, err)
CheckErrorID(t, err, "api.context.invalid_body_param.app_error")
CheckBadRequestStatus(t, resp)
})

t.Run("Too many preferences", func(t *testing.T) {
category := model.NewId()
preferences1 := model.Preferences{}
// should error if too many preferences
for i := 0; i <= 100; i++ {
preferences1 = append(preferences1, model.Preference{
UserId: user1.Id,
Category: category,
Name: model.NewId(),
Value: model.NewId(),
})
}
resp, err := client.DeletePreferences(context.Background(), user1.Id, preferences1)
require.Error(t, err)
CheckErrorID(t, err, "api.context.invalid_body_param.app_error")
CheckBadRequestStatus(t, resp)
})
}

func TestDeletePreferencesWebsocket(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
Expand Down

0 comments on commit 362b7d2

Please sign in to comment.