Skip to content

Make TaxonomyOrgView authz-aware to allow access for users with courses.manage_tags permission #448

Description

@BryanttV

Description

Currently, TaxonomyOrgView (which handles GET /taxonomies/?org=X) uses UserOrgFilterBackend, which relies on legacy role resolution (get_admin_orgs/get_user_orgs in rules.py). This means it only recognizes legacy roles (like OrgStaffRole, OrgInstructorRole, etc.). Users with openedx-authz roles, such as course_editor, return an empty list and hit queryset.none(), preventing them from seeing even global taxonomies.

To fix this, we need to extend the authz-aware pattern already used in ObjectTagTaxonomyOrgFilterBackend to UserOrgFilterBackend.

Key technical requirements for the solution:

  1. Reuse existing permissions: Do not create a new permission. Use the existing courses.manage_tags permission, which is already correctly assigned to course_editor, course_staff, and course_admin in the openedx-authz policy.
  2. Resolve scopes correctly: Since this endpoint receives an org instead of a course_key, and authz permissions are course-scoped, you cannot simply use is_user_allowed(user, perm, org). Instead, use get_scopes_for_user_and_permission(user, action) to retrieve the course keys where the user has the permission, extract the .org from those keys, and intersect it with the requested org.
  3. Additive logic (OR): This endpoint also serves Content Libraries (which use legacy roles) and courses where the authz toggle is disabled. The new authz check must be added as an OR condition to the legacy filter, rather than replacing it.

Expected Behavior

When a user with the courses.manage_tags permission requests taxonomies for a specific organization (GET /taxonomies/?org=X), the backend should successfully return the taxonomies. The system must evaluate the user's allowed scopes using get_scopes_for_user_and_permission, extract the organizations from those scopes, and allow access if there's a match, working seamlessly alongside the legacy role checks.

Current Behavior

UserOrgFilterBackend strictly evaluates legacy roles. If a user only has an openedx-authz role like course_editor, the legacy resolution returns empty lists, forcing an early queryset.none() return. This blocks the user from seeing any taxonomies, including global ones (where org=None).

Steps to reproduce

  1. Log in with a user who has an openedx-authz role (e.g., course_editor) in a course within a specific organization, but ensure they do not have any legacy roles (like OrgStaffRole or OrgInstructorRole).
  2. Navigate to a view or make a direct GET request to /taxonomies/?org=<org_id> for that organization.
  3. Observe that the endpoint returns an empty result (or the UI fails to display taxonomies) because the user's authz roles are completely ignored by the current filter backend.
  4. Log in with an account that has a legacy org role and repeat the request to see the taxonomies load successfully.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    willowReleased in Willow

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions