Implements the connection from the teams feature to the content groups feature. This implementation uses the dynamic partition generator extension point to associate content groups with the users that belong to a Team.
This implementation was heavily inspired by the enrollment tracks dynamic partitions.
* feat: Update search index when object tags updated
* feat: Update index when library block tags change
* refactor: Remove extra params
* docs: Add new event to hook events docs
* feat: Add and use upsert_block_tags_index_docs
This takes care of updating tags data in search index for both course and library blocks.
* chore: Update openedx-events
* fix: Update tests + include course block tags in reindex
* feat: Fix static-type issues + adjust tag_object
* fix: bug retrieving the Meilisearch API key UID (first time only)
* docs: Update comments
---------
Co-authored-by: Braden MacDonald <braden@opencraft.com>
* feat: adds SearchAccess model
Stores a numeric ID for each course + library, which will generally be
shorter than the full context_key, so we can pack more of them into the
the Meilisearch search filter.
Also:
* Adds data migration pre-populates the SearchAccess model from the existing
CourseOverview and ContentLibrary records
* Adds signal handlers to add/remove SearchAccess entries when content
is created or deleted.
* Adds get_access_ids_for_request() helper method for use in views.
* Adds tests.
* test: can't import content.search in lms tests
* feat: use SearchAccess in documents and views
* Adds an access_id field to the document, which stores the
SearchAccess.id for the block's context.
* Use the requesting user's allowed access_ids to filter search results
to documents with those access_ids.
* Since some users have a lot of individual access granted, limit the
number of access_ids in the filter to a large number (1_000)
* Updates tests to demonstrate.
* test: can't import content.search or content_staging in lms tests
* fix: make access_id field filterable
* fix: use SearchAccess.get_or_create in signal handlers
In theory, we shouldn't have to do this, because the CREATE and DELETE
events should keep the SearchAccess table up-to-date.
But in practice, signals can be missed (or in tests, they may be
disabled). So we assume that it's ok to re-use a SearchAccess.id created
for a given course or library context_key.
* refactor: refactors the view tests to make them clearer
Uses helper methods and decorators to wrap the settings and patches used
by multiple view tests.
* feat: adds org filters to meilisearch filter
* Uses content_tagging.rules.get_user_orgs to fetch the user's
content-related orgs for use in the meilisearch filter.
* Limits the number of orgs used to 1_000 to keep token size down
* refactor: removes data migration
Users should use the reindex_studio management command to populate SearchAccess.
* refactor: adds functions to common.djangoapps.student.role_helpers
to allow general access to the user's RoleCache without having to access
private attributes of User or RoleCache.
Related changes:
* Moves some functionality from openedx.core.djangoapps.enrollments.data.get_user_roles
to this new helper method.
* Use these new helper method in content_tagging.rules
* fix: get_access_ids_for_request only returns individual access
instead of all course keys that the user can read.
Org- and GlobalStaff access checks will handle the rest.
* fix: use org-level permissions when generating search filter
Also refactors tests to demonstrate this change for OrgStaff and
OrgInstructor users.
* refactor: remove SearchAccess creation signal handlers
Lets SearchAccess entries be created on demand during search indexing.
* feat: omit access_ids from the search filter that are covered by the user's org roles
---------
Co-authored-by: Rômulo Penido <romulo.penido@gmail.com>
[APER-3229]
The monolith and the Credentials IDA keep independent records of a course runs certificate availability/visibility preferences. This PR aims to improve the communication between the monolith and the Credentiala IDA to keep the availability date/preference in sync with the monoliths records.
The current code is too strict and actually prevents valid updates in some configurations.
Additionally, the Credentials IDA doesn't understand the concept of "course pacing" (instructor-paced vs self-paced) and has troubles with courses with an availability date of "end". Instead of having to add the concept of course pacing (and syncing more data between the two systems), this PR proposes sending the end date of a course as the "certificate available date" to Credentials.
This way, the Credentials IDA can manage the visibility of awarded credentials in a course run with a display behavior of "end" using the existing feature set and models of the Credentials service.
This does two major things:
* Removes subsections from a student's course outline if the
subsection's units are all restricted to a cohort that the student
is not a part of (see CohortPartitionGroupsOutlineProcessor).
* Removes sections from the course outline if the user is not allowed
to see any of its child subsections.
This retrieves user preferences for edxnotes visibility by:
1. Adding a `bind_course_for_student` method to course overview model.
2. Using a bound XBlock in the `toggle_notes.html` template.
The previously used unbound course instance was returning a default value.
This commit leaves behind just enough Old Mongo (DraftModulestore)
functionality to allow read-only access to static assets and the
root CourseBlock. It removes:
* create/update operations
* child/parent traversal
* inheritance related code
It also removes or converts tests for this functionality.
The ability to read from the root CourseBlock was maintained for
backwards compatibility, since top-level course settings are often
stored here, and this is used by various parts of the codebase,
like displaying dashboards and re-building CourseOverview models.
Any attempt to read the contents of a course by getting the
CourseBlock's children will return an empty list (i.e. it will look
empty).
This commit does _not_ delete content on MongoDB or run any sort of
data migration or cleanup.
* chore: typing + fixes for content_staging
* chore: typing + fixes for learning_sequences
* chore: typing + fixes for content_libraries
* chore: typing + fixes for new XBlock runtime
* feat: type hinting more code with mypy
This adds the ability to get a list of detailed courses based on their
keys provided in the newly added `keys` query param in the `GET /courses/v1/courses/`
endpoint.
Per this DEPR: https://github.com/openedx/public-engineering/issues/34
This was a temporary waffle and is no longer needed.
BREAKING_CHANGE: Setting the
`block_structure.raise_error_when_not_found` waffle switch via
django-waffle will be ignored.
Note for Operators: If you have this waffle swicth in your systems, it
should be removed.
An issue trying to get a course overview for a deleted course and trying
to write back into the DB had been raising unhandled errors. Catching
other classes of errors to keep this function from breaking. Should just
return None in these cases and log the exception.
This removes user-facing Studio edit support for Old Mongo courses
(courses that have a CourseKey of the format {org}/{course}/{run}).
This does not affect our normal courses, which have CourseKeys
starting with "course-v1:".
After this commit:
* Old Mongo courses will continue to appear on the Studio course
listing page, but are not clickable.
* Any attempt to directly access an Old Mongo course in Studio via URL
fail with a 404 error.
* Course certificates will still be available for Old Mongo courses.
* Old Mongo courses will continue to be returned by CourseOverviews
and get_course_summaries() calls.
We decided against removing Old Mongo courses from the listing entirely
because that would require very expensive CourseOverviews query to
filter them out. Making that query more efficient would involve a
database migration to add appropriate indexing, which is something else
that we are looking to avoid. CourseOverviews are used everywhere in
the system, so we want to avoid changing how they work so that we can
minimize risk.
This is part of the Old Mongo Modulestore deprecation effort:
https://github.com/openedx/public-engineering/issues/62