onaio / onaio/onadata

Add pagination, search and a role filter to the organizations list endpoint

Open
#3,263 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

API Discussion Module: Organizations
Dominant language
Python
Stars
188
Forks
142
Avg merge
2d 2h
Merged PRs (30d)
21

Description

Suggested Feature / Enhancement

GET /api/v1/orgs returns every organization the requesting user can access in a single response. There is no pagination, no way to search and no way to filter by the user's role; the only filter available today is shared_with.

Add three things to the endpoint:

  1. Pagination — support the page and page_size query params, the same way the projects and forms list endpoints already do.
  2. Search — support a search query param that matches against the organization's name and its username (the org field in the response).
  3. Role filter — support a role query param that returns only the organizations where the requesting user holds that role or a higher one. For example, ?role=manager returns the organizations the user manages or owns. This mirrors the role filter on the v2 projects endpoint.

All three should be combinable with each other and with the existing shared_with filter, e.g. GET /api/v1/orgs?role=manager&search=health&page=1&page_size=20.

Benefits of implementing the feature/enhancement

  • Users who belong to many organizations get a large response and a heavy query every time a client lists their organizations. Each item is also costly to build, since it includes the organization's users and their roles.
  • Clients that show an organization picker or typeahead currently have to download the full list and filter it themselves. Server-side search lets them request only what matches.
  • Clients that need "the organizations I can create a project in" or "the organizations I can transfer a project to" currently fetch every organization and look for their own entry in each users list. That only works while the client holds the full list. Once the list is paginated, a page may contain few or none of the matching organizations, so the role filter has to happen on the server.
  • It brings the endpoint in line with the projects, forms and data endpoints, which already paginate, and with the v2 projects endpoint, which already filters by role.

Suggested implementation plan(Steps to be taken to implement feature)

  1. Set pagination_class = StandardPageNumberPagination on OrganizationProfileViewSet. That class keeps the response body as a plain array and puts the page links in the Link header, so the response shape does not change for existing clients.
  2. Give the list queryset an explicit, stable ordering (the model defines none), so pages do not overlap or skip records.
  3. Add DRF's SearchFilter to the viewset's filter_backends with search_fields covering name and user__username, keeping the existing permission and shared_with filters in place. UserViewSet already uses the same approach.
  4. Add an organization role filter backend modelled on ProjectRoleFilter: read the role query param, return a 400 for an unknown role name, take that role's OrganizationProfile permission set and filter with get_objects_for_user(..., any_perm=False) so the result is "that role and above". Group permissions should count, since organization roles can be granted through teams, and the result should agree with what get_role_in_org reports in each item's users[].role.
  5. Decide how to treat roles below manager. On OrganizationProfile, only manager and owner hold permissions beyond view_organizationprofile, so a permission-based filter can tell apart owner, manager and above, and everyone else, but not editor from readonly or member. Supporting owner and manager covers the use cases above; lower role names could either be accepted (returning everything the user can view) or rejected.
  6. Decide on backwards compatibility for callers that send no page param: either always paginate with the default page size of 1000, as the projects endpoint does, or only paginate when page/page_size is supplied.
  7. Add tests for paging, page_size limits, the Link header, search by name and by username, role=manager returning managed and owned organizations, role=owner returning only owned ones, an unknown role returning a 400, the filters combined with each other and with shared_with, and that a user never sees organizations outside their permissions through search or the role filter.
  8. Document the new query params in docs/orgs.rst.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with OrganizationProfileViewSet, then compare the pagination and role-filter implementations used by the projects and forms list endpoints, ProjectRoleFilter, and UserViewSet. Check the existing organization endpoint tests before adding coverage for pagination, search, roles, combined filters, permissions, and the Link header; update docs/orgs.rst when the behavior and backwards-compatibility choice are settled.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
api, backend, documentation, testing
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.