The following changes are made to add LMS user_id:
* Adds user_id scope to the JWT to provide the LMS user_id.
* JWT cookies always use the user_id claim.
ARCH-379
Scheduled emails show "unsubscribe" link if waffle switch `schedules.course_update_show_unsubscribe` is enabled, and
settings.ACE_ENABLED_POLICIES respects `bulk_email_optout`.
API endpoint allows GET/POST requests, which:
* GET asks for confirmation of opt-out
* POST accepts "unsubscribe" or "cancel", where "unsubscribe" creates the
Optout entry, and "cancel" does nothing.
When an unknown content type is encountered, it's imported as a
RawDescriptor, which will preserve the OLX and export it back out. But
if we import a course while an XBlock is installed and then export it
after that XBlock is removed, we export RawDescriptors that never got to
save the original OLX and have a blank "data" field. Attempting to
export this used to fail and break export altogether. We now test that
the export continues to complete, and just skips over anything it can't
serialize out.
Note that this will stil export pointers in the export, so if you
uninstalled a "AmazingBlock" and exported, you might see something like
the following in a vertical's XML::
<vertical display_name="Unit">
<amazing url_name="2edebb68d5734395a06b8a62b9bb677e"/>
</vertical>
However there would be no corresponding file at:
/amazing/2edebb68d5734395a06b8a62b9bb677e.xml
In fact, there would be no /amazing directory at all in the export.
The better long term solution is probably to leave the pointer as-is
and export some generic file that can't be mistaken for OLX (say a
JSON file) that represents the raw key-value data we have in
Modulstore for the now unknown XBlock type. However, this commit at
least keeps export from crashing out entirely.
Prior to this commit, the course api (/api/courses/v1/courses/)
performed all the work necessary to return all courses available
to the user, and then only actually returned on page's worth of those
courses.
With this change, the api now does the work incrementally, computing
only the data needed to fetch the courses up to and including the page
being returned. This still increases approximately linearly as
the page number accessed being increases, but should be more cache-friendly.
One side effect of this is that the max_page reported by pagination
will be an overestimate (it will include pages that are removed due
to a users access restrictions).
This change also changes the sort-order of courses being returned by the
course_api. By sorting by course-id, rather than course-number, we
can sort in the database, rather than in Python, and defer loading data
from the end of the list until it is requested.
REVMI-90
Whenever user selects a beta language on account settings page,
show a page level warning message that this language is not
fully translated along with action to revert.
LEARNER-5654