diff --git a/lti/views.py b/lti/views.py index 1d346ba9..3737805f 100644 --- a/lti/views.py +++ b/lti/views.py @@ -10,7 +10,6 @@ Implements the LTI 1.3 / LTI Advantage flow: - Manual NRPS Sync """ -import json import logging import traceback import uuid @@ -237,24 +236,31 @@ class LaunchView(View): create_lti_session(request, user, message_launch, platform) # Check for media_friendly_token in custom claims - if custom_claims.get('media_friendly_token'): - logger.error(f"[LTI LAUNCH DEBUG] media_friendly_token value: {custom_claims.get('media_friendly_token')}") + media_token = custom_claims.get('media_friendly_token') + if media_token: + logger.error(f"[LTI LAUNCH DEBUG] Found media_friendly_token in custom claims: {media_token}") - lti_message_hint_str = custom_claims.get('lti_message_hint', '') - if lti_message_hint_str: - try: - message_hint_data = json.loads(lti_message_hint_str) - if isinstance(message_hint_data, dict): - # Store in session for later use - if 'lti_session' in request.session: - request.session['lti_session']['message_hint'] = message_hint_data - request.session.modified = True - except (json.JSONDecodeError, ValueError): - pass + # Check if media token was passed via OIDC session data (from filter launch) + # The state from the OIDC flow is used to retrieve session data + state = request.POST.get('state') + if state and not media_token: + session_key = f'state-{state}' + launch_session_data = request.session.get(session_key, {}) + logger.error(f"[LTI LAUNCH DEBUG] Checking OIDC session data for state {state}: {launch_session_data}") + media_token = launch_session_data.get('media_friendly_token') + if media_token: + logger.error(f"[LTI LAUNCH DEBUG] Found media_friendly_token in OIDC session data: {media_token}") + + # Store media_token in session for determine_redirect to use + if media_token: + request.session['filter_media_token'] = media_token + request.session.modified = True + logger.error(f"[LTI LAUNCH DEBUG] Stored media_token in session: {media_token}") LTILaunchLog.objects.create(platform=platform, user=user, resource_link=resource_link_obj, launch_type='resource_link', success=True, claims=claims) redirect_url = self.determine_redirect(launch_data, resource_link_obj) + logger.error(f"[LTI LAUNCH DEBUG] Redirecting to: {redirect_url}") return HttpResponseRedirect(redirect_url) diff --git a/moodle-plugins/filter_mediacmslti/launch.php b/moodle-plugins/filter_mediacmslti/launch.php index c78ff6dd..36283141 100644 --- a/moodle-plugins/filter_mediacmslti/launch.php +++ b/moodle-plugins/filter_mediacmslti/launch.php @@ -67,29 +67,23 @@ $instance->instructorchoicesendname = 1; $instance->instructorchoicesendemailaddr = 1; $instance->launchcontainer = LTI_LAUNCH_CONTAINER_EMBED_NO_BLOCKS; -// Add custom parameters for media token -$instance->instructorcustomparameters = "media_friendly_token={$mediatoken}"; - -// Get type config and merge in our custom parameters +// Get type config $typeconfig = lti_get_type_type_config($ltitoolid); -// Add custom parameters to typeconfig to ensure they're included in the launch -// typeconfig might be an array or object, handle both cases -if (is_array($typeconfig)) { - if (!isset($typeconfig['customparameters'])) { - $typeconfig['customparameters'] = ''; - } - $typeconfig['customparameters'] .= "\nmedia_friendly_token={$mediatoken}"; -} else { - if (!isset($typeconfig->customparameters)) { - $typeconfig->customparameters = ''; - } - $typeconfig->customparameters .= "\nmedia_friendly_token={$mediatoken}"; +// Store media token in session so we can add it to lti_message_hint +// This is how Moodle passes extra data through the LTI launch +$launchid = 'filter_mediacms_' . uniqid(); +if (!isset($SESSION->lti_initiatelogin_data)) { + $SESSION->lti_initiatelogin_data = []; } +$SESSION->lti_initiatelogin_data[$launchid] = [ + 'media_friendly_token' => $mediatoken, + 'courseid' => $courseid, +]; // Use Moodle's LTI launch function to initiate OIDC properly -// This ensures Moodle generates and tracks the state/nonce -$content = lti_initiate_login($course->id, null, $instance, $typeconfig, null, 'MediaCMS video resource'); +// Pass the launchid so Moodle includes it in lti_message_hint +$content = lti_initiate_login($course->id, $launchid, $instance, $typeconfig, null, 'MediaCMS video resource'); echo $OUTPUT->header(); echo $content; diff --git a/moodle-plugins/filter_mediacmslti/version.php b/moodle-plugins/filter_mediacmslti/version.php index df3ac910..77345529 100644 --- a/moodle-plugins/filter_mediacmslti/version.php +++ b/moodle-plugins/filter_mediacmslti/version.php @@ -24,7 +24,7 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2026012804; // The current plugin version (Date: YYYYMMDDXX). +$plugin->version = 2026012805; // The current plugin version (Date: YYYYMMDDXX). $plugin->requires = 2024100700; // Requires Moodle 5.0 or later. $plugin->component = 'filter_mediacmslti'; // Full name of the plugin (used for diagnostics). $plugin->maturity = MATURITY_STABLE;