@@ -714,8 +714,9 @@ def validate(self):
714714 # This validation is just for the Unit page in Studio; we don't want to block users from saving
715715 # a new LTI ID before they've added it to advanced settings, but we do want to warn them about it.
716716 # If we put this check in validate_field_data(), the settings editor wouldn't let them save changes.
717- if self .lti_version == "lti_1p1" and self .lti_id :
718- lti_passport_ids = [lti_passport .split (':' )[0 ].strip () for lti_passport in self .course .lti_passports ]
717+ course = self .course
718+ if course and self .lti_version == "lti_1p1" and self .lti_id :
719+ lti_passport_ids = [lti_passport .split (':' )[0 ].strip () for lti_passport in course .lti_passports ]
719720 if self .lti_id .strip () not in lti_passport_ids :
720721 validation .add (ValidationMessage (ValidationMessage .WARNING , str (
721722 _ ("The specified LTI ID is not configured in this course's Advanced Settings." )
@@ -846,24 +847,37 @@ def role(self):
846847 Get system user role.
847848 """
848849 user = self .runtime .service (self , 'user' ).get_current_user ()
849- if not user .opt_attrs [ "edx-platform.is_authenticated" ] :
850+ if not user .opt_attrs . get ( "edx-platform.is_authenticated" ) :
850851 raise LtiError (self .ugettext ("Could not get user data for current request" ))
851852
852853 return user .opt_attrs .get ('edx-platform.user_role' , 'student' )
853854
855+ @property
856+ def user_is_staff (self ):
857+ """
858+ Get system user's is_staff flag.
859+ """
860+ user = self .runtime .service (self , "user" ).get_current_user ()
861+ return (
862+ user .opt_attrs .get ("edx-platform.is_authenticated" , False ) and
863+ user .opt_attrs .get ("edx-platform.user_is_staff" , False )
864+ )
865+
854866 @property
855867 def course (self ):
856868 """
857869 Return course by course id.
858870 """
859- return self . runtime . modulestore . get_course (self .scope_ids .usage_id .context_key )
871+ return compat . get_course_by_id (self .scope_ids .usage_id .context_key )
860872
861873 @property
862874 def lti_provider_key_secret (self ):
863875 """
864876 Obtains client_key and client_secret credentials from current course.
865877 """
866- for lti_passport in self .course .lti_passports :
878+ course = self .course
879+ lti_passports = course .lti_passports if course else []
880+ for lti_passport in lti_passports :
867881 try :
868882 # NOTE While unpacking the lti_passport by using ":" as delimiter, first item will be lti_id,
869883 # last item will be client_secret and the rest are considered as client_key.
@@ -1073,7 +1087,7 @@ def prefixed_custom_parameters(self):
10731087
10741088 custom_parameters ['custom_component_display_name' ] = str (self .display_name )
10751089
1076- if self . due :
1090+ if getattr ( self , ' due' , None ) :
10771091 custom_parameters .update ({
10781092 'custom_component_due_date' : self .due .strftime ('%Y-%m-%d %H:%M:%S' )
10791093 })
@@ -1124,7 +1138,7 @@ def extract_real_user_data(self):
11241138 """
11251139 user = self .runtime .service (self , 'user' ).get_current_user ()
11261140
1127- if not user .opt_attrs [ "edx-platform.is_authenticated" ] :
1141+ if not user .opt_attrs . get ( "edx-platform.is_authenticated" ) :
11281142 raise LtiError (self .ugettext ("Could not get user data for current request" ))
11291143
11301144 user_data = {
@@ -1144,6 +1158,38 @@ def extract_real_user_data(self):
11441158
11451159 return user_data
11461160
1161+ def _add_author_view (self , context , loader , fragment ):
1162+ """
1163+ Adds the "author view" content to the given fragment.
1164+
1165+ Assumes that the CSS/JS will be added by the caller.
1166+ """
1167+ # Runtime import since this will only run in the
1168+ # Open edX LMS/Studio environments.
1169+ # pylint: disable=import-outside-toplevel
1170+ from lti_consumer .api import get_lti_1p3_launch_info
1171+
1172+ if not context :
1173+ context = {}
1174+
1175+ # Retrieve LTI 1.3 Launch information
1176+ launch_data = self .get_lti_1p3_launch_data ()
1177+ context .update (
1178+ get_lti_1p3_launch_info (
1179+ launch_data ,
1180+ )
1181+ )
1182+
1183+ # Render template
1184+ fragment .add_content (
1185+ loader .render_django_template (
1186+ '/templates/html/lti_1p3_studio.html' ,
1187+ context ,
1188+ i18n_service = self .runtime .service (self , 'i18n' )
1189+ ),
1190+ )
1191+ return fragment
1192+
11471193 def studio_view (self , context ):
11481194 """
11491195 Get Studio View fragment
@@ -1167,29 +1213,11 @@ def author_view(self, context):
11671213 if self .lti_version == "lti_1p1" :
11681214 return self .student_view (context )
11691215
1170- # Runtime import since this will only run in the
1171- # Open edX LMS/Studio environments.
1172- # pylint: disable=import-outside-toplevel
1173- from lti_consumer .api import get_lti_1p3_launch_info
1174-
1175- # Retrieve LTI 1.3 Launch information
1176- launch_data = self .get_lti_1p3_launch_data ()
1177- context .update (
1178- get_lti_1p3_launch_info (
1179- launch_data ,
1180- )
1181- )
1182-
11831216 # Render template
11841217 fragment = Fragment ()
11851218 loader = ResourceLoader (__name__ )
1186- fragment .add_content (
1187- loader .render_django_template (
1188- '/templates/html/lti_1p3_studio.html' ,
1189- context ,
1190- i18n_service = self .runtime .service (self , 'i18n' )
1191- ),
1192- )
1219+ self ._add_author_view (context , loader , fragment )
1220+
11931221 fragment .add_css (loader .load_unicode ('static/css/student.css' ))
11941222 fragment .add_javascript (loader .load_unicode ('static/js/xblock_lti_consumer.js' ))
11951223 statici18n_js_url = self ._get_statici18n_js_url ()
@@ -1215,8 +1243,16 @@ def student_view(self, context):
12151243 """
12161244 fragment = Fragment ()
12171245 loader = ResourceLoader (__name__ )
1246+ context = context or {}
12181247 context .update (self ._get_context_for_template ())
1248+
1249+ # Prepend the author view for LTI1.3 when rendering student view to staff users in Studio.
1250+ # This is needed so course staff can see the author view parameters when configuring within Libraries v2
1251+ if settings .SERVICE_VARIANT != 'lms' and self .lti_version == "lti_1p3" and self .user_is_staff :
1252+ self ._add_author_view (context , loader , fragment )
1253+
12191254 fragment .add_content (loader .render_mako_template ('/templates/html/student.html' , context ))
1255+
12201256 fragment .add_css (loader .load_unicode ('static/css/student.css' ))
12211257 fragment .add_javascript (loader .load_unicode ('static/js/xblock_lti_consumer.js' ))
12221258 statici18n_js_url = self ._get_statici18n_js_url ()
@@ -1285,10 +1321,11 @@ def lti_launch_handler(self, request, suffix=''): # pylint: disable=unused-argu
12851321 person_name_full = full_name ,
12861322 )
12871323
1324+ course = self .course
12881325 lti_consumer .set_context_data (
12891326 self .context_id ,
1290- self . course .display_name_with_default ,
1291- self . course .display_org_with_default
1327+ course .display_name_with_default if course else "" ,
1328+ course .display_org_with_default if course else "" ,
12921329 )
12931330
12941331 if self .has_score :
@@ -1659,12 +1696,10 @@ def get_context_title(self):
16591696 Return the title attribute of the context_claim for LTI 1.3 launches. This information is included in the
16601697 launch_data query or form parameter of the LTI 1.3 third-party login initiation request.
16611698 """
1662- course_key = self .scope_ids .usage_id .context_key
1663- course = compat .get_course_by_id (course_key )
1664-
1699+ course = self .course
16651700 return " - " .join ([
1666- course .display_name_with_default ,
1667- course .display_org_with_default
1701+ course .display_name_with_default if course else "" ,
1702+ course .display_org_with_default if course else "" ,
16681703 ])
16691704
16701705 def _get_lti_block_launch_handler (self ):
@@ -1732,7 +1767,7 @@ def _get_context_for_template(self):
17321767 'launch_url' : launch_url .strip (),
17331768 'lti_1p3_launch_url' : lti_1p3_launch_url ,
17341769 'element_id' : self .scope_ids .usage_id .html_id (),
1735- 'element_class' : self . category ,
1770+ 'element_class' : getattr ( self , ' category' , '' ) ,
17361771 'launch_target' : self .launch_target ,
17371772 'display_name' : self .display_name ,
17381773 'form_url' : lti_block_launch_handler ,
0 commit comments