Skip to content

Commit

Permalink
Refactor subscriber APIs list permission filtering.
Browse files Browse the repository at this point in the history
  • Loading branch information
knadh committed Oct 13, 2024
1 parent d9b4bae commit a268341
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 29 deletions.
8 changes: 4 additions & 4 deletions cmd/lists.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
33 changes: 8 additions & 25 deletions cmd/subscribers.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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
}
42 changes: 42 additions & 0 deletions models/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

0 comments on commit a268341

Please sign in to comment.