This commit is contained in:
Markos Gogoulos
2025-12-29 19:33:24 +02:00
parent 01b061a47b
commit 5cc72357c6
3 changed files with 45 additions and 3 deletions

View File

@@ -213,14 +213,21 @@ class SelectMediaView(View):
'https://purl.imsglobal.org/spec/lti/claim/version': '1.3.0', 'https://purl.imsglobal.org/spec/lti/claim/version': '1.3.0',
'https://purl.imsglobal.org/spec/lti/claim/deployment_id': deployment_id, 'https://purl.imsglobal.org/spec/lti/claim/deployment_id': deployment_id,
'https://purl.imsglobal.org/spec/lti-dl/claim/content_items': lti_content_items, 'https://purl.imsglobal.org/spec/lti-dl/claim/content_items': lti_content_items,
'https://purl.imsglobal.org/spec/lti-dl/claim/data': deep_linking_settings.get('data', ''),
} }
# Echo back data claim if it was present in the request
if 'data' in deep_linking_settings:
payload['https://purl.imsglobal.org/spec/lti-dl/claim/data'] = deep_linking_settings['data']
print("JWT Payload:") print("JWT Payload:")
print(f" iss (issuer): {tool_issuer}") print(f" iss (issuer): {tool_issuer}")
print(f" aud (audience): {audience}") print(f" aud (audience): {audience}")
print(f" deployment_id: {deployment_id}") print(f" deployment_id: {deployment_id} (type: {type(deployment_id).__name__})")
print(f" content_items count: {len(lti_content_items)}") print(f" content_items count: {len(lti_content_items)}")
print(" Full payload:")
import json
print(json.dumps(payload, indent=2, default=str))
# Sign JWT with tool's private key # Sign JWT with tool's private key
kid = key_obj.private_key_jwk['kid'] kid = key_obj.private_key_jwk['kid']

View File

@@ -13,6 +13,7 @@ urlpatterns = [
path('oidc/login/', views.OIDCLoginView.as_view(), name='oidc_login'), path('oidc/login/', views.OIDCLoginView.as_view(), name='oidc_login'),
path('launch/', views.LaunchView.as_view(), name='launch'), path('launch/', views.LaunchView.as_view(), name='launch'),
path('jwks/', views.JWKSView.as_view(), name='jwks'), path('jwks/', views.JWKSView.as_view(), name='jwks'),
path('public-key/', views.PublicKeyPEMView.as_view(), name='public_key_pem'),
# Deep Linking # Deep Linking
path('select-media/', deep_linking.SelectMediaView.as_view(), name='select_media'), path('select-media/', deep_linking.SelectMediaView.as_view(), name='select_media'),
# LTI-authenticated pages # LTI-authenticated pages

View File

@@ -15,7 +15,7 @@ import uuid
from urllib.parse import urlencode from urllib.parse import urlencode
import jwt import jwt
from django.http import HttpResponseRedirect, JsonResponse from django.http import HttpResponse, HttpResponseRedirect, JsonResponse
from django.shortcuts import get_object_or_404, render from django.shortcuts import get_object_or_404, render
from django.urls import reverse from django.urls import reverse
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
@@ -362,6 +362,40 @@ class JWKSView(View):
return JsonResponse(jwks, content_type='application/json') return JsonResponse(jwks, content_type='application/json')
class PublicKeyPEMView(View):
"""
Display public key in PEM format for easy copy/paste into Moodle
"""
def get(self, request):
"""Return public key in PEM format"""
from jwcrypto import jwk
from .models import LTIToolKeys
# Get key from database
key_obj = LTIToolKeys.get_or_create_keys()
# Convert to PEM
jwk_obj = jwk.JWK(**key_obj.public_key_jwk)
pem_bytes = jwk_obj.export_to_pem()
pem_string = pem_bytes.decode('utf-8')
# Return as plain text for easy copy/paste
return HttpResponse(
f"MediaCMS LTI Public Key (PEM Format)\n"
f"{'=' * 80}\n\n"
f"{pem_string}\n"
f"{'=' * 80}\n\n"
f"Instructions:\n"
f"1. Copy the entire key above (including BEGIN/END lines)\n"
f"2. In Moodle LTI tool configuration, change 'Public key type' to 'Public key'\n"
f"3. Paste the key into the 'Public key' field\n"
f"4. Save and try Deep Linking again\n",
content_type='text/plain',
)
@method_decorator(xframe_options_exempt, name='dispatch') @method_decorator(xframe_options_exempt, name='dispatch')
class MyMediaLTIView(View): class MyMediaLTIView(View):
""" """