Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
zacharis278 committed Jun 26, 2023
1 parent cb33ae5 commit fdb5aa9
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 3 deletions.
13 changes: 12 additions & 1 deletion lti_consumer/plugin/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,27 @@
LtiNrpsContextMembershipViewSet, access_token_endpoint,
deep_linking_content_endpoint, deep_linking_response_endpoint,
launch_gate_endpoint, public_keyset_endpoint,
start_proctoring_assessment_endpoint)
start_proctoring_assessment_endpoint,
initiate_course_tool_launch_endpoint)

# LTI 1.3 APIs router
router = routers.SimpleRouter(trailing_slash=False)
router.register(r'lti-ags', LtiAgsLineItemViewset, basename='lti-ags-view')
router.register(r'memberships', LtiNrpsContextMembershipViewSet, basename='lti-nrps-memberships-view')

INTERNAL_COURSE_KEY_PATTERN = r'([^/+]+(/|\+)[^/+]+(/|\+)[^/?]+)'

EXTERNAL_COURSE_KEY_PATTERN = r'([A-Za-z0-9-_:]+)'

COURSE_ID_PATTERN = rf'(?P<course_id>({INTERNAL_COURSE_KEY_PATTERN}|{EXTERNAL_COURSE_KEY_PATTERN}))'

app_name = 'lti_consumer'
urlpatterns = [
re_path(
rf'lti_consumer/v1/lti/(?P<lti_config_id>[-\w]+)/initiate_launch/course/{COURSE_ID_PATTERN}',
initiate_course_tool_launch_endpoint,
name='lti_consumer.initiate_course_tool_launch_endpoint'
),
path(
'lti_consumer/v1/public_keysets/<uuid:lti_config_id>',
public_keyset_endpoint,
Expand Down
47 changes: 45 additions & 2 deletions lti_consumer/plugin/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied, ValidationError
from django.db import transaction
from django.http import Http404, JsonResponse
from django.shortcuts import render
from django.shortcuts import redirect, render
from django.utils.crypto import get_random_string
from django.views.decorators.clickjacking import xframe_options_exempt, xframe_options_sameorigin
from django.views.decorators.csrf import csrf_exempt
Expand All @@ -18,7 +18,7 @@
from edx_django_utils.cache import TieredCache, get_cache_key
from jwkest.jwt import JWT, BadSyntax
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import UsageKey
from opaque_keys.edx.keys import CourseKey, UsageKey
from rest_framework import status, viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
Expand All @@ -44,6 +44,7 @@
LtiNrpsContextMembershipBasicSerializer,
LtiNrpsContextMembershipPIISerializer)
from lti_consumer.lti_1p3.extensions.rest_framework.utils import IgnoreContentNegotiation
from lti_consumer.data import Lti1p3LaunchData
from lti_consumer.models import LtiAgsLineItem, LtiConfiguration, LtiDlContentItem
from lti_consumer.plugin import compat
from lti_consumer.signals.signals import LTI_1P3_PROCTORING_ASSESSMENT_STARTED
Expand Down Expand Up @@ -82,6 +83,48 @@ def has_block_access(user, block, course_key):
return course_access and block_access


@require_http_methods(["GET"])
def initiate_course_tool_launch_endpoint(request, course_id, lti_config_id):
"""
Launch an LTI tool configured platform wide with a given course_id as the learning context.
"""
try:
lti_config = LtiConfiguration.objects.get(config_id=lti_config_id)

if lti_config.version != lti_config.LTI_1P3:
raise LtiError(
"LTI Error: LTI 1.1 configurations not supported."
)
except (LtiError, ObjectDoesNotExist):
raise Http404 from exc

# Tools configured with a specific placement cannot be launched course wide
# Mostly a hack in place of properly modeling 'platform wide' configurations
if lti_config.location:
raise PermissionDenied

# Check user for course access
course_key = CourseKey.from_string(course_id)
# course = compat.get_course_by_id(course_key)
# if not compat.user_course_access(course, user, 'load', check_if_enrolled=True, check_if_authenticated=True):
# log.warning(
# "Permission on LTI Config %r denied for user %r.",
# lti_config_id,
# request.user,
# )
# raise PermissionDenied

consumer = lti_config.get_lti_consumer()
launch_data = Lti1p3LaunchData(
user_id=request.user.id,
config_id=lti_config.id,
context_id=course_key,
resource_link_id=course_key,
user_role=None,
)

return redirect(consumer.prepare_preflight_url(launch_data))

@require_http_methods(["GET"])
def public_keyset_endpoint(request, usage_id=None, lti_config_id=None):
"""
Expand Down

0 comments on commit fdb5aa9

Please sign in to comment.