Permalink
Switch branches/tags
HarryRein/Learner-Dashboard-v2-rearrange HarryRein/add-calendar-prototype HarryRein/course-run-selection-dashboard_rebase HarryRein/entitlements-without-sessions-prettify HarryRein/no-available-course-runs HarryRein/remove-header-waffle-flag-to-release-candidate LEARNER-1417/mobile_authentication LEARNER-1489/management-command-for-send-emails LEARNER-4881-add-button-to-student-account-page LEARNER-5032-create-retirement-queue-endpoint MLoTurco/learner-3925-create-modal MLoTurco/learner-3925-feature-main-component MLoTurco/learner-3925-remove-reason-field McKenzieW/learner-3472 REV-73 REV-620 REVE-156 Salomari/salah/copyright-year WL-399-backup aamishbaloch/YONK-643-B aamishbaloch/YONK-691 aamishbaloch/testing adam-hackathon-seq-depth-nudge adam/add-next-relationship adam/fix-flaky-bok-choy adam/fix-flaky-bokchoy adam/refactor-modulestore-serializer-initialization adam/update-neo4j-on-course-publish add-log-to-identify-instructor-enrollments add-missing-context-variables-for-portfolio-test add_cohort_to_metadata add_mobile_exclusion_for_vop_and_cgv3 add_modal adeel/learner_4904 adeel/learner_4909_reverting_learner_1487 adeel/learner_6611_exposing_selection_state adeel/learner_6729_dynamic_type_course_dates_fragment adeel/learner_6730_dynamic_type_for_xblocks_content aed/analytics-exporter-settings-hotfix-backup aed/analytics-exporter-settings-hotfix aed/badwords aed/grades-replica aed/short-label-transformer aed/visible-blocks-fix afzaledx/WL-869_language_preference afzaledx/email_template_path_change afzaledx/wl-774_filtered_list_of_programs afzaledx/wl-912_add_instructor_info_to_lms_course_api afzaledx/xblock_django_templates_i18n ahsan/LEARNER-635-program-page-LMS-bug ahsan/LEARNER-3759-secondary-signature-on-certificate-discovery ahsan/LEARNER-5654-Add-support-for-beta-languages ahsan/LEARNER-6039-Batch-completion-update ahsan/LEARNER-6194-add-jwt-authentication-classes-sandbox ahsan/LEARNER-6469 ahsan/LEARNER-6517-Remove-OAuth2AuthenticationAllowInactiveUser ai/fixed-failing-firefox-tests aj/LEARNER-6360_canonical_run aj/LEARNER-6360 aj/bump-studio-frontend aj/create-lti-sandbox aj/enable-cms-test aj/entitlement_prototype aj/fix-ccx-download-report-call aj/fix-celery-email-reistration aj/generate_cert_from_progress_page aj/pervent-course-regrade aj/remove_credit_change_enrollment aj/update-log alasdair/logistration-safe-template-updates alasdair/paragon-version-bump-2-6-4-up-to-3-0-5 ammar/EDUCATOR-2606-thumbnail-issue-with-hls arch/jwt-auth-consolidate arch/jwt-http-cookies arch/refactor-jwt-builder arch/remove-grades-v0 arch/remove-token-utils ari/account-settings-poc ari/backbone-tourniquet ari/eslint-es5-upgrade ari/graphql-client ari/pa11ycrawler-by-course ari/sfe-platform-webpack ari/sfe-webpack-cleanup ari/studio-components-poc ari/update-package-lock ari/webpack-require-docs arizzitano/pa11ycrawler-unique asad/educator-366-enable-quality-waffle asadiqbal08/ENT-769-Tests asadiqbal08/ENT-1115-New asadiqbal08/ENT-1115 asadiqbal08/WL-452 asadiqbal08/enterprise-version-bump-0.73.1 astankiewicz/populate-id-verification-aggregate-command atiya/add-logging-in-registration awais/fix_grading_flaky_test awais/lett_2_bc_advance_settings_III awais/lett_2_bc_advanced_settings_III awais/lett_2_bc_advanced_settings_2nd awais/lett_2_bc_course_create awais/lett_2_bc_course_info awais/lett_2_bc_courseware_word_cloud awais/lett_2_bc_discussion_component awais/lett_2_bc_discussion_components awais/lett_2_bc_grading_II awais/lett_2_bc_grading_III awais/lett_2_bc_grading_IV awais/lett_2_bc_grading_4 awais/lett_2_bc_html_editor_I awais/lett_2_bc_html_editor_2 awais/lett_2_bc_instructor_data_download awais/lett_2_bc_pages awais/lett_2_bc_problem_editor_I awais/lett_2_bc_psges_2 awais/lett_2_bc_registration awais/lett_2_bc_textbook awais/lett_2_bc_textbooks awais/lett_2_bokchoy_html_editor_2 awais/lettuce_conversion awais/remove_frading_flaky_test awais/removed_lettuce_tests_for_discussions ayeshabaig/WL-831 bbeggs/allowed-hosts bbeggs/asset_watch bbeggs/copyright bbeggs/data-16 bbeggs/django_111_urls_cleanup bbeggs/hawthorn-gdpr bbeggs/nose-mako-plugin bbeggs/queue_versioning bbeggs/test_drf bbeggs/ungdpr-password-reset bdero/bulk-enroll bdero/opencraft-celery-broker-tls bderusha/HACK/pw-reset-not-found bderusha/backpopulate-creds bderusha/hack-course-mode bderusha/verified-xblock-template benp/collect2 benp/hackathon-css-sourcemaps benp/paver-howtotest beryl/access-mode-enum beryl/celery-update beryl/gradez-sandbox beryl/spike-sequence-sql bessiesteinberg/REVE-23-test-staff-types bessiesteinberg/WL-1317-course-ouline-gated-content bessiesteinberg/add-waffle-flags bessiesteinberg/digital-book bessiesteinberg/gated-content-old bessiesteinberg/journals-dashboard-copy-course-dashboard bessiesteinberg/journals-dashboard bessiesteinberg/local-configs bessiesteinberg/modernize bexline/hackathon_xix bexline/on_blur_validation bexline/test_all_the_things bexline/test_sap_integration bfiller/REVE-39-fix bfiller/REVE-39 bfiller/REVE-88 bfiller/REVE-143 bfiller/add-journal-styles bfiller/debug-and-enterprise bfiller/enable-search bfiller/fix-dynamic-tabs bfiller/fix-journal-path bfiller/hackathon bfiller/journal-context-rework bfiller/journal-fragments bfiller/journal-prod-settings bfiller/mobile-test bfiller/ptvsd bfiller/sprint-demo bfiller/studio-s3 bfiller/whitelabel-journal bjacobel/inline-empty-state bjacobel/theme-dirs bjacobel/utik-2.0 bjacobel/webpack-bookmarks bmedx/PLAT-2179_update_duplicate_messages bmedx/pii_documentation business/applewood business/camembert business/etorki business/fontina business/hornets business/improptu business/kasseri business/locusts business/mostly_cloudy business/sprint_k business/sprint_l business/sprint_m business/sprint_n business/sprint_v business/sprint_w business/sprint_x cdyer/ubcpi-0.6.0 cdyer/version-visblocks christina/add-radio-buttons christina/capa-graded christina/ed-427 christina/enrollment_track_partition_review_pre_squash christina/multiple-hints clee/LEARNER-1278 clee/add-country clee/edx-mktg clee/hack cliff/aggregator-integration-tests cliff/aggregator-settings cliff/completion-exclude-discussions cliff/completion-tests cliff/extract-opaque-key-fields cliff/score-completion-preconditions clintonb/api-docs clintonb/chromecast clintonb/resend-credit-request clintonb/video.js clrux/ac-530-ccx-fix clrux/ac-551 clrux/ac-553-zooming-image-tool clrux/ac-555-codemirror cookie-policy-banner-1.1.5 cornwell/create-model coryleeio/OPS-3008 cpappas/ENT-1026 cpappas/hackathon credo_ospr cstenson/has_purchased_metadata dahlia/proctoring-master dahlia/react-backbone-discovery dcs/remove-verifiedcohort diana/fix-a11y-test diana/interpolated-video diana/remove-datadog diana/remove-old-logistration diana/update-login-registration-tests diana/view-course-before-start douglashall/ENT-307 douglashall/allow_subdomain_redirects douglashall/csrf-spa douglashall/dot_upgrade_fix douglashall/enterprise_0_34_3 douglashall/logistration_redesign douglashall/oauth_scopes_final douglashall/oauth_scopes_part1 douglashall/oauth_scopes douglashall/program_detail douglashall/susy-reup douglashall/translations dsheraz/educator_1714_special_exam_config dsheraz/educator_3764 dump-to-neo4j-updates e0d/INCR-27 e0d/test-jenkins edx-pacing/studio-modal efischer/nomerge efischer/ospr_add_jest efischer/ospr_base efischer/revert_cale ekafeel/fedx-161-alt ekafeel/fedx-161-no-condition ekafeel/fedx-175-show-warning ekafeel/solution-accessibility ekafeel/video-test-fix emma-green/bundle-discount-adding-type-and-title emma-green/hackathonXX-accessibility-stuffs emma-green/reve-74/make-sure-content-experiments-work-b emma-green/reve-74/make-sure-content-experiments-work emma.green/rev-bundling-fix-bundle-info enable-content-gate-partition-when-override-enabled escalations/LEARNER-6668 estute/TE-846 estute/TE-2456 estute/TE-2481 estute/TE-2488 estute/TE-2544-a11y estute/TE-2544 estute/TE-2660 estute/TE-2680 estute/adjust-codecov-to-fail-builds estute/bump-npm-installation-timeouts estute/cherry-pick-19038 estute/cherry-pick-npm-cache-loading estute/ci-testing-django-versions estute/django-1.11-ci-tests estute/dummy-commit estute/dummy-for-testing estute/env-var-to-disable-coverage estute/experiment2 estute/fake-target-branch estute/fake-target-for-sharding estute/fetch-correct-target-branch estute/ficus-job-testing estute/ficus-testing-branch estute/fixup-toxenv-var estute/flaky-unit-test-shakeout estute/flaky-xdist estute/force-clean-npm-cache estute/ginkgo-testing-branch estute/hanging-geckodriver estute/hard-fail-on-ecs-not-spinning-up estute/jenkins-testing-branch estute/load-npm-cache-on-jenkins-workers estute/move-nodenv-to-requirements estute/new-worker-testing estute/no-violations estute/npm-cache-experiment estute/packer-testing-branch estute/parallelize-pylint estute/patch-1 estute/paver-db-caching-automation-for-jenkins estute/python-shard-testing estute/remove-circle-ci estute/remove-dead-ip-filter-functions estute/remove-flaky-proctor-exam-test estute/remove-paver-timeout-decorator estute/reopen-aws_with_filesystem_storage estute/reorder-a11y-script estute/run-a11y-tests-w-firefox estute/run-codecov-on-platform estute/run-lettuce-tests-with-chromium estute/run-lettuce-tests-with-firefox estute/run-lettuce-w-chrome estute/speed-ci estute/targetting-the-shards estute/test-disable-a11y-services-via-bokchoy estute/testing-django-1-11-ci estute/testing-hawthorn estute/testing-new-workers estute/testing-pr estute/testing-py3-ci-scripts estute/testing-python3 estute/update-edx-lint-version estute/update-lettuce-db-caches estute/use-cached-prereqs estute/use-codecov-for-unittest-coverage estute/video-tests failing_karma_test feanil/simplify_logging fsheets/fix-unicode fsheets/print-course fsheets/sfe-test gabe/block-fields gh-pages-obsolete greenkeeper/initial hack/learner_dashboard hack/physical_certs hack_xix/PLAT-1402 hack14/student_account_cleanup hackathon/celebration hackathon/universal-header hackathon13/swagger-api-doc hammad/WL-1798 handler_test has-access-tests hasnain-naveed/WL-474/Boilerplate-theme hasnain-naveed/WL-912 hasnain-naveed/WL-993 hasnain-naveed/WL-1559 hasnain-naveed/WL-1645 hasnain-naveed/instructor-uuid-population hasnain-naveed/make-certificate-celery-task-site-compatible hasnain-naveed/marko437-afzal1146-ibrhim-merged hasnain-naveed/program-detail-front-end/WL-819 hasnain-naveed/program-detail-view-test hasnain-naveed/program-detail/WL-766 hotfix/2016-07-20 hotfix/2016-11-22 hotpatch/TNL-3818 ibrahimahmed443/MAYN-280-explore-new-courses-button-fix-revert ibrahimahmed443/OLIVE-49-partners-url ibrahimahmed443/OLIVE-50-partner-description ibrahimahmed443/WL-819_program_details_frontend ibrahimahmed443/WL-1150 ibrahimahmed443/WL-1365-templates-refactor ibrahimahmed443/WL-1491-dashboard-changes ibrahimahmed443/program-details-changes ibrahimahmed443/program-details-start-button-fix ibrahimahmed443/programs-changes ibrahimahmed443/receipt-callback ibrahimahmed443/temp-LEARNER-316 ibrahimahmed443/whitelabel/journal ibrahimahmed443/wl-819_program_details_ui inmates/export-course inmates/video-export jaebradley-paragon-react-16 jaebradley-peer-dependency-warnings jbarciauskas/add-developers-guide-to-release-section jbarciauskas/ospr-1429-account-me-api jdmulloy/ormsbee/old_mongo_migration jdmulloy/remove_devstack_py jeskew/PLAT_2001_retire_lms_user jeskew/bump_completion_organizations jeskew/codejail_move_to_master_branch jeskew/fix_lms_shard_4_tests_django_111-BACKUP jeskew/remove_more_pytest_warnings jia/MA-2497 jia/MA-2684-courserun-cache jia/MA-2684-new jia/MA-3052-fix jia/disable-course-run-integration jibsheet/better-auth_user-searches jibsheet/enable-memcachedhashring jibsheet/limit-django-admin jibsheet/send_client_name_to_newrelic jkantor/list-user-roles jlajoie/EDUCATOR-12 jlajoie/EDUCATOR-369 jlajoie/LEARNER-5050 jlajoie/add-course-discussion-settings jmbowman/TE-2647 jmbowman/omit_capture_on_passing_tests karma_test kashif/bokchoy_experiment kkim/time_zone_AS kkim/visual_trigger lett_2_bc_lti_consumer_tests loadtest mahyard malikshahzad228/SOL-1811 marco/dashboard/spacing-adjustment marco/dashboard/upgrade-message-update marco/lti-button-style master mattdrayer/profiler-merge matthugs/mockprock-to-dev-dependencies matthugs/webpack-prod-experiment mikix/es2015-course-search mikix/password-history-removal mikix/visible_date mjfrey/hackathon move-babel-to-dependencies mrehan/bump-platform-lti-version mrehan/fix-coursekey-parsing mrehan/safe-templates mrehan/transcript-ajax-handlers mroytman/EDUCATOR-3799-remove-rules-configuration mroytman/remove-waffle-flags-switches mroytman/sandbox-studio-frontend mroytman/studio-frontend-sandbox mroytman/update-enable-checklists-quality-waffle-flag muddasser/bok-choy-to-lettuce/advanced-settings muddasser/lettuce-to-bok/cms/advanced_settings_full muddasser/lettuce-to-bok/cms/advanced_settings mulby/ace-push-notification-support mulby/ace-test mulby/extract-dynamic-deadline-method mulby/fix-settings-order mulby/support-transactional-email mushtaq/fix-svg-text-html-transformation mushtaq/slideout-course-video-settings-pane mwg/docs-cleanup mzfr/bookmarks-txt-tnl6346 mzfr/transcripts-settings na/TNL-5718 naa/test named-release/birch.rc named-release/cypress.rc named-release/dogwood.rc ned/update-codejail nedbat/pylint-19-pylint-django nedbat/remove-unused-features nedbat/restore-docs nedbat/stop-edx-subdomains nedbat/unicode-format-check nedbat/update-edx-lint neem/course-blocks-staff-fields neem/revert_grade_reports noraiz/EDUCATOR-848 noraiz/EDUCATOR-2773 noraiz/EDUCATOR-3016-fix noraiz/EDUCATOR-3074_lms_setting noraiz/EDUCATOR-3091 noraiz/EDUCATOR-3292 noraiz/EDUCATOR-3296 noraiz/EDUCATOR-3416 noraiz/EDUCATOR-3518 noraiz/EDUCATOR-3602 noraiz/EDUCATOR-3603 noraiz/EDUCATOR-3612 noraiz/EDUCATOR-3655 noraiz/edx-val-version-update-EDUCATOR-3794 noraiz/test-fix-on-sandbox-EDUCATOR-1696 noraiz/test-on-sandbox notification olive open-release/eucalyptus.master open-release/ficus.master open-release/ficus.1 open-release/ginkgo.master open-release/hawthorn.beta1 open-release/hawthorn.master open_response_assessment_tab_for_instructor_dashboard openedx-workshop-sfe ormsbee/block-cache-storage-v2 ormsbee/faster_test_startup ormsbee/faster_tests_verify_student ormsbee/faster_webpack_config ormsbee/fix_ccx_data_migration ormsbee/forum_roles_caching ormsbee/hackathon_csv_certs ormsbee/kill_html_vscompat ormsbee/old_mongo_migration ormsbee/proxyblock ormsbee/remove_common_static ormsbee/rerun_with_start_date ormsbee/test_startup_patch_loaddata ormsbee/urls_reset_madness ormsbee/xblock_viewify_hiddenmodule pa11ycrawler-unicode peter-fogg/safe-templates phase2-transcripts-work prevent_activation_time_error private_to_public_06d4044 private_to_public_7a92944 program_fragments_dynamic_type_text progressive-profile pwnage101/bump-django-to-1.10 pwnage101/bump-django-to-1.11-memory-monitoring pwnage101/collectstatic_works_for_1.11_no_wiki_change pwnage101/django-1.10-from-rc pwnage101/hackachat-3 pwnage101/hackachat raees/update-bootstrap re-add-asset-index-changes refactor-xsslint-again release-2016-10-05-conflict2 release-candidate-1337 release-candidate-1530 release-candidate-1641 release-candidate-1642 release-candidate-1643 release-candidate-1644 release-candidate-1645 release-candidate-1646 release-candidate-1647 release-candidate-1648 release-candidate-1649 release-candidate-1650 release-candidate-1651 release-candidate-1652 release-candidate-1653 release-candidate-1654 release-candidate-1655 release-candidate-1656 release-candidate-1657 release-candidate-1658 release-candidate-1659 release-candidate-1660 release-candidate-1661 release-candidate-1662 release-candidate-1663 release-candidate-1664 release-candidate-1665 release-candidate-1666 release-candidate-1667 release-candidate-1668 release-candidate-1669 release-candidate-1670 release-candidate-1671 release-candidate-1672 release-candidate-1673 release-candidate-1674 release-candidate-1675 release-candidate-1676 release-candidate-1677 release-candidate-1678 release-candidate-1679 release-candidate-1680 release-candidate-1681 release-candidate-1682 release-candidate-1683 release-candidate-1684 release-candidate-1685 release-candidate-1686 release-candidate-1687 release-candidate-1688 release-candidate-1689 release-candidate-1690 release-candidate-1691 release-candidate-1692 release-candidate-1693 release-candidate-1694 release-candidate-1695 release-candidate-1696 release-candidate-1697 release-candidate-1698 release-candidate-1699 release-candidate-1700 release-candidate-1701 release-candidate-1702 release-candidate-1703 release-candidate-1704 release-candidate-1705 release-candidate-1706 release-candidate-1707 release-candidate-1708 release-candidate-1709 release-candidate-1710 release-candidate-1711 release-candidate-1712 release-candidate-1713 release-candidate-1714 release-candidate-1715 release-candidate-1716 release-candidate-1717 release-candidate-1718 release-candidate-1719 release-candidate-1720 release-candidate-1721 release-candidate-1722 release-candidate-1723 release-candidate-1724 release-candidate-1725 release-candidate-1726 release-candidate-1727 release-candidate-1728 release-candidate-1729 release-candidate-1730 release-candidate-1731 release-candidate-1732 release-candidate-1733 release-candidate-1734 release-candidate-1735 release-candidate-1736 release-candidate-1737 release-candidate-1738 release-candidate-1739 release-candidate-1740 release-candidate-1741 release-candidate-1742 release-candidate-1743 release-candidate-1744 release-candidate-1745 release-candidate-1746 release-candidate-1747 release-candidate-1748 release-candidate-1749 release-candidate-1750 release-candidate-1751 release-candidate-1752 release-candidate-1753 release-candidate-1754 release-candidate-1755 release-candidate-1756 release-candidate-1757 release-candidate-1758 release-candidate-1759 release-candidate-1760 release-candidate-1761 release-candidate-1762 release-candidate-1763 release-candidate-1764 release-candidate-1765 release-candidate-1766 release-candidate-1767 release-candidate-1768 release-candidate-1769 release-candidate-1770 release-candidate-1771 release-candidate-1772 release-candidate-1773 release-candidate-1774 release-candidate-1775 release-candidate-1776 release-candidate-1777 release-candidate-1778 release-candidate-1779 release-candidate-1780 release-candidate-1781 release-candidate-1782 release-candidate-1783 release-candidate-1784 release-candidate-1785 release-candidate-1786 release-candidate-1787 release-candidate-1788 release-candidate-1789 release-candidate-1790 release-candidate-1791 release-candidate-1792 release-candidate-1793 release-candidate-1794 release-candidate-1795 release-candidate-1796 release-candidate-1797 release-candidate-1798 release-candidate-1799 release-candidate-1800 release-candidate-1801 release-candidate-1802 release-candidate-1803 release-candidate-1804 release-candidate-1805 release-candidate-1806 release-candidate-1807 release-candidate-1808 release-candidate-1809 release-candidate-1810 release-candidate-1811 release-candidate-1812 release-candidate-1813 release-candidate-1814 release-candidate-1815 release-candidate-1816 release-candidate-1817 release-candidate-1818 release-candidate-1819 release-candidate-1820 release-candidate-1821 release-candidate-1822 release-candidate-1823 release-candidate-1824 release-candidate-1825 release-candidate-1826 release-candidate-1827 release-candidate-1828 release-candidate-1829 release-candidate-1830 release-candidate-1831 release-candidate-1832 release-candidate-1833 release-candidate-1835 release-candidate-1836 release-candidate-1837 release-candidate-1838 release-candidate-1839 release-candidate-1840 release-candidate-1841 release-candidate-1842 release-candidate-1843 release-candidate-1844 release-candidate-1845 release-candidate-1846 release-candidate-1847 release-candidate-1848 release-candidate-1849 release-candidate-1850 release-candidate-1851 release-candidate-1852 release-candidate-1853 release-candidate-1854 release-candidate-1855 release-candidate-1856 release-candidate-1857 release-candidate-1858 release-candidate-1859 release-candidate-1860 release-candidate-1861 release-candidate-1862 release-candidate-1863 release-candidate-1864 release-candidate-1865 release-candidate-1866 release-candidate-1867 release-candidate-1868 release-candidate-1869 release-candidate-1870 release-candidate-1871 release-candidate-1872 release-candidate-1873 release-candidate-1874 release-candidate-1875 release-candidate-1876 release-candidate-1877 release-candidate-1878 release-candidate-1879 release-candidate-1880 release-candidate-1881 release-candidate-1882 release-candidate-1883 release-candidate-1884 release-candidate-1885 release-candidate-1886 release-candidate-1887 release-candidate-1888 release-candidate-1889 release-candidate-1890 release-candidate-1891 release-candidate-1892 release-candidate-1893 release-candidate-1894 release-candidate-1895 release-candidate-1896 release-candidate-1897 release-candidate-1898 release-candidate-1899 release-candidate-1900 release-candidate-1901 release-candidate-1902 release-candidate-1903 release-candidate-1904 release-candidate-1905 release-candidate-1906 release-candidate-1907 release-candidate-1908 release-candidate-1909 release-candidate-1910 release-candidate-1911 release-candidate-1912 release-candidate-1913 release-candidate-1914 release-candidate-1915 release-candidate-1916 release-candidate-1917 release-candidate-1918 release-candidate-1919 release-candidate-1920 release-candidate-1921 release-candidate-1922 release-candidate-1923 release-candidate-1924 release-candidate-1925 release-candidate-1926 release-candidate-1927 release-candidate-1928 release-candidate-1929 release-candidate-1930 release-candidate-1931 release-candidate-1932 release-candidate-1933 release-candidate-1934 release-candidate-1935 release-candidate-1936 release-candidate-1937 release-candidate-1938 release-candidate-1939 release-candidate-1940 release-candidate-1941 release-candidate-1942 release-candidate-1943 release-candidate-1944 release-candidate-1945 release-candidate-1946 release-candidate-1947 release-candidate-1948 release-candidate-1949 release-candidate-1950 release-candidate-1951 release-candidate-1952 release-candidate-1953 release-candidate-1954 release-candidate-1955 release-candidate-1956 release-candidate-1957 release-candidate-1958 release-candidate-1959 release-candidate-1960 release-candidate-1961 release-candidate-1962 release-candidate-1963 release-candidate-1964 release-candidate-1965 release-candidate-1966 release-candidate-1967 release-candidate-1968 release-candidate-1969 release-candidate-1970 release-candidate-1971 release-candidate-1972 release-candidate-1973 release-candidate-1974 release-candidate-1975 release-candidate-1976 release-candidate-1977 release-candidate-1978 release-candidate-1979 release-candidate-1980 release-candidate-1981 release-candidate-1982 release-candidate-1983 release-candidate-1984 release-candidate-1985 release-candidate-1986 release-candidate-1987 release-candidate-1988 release-candidate-1989 release-candidate-1990 release-candidate-1991 release-candidate-1992 release-candidate-1993 release-candidate-1994 release-candidate-1995 release-candidate-1996 release-candidate-1997 release-candidate-1998 release-candidate-1999 release-candidate-2000 release-candidate-2001 release-candidate-2002 release-candidate-2003 release-candidate-2004 release-candidate-2005 release-candidate-2006 release-candidate-2007 release-candidate-2008 release-candidate-2009 release-candidate-2010 release-candidate-2011 release-candidate-2012 release-candidate-2013 release-candidate-2014 release-candidate-2015 release-candidate-2016 release-candidate-2017 release-candidate-2018 release-candidate-2019 release-candidate-2020 release-candidate-2021 release-candidate-2022 release-candidate-2023 release-candidate-2024 release-candidate-2025 release-candidate-2026 release-candidate-2027 release-candidate-2028 release-candidate-2029 release-candidate-2030 release-candidate-2031 release-candidate-2032 release-candidate-2033 release-candidate-2034 release-candidate-2035 release-candidate-2036 release-candidate-2037 release-candidate-2038 release-candidate-2039 release-candidate-2040 release-candidate-2041 release-candidate-2042 release-candidate-2043 release-candidate-2044 release-candidate-2045 release-candidate-2046 release-candidate-2047 release-candidate-2048 release-candidate-2049 release-candidate-2050 release-candidate-2051 release-candidate-2052 release-candidate-2053 release-candidate-2054 release-candidate-2055 release-candidate-2056 release-candidate-2057 release-candidate-2058 release-candidate-2059 release-candidate-2060 release-candidate-2061 release-candidate-2062 release-candidate-2063 release-candidate-2064 release-candidate-2065 release-candidate-2066 release-candidate-2067 release-candidate-2068 release-candidate-2069 release-candidate-2070 release-candidate-2071 release-candidate-2072 release-candidate-2073 release-candidate-2074 release-candidate-2075 release-candidate-2076 release-candidate-2077 release-candidate-2078 release-candidate-2079 release-candidate-2080 release-candidate-2081 release-candidate-2082 release-candidate-2083 release-candidate-2084 release-candidate-2085 release-candidate-2086 release-candidate-2087 release-candidate-2088 release-candidate-2089 release-candidate-2090 release-candidate-2091 release-candidate-2092 release-candidate-2093 release-candidate-2094 release-candidate-2095 release-candidate-2096 release-candidate-2097 release-candidate-2098 release-candidate-2099 release-candidate-2100 release-candidate-2101 release-candidate-2102 release-candidate-2103 release-candidate-2104 release-candidate-2105 release-candidate-2106 release-candidate-2107 release-candidate-2108 release-candidate-2109 release-candidate-2110 release-candidate-2111 release-candidate-2112 release-candidate-2113 release-candidate-2114 release-candidate-2115 release-candidate-2116 release-candidate-2117 release-candidate-2118 release-candidate-2119 release-candidate-2120 release-candidate-2121 release-candidate-2122 release-candidate-2123 release-candidate-2124 release-candidate-2125 release-candidate-2126 release-candidate-2127 release-candidate-2128 release-candidate-2129 release-candidate-2130 release-candidate-2131 release-candidate-2132 release-candidate-2133 release-candidate-2134 release-candidate-2135 release-candidate-2136 release-candidate-2137 release-candidate-2138 release-candidate-2139 release-candidate-2140 release-candidate-2141 release-candidate-2142 release-candidate-2143 release-candidate-2144 release-candidate-2145 release-candidate-2146 release-candidate-2147 release-candidate-2148 release-candidate-2149 release-candidate-2150 release-candidate-2151 release-candidate-2152 release-candidate-2153 release-candidate-2154 release-candidate-2155 release-candidate-2156 release-candidate-2157 release-candidate-2158 release-candidate-2159 release-candidate-2160 release-candidate-2161 release-candidate-2162 release-candidate-2163 release-candidate-2164 release-candidate-temp release-candidate release-mergeback-to-master release remove-upsell-modal-click responsive-cleanups/wave-two responsive-header-cleanup-marco ret/backup-for-handle-multiple-emails ret/email-policies ret/remove-get-logging-config rev/content-gating-spike rev/content-gating-upsell rev/content-gating-waffle rev/handle-missing-duration revert-13392-atiya/add-retries-in-registration revert-14199-revert-wajeeha revert-15289-jlajoie/EDUCATOR-434 revert-15592-yro-cert-pacing-signal revert-17049-improve-logging-over-generate-cert-btn revert-17486-jmbowman/PLAT-1957 revert-17777-mrehan/remove-subs-from-metadata revert-temp-log revert-transcript-escape ri/EDUCATOR-1648-edx-proctoring-commit ri/EDUCATOR-1672-edx-organizations-commit ri/TNL-6425-fix-show-discussion-button ri/add-flaky-tests robrap/ARCH-247-remove-jwt-cookie-flag robrap/hackathon-impersonate roux/base_commit roux/discussions-before-the-fix roux/remove-copied-assets roux/rollback-platform roux/sandbox-experiment sailthru saleem-latif/ENT-1080 saleem-latif/ENT-1116 saleem-latif/ENT-1117 saleem-latif/SOL-1951-patch-release sarahkf/components-with-translation sarahkf/fix-bokchoy-failure sarahkf/pa11crawler-supported-components schen/install_react_gradebook scrape-youtube-video-images shr/bug/plat-1048-Course-blocks-api-opaque-Key-equality solutions/data-sharing-consent sstudent/EDUCATOR-2731 sstudent/TNL-6281 sstudent/delete_state_ sstudent/revert-TNL-4924 switch-container-factory-to-webpack sylvia/DOC-2582 tasawer/learner-5867/fix-contrast-of-button-on-contact-us-page test-super-user-access test/find_one testeng/bokchoy_auto_cache_update_b480b115d499240404ff58542305060895d74c9a testeng/bokchoy_auto_cache_update_e4252594b6cdd4fc097ce348cb47b6dd1e819283 testeng/bokchoy_auto_cache_update_3a4db00b04d315cb68bf3d501b28459713bbd9ed testeng/bokchoy_auto_cache_update_4b964c58e34263236d695b1e89e8ea1941e5e87e testeng/bokchoy_auto_cache_update_5b5d9cb0eb5453505fd8c9da80ee0607b26b2f6c testeng/bokchoy_auto_cache_update_5f06ea40003105ed26d042509c33f30d67aa5e6e testeng/bokchoy_auto_cache_update_8b0dc337feb1179c171751524b53126652d38052 testeng/bokchoy_auto_cache_update_8f2fbeb4aa089dd756f7a7628d5cdecde61ec354 testeng/bokchoy_auto_cache_update_133ba73954bdfcee6d76985a04f8e94af5b1e533 testeng/bokchoy_auto_cache_update_446ca1f49b46ee2aa82263fd6a190181702d6c6e testeng/bokchoy_auto_cache_update_67075dab4603b6bf8974c4c8274c1e1afc7db301 testeng/bokchoy_auto_cache_update_6446814ca76db06622fb199022107e5357090aa2 thallada/PLAT-1849-remove-sys-path-hacks thallada/SFE-aria-live-fix thallada/assets-search-ui thallada/remove-course-structure thallada/sfe-styles-isolation thallada/studio-frontend thallada/xss-lint-edx-htmlutils tuchfarber/REV-351 tuchfarber/add_usd_to_content_gating tuchfarber/content_gating_i18n update-numpy-test update-problem-builder update-translation-strings update_mobile_exclusion waheed/LEARNER-4434-discovery-support-beta-langs whitelabel/journal xiaolu/shared_field youngstrom/add-quality-jenkinsfile youngstrom/commit youngstrom/npm-install-unittests youngstrom/one-comm youngstrom/test_middleware_flakiness youngstrom/testing-jenkinsfile youngstrom/try-one-process youngstrom/xdist-flaky-test zafft/analytics-exporter-hotfix-admin-jenkins zafft/analytics-exporter-settings-hotfix ziafazal/SOL-2107 ziafazal/WL-1543 ziafazal/WL-1572 ziafazal/WL-1796 ziafazal/WL-1810 ziafazal/YONK-512 ziafazal/YONK-523 ziafazal/gating-exclude-non-completable ziafazal/recursive-inheritance zoldak/TE-1672 zoldak/TE-2319 zoldak/easier-packer-troubleshooting zoldak/noop-tests zoldak/remove-gitpy-requirement zoldak/swagger zub/sol-2107-instructor-dashboard-add-seat-type-selection
Nothing to show
Find file Copy path
792 lines (636 sloc) 34.7 KB
"""
The Enrollment API Views should be simple, lean HTTP endpoints for API access. This should
consist primarily of authentication, request validation, and serialization.
"""
import logging
from course_modes.models import CourseMode
from django.core.exceptions import ObjectDoesNotExist
from django.utils.decorators import method_decorator
from edx_rest_framework_extensions.auth.jwt.authentication import JwtAuthentication
from edx_rest_framework_extensions.auth.session.authentication import SessionAuthenticationAllowInactiveUser
from enrollment import api
from enrollment.errors import CourseEnrollmentError, CourseEnrollmentExistsError, CourseModeNotFoundError
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey
from openedx.core.djangoapps.cors_csrf.authentication import SessionAuthenticationCrossDomainCsrf
from openedx.core.djangoapps.cors_csrf.decorators import ensure_csrf_cookie_cross_domain
from openedx.core.djangoapps.embargo import api as embargo_api
from openedx.core.djangoapps.user_api.accounts.permissions import CanRetireUser
from openedx.core.djangoapps.user_api.models import UserRetirementStatus
from openedx.core.djangoapps.user_api.preferences.api import update_email_opt_in
from openedx.core.djangoapps.course_groups.cohorts import add_user_to_cohort, get_cohort_by_name, CourseUserGroup
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUser
from openedx.core.lib.api.permissions import ApiKeyHeaderPermission, ApiKeyHeaderPermissionIsAuthenticated
from openedx.core.lib.exceptions import CourseNotFoundError
from openedx.core.lib.log_utils import audit_log
from openedx.features.enterprise_support.api import (
ConsentApiServiceClient,
EnterpriseApiException,
EnterpriseApiServiceClient,
enterprise_enabled
)
from rest_framework import permissions, status
from rest_framework.response import Response
from rest_framework.throttling import UserRateThrottle
from rest_framework.views import APIView
from six import text_type
from student.auth import user_has_role
from student.models import User
from student.roles import CourseStaffRole, GlobalStaff
from util.disable_rate_limit import can_disable_rate_limit
log = logging.getLogger(__name__)
REQUIRED_ATTRIBUTES = {
"credit": ["credit:provider_id"],
}
class EnrollmentCrossDomainSessionAuth(SessionAuthenticationAllowInactiveUser, SessionAuthenticationCrossDomainCsrf):
"""Session authentication that allows inactive users and cross-domain requests. """
pass
class ApiKeyPermissionMixIn(object):
"""
This mixin is used to provide a convenience function for doing individual permission checks
for the presence of API keys.
"""
def has_api_key_permissions(self, request):
"""
Checks to see if the request was made by a server with an API key.
Args:
request (Request): the request being made into the view
Return:
True if the request has been made with a valid API key
False otherwise
"""
return ApiKeyHeaderPermission().has_permission(request, self)
class EnrollmentUserThrottle(UserRateThrottle, ApiKeyPermissionMixIn):
"""Limit the number of requests users can make to the enrollment API."""
# To see how the staff rate limit was selected, see https://github.com/edx/edx-platform/pull/18360
THROTTLE_RATES = {
'user': '40/minute',
'staff': '120/minute',
}
def allow_request(self, request, view):
# Use a special scope for staff to allow for a separate throttle rate
user = request.user
if user.is_authenticated and (user.is_staff or user.is_superuser):
self.scope = 'staff'
self.rate = self.get_rate()
self.num_requests, self.duration = self.parse_rate(self.rate)
return self.has_api_key_permissions(request) or super(EnrollmentUserThrottle, self).allow_request(request, view)
@can_disable_rate_limit
class EnrollmentView(APIView, ApiKeyPermissionMixIn):
"""
**Use Case**
Get the user's enrollment status for a course.
**Example Request**
GET /api/enrollment/v1/enrollment/{username},{course_id}
**Response Values**
If the request for information about the user is successful, an HTTP 200 "OK" response
is returned.
The HTTP 200 response has the following values.
* course_details: A collection that includes the following
values.
* course_end: The date and time when the course closes. If
null, the course never ends.
* course_id: The unique identifier for the course.
* course_name: The name of the course.
* course_modes: An array of data about the enrollment modes
supported for the course. If the request uses the parameter
include_expired=1, the array also includes expired
enrollment modes.
Each enrollment mode collection includes the following
values.
* currency: The currency of the listed prices.
* description: A description of this mode.
* expiration_datetime: The date and time after which
users cannot enroll in the course in this mode.
* min_price: The minimum price for which a user can
enroll in this mode.
* name: The full name of the enrollment mode.
* slug: The short name for the enrollment mode.
* suggested_prices: A list of suggested prices for
this enrollment mode.
* course_end: The date and time at which the course closes. If
null, the course never ends.
* course_start: The date and time when the course opens. If
null, the course opens immediately when it is created.
* enrollment_end: The date and time after which users cannot
enroll for the course. If null, the enrollment period never
ends.
* enrollment_start: The date and time when users can begin
enrolling in the course. If null, enrollment opens
immediately when the course is created.
* invite_only: A value indicating whether students must be
invited to enroll in the course. Possible values are true or
false.
* created: The date the user account was created.
* is_active: Whether the enrollment is currently active.
* mode: The enrollment mode of the user in this course.
* user: The ID of the user.
"""
authentication_classes = (JwtAuthentication, OAuth2AuthenticationAllowInactiveUser,
SessionAuthenticationAllowInactiveUser,)
permission_classes = ApiKeyHeaderPermissionIsAuthenticated,
throttle_classes = EnrollmentUserThrottle,
# Since the course about page on the marketing site uses this API to auto-enroll users,
# we need to support cross-domain CSRF.
@method_decorator(ensure_csrf_cookie_cross_domain)
def get(self, request, course_id=None, username=None):
"""Create, read, or update enrollment information for a user.
HTTP Endpoint for all CRUD operations for a user course enrollment. Allows creation, reading, and
updates of the current enrollment for a particular course.
Args:
request (Request): To get current course enrollment information, a GET request will return
information for the current user and the specified course.
course_id (str): URI element specifying the course location. Enrollment information will be
returned, created, or updated for this particular course.
username (str): The username associated with this enrollment request.
Return:
A JSON serialized representation of the course enrollment.
"""
username = username or request.user.username
# TODO Implement proper permissions
if request.user.username != username and not self.has_api_key_permissions(request) \
and not request.user.is_staff:
# Return a 404 instead of a 403 (Unauthorized). If one user is looking up
# other users, do not let them deduce the existence of an enrollment.
return Response(status=status.HTTP_404_NOT_FOUND)
try:
return Response(api.get_enrollment(username, course_id))
except CourseEnrollmentError:
return Response(
status=status.HTTP_400_BAD_REQUEST,
data={
"message": (
u"An error occurred while retrieving enrollments for user "
u"'{username}' in course '{course_id}'"
).format(username=username, course_id=course_id)
}
)
@can_disable_rate_limit
class EnrollmentCourseDetailView(APIView):
"""
**Use Case**
Get enrollment details for a course.
Response values include the course schedule and enrollment modes
supported by the course. Use the parameter include_expired=1 to
include expired enrollment modes in the response.
**Note:** Getting enrollment details for a course does not require
authentication.
**Example Requests**
GET /api/enrollment/v1/course/{course_id}
GET /api/enrollment/v1/course/{course_id}?include_expired=1
**Response Values**
If the request is successful, an HTTP 200 "OK" response is
returned along with a collection of course enrollments for the
user or for the newly created enrollment.
Each course enrollment contains the following values.
* course_end: The date and time when the course closes. If
null, the course never ends.
* course_id: The unique identifier for the course.
* course_name: The name of the course.
* course_modes: An array of data about the enrollment modes
supported for the course. If the request uses the parameter
include_expired=1, the array also includes expired
enrollment modes.
Each enrollment mode collection includes the following
values.
* currency: The currency of the listed prices.
* description: A description of this mode.
* expiration_datetime: The date and time after which
users cannot enroll in the course in this mode.
* min_price: The minimum price for which a user can
enroll in this mode.
* name: The full name of the enrollment mode.
* slug: The short name for the enrollment mode.
* suggested_prices: A list of suggested prices for
this enrollment mode.
* course_start: The date and time when the course opens. If
null, the course opens immediately when it is created.
* enrollment_end: The date and time after which users cannot
enroll for the course. If null, the enrollment period never
ends.
* enrollment_start: The date and time when users can begin
enrolling in the course. If null, enrollment opens
immediately when the course is created.
* invite_only: A value indicating whether students must be
invited to enroll in the course. Possible values are true or
false.
"""
authentication_classes = []
permission_classes = []
throttle_classes = EnrollmentUserThrottle,
def get(self, request, course_id=None):
"""Read enrollment information for a particular course.
HTTP Endpoint for retrieving course level enrollment information.
Args:
request (Request): To get current course enrollment information, a GET request will return
information for the specified course.
course_id (str): URI element specifying the course location. Enrollment information will be
returned.
Return:
A JSON serialized representation of the course enrollment details.
"""