From a26834196e5ef7419459c8803154f15c24f19f51 Mon Sep 17 00:00:00 2001 From: Kailash Nadh Date: Mon, 16 Sep 2024 22:59:10 +0530 Subject: [PATCH] Refactor subscriber APIs list permission filtering. --- cmd/lists.go | 8 ++++---- cmd/subscribers.go | 33 ++++++++------------------------- models/models.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 29 deletions(-) diff --git a/cmd/lists.go b/cmd/lists.go index 0570215b..0968b121 100644 --- a/cmd/lists.go +++ b/cmd/lists.go @@ -176,12 +176,12 @@ func listPerm(next echo.HandlerFunc) echo.HandlerFunc { // Define permissions based on HTTP read/write. var ( - permAll = "lists:manage_all" - perm = "list:manage" + permAll = models.PermListManageAll + perm = models.PermListManage ) if c.Request().Method == http.MethodGet { - permAll = "lists:get_all" - perm = "list:get" + permAll = models.PermListGetAll + perm = models.PermListGet } // Check if the user has permissions for all lists or the specific list. diff --git a/cmd/subscribers.go b/cmd/subscribers.go index 8907c436..7947d306 100644 --- a/cmd/subscribers.go +++ b/cmd/subscribers.go @@ -213,7 +213,7 @@ func handleCreateSubscriber(c echo.Context) error { } // Filter lists against the current user's permitted lists. - listIDs := filterListsByPerm(req.Lists, user) + listIDs := user.FilterListsByPerm(req.Lists, false, true) // Insert the subscriber into the DB. sub, _, err := app.core.InsertSubscriber(req.Subscriber, listIDs, nil, req.PreconfirmSubs) @@ -258,7 +258,7 @@ func handleUpdateSubscriber(c echo.Context) error { } // Filter lists against the current user's permitted lists. - listIDs := filterListsByPerm(req.Lists, user) + listIDs := user.FilterListsByPerm(req.Lists, false, true) out, _, err := app.core.UpdateSubscriberWithLists(id, req.Subscriber, listIDs, nil, req.PreconfirmSubs, true) if err != nil { @@ -368,7 +368,7 @@ func handleManageSubscriberLists(c echo.Context) error { } // Filter lists against the current user's permitted lists. - listIDs := filterListsByPerm(req.TargetListIDs, user) + listIDs := user.FilterListsByPerm(req.TargetListIDs, false, true) // Action. var err error @@ -484,8 +484,8 @@ func handleManageSubscriberListsByQuery(c echo.Context) error { } // Filter lists against the current user's permitted lists. - sourceListIDs := filterListsByPerm(req.ListIDs, user) - targetListIDs := filterListsByPerm(req.TargetListIDs, user) + sourceListIDs := user.FilterListsByPerm(req.ListIDs, false, true) + targetListIDs := user.FilterListsByPerm(req.TargetListIDs, false, true) // Action. var err error @@ -669,7 +669,7 @@ func hasSubPerm(u models.User, subIDs []int, app *App) error { return nil } - if _, ok := u.PermissionsMap["subscribers:get_all"]; ok { + if _, ok := u.PermissionsMap[models.PermSubscribersGetAll]; ok { return nil } @@ -697,31 +697,14 @@ func filterListQeryByPerm(qp url.Values, user models.User, app *App) ([]int, err return nil, echo.NewHTTPError(http.StatusBadRequest, app.i18n.T("globals.messages.invalidID")) } - listIDs = []int{} - for _, id := range ids { - if _, ok := user.ListPermissionsMap[id]; ok { - listIDs = append(listIDs, id) - } - } + listIDs = user.FilterListsByPerm(ids, true, true) } else { // There are no incoming params. If the user doesn't have permission to get all subscribers, // filter by the lists they have access to. - if _, ok := user.PermissionsMap["subscribers:get_all"]; !ok { + if _, ok := user.PermissionsMap[models.PermSubscribersGetAll]; !ok { listIDs = user.GetListIDs } } return listIDs, nil } - -// filterListsByPerm filters the given list IDs against the given user's permitted lists. -func filterListsByPerm(listIDs []int, user models.User) []int { - out := make([]int, 0, len(listIDs)) - for _, id := range listIDs { - if _, ok := user.ListPermissionsMap[id]; ok { - listIDs = append(listIDs, id) - } - } - - return out -} diff --git a/models/models.go b/models/models.go index 468573f8..51d18e3f 100644 --- a/models/models.go +++ b/models/models.go @@ -814,3 +814,45 @@ func (h Headers) Value() (driver.Value, error) { return "[]", nil } + +func (u *User) HasPerm(perm string) bool { + _, ok := u.PermissionsMap[perm] + return ok +} + +// FilterListsByPerm returns list IDs filtered by either of the given perms. +func (u *User) FilterListsByPerm(listIDs []int, get, manage bool) []int { + // If the user has full list management permission, + // no further checks are required. + if get { + if _, ok := u.PermissionsMap[PermListGetAll]; ok { + return listIDs + } + } + if manage { + if _, ok := u.PermissionsMap[PermListManageAll]; ok { + return listIDs + } + } + + out := make([]int, 0, len(listIDs)) + + // Go through every list ID. + for _, id := range listIDs { + // Check if it exists in the map. + if l, ok := u.ListPermissionsMap[id]; ok { + // Check if any of the given permission exists for it. + if get { + if _, ok := l[PermListGet]; ok { + out = append(out, id) + } + } else if manage { + if _, ok := l[PermListManage]; ok { + out = append(out, id) + } + } + } + } + + return out +}