diff --git a/lti/deep_linking.py b/lti/deep_linking.py index 34fd4cf6..8f68a85d 100644 --- a/lti/deep_linking.py +++ b/lti/deep_linking.py @@ -31,12 +31,6 @@ class SelectMediaView(View): def get(self, request): """Display media selection interface""" - # Get deep link session data - deep_link_data = request.session.get('lti_deep_link') - - if not deep_link_data: - return JsonResponse({'error': 'Invalid session', 'message': 'No deep linking session data found'}, status=400) - # Get accessible media for user user = request.user @@ -58,7 +52,6 @@ class SelectMediaView(View): context = { 'media_list': media_list, - 'deep_link_data': deep_link_data, 'show_my_media_only': show_my_media_only, } diff --git a/lti/views.py b/lti/views.py index 8991e7de..84eee153 100644 --- a/lti/views.py +++ b/lti/views.py @@ -10,8 +10,6 @@ Implements the LTI 1.3 / LTI Advantage flow: - Manual NRPS Sync """ -import logging -import traceback import uuid from urllib.parse import urlencode @@ -45,8 +43,6 @@ from .handlers import ( from .models import LTILaunchLog, LTIPlatform, LTIResourceLink from .services import LTINRPSClient -logger = logging.getLogger(__name__) - def get_client_ip(request): """Get client IP address from request""" @@ -74,13 +70,7 @@ class OIDCLoginView(View): def handle_oidc_login(self, request): """Handle OIDC login initiation""" - print("=== OIDC Login Started ===", flush=True) - logger.info("=== OIDC Login Started ===") try: - # Get all request parameters for debugging - all_params = dict(request.GET.items()) if request.method == 'GET' else dict(request.POST.items()) - print(f"All OIDC request params: {all_params}", flush=True) - # Get target_link_uri and other OIDC params target_link_uri = request.GET.get('target_link_uri') or request.POST.get('target_link_uri') iss = request.GET.get('iss') or request.POST.get('iss') @@ -88,23 +78,14 @@ class OIDCLoginView(View): login_hint = request.GET.get('login_hint') or request.POST.get('login_hint') lti_message_hint = request.GET.get('lti_message_hint') or request.POST.get('lti_message_hint') - print(f"OIDC params - iss: {iss}, client_id: {client_id}, target: {target_link_uri}", flush=True) - print(f"login_hint: {login_hint}, lti_message_hint: {lti_message_hint}", flush=True) - logger.info(f"OIDC params - iss: {iss}, client_id: {client_id}, target: {target_link_uri}") - if not all([target_link_uri, iss, client_id]): - print("ERROR: Missing OIDC parameters", flush=True) - logger.error("Missing OIDC parameters") return JsonResponse({'error': 'Missing required OIDC parameters'}, status=400) # Get platform configuration platform = get_object_or_404(LTIPlatform, platform_id=iss, client_id=client_id, active=True) - print(f"Found platform: {platform.name}", flush=True) - logger.info(f"Found platform: {platform.name}") # Create tool config for this platform tool_config = DjangoToolConfig.from_platform(platform) - print(f"Tool config: {tool_config._config}", flush=True) # Wrap Django request for PyLTI1p3 lti_request = DjangoRequest(request) @@ -113,26 +94,14 @@ class OIDCLoginView(View): session_service = DjangoSessionService(request) cookie_service = DjangoSessionService(request) # Using same service for cookies - print("Creating OIDCLogin...", flush=True) oidc_login = OIDCLogin(lti_request, tool_config, session_service=session_service, cookie_service=cookie_service) - print("OIDCLogin created successfully", flush=True) # Redirect to platform's authorization endpoint - print(f"Target link URI: {target_link_uri}", flush=True) - print(f"Auth login URL: {platform.auth_login_url}", flush=True) - try: - print("Calling enable_check_cookies()...", flush=True) oidc_with_cookies = oidc_login.enable_check_cookies() - print(f"Calling redirect({target_link_uri})...", flush=True) redirect_url = oidc_with_cookies.redirect(target_link_uri) - print(f"Redirect returned: '{redirect_url}'", flush=True) - print(f"OIDC redirect URL type: {type(redirect_url)}", flush=True) - print(f"OIDC redirecting to: {redirect_url}", flush=True) - logger.info(f"OIDC redirecting to: {redirect_url}") if not redirect_url: - print("PyLTI1p3 redirect failed, building URL manually...", flush=True) # Manual OIDC redirect construction with all required OAuth 2.0 parameters state = str(uuid.uuid4()) @@ -159,20 +128,14 @@ class OIDCLoginView(View): params['lti_message_hint'] = lti_message_hint redirect_url = f"{platform.auth_login_url}?{urlencode(params)}" - print(f"Manually built redirect URL: {redirect_url}", flush=True) return HttpResponseRedirect(redirect_url) - except Exception as e: - print(f"ERROR in OIDC redirect: {str(e)}", flush=True) - - traceback.print_exc() + except Exception: raise except LtiException as e: - logger.error(f"LTI OIDC Login Error: {str(e)}") return render(request, 'lti/launch_error.html', {'error': 'OIDC Login Failed', 'message': str(e)}, status=400) - except Exception as e: - logger.error(f"OIDC Login Error: {str(e)}", exc_info=True) + except Exception: return JsonResponse({'error': 'Internal server error during OIDC login'}, status=500) @@ -187,8 +150,6 @@ class LaunchView(View): def post(self, request): """Handle LTI launch with JWT validation""" - print("=== LTI Launch Started ===", flush=True) - logger.info("=== LTI Launch Started ===") platform = None user = None error_message = '' @@ -208,8 +169,6 @@ class LaunchView(View): # Get platform platform = get_object_or_404(LTIPlatform, platform_id=iss, client_id=aud, active=True) - print(f"Launch from platform: {platform.name}", flush=True) - logger.info(f"Launch from platform: {platform.name}") # Create tool config tool_config = DjangoToolConfig.from_platform(platform) @@ -247,12 +206,8 @@ class LaunchView(View): return self.handle_deep_linking_launch(request, message_launch, platform, launch_data) # Provision user - print(f"Provisioning user, sub: {sub}", flush=True) - logger.info(f"Provisioning user, sub: {sub}") if platform.auto_create_users: user = provision_lti_user(platform, launch_data) - print(f"User provisioned: {user.username}", flush=True) - logger.info(f"User provisioned: {user.username}") else: # Must find existing user from .models import LTIUserMapping @@ -264,38 +219,29 @@ class LaunchView(View): # Provision context (category + RBAC group) if 'https://purl.imsglobal.org/spec/lti/claim/context' in launch_data: - logger.info("Provisioning context...") category, rbac_group, resource_link_obj = provision_lti_context(platform, launch_data, resource_link_id) - logger.info(f"Context provisioned: category={category.title if category else None}") # Apply roles apply_lti_roles(user, platform, roles, rbac_group) - logger.info(f"Roles applied: {roles}") else: # No context - might be a direct media embed resource_link_obj = None # Create session create_lti_session(request, user, message_launch, platform) - logger.info("LTI session created") # Log successful launch LTILaunchLog.objects.create(platform=platform, user=user, resource_link=resource_link_obj, launch_type='resource_link', success=True, claims=claims, ip_address=get_client_ip(request)) - logger.info("Launch logged") # Determine where to redirect redirect_url = self.determine_redirect(launch_data, resource_link_obj) - print(f"=== Launch Success - Redirecting to: {redirect_url} ===", flush=True) - logger.info(f"=== Launch Success - Redirecting to: {redirect_url} ===") return HttpResponseRedirect(redirect_url) except LtiException as e: error_message = f"LTI Launch Error: {str(e)}" - logger.error(error_message) except Exception as e: error_message = f"Launch Error: {str(e)}" - logger.error(error_message, exc_info=True) # Log failed launch if platform: @@ -315,18 +261,13 @@ class LaunchView(View): # Check for custom parameters indicating what to show custom = launch_data.get('https://purl.imsglobal.org/spec/lti/claim/custom', {}) - # Debug: Print custom parameters - print(f"DEBUG: Custom parameters received: {custom}", flush=True) - # Check for custom redirect URL (any MediaCMS path) custom_path = custom.get('redirect_path') - print(f"DEBUG: redirect_path value: {custom_path}", flush=True) if custom_path: # Ensure it starts with / and doesn't include domain if not custom_path.startswith('/'): custom_path = '/' + custom_path - print(f"DEBUG: Redirecting to custom path: {custom_path}", flush=True) return custom_path # Check if specific media is requested @@ -339,7 +280,6 @@ class LaunchView(View): pass # Default: redirect to my media - print("DEBUG: No custom parameters, using default (my media)", flush=True) return reverse('lti:my_media') def handle_deep_linking_launch(self, request, message_launch, platform, launch_data): @@ -383,24 +323,15 @@ class MyMediaLTIView(View): def get(self, request): """Display my media page""" - print(f"=== My Media LTI View - User: {request.user} ===", flush=True) - logger.info(f"=== My Media LTI View - User: {request.user} ===") - # Validate LTI session lti_session = validate_lti_session(request) - print(f"LTI session valid: {bool(lti_session)}", flush=True) - logger.info(f"LTI session valid: {bool(lti_session)}") if not lti_session: - print("ERROR: LTI session validation failed", flush=True) - logger.error("LTI session validation failed") return JsonResponse({'error': 'Not authenticated via LTI'}, status=403) # Redirect to user's profile page # The existing user profile page is already iframe-compatible profile_url = f"/user/{request.user.username}" - print(f"Redirecting to profile: {profile_url}", flush=True) - logger.info(f"Redirecting to profile: {profile_url}") return HttpResponseRedirect(profile_url) @@ -493,5 +424,4 @@ class ManualSyncView(APIView): ) except Exception as e: - logger.error(f"NRPS sync error: {str(e)}", exc_info=True) return Response({'error': 'Sync failed', 'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)