Refactor subscriber APIs list permission filtering.

This commit is contained in:
Kailash Nadh 2024-09-16 22:59:10 +05:30
parent d9b4bae0a8
commit a26834196e
3 changed files with 54 additions and 29 deletions

View file

@ -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.

View file

@ -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
}

View file

@ -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
}