diff --git a/lms/djangoapps/course_home_api/progress/v1/__init__.py b/lms/djangoapps/course_home_api/progress/v1/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lms/djangoapps/course_home_api/progress/v1/serializers.py b/lms/djangoapps/course_home_api/progress/v1/serializers.py new file mode 100644 index 0000000000..2565bd5ccf --- /dev/null +++ b/lms/djangoapps/course_home_api/progress/v1/serializers.py @@ -0,0 +1,14 @@ +""" +Progress Tab Serializers +""" + +from rest_framework import serializers +from lms.djangoapps.course_home_api.outline.v1.serializers import CourseBlockSerializer + + +class ProgressTabSerializer(serializers.Serializer): + """ + Serializer for progress tab + """ + course_blocks = CourseBlockSerializer() + enrollment_mode = serializers.CharField() diff --git a/lms/djangoapps/course_home_api/progress/v1/views.py b/lms/djangoapps/course_home_api/progress/v1/views.py new file mode 100644 index 0000000000..5cae6e5e4e --- /dev/null +++ b/lms/djangoapps/course_home_api/progress/v1/views.py @@ -0,0 +1,102 @@ +""" +Progress Tab Views +""" + +from rest_framework.generics import RetrieveAPIView +from rest_framework.permissions import IsAuthenticated +from rest_framework.response import Response + +from edx_django_utils import monitoring as monitoring_utils +from opaque_keys.edx.keys import CourseKey + +from lms.djangoapps.course_home_api.progress.v1.serializers import ProgressTabSerializer + +from student.models import CourseEnrollment, UserTestGroup +from lms.djangoapps.course_api.blocks.transformers.blocks_api import BlocksAPITransformer +from lms.djangoapps.courseware.courses import get_course_with_access +from lms.djangoapps.courseware.masquerade import setup_masquerade +from lms.djangoapps.courseware.access import has_access +from xmodule.modulestore.django import modulestore + +from lms.djangoapps.course_blocks.api import get_course_blocks +import lms.djangoapps.course_blocks.api as course_blocks_api +from openedx.core.djangoapps.content.block_structure.transformers import BlockStructureTransformers + + +class ProgressTabView(RetrieveAPIView): + """ + **Use Cases** + + Request details for the Progress Tab + + **Example Requests** + + GET api/course_home/v1/progress/{course_key} + + **Response Values** + + Body consists of the following fields: + + user: Serialized User object. The serialization has the following fields: + username: (str) The username of the user + email: (str) the email of the user + is_staff: (bool) boolean indicating whether the user has staff permisions or not + course_blocks: + blocks: List of serialized Course Block objects. Each serialization has the following fields: + id: (str) The usage ID of the block. + type: (str) The type of block. Possible values the names of any + XBlock type in the system, including custom blocks. Examples are + course, chapter, sequential, vertical, html, problem, video, and + discussion. + display_name: (str) The display name of the block. + lms_web_url: (str) The URL to the navigational container of the + xBlock on the web LMS. + children: (list) If the block has child blocks, a list of IDs of + the child blocks. + enrollment_mode: (str) a str representing the enrollment the user has ('audit', 'verified', ...) + + **Returns** + + * 200 on success with above fields. + * 403 if the user is not authenticated. + * 404 if the course is not available or cannot be seen. + """ + + permission_classes = (IsAuthenticated,) + serializer_class = ProgressTabSerializer + + def get(self, request, *args, **kwargs): + course_key_string = kwargs.get('course_key_string') + course_key = CourseKey.from_string(course_key_string) + course_usage_key = modulestore().make_course_usage_key(course_key) + + # Enable NR tracing for this view based on course + monitoring_utils.set_custom_metric('course_id', course_key_string) + monitoring_utils.set_custom_metric('user_id', request.user.id) + monitoring_utils.set_custom_metric('is_staff', request.user.is_staff) + + _, request.user = setup_masquerade( + request, + course_key, + staff_access=has_access(request.user, 'staff', course_key), + reset_masquerade_data=True + ) + + transformers = BlockStructureTransformers() + transformers += course_blocks_api.get_course_block_access_transformers(request.user) + transformers += [ + BlocksAPITransformer(None, None, depth=3), + ] + get_course_with_access(request.user, 'load', course_key, check_if_enrolled=True) + course_blocks = get_course_blocks(request.user, course_usage_key, transformers, include_completion=True) + + enrollment_mode, _ = CourseEnrollment.enrollment_mode_for_user(request.user, course_key) + + data = { + 'course_blocks': course_blocks, + 'enrollment_mode': enrollment_mode, + } + + serializer = self.get_serializer(data) + + return Response(serializer.data) diff --git a/lms/djangoapps/course_home_api/urls.py b/lms/djangoapps/course_home_api/urls.py index f5e3f94e63..3a2c3c0771 100644 --- a/lms/djangoapps/course_home_api/urls.py +++ b/lms/djangoapps/course_home_api/urls.py @@ -9,6 +9,7 @@ from django.urls import re_path from lms.djangoapps.course_home_api.dates.v1.views import DatesTabView from lms.djangoapps.course_home_api.course_metadata.v1.views import CourseHomeMetadataView from lms.djangoapps.course_home_api.outline.v1.views import OutlineTabView +from lms.djangoapps.course_home_api.progress.v1.views import ProgressTabView urlpatterns = [] @@ -38,3 +39,12 @@ urlpatterns += [ name='course-home-outline-tab' ), ] + +# Progress Tab URLs +urlpatterns += [ + re_path( + r'v1/progress/{}'.format(settings.COURSE_KEY_PATTERN), + ProgressTabView.as_view(), + name='course-home-progress-tab' + ), +] diff --git a/lms/envs/devstack.py b/lms/envs/devstack.py index 4bafcbea24..31d8bb2fe4 100644 --- a/lms/envs/devstack.py +++ b/lms/envs/devstack.py @@ -323,7 +323,12 @@ FEATURES.update({ 'AUTOMATIC_AUTH_FOR_TESTING': True, 'ENABLE_DISCUSSION_SERVICE': True, 'SHOW_HEADER_LANGUAGE_SELECTOR': True, - 'ENABLE_ENTERPRISE_INTEGRATION': False, + + # Enable enterprise integration by default. + # See https://github.com/edx/edx-enterprise/blob/master/docs/development.rst for + # more background on edx-enterprise. + # Toggle this off if you don't want anything to do with enterprise in devstack. + 'ENABLE_ENTERPRISE_INTEGRATION': True, }) ENABLE_MKTG_SITE = os.environ.get('ENABLE_MARKETING_SITE', False) @@ -362,14 +367,15 @@ CREDENTIALS_SERVICE_USERNAME = 'credentials_worker' COURSE_CATALOG_URL_ROOT = 'http://edx.devstack.discovery:18381' COURSE_CATALOG_API_URL = '{}/api/v1'.format(COURSE_CATALOG_URL_ROOT) -# Enable enterprise integration so that we can include enterprise System-wide -# role logic without having to manipulate private settings. -FEATURES['ENABLE_ENTERPRISE_INTEGRATION'] = True SYSTEM_WIDE_ROLE_CLASSES = os.environ.get("SYSTEM_WIDE_ROLE_CLASSES", SYSTEM_WIDE_ROLE_CLASSES) -SYSTEM_WIDE_ROLE_CLASSES.extend([ +SYSTEM_WIDE_ROLE_CLASSES.append( 'system_wide_roles.SystemWideRoleAssignment', - 'enterprise.SystemWideEnterpriseUserRoleAssignment', -]) +) + +if FEATURES.get('ENABLE_ENTERPRISE_INTEGRATION'): + SYSTEM_WIDE_ROLE_CLASSES.append( + 'enterprise.SystemWideEnterpriseUserRoleAssignment', + ) # List of enterprise customer uuids to exclude from transition to use of enterprise-catalog ENTERPRISE_CUSTOMERS_EXCLUDED_FROM_CATALOG = () diff --git a/lms/envs/production.py b/lms/envs/production.py index e451166a43..21f5c494a8 100644 --- a/lms/envs/production.py +++ b/lms/envs/production.py @@ -619,6 +619,7 @@ if FEATURES.get('ENABLE_THIRD_PARTY_AUTH'): 'social_core.backends.linkedin.LinkedinOAuth2', 'social_core.backends.facebook.FacebookOAuth2', 'social_core.backends.azuread.AzureADOAuth2', + 'social_core.backends.apple.AppleIdAuth', 'third_party_auth.identityserver3.IdentityServer3', 'third_party_auth.saml.SAMLAuthBackend', 'third_party_auth.lti.LTIAuthBackend', diff --git a/openedx/core/djangoapps/waffle_utils/__init__.py b/openedx/core/djangoapps/waffle_utils/__init__.py index 2b97a3de92..0cec6c7ddd 100644 --- a/openedx/core/djangoapps/waffle_utils/__init__.py +++ b/openedx/core/djangoapps/waffle_utils/__init__.py @@ -271,11 +271,12 @@ class WaffleFlagNamespace(six.with_metaclass(ABCMeta, WaffleNamespace)): # The callback needs to handle its own caching if it wants it. value = self._cached_flags.get(namespaced_flag_name) if value is None: - + is_flag_active_for_everyone = False if flag_undefined_default is not None: # determine if the flag is undefined in waffle try: - Flag.objects.get(name=namespaced_flag_name) + waffle_flag = Flag.objects.get(name=namespaced_flag_name) + is_flag_active_for_everyone = (waffle_flag.everyone is True) except Flag.DoesNotExist: if flag_undefined_default: # This metric will go away once this has been fully retired with ARCHBOM-132. @@ -289,7 +290,6 @@ class WaffleFlagNamespace(six.with_metaclass(ABCMeta, WaffleNamespace)): value = flag_is_active(request, namespaced_flag_name) else: log.warning(u"%sFlag '%s' accessed without a request", self.log_prefix, namespaced_flag_name) - set_custom_metric('warn_flag_no_request', True) # Return the default value if not in a request context. # Note: this skips the cache as the value might be different # in a normal request context. This case seems to occur when @@ -297,6 +297,9 @@ class WaffleFlagNamespace(six.with_metaclass(ABCMeta, WaffleNamespace)): # the default value. value = bool(flag_undefined_default) self._set_waffle_flag_metric(namespaced_flag_name, value) + no_request_default_match = is_flag_active_for_everyone == value + set_custom_metric('temp_flag_no_request_default_match_2', no_request_default_match) + set_custom_metric('warn_flag_no_request_return_value', value) return value self._cached_flags[namespaced_flag_name] = value diff --git a/openedx/features/course_experience/__init__.py b/openedx/features/course_experience/__init__.py index 5bbe6004e8..4ebf33e98f 100644 --- a/openedx/features/course_experience/__init__.py +++ b/openedx/features/course_experience/__init__.py @@ -2,7 +2,6 @@ Unified course experience settings and helper methods. """ import crum -from django.conf import settings from django.utils.translation import ugettext as _ from edx_django_utils.monitoring import set_custom_metric from waffle import flag_is_active @@ -14,19 +13,6 @@ from openedx.core.djangoapps.waffle_utils import CourseWaffleFlag, WaffleFlag, W # Namespace for course experience waffle flags. WAFFLE_FLAG_NAMESPACE = WaffleFlagNamespace(name='course_experience') -# .. toggle_name: USE_DEFAULT_TRUE_NAMESPACE -# .. toggle_implementation: DjangoSetting -# .. toggle_default: False -# .. toggle_description: When True, uses the new default_true namespace to help deprecate flag_undefined_default. -# .. toggle_category: course_experience -# .. toggle_use_cases: monitored_rollout -# .. toggle_creation_date: 2020-06-30 -# .. toggle_expiration_date: 2020-07 -# .. toggle_warnings: n/a -# .. toggle_tickets: n/a -# .. toggle_status: supported -_USE_DEFAULT_TRUE_NAMESPACE = 'USE_DEFAULT_TRUE_NAMESPACE' - class DefaultTrueWaffleFlagNamespace(WaffleFlagNamespace): """ @@ -36,9 +22,9 @@ class DefaultTrueWaffleFlagNamespace(WaffleFlagNamespace): and refactor/fix any tests that shouldn't be removed. """ - def _is_flag_active(self, flag_name): + def is_flag_active(self, flag_name, check_before_waffle_callback=None, flag_undefined_default=None): """ - Returns and caches whether the provided flag is active. + Overrides is_flag_active, and returns and caches whether the provided flag is active. If the flag value is already cached in the request, it is returned. If the flag doesn't exist, always returns default of True. @@ -80,17 +66,6 @@ class DefaultTrueWaffleFlagNamespace(WaffleFlagNamespace): self._set_waffle_flag_metric(namespaced_flag_name, value) return value - def is_flag_active(self, flag_name, check_before_waffle_callback=None, flag_undefined_default=None): - """ - Overrides is_flag_active if setting USE_DEFAULT_TRUE_NAMESPACE is True. - """ - use_default_true_namespace = getattr(settings, _USE_DEFAULT_TRUE_NAMESPACE, False) - set_custom_metric('temp_use_default_true_namespace', use_default_true_namespace) - if use_default_true_namespace: - return self._is_flag_active(flag_name) - else: - return super().is_flag_active(flag_name, check_before_waffle_callback, flag_undefined_default=True) - DEFAULT_TRUE_WAFFLE_FLAG_NAMESPACE = DefaultTrueWaffleFlagNamespace(name='course_experience') diff --git a/openedx/features/course_experience/views/course_home.py b/openedx/features/course_experience/views/course_home.py index 446fb22fa1..15fa55d803 100644 --- a/openedx/features/course_experience/views/course_home.py +++ b/openedx/features/course_experience/views/course_home.py @@ -84,6 +84,7 @@ class CourseHomeFragmentView(EdxFragmentView): """ A fragment to render the home page for a course. """ + _uses_pattern_library = False def _get_resume_course_info(self, request, course_id): """ @@ -258,7 +259,7 @@ class CourseHomeFragmentView(EdxFragmentView): 'update_message_fragment': update_message_fragment, 'course_sock_fragment': course_sock_fragment, 'disable_courseware_js': True, - 'uses_pattern_library': True, + 'uses_bootstrap': True, 'upgrade_price': upgrade_price, 'upgrade_url': upgrade_url, 'has_discount': has_discount, diff --git a/requirements/constraints.txt b/requirements/constraints.txt index bfc99cf2fa..48f1107e80 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -40,6 +40,11 @@ drf-yasg<1.17.1 # drf-jwt 1.15.0 contains a migration that breaks on MySQL: https://github.com/Styria-Digital/django-rest-framework-jwt/issues/40 drf-jwt==1.14.0 +# The team that owns this package will manually bump this package rather than having it pulled in automatically. +# This is to allow them to better control its deployment and to do it in a process that works better +# for them. +edx-enterprise==3.3.17 + # Upgrading to 2.12.0 breaks several test classes due to API changes, need to update our code accordingly factory-boy==2.8.1 diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index 67050546f3..29325fae43 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -99,13 +99,13 @@ edx-django-release-util==0.4.4 # via -r requirements/edx/base.in edx-django-sites-extensions==2.5.1 # via -r requirements/edx/base.in edx-django-utils==3.2.3 # via -r requirements/edx/base.in, django-config-models, edx-drf-extensions, edx-enterprise, edx-rest-api-client, edx-when edx-drf-extensions==6.1.0 # via -r requirements/edx/base.in, edx-completion, edx-enterprise, edx-organizations, edx-proctoring, edx-rbac, edx-when, edxval -edx-enterprise==3.3.15 # via -r requirements/edx/base.in +edx-enterprise==3.3.17 # via -c requirements/edx/../constraints.txt, -r requirements/edx/base.in edx-i18n-tools==0.5.3 # via ora2 edx-milestones==0.3.0 # via -r requirements/edx/base.in edx-opaque-keys[django]==2.1.0 # via -r requirements/edx/paver.txt, edx-bulk-grades, edx-ccx-keys, edx-completion, edx-drf-extensions, edx-enterprise, edx-milestones, edx-organizations, edx-proctoring, edx-user-state-client, edx-when, xmodule edx-organizations==5.2.0 # via -r requirements/edx/base.in edx-proctoring-proctortrack==1.0.5 # via -r requirements/edx/base.in -edx-proctoring==2.4.3 # via -r requirements/edx/base.in, edx-proctoring-proctortrack +edx-proctoring==2.4.4 # via -r requirements/edx/base.in, edx-proctoring-proctortrack edx-rbac==1.3.1 # via edx-enterprise edx-rest-api-client==5.2.1 # via -r requirements/edx/base.in, edx-enterprise, edx-proctoring edx-search==1.4.1 # via -r requirements/edx/base.in @@ -145,7 +145,7 @@ lazy==1.4 # via -r requirements/edx/paver.txt, acid-xblock, lti- lepl==5.1.3 # via rfc6266-parser libsass==0.10.0 # via -r requirements/edx/paver.txt, ora2 loremipsum==1.0.5 # via ora2 -lti-consumer-xblock==2.0.1.1 # via -r requirements/edx/base.in +lti-consumer-xblock==2.0.2 # via -r requirements/edx/base.in lxml==4.5.0 # via -c requirements/edx/../constraints.txt, -r requirements/edx/../edx-sandbox/shared.txt, capa, edxval, lti-consumer-xblock, ora2, safe-lxml, xblock, xmlsec mailsnake==1.6.4 # via -r requirements/edx/base.in mako==1.1.3 # via -r requirements/edx/base.in, acid-xblock, lti-consumer-xblock, xblock-google-drive, xblock-utils @@ -179,7 +179,7 @@ polib==1.1.0 # via edx-i18n-tools psutil==1.2.1 # via -r requirements/edx/paver.txt, edx-django-utils py2neo==3.1.2 # via -r requirements/edx/base.in pycontracts==1.8.12 # via -r requirements/edx/base.in, edx-user-state-client -pycountry==19.8.18 # via -r requirements/edx/base.in +pycountry==20.7.2 # via -r requirements/edx/base.in pycparser==2.20 # via -r requirements/edx/../edx-sandbox/shared.txt, cffi pycryptodome==3.9.8 # via lti-consumer-xblock, pdfminer.six pycryptodomex==3.9.8 # via -r requirements/edx/base.in, edx-proctoring, pyjwkest @@ -228,7 +228,7 @@ sqlparse==0.3.1 # via -r requirements/edx/base.in, django staff-graded-xblock==0.8 # via -r requirements/edx/base.in stevedore==1.32.0 # via -c requirements/edx/../constraints.txt, -r requirements/edx/base.in, -r requirements/edx/paver.txt, code-annotations, edx-ace, edx-enterprise, edx-opaque-keys super-csv==0.9.9 # via -r requirements/edx/base.in, edx-bulk-grades -sympy==1.6 # via symmath +sympy==1.6.1 # via symmath testfixtures==6.14.1 # via edx-enterprise text-unidecode==1.3 # via python-slugify tqdm==4.47.0 # via -r requirements/edx/../edx-sandbox/shared.txt, nltk diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index fab5c57778..e17ce22ec6 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -111,14 +111,14 @@ edx-django-release-util==0.4.4 # via -r requirements/edx/testing.txt edx-django-sites-extensions==2.5.1 # via -r requirements/edx/testing.txt edx-django-utils==3.2.3 # via -r requirements/edx/testing.txt, django-config-models, edx-drf-extensions, edx-enterprise, edx-rest-api-client, edx-when edx-drf-extensions==6.1.0 # via -r requirements/edx/testing.txt, edx-completion, edx-enterprise, edx-organizations, edx-proctoring, edx-rbac, edx-when, edxval -edx-enterprise==3.3.15 # via -r requirements/edx/testing.txt +edx-enterprise==3.3.17 # via -c requirements/edx/../constraints.txt, -r requirements/edx/testing.txt edx-i18n-tools==0.5.3 # via -r requirements/edx/testing.txt, ora2 edx-lint==1.5.0 # via -r requirements/edx/testing.txt edx-milestones==0.3.0 # via -r requirements/edx/testing.txt edx-opaque-keys[django]==2.1.0 # via -r requirements/edx/testing.txt, edx-bulk-grades, edx-ccx-keys, edx-completion, edx-drf-extensions, edx-enterprise, edx-milestones, edx-organizations, edx-proctoring, edx-user-state-client, edx-when, xmodule edx-organizations==5.2.0 # via -r requirements/edx/testing.txt edx-proctoring-proctortrack==1.0.5 # via -r requirements/edx/testing.txt -edx-proctoring==2.4.3 # via -r requirements/edx/testing.txt, edx-proctoring-proctortrack +edx-proctoring==2.4.4 # via -r requirements/edx/testing.txt, edx-proctoring-proctortrack edx-rbac==1.3.1 # via -r requirements/edx/testing.txt, edx-enterprise edx-rest-api-client==5.2.1 # via -r requirements/edx/testing.txt, edx-enterprise, edx-proctoring edx-search==1.4.1 # via -r requirements/edx/testing.txt @@ -176,7 +176,7 @@ lazy==1.4 # via -r requirements/edx/testing.txt, acid-xblock, bo lepl==5.1.3 # via -r requirements/edx/testing.txt, rfc6266-parser libsass==0.10.0 # via -r requirements/edx/testing.txt, ora2 loremipsum==1.0.5 # via -r requirements/edx/testing.txt, ora2 -lti-consumer-xblock==2.0.1.1 # via -r requirements/edx/testing.txt +lti-consumer-xblock==2.0.2 # via -r requirements/edx/testing.txt lxml==4.5.0 # via -c requirements/edx/../constraints.txt, -r requirements/edx/testing.txt, capa, edxval, lti-consumer-xblock, ora2, pyquery, safe-lxml, xblock, xmlsec m2r==0.2.1 # via sphinxcontrib-openapi mailsnake==1.6.4 # via -r requirements/edx/testing.txt @@ -219,7 +219,7 @@ py2neo==3.1.2 # via -r requirements/edx/testing.txt py==1.9.0 # via -r requirements/edx/testing.txt, pytest, tox pycodestyle==2.6.0 # via -r requirements/edx/testing.txt, flake8 pycontracts==1.8.12 # via -r requirements/edx/testing.txt, edx-user-state-client -pycountry==19.8.18 # via -r requirements/edx/testing.txt +pycountry==20.7.2 # via -r requirements/edx/testing.txt pycparser==2.20 # via -r requirements/edx/testing.txt, cffi pycryptodome==3.9.8 # via -r requirements/edx/testing.txt, lti-consumer-xblock, pdfminer.six pycryptodomex==3.9.8 # via -r requirements/edx/testing.txt, edx-proctoring, pyjwkest @@ -299,7 +299,7 @@ sqlparse==0.3.1 # via -r requirements/edx/testing.txt, django, django- staff-graded-xblock==0.8 # via -r requirements/edx/testing.txt stevedore==1.32.0 # via -c requirements/edx/../constraints.txt, -r requirements/edx/testing.txt, code-annotations, edx-ace, edx-enterprise, edx-opaque-keys super-csv==0.9.9 # via -r requirements/edx/testing.txt, edx-bulk-grades -sympy==1.6 # via -r requirements/edx/testing.txt, symmath +sympy==1.6.1 # via -r requirements/edx/testing.txt, symmath testfixtures==6.14.1 # via -r requirements/edx/testing.txt, edx-enterprise text-unidecode==1.3 # via -r requirements/edx/testing.txt, faker, python-slugify toml==0.10.1 # via -r requirements/edx/testing.txt, tox diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index c4e0d7ebe9..fa92bf1420 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -108,14 +108,14 @@ edx-django-release-util==0.4.4 # via -r requirements/edx/base.txt edx-django-sites-extensions==2.5.1 # via -r requirements/edx/base.txt edx-django-utils==3.2.3 # via -r requirements/edx/base.txt, django-config-models, edx-drf-extensions, edx-enterprise, edx-rest-api-client, edx-when edx-drf-extensions==6.1.0 # via -r requirements/edx/base.txt, edx-completion, edx-enterprise, edx-organizations, edx-proctoring, edx-rbac, edx-when, edxval -edx-enterprise==3.3.15 # via -r requirements/edx/base.txt +edx-enterprise==3.3.17 # via -c requirements/edx/../constraints.txt, -r requirements/edx/base.txt edx-i18n-tools==0.5.3 # via -r requirements/edx/base.txt, -r requirements/edx/testing.in, ora2 edx-lint==1.5.0 # via -r requirements/edx/testing.in edx-milestones==0.3.0 # via -r requirements/edx/base.txt edx-opaque-keys[django]==2.1.0 # via -r requirements/edx/base.txt, edx-bulk-grades, edx-ccx-keys, edx-completion, edx-drf-extensions, edx-enterprise, edx-milestones, edx-organizations, edx-proctoring, edx-user-state-client, edx-when, xmodule edx-organizations==5.2.0 # via -r requirements/edx/base.txt edx-proctoring-proctortrack==1.0.5 # via -r requirements/edx/base.txt -edx-proctoring==2.4.3 # via -r requirements/edx/base.txt, edx-proctoring-proctortrack +edx-proctoring==2.4.4 # via -r requirements/edx/base.txt, edx-proctoring-proctortrack edx-rbac==1.3.1 # via -r requirements/edx/base.txt, edx-enterprise edx-rest-api-client==5.2.1 # via -r requirements/edx/base.txt, edx-enterprise, edx-proctoring edx-search==1.4.1 # via -r requirements/edx/base.txt @@ -170,7 +170,7 @@ lazy==1.4 # via -r requirements/edx/base.txt, acid-xblock, bok-c lepl==5.1.3 # via -r requirements/edx/base.txt, rfc6266-parser libsass==0.10.0 # via -r requirements/edx/base.txt, ora2 loremipsum==1.0.5 # via -r requirements/edx/base.txt, ora2 -lti-consumer-xblock==2.0.1.1 # via -r requirements/edx/base.txt +lti-consumer-xblock==2.0.2 # via -r requirements/edx/base.txt lxml==4.5.0 # via -c requirements/edx/../constraints.txt, -r requirements/edx/base.txt, capa, edxval, lti-consumer-xblock, ora2, pyquery, safe-lxml, xblock, xmlsec mailsnake==1.6.4 # via -r requirements/edx/base.txt mako==1.1.3 # via -r requirements/edx/base.txt, acid-xblock, lti-consumer-xblock, xblock-google-drive, xblock-utils @@ -210,7 +210,7 @@ py2neo==3.1.2 # via -r requirements/edx/base.txt py==1.9.0 # via pytest, tox pycodestyle==2.6.0 # via -r requirements/edx/testing.in, flake8 pycontracts==1.8.12 # via -r requirements/edx/base.txt, edx-user-state-client -pycountry==19.8.18 # via -r requirements/edx/base.txt +pycountry==20.7.2 # via -r requirements/edx/base.txt pycparser==2.20 # via -r requirements/edx/base.txt, cffi pycryptodome==3.9.8 # via -r requirements/edx/base.txt, lti-consumer-xblock, pdfminer.six pycryptodomex==3.9.8 # via -r requirements/edx/base.txt, edx-proctoring, pyjwkest @@ -278,7 +278,7 @@ sqlparse==0.3.1 # via -r requirements/edx/base.txt, django staff-graded-xblock==0.8 # via -r requirements/edx/base.txt stevedore==1.32.0 # via -c requirements/edx/../constraints.txt, -r requirements/edx/base.txt, code-annotations, edx-ace, edx-enterprise, edx-opaque-keys super-csv==0.9.9 # via -r requirements/edx/base.txt, edx-bulk-grades -sympy==1.6 # via -r requirements/edx/base.txt, symmath +sympy==1.6.1 # via -r requirements/edx/base.txt, symmath testfixtures==6.14.1 # via -r requirements/edx/base.txt, -r requirements/edx/testing.in, edx-enterprise text-unidecode==1.3 # via -r requirements/edx/base.txt, faker, python-slugify toml==0.10.1 # via tox