66"""
77
88import json
9+ from typing import Any
910
1011from opaque_keys .edx .keys import CourseKey , UsageKey
1112
1213from lti_consumer .lti_1p3 .constants import LTI_1P3_ROLE_MAP
14+ from lti_consumer .lti_1p3 .exceptions import Lti1p3Exception
1315
1416from .filters import get_external_config_from_filter
1517from .models import CourseAllowPIISharingInLTIFlag , LtiConfiguration , LtiDlContentItem , LtiXBlockConfig
@@ -87,6 +89,17 @@ def _get_config_by_config_id(config_id) -> LtiConfiguration:
8789 return LtiConfiguration .objects .get (config_id = config_id )
8890
8991
92+ def get_lti_config_by_location (location : str , ** filters : dict [str , Any ]) -> LtiXBlockConfig :
93+ """
94+ Gets the LTI xblock config by location
95+ """
96+ config = LtiXBlockConfig .objects .get (
97+ location = location ,
98+ ** filters ,
99+ )
100+ return config
101+
102+
90103def try_get_config_by_id (config_id ) -> LtiConfiguration | None :
91104 """
92105 Tries to get the LTI config by its UUID config ID
@@ -142,28 +155,19 @@ def config_for_block(block):
142155 return xblock_config
143156
144157
145- def get_lti_consumer (config_id : str , location : UsageKey | None = None ):
146- """
147- Retrieves an LTI Consumer instance for a given location.
148-
149- Returns an instance of LtiConsumer1p1 or LtiConsumer1p3 depending
150- on the configuration.
151- """
152- # Return an instance of LTI 1.1 or 1.3 consumer, depending
153- # on the configuration stored in the model.
154- return _get_config_by_config_id (config_id ).get_lti_consumer (location )
155-
156-
157158def get_lti_1p3_launch_info (
158159 launch_data ,
159- location : UsageKey | None = None ,
160+ location : UsageKey ,
160161):
161162 """
162163 Retrieves the Client ID, Keyset URL and other urls used to configure a LTI tool.
163164 """
164165 # Retrieve LTI Config and consumer
165- lti_config = _get_config_by_config_id (launch_data .config_id )
166- lti_consumer = lti_config .get_lti_consumer (location )
166+ lti_xblock_config = get_lti_config_by_location (
167+ str (location ),
168+ lti_configuration__config_id = launch_data .config_id ,
169+ )
170+ lti_consumer = lti_xblock_config .get_lti_consumer ()
167171
168172 # Check if deep Linking is available, if so, add some extra context:
169173 # Deep linking launch URL, and if deep linking is already configured
@@ -180,19 +184,22 @@ def get_lti_1p3_launch_info(
180184
181185 # Retrieve LTI Content Items (if any was set up)
182186 dl_content_items = LtiDlContentItem .objects .filter (
183- lti_configuration = lti_config
187+ lti_xblock_config = lti_xblock_config
184188 )
185189 # Add content item attributes to context
186190 if dl_content_items .exists ():
187191 deep_linking_content_items = [item .attributes for item in dl_content_items ]
188192
193+ lti_config = lti_xblock_config .lti_configuration
194+ if not lti_config :
195+ raise Lti1p3Exception ("LTI configuration not found." )
189196 config_id = lti_config .config_id
190197 client_id = lti_config .lti_1p3_client_id
191198 deployment_id = "1"
192199
193200 # Display LTI launch information from external configuration.
194201 # if an external configuration is being used.
195- if lti_config .config_store == CONFIG_EXTERNAL :
202+ if lti_config .config_store == CONFIG_EXTERNAL and lti_config . external_id :
196203 external_config = get_external_config_from_filter ({}, lti_config .external_id )
197204 config_id = lti_config .external_id .replace (':' , '/' )
198205 client_id = external_config .get ('lti_1p3_client_id' )
@@ -213,15 +220,19 @@ def get_lti_1p3_launch_info(
213220
214221def get_lti_1p3_launch_start_url (
215222 launch_data ,
216- location : UsageKey | None = None ,
223+ location : UsageKey ,
217224 deep_link_launch = False ,
218225 dl_content_id = None ,
219226):
220227 """
221228 Computes and retrieves the LTI URL that starts the OIDC flow.
222229 """
223230 # Retrieve LTI consumer
224- lti_consumer = get_lti_consumer (launch_data .config_id , location )
231+ lti_xblock_config = get_lti_config_by_location (
232+ str (location ),
233+ lti_configuration__config_id = launch_data .config_id ,
234+ )
235+ lti_consumer = lti_xblock_config .get_lti_consumer ()
225236
226237 # Include a message hint in the launch_data depending on LTI launch type
227238 # Case 1: Performs Deep Linking configuration flow. Triggered by staff users to
@@ -239,7 +250,7 @@ def get_lti_1p3_launch_start_url(
239250
240251def get_lti_1p3_content_url (
241252 launch_data ,
242- location : UsageKey | None = None ,
253+ location : UsageKey ,
243254):
244255 """
245256 Computes and returns which URL the LTI consumer should launch to.
@@ -252,10 +263,13 @@ def get_lti_1p3_content_url(
252263 Lti DL content in the database.
253264 """
254265 # Retrieve LTI consumer
255- lti_config = _get_config_by_config_id (launch_data .config_id )
266+ lti_xblock_config = get_lti_config_by_location (
267+ str (location ),
268+ lti_configuration__config_id = launch_data .config_id ,
269+ )
256270
257271 # List content items
258- content_items = lti_config .ltidlcontentitem_set .all ()
272+ content_items = lti_xblock_config .ltidlcontentitem_set .all ()
259273
260274 # If there's no content items, return normal LTI launch URL
261275 if not content_items .count ():
@@ -271,23 +285,7 @@ def get_lti_1p3_content_url(
271285 )
272286
273287 # If there's more than one content item, return content presentation URL
274- return get_lti_deeplinking_content_url (lti_config .id , launch_data )
275-
276-
277- def get_deep_linking_data (deep_linking_id , config_id ):
278- """
279- Retrieves deep linking attributes.
280-
281- Only works with a single line item, this is a limitation in the
282- current content presentation implementation.
283- """
284- # Retrieve LTI Configuration
285- lti_config = _get_config_by_config_id (config_id )
286- # Only filter DL content item from content item set in the same LTI configuration.
287- # This avoids a malicious user to input a random LTI id and perform LTI DL
288- # content launches outside the scope of its configuration.
289- content_item = lti_config .ltidlcontentitem_set .get (pk = deep_linking_id )
290- return content_item .attributes
288+ return get_lti_deeplinking_content_url (lti_xblock_config .id , launch_data )
291289
292290
293291def get_lti_pii_sharing_state_for_course (course_key : CourseKey ) -> bool :
0 commit comments