def _update_lti(self, instance: DiscussionsConfiguration, validated_data: dict, course_key: CourseKey) -> DiscussionsConfiguration: """ Update LtiConfiguration """ lti_configuration_data = validated_data.get('lti_configuration') supports_lti = instance.supports( Features.LTI_BASIC_CONFIGURATION.value) if not supports_lti: instance.lti_configuration = None elif lti_configuration_data: lti_configuration = instance.lti_configuration or LtiConfiguration( ) lti_serializer = LtiSerializer( lti_configuration, data=lti_configuration_data, partial=True, context={ 'pii_sharing_allowed': get_lti_pii_sharing_state_for_course(course_key), }) if lti_serializer.is_valid(raise_exception=True): lti_serializer.save() instance.lti_configuration = lti_configuration return instance
def _update_lti( self, instance: DiscussionsConfiguration, validated_data: dict, ) -> DiscussionsConfiguration: """ Update LtiConfiguration """ lti_configuration_data = validated_data.get('lti_configuration') if not instance.supports_lti(): instance.lti_configuration = None elif lti_configuration_data: lti_configuration = instance.lti_configuration or LtiConfiguration( ) lti_serializer = LtiSerializer( lti_configuration, data=lti_configuration_data, partial=True, context={ 'pii_sharing_allowed': get_lti_pii_sharing_state_for_course(instance.context_key), }) if lti_serializer.is_valid(raise_exception=True): lti_serializer.save() instance.lti_configuration = lti_configuration return instance
def _get_pii_lti_parameters(self, course: CourseBlock, request: HttpRequest) -> Dict[str, str]: """ Get LTI parameters that contain PII. Args: course (CourseBlock): CourseBlock object. request (HttpRequest): Request object for view in which LTI will be embedded. Returns: Dictionary with LTI parameters containing PII. """ pii_sharing_allowed = get_lti_pii_sharing_state_for_course(course.id) if not pii_sharing_allowed: return {} lti_config = self._get_lti_config(course) # Currently only LTI 1.1 is supported by the tab if lti_config.version != lti_config.LTI_1P1: return {} pii_config = {} if lti_config.pii_share_username: pii_config['person_sourcedid'] = request.user.username if lti_config.pii_share_email: pii_config['person_contact_email_primary'] = request.user.email return pii_config
def to_representation(self, instance: DiscussionsConfiguration) -> dict: """ Serialize data into a dictionary, to be used as a response """ course_key = instance.context_key active_provider = instance.provider_type provider_type = self.context.get('provider_type') or active_provider payload = super().to_representation(instance) course_pii_sharing_allowed = get_lti_pii_sharing_state_for_course(course_key) # LTI configuration is only stored for the active provider. if provider_type == active_provider: lti_configuration = LtiSerializer(instance=instance.lti_configuration) lti_configuration_data = lti_configuration.data plugin_configuration = instance.plugin_configuration else: lti_configuration_data = {} plugin_configuration = {} course = get_course_by_id(course_key) if provider_type in [Provider.LEGACY, Provider.OPEN_EDX]: legacy_settings = LegacySettingsSerializer(course, data=plugin_configuration) if legacy_settings.is_valid(raise_exception=True): plugin_configuration = legacy_settings.data if provider_type == Provider.OPEN_EDX: plugin_configuration.update({ "group_at_subsection": instance.plugin_configuration.get("group_at_subsection", False) }) lti_configuration_data.update({'pii_sharing_allowed': course_pii_sharing_allowed}) payload.update({ 'provider_type': provider_type, 'lti_configuration': lti_configuration_data, 'plugin_configuration': plugin_configuration, }) return payload
def post(self, request, course_id: str) -> Response: """ Handle HTTP/POST requests """ pii_sharing_allowed = get_lti_pii_sharing_state_for_course(course_id) if not pii_sharing_allowed and provider_requires_pii_sharing( request.data.get('provider_type', '')): return Response({ "pii_sharing_allowed": pii_sharing_allowed, "message": "PII sharing is not allowed on this course" }) configuration = CourseLiveConfiguration.get(course_id) serializer = CourseLiveConfigurationSerializer( configuration, data=request.data, context={ "pii_sharing_allowed": pii_sharing_allowed, "course_id": course_id }) if not serializer.is_valid(): raise ValidationError(serializer.errors) serializer.save() return Response(serializer.data)
def get_serializer_class(self): """ Overrides ModelViewSet's `get_serializer_class` method. Checks if PII fields can be exposed and returns appropiate serializer. """ if get_lti_pii_sharing_state_for_course(self.request.lti_configuration.location.course_key): return LtiNrpsContextMembershipPIISerializer else: return LtiNrpsContextMembershipBasicSerializer
def get(self, request: Request, course_id: str) -> Response: """ Handle HTTP/GET requests """ configuration = CourseLiveConfiguration.get( course_id) or CourseLiveConfiguration() serializer = CourseLiveConfigurationSerializer( configuration, context={ "pii_sharing_allowed": get_lti_pii_sharing_state_for_course(course_id), "course_id": course_id }) return Response(serializer.data)
def to_representation(self, instance: DiscussionsConfiguration) -> dict: """ Serialize data into a dictionary, to be used as a response """ course_key = instance.context_key payload = super().to_representation(instance) lti_configuration_data = {} supports_lti = instance.supports( Features.LTI_BASIC_CONFIGURATION.value.id) if supports_lti: lti_configuration = LtiSerializer( instance.lti_configuration, context={ 'pii_sharing_allowed': get_lti_pii_sharing_state_for_course(course_key), }) lti_configuration_data = lti_configuration.data provider_type = instance.provider_type or DEFAULT_PROVIDER_TYPE plugin_configuration = instance.plugin_configuration if provider_type == 'legacy': course = get_course_by_id(course_key) legacy_settings = LegacySettingsSerializer( course, data=plugin_configuration, ) if legacy_settings.is_valid(raise_exception=True): plugin_configuration = legacy_settings.data features_list = [{ 'id': feature.value.id, 'feature_support_type': feature.value.feature_support_type } for feature in Features] payload.update({ 'features': features_list, 'lti_configuration': lti_configuration_data, 'plugin_configuration': plugin_configuration, 'providers': { 'active': provider_type or DEFAULT_PROVIDER_TYPE, 'available': AVAILABLE_PROVIDER_MAP, }, }) return payload
def to_representation(self, instance: DiscussionsConfiguration) -> dict: """ Serialize data into a dictionary, to be used as a response """ course_key = instance.context_key payload = super().to_representation(instance) course_pii_sharing_allowed = get_lti_pii_sharing_state_for_course( course_key) lti_configuration = LtiSerializer(instance=instance.lti_configuration) lti_configuration_data = lti_configuration.data lti_configuration_data.update( {'pii_sharing_allowed': course_pii_sharing_allowed}) provider_type = instance.provider_type plugin_configuration = instance.plugin_configuration course = get_course_by_id(course_key) legacy_settings = LegacySettingsSerializer( course, data=plugin_configuration, ) if legacy_settings.is_valid(raise_exception=True): plugin_configuration = legacy_settings.data features_list = [{ 'id': feature.value, 'feature_support_type': feature.feature_support_type } for feature in Features] payload.update({ 'features': features_list, 'lti_configuration': lti_configuration_data, 'plugin_configuration': plugin_configuration, 'providers': { 'active': provider_type or DEFAULT_PROVIDER_TYPE, 'available': { key: value for key, value in AVAILABLE_PROVIDER_MAP.items() if value.get('visible', True) }, }, }) return payload
def get(self, request: Request, course_id: str) -> Response: """ Handle HTTP/GET requests """ pii_sharing_allowed = get_lti_pii_sharing_state_for_course(course_id) if not pii_sharing_allowed: return Response({ "pii_sharing_allowed": pii_sharing_allowed, "message": "PII sharing is not allowed on this course" }) configuration = CourseLiveConfiguration.get( course_id) or CourseLiveConfiguration() serializer = CourseLiveConfigurationSerializer( configuration, context={ "pii_sharing_allowed": pii_sharing_allowed, "course_id": course_id }) return Response(serializer.data)