Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Tagging] Taxonomies for Org API #74

Closed
pomegranited opened this issue Jul 20, 2023 · 7 comments · Fixed by openedx/edx-platform#32871
Closed

[Tagging] Taxonomies for Org API #74

pomegranited opened this issue Jul 20, 2023 · 7 comments · Fixed by openedx/edx-platform#32871

Comments

@pomegranited
Copy link

pomegranited commented Jul 20, 2023

Story

"As a content author, I want to see all the taxonomies available for use with my course, block, or library, so that I can tag my content."

Description

Implement a Python and a REST API that allows retrieving the full list of taxonomies given a certain block/context.
This API will be used to fetch the taxonomies relevant to creating/editing content on Studio.

Note: this API should be marked as “unstable” for the MVP.

Completion criteria

Build on/subclass the "taxonomy REST API view" added by #73, and implement this REST API endpoint:

/api/content_tagging/v1/taxonomy?org=<org>&enabled=True|False&page_size=<size>&page=1

  • Returns a paginated list of Taxonomy metadata (including their pks), with the same fields and serializers as the "oel_tagging taxonomy list view".
  • Always returns the system-defined and instance-wide Taxonomies (subject to the enabled parameter)
  • org parameter: (optional) Organization short name
    • Limits the returned taxonomies to the ones that are "owned by" the requested .
  • (optional) enabled parameter: bool (same behavior as [Tagging] Taxonomy view/management APIs #73)
    • If omitted, then returns both enabled and disabled Taxonomies.
    • If True, then returns only enabled Taxonomies
    • If False, then returns only disabled Taxonomies
  • Paginate this data, with a default MAX_PAGE_SIZE = 100, to allow most people to retrieve all of their taxonomies in one hit.
    People with more taxonomies will need to know where to go to get their next page of data, and so this endpoint should support that too.

Note: it's ok to adjust the openedx.features.content_tagging.rules to meet the behavioral requirements noted below.

Automated testing must cover common paths in behavioral specification.

Pagination

You're welcome to rename the pagination parameters and data specified here to whatever is the standard recommended by DRF Pagination or Django Pagination.

For your tests, feel free to set a more reasonable MAX_PAGE_SIZE to test the next page behavior.

Behavioral specifications

Suppose the Open edX instance has these taxonomies:

  • system-defined taxonomies: st1 (enabled), st2 (disabled)
  • 1 instance-wide taxonomy: t1 (enabled), t2 (disabled)
  • 2 taxonomies owned by organization A: tA1 (enabled), tA2 (disabled)
  • 2 taxonomies owned by organization B: tB1 (enabled), tB2 (disabled)
  • 2 taxonomies owned by both organizations A & B: tC1 (enabled), tC2 (disabled)

and the following users:

  • userA: ordinary, non-staff user

  • userS: global staff user

  • Anyone can view an enabled taxonomy or its tags

  • Only superusers or global staff can view a disabled taxonomy or its tags.

  • Only superusers or global staff can assign orgs to a taxonomy.
    These assigned "orgs" will be used to filter which taxonomies returned when the org parameter is provided for the list view, but don't affect taxonomy/tag permissions.

  • No users can add/edit/delete a system-defined taxonomy.

  • Only superusers or global staff can add/edit/delete a taxonomy (so long as it isn't system-defined)

  • Only superusers can add/edit/delete tags on a taxonomy (where allow_free_text=False)

  • No users can add/edit/delete tags on a free text taxonomy.

/api/content_tagging/v1/taxonomy/ -- returns all taxonomies the user is allowed to view.

  • When userA requests ^, they receive taxonomy metadata for these taxonomies: s1, t1, tA1, tB1, tC1
  • When userS requests ^ they receive taxonomy metadata for these taxonomies: s1, s2, t1, t2, tA1, tA2, tB1, tB2, tC1, tC2

/api/content_tagging/v1/taxonomy/context/?enabled=True -- returns enabled taxonomies the user is allowed to view.

  • When userA or userS requests ^, they receive taxonomy metadata for these taxonomies: s1, t1, tA1, tB1, tC1

/api/content_tagging/v1/taxonomy/context/?enabled=False -- returns disabled taxonomies the user is allowed to view.

  • When userA requests ^, they receive no taxonomy metadata at all
  • When userS requests ^ they receive taxonomy metadata for these taxonomies: s2, t2, tA2, tB2, tC2

/api/content_tagging/v1/taxonomy/?org=A -- returns taxonomies the user is allowed to view which are configured for use with content owned by org A

  • When userA requests ^, they receive taxonomy metadata for these taxonomies: s1, t1, tA1, tA2, tC1, tC2
  • When userS requests ^ they receive taxonomy metadata for these taxonomies: s1, s2, t1, t2, tA1, tA2, tC1, tC2

/api/content_tagging/v1/taxonomy/?org=B -- returns taxonomies the user is allowed to view which are configured for use with content owned by org B

  • When userA requests ^, they receive taxonomy metadata for these taxonomies: s1, t1, tB1, tB2, tC1, tC2
  • When userS requests ^ they receive taxonomy metadata for these taxonomies: s1, s2, t1, t2, tB1, tB2, tC1, tC2

/api/content_tagging/v1/taxonomy/?org=A&enabled=True -- returns enabled taxonomies the user is allowed to view which are configured for use with content owned by org A

  • When userA requests ^, they receive taxonomy metadata for these taxonomies: s1, t1, tA1, tC1
  • When userS requests ^ they receive taxonomy metadata for these taxonomies: s1, t1, tA1, tC1

/api/content_tagging/v1/taxonomy/?org=A&enabled=False -- returns disabled taxonomies the user is allowed to view which are configured for use with content owned by org A (No explicit use case exists for this combination, but it's included here for completeness.)

  • When userA requests ^, they receive no taxonomy metadata at all
  • When userS requests ^ they receive taxonomy metadata for these taxonomies: s2, t2, tA2, tC2

/api/content_tagging/v1/taxonomy/?org=X -- returns taxonomies the user is allowed to view which are configured for use with content owned by org X.
But there are no taxonomies configured for use with org X -- org X may not even exist -- and so only returns:

  • When userA requests ^, they receive taxonomy metadata for these taxonomies: s1, t1
  • When userS requests ^ they receive taxonomy metadata for these taxonomies: s1, s2, t1, t2

/api/content_tagging/v1/taxonomy/?page_size=2&page=3 -- returns "page 3 of the taxonomies the user is allowed to view.
Since we've specified page_size=2, we'd see the following returned taxonomies here:

  • When userA requests ^, they receive taxonomy metadata for these taxonomies: tC1
  • When userS requests ^ they receive taxonomy metadata for these taxonomies: tA1, tA2 (with next url providing page=4)

Documentation updates & improvements criteria

  • API endpoint and its parameters should be well-documented

Relevant PRs/repositories

@pomegranited pomegranited changed the title Taxonomy view API [Tagging] Taxonomy view API Jul 20, 2023
@pomegranited pomegranited changed the title [Tagging] Taxonomy view API [Tagging] Taxonomies for Org API Jul 20, 2023
@rpenido
Copy link

rpenido commented Jul 25, 2023

/api/content_tagging/v1/taxonomy/ -- returns all taxonomies the user is allowed to view.

  • When userA requests ^, they receive taxonomy metadata for these taxonomies: s1, t1, tA1, tA2, tC1, tC2
  • When userB requests ^, they receive taxonomy metadata for these taxonomies: s1, t1, tA1, tB1, tB2, tC1, tC2

Hi @pomegranited!
I think that is a typo here. It should be either:

  • When userA requests ^, they receive taxonomy metadata for these taxonomies: s1, t1, tA1, tA2, tB1, tC1, tC2
  • When userB requests ^, they receive taxonomy metadata for these taxonomies: s1, t1, tA1, tB1, tB2, tC1, tC2

Or:

  • When userA requests ^, they receive taxonomy metadata for these taxonomies: s1, t1, tA1, tA2, tC1, tC2
  • When userB requests ^, they receive taxonomy metadata for these taxonomies: s1, t1, tA1, tB1, tB2, tC1, tC2

I supose the former, right?

@pomegranited
Copy link
Author

Good catch, thank you @rpenido ! Issue updated with your first suggestion.

@rpenido
Copy link

rpenido commented Jul 28, 2023

/api/content_tagging/v1/taxonomy/?org=X -- returns taxonomies the user is allowed to view which are configured for use with content owned by org X. But there are no taxonomies configured for use with org X -- org X may not even exist -- and so only returns:

  • When userA requests ^, they receive taxonomy metadata for these taxonomies: s1, t1
  • When userB requests ^, they receive taxonomy metadata for these taxonomies: s1, t1
  • When userC requests ^, they receive taxonomy metadata for these taxonomies: s1, t1
  • When userS requests ^ they receive taxonomy metadata for these taxonomies: s1, s2, t1, t2

What about returning 400 with {'org': [ErrorDetail(string='Invalid organization short name', code='invalid')]} message in case orgX doesn't exist here?

@pomegranited
Copy link
Author

@rpenido I'm not sure.. it's ok to return a 400 for now, and if we need to change it to return an empty list, we can do that later.

@pomegranited pomegranited moved this from To do to In Progress in Modular Learning - Tagging and Libraries Aug 6, 2023
@pomegranited
Copy link
Author

I updated this issue with the effects of Product's amendment to our interpretation of taxonomy permissions:

we don't want to open up the possibility for anyone who can create a course to also create or edit a taxonomy. It needs to be more limited than that, so confining it to a superuser admin and global staff might be the best way forward

@rpenido
Copy link

rpenido commented Aug 9, 2023

Hi @pomegranited!

Some small questions:


  • userA: ordinary, non-staff user

This should be

  • userA: content creator for orgA, non-staff user

This doesn't change anything for the Taxonomy API, but only content creators will tag objects, right?


Is ok to restrict the list by user org?

/api/content_tagging/v1/taxonomy/ -- returns all taxonomies the user is allowed to view.

  • When userA requests ^, they receive taxonomy metadata for these taxonomies: s1, t1, tA1, tB1, tC1

  • When userS requests ^ they receive taxonomy metadata for these taxonomies: s1, s2, t1, t2, tA1, tA2, tB1, tB2, tC1, tC2

/api/content_tagging/v1/taxonomy/ -- returns all taxonomies the user is allowed to view.

  • When userA requests ^, they receive taxonomy metadata for these taxonomies: s1, t1, tA1, tC1
  • When userS requests ^ they receive taxonomy metadata for these taxonomies: s1, s2, t1, t2, tA1, tA2, tB1, tB2, tC1, tC2

/api/content_tagging/v1/taxonomy/context/?enabled=True -- returns enabled taxonomies the user is allowed to view.

  • When userA or userS requests ^, they receive taxonomy metadata for these taxonomies: s1, t1, tA1, tB1, tC1

/api/content_tagging/v1/taxonomy/context/?enabled=True -- returns enabled taxonomies the user is allowed to view.

  • When userA or userS requests ^, they receive taxonomy metadata for these taxonomies: s1, t1, tA1, tC1

@pomegranited
Copy link
Author

@rpenido

This doesn't change anything for the Taxonomy API, but only content creators will tag objects, right?

Correct -- users will have to be "content creators for the content object's org" in order to tag objects.

Is ok to restrict the list by user org?

No.

There is no need to involve the user's orgs here at all. It simplifies/speeds up the queries, and keeps the code simple too. This data is not protected or precious, so we don't need to treat it as such.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

Successfully merging a pull request may close this issue.

3 participants