- Jan 24, 2023
-
-
michaelroytman authored
This commit fixes a bug in the PII sharing consent dialog. The bug resulted in bizarre behavior when there were more than one LTI component in a unit. For example, if there were two LTI inline launches in a unit, two "OK" button would appear in a single component, instead of in their respective components. Another example is that clicking the "View resource in a [modal|new] window" buttons under two LTI components resulted in the "OK" and "Cancel" buttons as well as the PII sharing prompt appearing in a single component, instead of in their respective components. This is because the dialog-container div that is dynamically created in the Javascript was not scoped to the LTI component, so there was a div with a id of "dialog-container" for each component configured to share PII. When dynamically inserting and removing buttons and the PII sharing prompt, the Javascript would simply find the first div with the dialog-container ID and operate on it, instead of the div appropriate to the component the user is interacting with.
-
Zachary Hancock authored
-
Giovanni Cimolin da Silva authored
* fix: Tool can only push grade to value in config Before this commit, LTI tools were able to push grades to any block simply by modifying or creating a new line item with a `resource_link_id` containing a valid block. This commit closes that loophole and resolves security advisory GHSA-7j9p-67mm-5g87. * chore: create release version Co-authored-by:
Zach Hancock <zhancock@edx.org>
-
- Jan 10, 2023
-
-
Zachary Hancock authored
-
Zachary Hancock authored
Allows independent configuration of the base URL used for LTI API requests and LTI browser flow. This primarily aids local development because we no longer have to tunnel the entire LMS in order to test against the IMS tools.
-
- Dec 15, 2022
-
-
michaelroytman authored
-
michaelroytman authored
This commit enables sharing username and email in LTI 1.3 basic launches. This commit adds preferred_username and email as attributes of the Lti1p3LaunchData. The application or context that instantiates Lti1p3LaunchData is responsible for ensuring that username and email can be sent via an LTI 1.3 launch and supplying these data, if appropriate. This commit sends username and email as part of an LTI 1.3 basic launch when the XBlock fields ask_to_send_username and ask_to_send_email are set to True, respectively. Code was also added to block the transmission of username and email in both LTI 1.1 and LTI 1.3 launches if the value of the lti_access_to_learners_editable method of the LTI configuration service (i.e. the value of the CourseAllowPIISharingInLTIFlag ConfigurationModel) returns False, as originally intended and documented in the "Unified Flag for Enabling Sharing of PII in LTI " decision record. However, the LTI configuration service is not currently available or defined in all runtime contexts, so this behavior only works when editing the XBlock in Studio (i.e. the studio_view). It does not work from the XBlock preview in Studio (i.e. the author_view) or from the LMS (i.e. the student_view). The impact of this is that the ask_to_send_username and ask_to_send_email fields will be hidden in LTI XBlocks in courses for which an instance of the CourseAllowPIISharingInLTIFlag ConfigurationModel does not exist or for which an existing instance of the CourseAllowPIISharingInLTIFlag ConfigurationModel is disabled. If there already exists an instance of the CourseAllowPIISharingInLTIFlag ConfigurationModel for a course, then disabling the flag will only hide the ask_to_send_username and ask_to_send_email in the LTI XBlock edit menu. It will not prevent the transmission of username or email via the launch in Studio preview or via the launch in the LMS. If a course has already set ask_to_send_username or ask_to_send_email to True in the XBlock edit menu, that information will continue to be sent via the LTI 1.1 or LTI 1.3 launch. We plan to fix this bug in the future.
-
michaelroytman authored
This commit fixes a bug in the way that the the form_url is used in the Javascript. For LTI modal launches in the courseware microfrontend (MFE), the Javascript prepends the value of window.location.origin to the form_url when sending a message via postMessage to window.parent. This is because the form_url included in the template by the XBlock handler does not include a port and hostname for LTI 1.1 launches. In LTI 1.3, however, the form_url should include the port and hostname, because it's user input (e.g. fields on the XBlock). Because of this, LTI 1.3 modal launches do not work, because the Javascript appends a port and hostname to a URL that already has a port and hostname, resulting in something like "http://localhost:18000http//localhost..." This commit changes the way that the launch URL is calculated by the Javascript. The version of LTI being used is included in the template by the Python code, which is read by the Javascript. The Javascript then adds the port and hostname for LTI 1.1 form URLs but not for LTI 1.1 form URLs.
-
michaelroytman authored
This commit removes the request_cached decorator on the method lti_access_to_learners_editable. The caching was not working correctly. It appeared that the cached value was not being recomputed on a per-request basis, which meant that the cached value was not successfully being updated. Also, the initial cached value was computed incorrectly. The effect was that the PII sharing XBlock fields were always being displayed in Studio and CourseAllowPIISharingInLTIFlag instances were not being created for courses that had PII sharing XBlocks that did not already have CourseAllowPIISharingInLTIFlag instances. Note that this commit fixes the backwards compatibility of the CourseAllowPIISharingInLTIFlag. This means that CourseAllowPIISharingInLTIFlag will now be created for all courses that contain an LTI XBlock that shares username and/or email for which a CourseAllowPIISharingInLTIFlag does not already exist. Time was spent on determining why the caching was failing, but it was challenging. If the issue is in the request_cached decorator, then the impact of changing it is large - it's used elsewhere in the platform. The need for a fix was urgent, and the supposed performance enhancement of leaving the caching in doesn't justify delaying a fix.
-
michaelroytman authored
This commit replaces the consent modal that appears before personally identifiable information (PII) is shared via an LTI launch with an inline consent dialog. The consent dialog better supports the three LTI launch types (i.e. inline, modal, and new_window). This commit also fixes a bug where the PII consent modal was not being displayed for inline or modal launches.
-
- Dec 09, 2022
-
-
Zachary Hancock authored
We would like to enable PII in an LTI1.3 launch but turning that flag on would allow the tool to grab PII for the entire course roster via NRPS. We have not fully evaluated the privacy concerns if that is allowed. For the time being this platform setting can wholly disable PII over NRPS to avoid the issue
-
- Dec 02, 2022
-
-
Zachary Hancock authored
* fix: remove lms specific waffle check
-
- Nov 29, 2022
-
-
michaelroytman authored
In #307, we added the ability to send a stable, static user identifier (i.e. external user ID) to fix failed launches with the QwikLabs tool. This is because the QwikLabs tool did not work with the course-anonymized user IDs we used to send (i.e. anonymous user IDs). Inadvertently, this change broke the LTI 1.1 Basic Outcomes Service and the LTI 2.0 Result Service for courses that use the external user ID (i.e. they have the lti_consumer.enable_external_user_id_1p1_launches CourseWaffleFlag enabled). The Basic Outcomes Service and Result Service handle grade pass backs. Because we now have two ways to identify a user in LTI 1.1/2.0, we must update the Basic Outcomes Service and Result Service to support both. This commit fixes this bug.
-
Andy Shultz authored
the block is not loadable in exams so clean fails in that IDA, but we shouldn't need the block to ask a question about the course
-
Kshitij Sobti authored
-
Kshitij Sobti authored
Replaces usages of runtime.course_id with runtime.scope_ids.usage_id.context_key.
-
Kshitij Sobti authored
-
Arunmozhi authored
The hostname used to construct the resource link ID is moved from using a runtime attribute to the LMS_BASE setting.
-
Arunmozhi authored
The `rebind_noauth_module_to_user` function is deprecated in the core edx-platform [1]. This is now replaced with a "rebind_user" service. This commit brings this change to the LTI Consumer XBlock. [1] - https://github.com/openedx/edx-platform/pull/30320/
-
- Nov 28, 2022
-
-
Arunmozhi authored
The OAuthlib 1.0 Client's get_oauth_params fails when processing Webob request object with the body stored as a binary instead of string. This commit replaces the client function with a different one which doesn't involve body hashing, as the body hash is calculated explicitly.
-
- Nov 21, 2022
-
-
Sarina Canelake authored
-
- Nov 18, 2022
-
-
michaelroytman authored
This commit introduces a new CourseWaffleFlag lti_consumer.enable_external_user_id_1p1_launches. When this flag is enabled for a course, LTI 1.1 XBlock launches in that course will send the user's external_user_id as the user_id attribute of the launch. external_user_id is the user's external user ID as defined, created, and stored by the external_user_ids Djangoapp in the edx-platform. When this waffle is not enabled for a course - the default case - LTI 1.1 XBlock launches in that course will continue to send the user's anonymous_user_id as the user_id attribute of the launch, as before. This provides an opt-in opportunity for courses to send a consistent, static, and opaque user identifier in an LTI 1.1 XBlock launch. This may be necessary for integration with LTI tools that require such an identifier. Please be aware that toggling this flag in a running course carries the risk of breaking the LTI integrations in the course. This flag should also only be enabled for new courses in which no LTI attempts have been made.
-
- Nov 16, 2022
-
-
michaelroytman authored
-
michaelroytman authored
-
michaelroytman authored
* Adds an Lti1p3ProctoringLaunchData data class. It should be included as an attribute of the Lti1p3LaunchData data class to provide necessary proctoring data for a proctoring launch. * Adds an LtiProctoringConsumer class. This class is used to generate LTI proctoring launch requests and to decode and validate the JWT send back by the Tool with the LtiStartAssessment message. * Adds an lti_1p3_proctoring_enabled BooleanField to the LtiConfiguration model. This field controls whether proctoring is enabled for a particular LTI integration. * Modifies the launch_gate_endpoint to support LtiStartProctoring and LtiEndAssessment LTI launch messages. * Adds an start_proctoring_assessment_endpoint to support LtiStartAssessment messages from the Tool. * Adds an LTI_1P3_PROCTORING_ASSESSMENT_STARTED signal. This signal is emitted when the LtiStartAssessment message is sent from the Tool to inform users of the library that the LtiStartAssessment message has been received.
-
- Nov 07, 2022
-
-
Andy Shultz authored
For the config model we do not need to go as far as binding the block to the user and already get enough data out of the modulestore to satisfy the storage on the xblock case. Add a new function to get that much xblock only. For the limited cases where we are using the block more directly as a block we maintain the old function. Also includes a fix to test_views that was closing the wrong level mock and leaving an open patch into other tests.
-
- Oct 25, 2022
-
-
Andy Shultz authored
... without messing up the rest of your world by changing the LMS base URL for everyone. Meant for ngrok testing of LTI 1.3.
-
- Oct 20, 2022
-
-
Andy Shultz authored
these functions require the LMS environment which is not available in test so they are generally mocked away. Mark them as such.
-
Andy Shultz authored
-
Andy Shultz authored
Note that this uses config_id (the UUID) not config.id (the int) This required a way to get config_id if we only have the block. And it means that we are more likely to go through load_block_as_user because we have not created the config off the block even when calling from the block (since the block has to go through that config ID). A lot of tests had to be updated to have more complete configuration setup because config_id is now load bearing.
-
Andy Shultz authored
Sometimes we need to load the block. Current code always rebinds the block to the anonymous user because we might not have a user. But in many cases we do have a user and may have already loaded and bound the block in question. Check for user and request and if the block is already bound and just use that block if possible or at least load the block with the user you actually have.
-
- Oct 19, 2022
-
-
Andy Shultz authored
-
- Oct 17, 2022
-
-
michaelroytman authored
-
michaelroytman authored
This commit fixes a bug in the way we determine where to send the authentication response - the LTI 1.3 launch message - as part of an LTI 1.3 launch. According to the 1EdTech Security Framework 1.0, during an LTI 1.3 launch, "the authentication response is sent to the redirect_uri." The redirect_uri is a query or form parameter provided by the tool when it directs the browser to make a request to the Platform's authentication endpoint. However, we currently send the authentication response to the preregistered launch URL - lti_1p3_launch_url in the LtiConsumerXBlock or the LtiConfiguration model. The difference is subtle, but it is important, because the specification indicates the Platform should respect the redirect_uri provided by the Tool, assuming it is a valid redirect_uri. During the pregistration phase, "the Tool must provide one or multiple redirect URIs that are valid end points where the authorization response can be sent. The number of distinct redirect URIs to be supported by a platform is not specified." Currently, we do not support multiple redirect URIs, so the change is not immediately impactful. However, we should follow the specification and ensure that we return the authentication response to the correct URL.
-
michaelroytman authored
This commit fixes a bug caused by the X-Frame-Options response header. The X-Frame-Options response header indicates to the browser whether a site's content can be loaded within certain tags, including the <iframe> tag. This is a form of clickjacking protection. In Django, this response header is set by the django.middleware.clickjacking.XFrameOptionsMiddleware middleware. In the edx-platform, by default, X-Frame-Options is set to DENY (see the X_FRAME_OPTIONS Django setting), which means that the response content returned by Django views cannot be loaded within certain tags. However, this behavior can be disabled by decorating views with the django.views.decorators.clickjacking.xframe_options_exempt view decorator. This creates a problem for LTI 1.3 lauches in the edx-platform. When an LTI component is loaded, the LtiConsumerXBlock is loaded via the lms.djangoapps.courseware.views.views.render_xblock_view view. This view is called an <iframe> tag, but the view is decorated by the xfame_options_exempt decorator, which disables clickjacking protection and communicates to the browser that the content can be loaded in the <iframe> tag. Once the third-party login request of the LTI 1.3 launch is completed, the LTI tool directs the browser to make a request to the launch_gate_endpoint. This endpoint returns a response, which is an auto-submitting form that makes a POST request - the LTI launch request - to the tool. This view has clickjacking enabled, so the browser blocks the requests, which prevents the launch from occurring. This commit adds the xframe_options_exempt view decorator to the launch_gate_endpoint view. Note that LTI 1.1 does not have this bug, because the LTI launch request is handled via the lti_launch_handler. The XBlock runtime handles requests to the LTI handlers via the openedx.core.djangoapps.xblock.rest_api.views.xblock_handler view, which is also decorated by the xframe_options_exempt view decorator.
-
- Oct 13, 2022
-
-
michaelroytman authored
Purpose ------- The purpose of these changes is to decouple the LTI 1.3 launch from the LtiConsumerXBlock. It is in accordance with the ADR "0007 Decouple LTI 1.3 Launch from XBlock and edX Platform", which is currently under review. The pull request for the ADR is here: https://github.com/openedx/xblock-lti-consumer/pull/281. The general premise of these changes is to shift the responsibility of defining key launch claims to users of the library. Such claims include user ID, user role, resource link ID, etc. Prior to this change, this context was defined directly in the launch view by referencing XBlock fields and functions, thereby tying the LTI 1.3 launch to the XBlock. By shifting the responsibility out of the view, we will be able to genericize the launch and make it functional in more contexts than just the XBlock and the XBlock runtime. In short, the key launch claims are encoded in an instance of a data class Lti1p3LaunchData. Users of the library will instantiate this class with necessary launch data to it and pass the instance to various methods of the Python API to communicate the data to the library. Please see the aforementioned ADR for more details about this decoupling strategy. Note that the majority of these changes affect only the basic LTI 1.3 launch. There have largely been no changes to LTI 1.3 Advantage Services. The one exception is the Deep Linking content launch endpoint. This is because this launch is implemented in the basic LTI 1.3 launch, and it was necessary to make the same changes to the deep linking content launch to ensure that it works properly. Otherwise, LTI 1.3 Advantage Services are out of scope of these changes. Change Summary for Developers ----------------------------- Below is a summary of changes contained in this pull request. * added an Lti1p3LaunchData data class * added caching for Lti1p3LaunchData to limit data sent in request query or form parameters * BREAKING CHANGE: modified Python API methods to take Lti1p3LaunchData as a required argument ** get_lti_1p3_launch_info ** get_lti_1p3_launch_start_url ** get_lti_1p3_content_url * replaced references to LtiConsumerXBlock.location with Lti1p3LaunchData.config_id * removed definition of key LTI 1.3 claims from the launch_gate_endpoint and instantiated Lti1p3LaunchData from within the LtiConsumerXBlock instead * added a required launch_data_key request query parameter to the deep_linking_content_endpoint and refactored associated templates and template tags to pass this parameter in the request to the view Change Summary for Course Staff and Instructors ----------------------------------------------- The only changes relevant for course staff and instructors is that the access token and keyset URLs displayed in Studio have changed in format. The old format was: Access Token URL: https://courses.edx.org/api/lti_consumer/v1/token/block-v1:edX+999+2022Q3+type@lti_consumer+block@714c10a5e4df452da9d058788acb56be Keyset URL: https://courses.edx.org/api/lti_consumer/v1/public_keysets/block-v1:edX+999+2022Q3+type@lti_consumer+block@714c10a5e4df452da9d058788acb56be The new format is: Access Token URL: https://courses.edx.org/api/lti_consumer/v1/token/c3f6af60-dbf2-4f85-8974-4ff870068d43 Keyset URL: https://courses.edx.org/api/lti_consumer/v1/public_keysets/c3f6af60-dbf2-4f85-8974-4ff870068d43 The difference is in the slug at the end of the URL. In the old format, the slug was the UsageKey of the XBlock associated with the LTI integration. In the new format, the slug is the config_id of the LtiConfiguration associated with the LTI integration. This is an iterative step toward decoupling the access_token_endpoint and the public_keyset_endpoint views from the XBlock location field. The XBlock location field appears as the usage_key parameter to both views. We cannot simply remove the usage_key parameter from the views, because existing LTI 1.3 integrations may have been created using the old format, and we need to maintain backwards compatibility. This change, however, prevents new integrations from being created that are coupled to the XBlock. In the future, we may address integrations that use the old format to fully decouple the XBlock from the views. Testing ------- Unit tests were added for all changes. In addition, manual testing was performed using the instructions in the documents listed below. * https://github.com/openedx/xblock-lti-consumer#lti-13 * https://openedx.atlassian.net/wiki/spaces/COMM/pages/1858601008/How+to+run+the+LTI+Validation+test Resources --------- JIRA: MST-1603: https://2u-internal.atlassian.net/browse/MST-1603 BREAKING CHANGE
-
- Oct 03, 2022
-
-
edX requirements bot authored
* chore: Updating Python Requirements * fix: update is_valid arg Co-authored-by:
Alie Langston <alangsto@wellesley.edu>
-
- Aug 22, 2022
-
-
michaelroytman authored
In the LTI 1.1 launch handler, we set the user context, including the user_id. We do this by calling to the LMS's DjangoXBlockUserService to get information about the user. Sometimes, the user is unauthenticated. Sometimes, this is because the user is a web crawler. Other times, the user is a real user, but we do not know why the user is unauthenticated. We have some theories, but we have been unable to confirm them. Regardless, we should not surface a 500 error to the user. This commit adds handling for the LtiError that is raised when a user is unauthenticated during an LTI 1.1 launch. It catches the LtiError and renders an error page. The error page that was used for LTI 1.3 launches, formerly named "lti_1p3_launch_error.html", has been renamed to "lti_launch_error.html" to reflect the fact that it is used for both LTI 1.1 and 1.3 launches. It was modified to remove the reference to the version of LTI used by the XBlock; these details are unnecessary for a learner, and removing them allows us to reuse a single template for both LTI versions.
-
- Aug 19, 2022
-
-
michaelroytman authored
This reverts commit 617d8781. We have determined an appropriate course of action for these errors, so the additional logging is no longer necessary and should be removed.
-
- Aug 17, 2022
-
-
Arunmozhi authored
Move XBlock endpoints to Django models and implement backwards compatible views. Relevant commits: * refactor: move LTI 1.3 access token endpoint to plugin view * refactor: remove the xblock handler and add tests to api view * refactor: move the lti_1p3_launch_callback logic to the django view * feat: adds access token view for backward compatibility * refactor: make launch urls use config_id when block is missing * refactor: remove launch_callback_handler from XBlock
-