def test_signature_port(self): ''' Should generate a correct signature with a non-standard port. ''' tc = ToolConsumer('12345', 'secret', {'resource_link_id': 1}) tc.timestamp = '1251600739' tc.nonce = 'c8350c0e47782d16d2fa48b2090c1d8f' def test_url(url, sig): tc.launch_url = url ld = tc.generate_launch_data() self.assertNotEqual(ld, None) self.assertEquals(ld['oauth_signature'], sig) test_url('http://dr-chuck.com:123/ims/php-simple/tool.php', 'Y/QdFIdVeGkXnnT77h8FXaSp4T4=') test_url('http://dr-chuck.com/ims/php-simple/tool.php', 'mSoeJJMmtFCmMYgpHZ8hCnc5Gzo=') test_url('http://dr-chuck.com:80/ims/php-simple/tool.php', 'mSoeJJMmtFCmMYgpHZ8hCnc5Gzo=') test_url('http://dr-chuck.com:443/ims/php-simple/tool.php', 'KaISX3G2Q+zHW/BZI1vNKyGoblo=') test_url('https://dr-chuck.com/ims/php-simple/tool.php', 'yCtVB+/6njhnKKzxvYkIR8hUD3Q=') test_url('https://dr-chuck.com:443/ims/php-simple/tool.php', 'yCtVB+/6njhnKKzxvYkIR8hUD3Q=') test_url('https://dr-chuck.com:80/ims/php-simple/tool.php', 'tz94qHbVCmx2u/PZyO4l0XXWU+s=') test_url('https://dr-chuck.com:80/ims/php-simple/tool.php?oi=hoyt', 'jRCj3U8JwHI4rEsgNMihOSE8xCQ=')
def test_allow_lti_version_in_params(self): ''' Should not overwrite an LTI version passed in params ''' tc = ToolConsumer('12345', 'secret', { 'resource_link_id': 1, 'user_id': 2, 'lti_version': 'LTI-1.0p' }) tc.launch_url = 'http://www.yahoo.com?user_id=123<i_message_type=1234' result = tc.generate_launch_data() self.assertEqual(result['lti_version'], 'LTI-1.0')
def test_allow_lti_version_in_params(self): ''' Should not overwrite an LTI version passed in params ''' tc = ToolConsumer('12345', 'secret', { 'resource_link_id': 1, 'user_id': 2, 'lti_version': 'LTI-1.0p' }) result = tc.generate_launch_data() self.assertEqual(result['lti_version'], 'LTI-1.0p')
def test_uri_query_parameters(self): ''' Should include URI query parameters. ''' tc = ToolConsumer('12345', 'secret', { 'resource_link_id': 1, 'user_id': 2 }) tc.launch_url = 'http://www.yahoo.com?a=1&b=2' result = tc.generate_launch_data() self.assertNotEqual(result, None) self.assertEqual(result['a'], '1') self.assertEqual(result['b'], '2')
def test_overite_uri_query_parameters(self): ''' Should not allow overwriting other parameters from the URI query string. ''' tc = ToolConsumer('12345', 'secret', { 'resource_link_id': 1, 'user_id': 2 }) tc.launch_url = 'http://www.yahoo.com?user_id=123<i_message_type=1234' result = tc.generate_launch_data() self.assertNotEqual(result, None) self.assertEqual(result['user_id'], '2') self.assertEqual(result['lti_message_type'], 'basic-lti-launch-request')
def create_test_tc(params=None): ''' Returns a new ToolConsumer. ''' params = create_params_tc() if params == None else params consumer_key = '12345' tc = ToolConsumer(consumer_key, 'secret', params) tc.launch_url = 'http://dr-chuck.com/ims/php-simple/tool.php' tc.timestamp = '1251600739' tc.nonce = 'c8350c0e47782d16d2fa48b2090c1d8f' tc.set_non_spec_param('lis_person_sourced_id', 'school.edu:user') tc.set_non_spec_param('basiclti_submit', 'Launch Endpoint with BasicLTI Data') tc._params_update = lambda: { 'oauth_nonce': "c8350c0e47782d16d2fa48b2090c1d8f", 'oauth_timestamp': "1251600739", 'oauth_scheme': 'body', } return tc
def create_test_tc(params = None): ''' Returns a new ToolConsumer. ''' params = create_params_tc() if params == None else params tc = ToolConsumer('12345', 'secret', params) tc.launch_url = 'http://dr-chuck.com/ims/php-simple/tool.php' tc.timestamp = '1251600739' tc.nonce = 'c8350c0e47782d16d2fa48b2090c1d8f' tc.set_non_spec_param('lis_person_sourced_id', 'school.edu:user') tc.set_non_spec_param('basiclti_submit', 'Launch Endpoint with BasicLTI Data') return tc
def create_test_tc(params = None): ''' Returns a new ToolConsumer. ''' params = create_params_tc() if params == None else params consumer_key = '123key' tc = ToolConsumer(consumer_key, 'secret', params) tc.launch_url = 'http://testserver/launch_lti/' tc.timestamp = '1251600739' tc.nonce = 'c8350c0e47782d16d2fa48b2090c1d8f' tc.set_non_spec_param('lis_person_sourced_id', 'school.edu:user') tc.set_non_spec_param('basiclti_submit', 'Launch Endpoint with BasicLTI Data') tc._params_update = lambda:{ 'oauth_nonce': "c8350c0e47782d16d2fa48b2090c1d8f", 'oauth_timestamp': "1251600739", 'oauth_scheme': 'body', } return tc
def grade_passback(): outcome_request = OutcomeRequest.from_post_request(request) sourcedid = outcome_request.lis_result_sourcedid consumer = ToolConsumer('test', 'secret') print "outcomes service url triggered" # if consumer.is_valid_request(request): if True: # TODO: Check oauth timestamp # TODO: Check oauth nonce response = OutcomeResponse() response.message_ref_identifier = outcome_request.message_identifier response.operation = outcome_request.operation response.code_major = 'success' response.severity = 'status' if outcome_request.is_replace_request(): response.description = 'Your old score of 0 has been replaced with %s' % ( outcome_request.score) global outcome outcome = outcome_request.score elif outcome_request.is_read_request(): response.description = 'Your score is 50' response.score = 50 elif outcome_request.is_delete_request(): response.description = 'Your score has been cleared' else: response.code_major = 'unsupported' response.severity = 'status' response.description = '%s is not supported' % ( outcome_request.operation) return response.generate_response_xml() else: throw_oauth_error()
def tool_launch(): # Parse form and ensure necessary parameters are included for param in ['tool_name', 'launch_url', 'consumer_key', 'consumer_secret']: if request.form.get(param) == None: return redirect(url_for('tool_config?message=Please%20set%20all%values')) # Create a new tool configuration config = ToolConfig(title = request.form.get('tool_name'), launch_url = request.form.get('launch_url')) config.set_custom_param('message_from_flask', 'hey from the flask example consumer') # Create LTI tool consumer consumer = ToolConsumer(request.form.get('consumer_key'), request.form.get('consumer_secret')) consumer.set_config(config) # Set some launch data from: http://www.imsglobal.org/LTI/v1p1pd/ltiIMGv1p1pd.html#_Toc309649684 # Only this first one is required, but the rest are recommended consumer.resource_link_id = 'thisistotallyunique' consumer.launch_presentation_return_url = request.url + '/tool_return' consumer.lis_person_name_given = session['username'] hash = hashlib.md5() hash.update(session['username']) consumer.user_id = hash.hexdigest() consumer.roles = 'learner' consumer.context_id = 'bestcourseever' consumer.context_title = 'Example Flask Tool Consumer' consumer.tool_consumer_instance_name = 'Frankie' if request.form.get('assignment'): consumer.lis_outcome_service_url = request.scheme + '://' + request.host + '/grade_passback' consumer.lis_result_sourcedid = 'oi' autolaunch = True if request.form.get('autolaunch') else False return render_template('tool_launch.html', autolaunch=autolaunch, launch_data=consumer.generate_launch_data(), launch_url=consumer.launch_url)
def piazza_test(request, course_id): # Create a new tool configuration config = ToolConfig(title='Piazza', launch_url=LTI_LAUNCH_URL) # Create tool consumer using LTI! consumer = ToolConsumer(LTI_CONSUMER_KEY, LTI_CONSUMER_SECRET) consumer.set_config(config) #retrieve user and course models user = User.objects.prefetch_related("groups").get(id=request.user.id) userProfile = UserProfile.objects.get(user_id=user.id) course = course_from_id(course_id) #check for permissions to determine what role to pass to Piazza.com through piazza_role = '' if user.groups.filter(name=( 'instructor_' + course_id)).count() != 0 or request.user.is_staff: piazza_role = 'Instructor' elif user.groups.filter(name=('staff_' + course_id)).count() != 0: piazza_role = 'Staff' else: piazza_role = 'Learner' # Set some launch data from: http://www.imsglobal.org/LTI/v1p1pd/ltiIMGv1p1pd.html#_Toc309649684 consumer.resource_link_id = course_id consumer.lis_person_contact_email_primary = user.email consumer.lis_person_name_full = str(userProfile.name) hash = hashlib.md5() hash.update(str(userProfile.user_id)) consumer.user_id = hash.hexdigest() #TODO: check if user is is_staff, student, professor, or staff and set the role appropriately #consumer.roles = 'Learner' consumer.roles = piazza_role consumer.context_id = course_id consumer.context_title = course.display_name_with_default consumer.context_label = course.number.replace('_', ' ') consumer.tool_consumer_instance_guid = 'lms.cvn.columbia.edu' consumer.tool_consumer_instance_description = 'Columbia University' launch_data = consumer.generate_launch_data() launch_url = consumer.launch_url #render a self-submitting form that sends all data to Piazza.com via the LTI standard returnable = '<form id="ltiLaunchFormSubmitArea" action="' + launch_url + '" name="ltiLaunchForm" id="ltiLaunchForm" method="post" encType="application/x-www-form-urlencoded">' for key in launch_data: returnable += '<input type="hidden" name="' + key + '" value="' + str( launch_data[key]) + '"/>' returnable += '<input type="submit" value="Go to Piazza"></input>' returnable += '</form>' returnable += '<script language="javascript">document.getElementById("ltiLaunchFormSubmitArea").style.display = "none";document.ltiLaunchForm.submit();</script>' return HttpResponse(returnable)
def piazza_discussion(request, course_id): ''' Shows the page under the Discussion tab with an iframe containing Piazza ''' # Create a new tool configuration config = ToolConfig(title='Piazza', launch_url=LTI_LAUNCH_URL) # Create tool consumer using LTI! consumer = ToolConsumer(LTI_CONSUMER_KEY, LTI_CONSUMER_SECRET) consumer.set_config(config) #retrieve user and course models user = User.objects.prefetch_related("groups").get(id=request.user.id) userProfile = UserProfile.objects.get(user_id=user.id) course = course_from_id(course_id) #check for permissions to determine what role to pass to Piazza.com through piazza_role = '' if user.groups.filter(name=( 'instructor_' + course_id)).count() != 0 or request.user.is_staff: piazza_role = 'Instructor' elif user.groups.filter(name=('staff_' + course_id)).count() != 0: piazza_role = 'Staff' else: piazza_role = 'Learner' # Set some launch data from: http://www.imsglobal.org/LTI/v1p1pd/ltiIMGv1p1pd.html#_Toc309649684 consumer.resource_link_id = course_id consumer.lis_person_contact_email_primary = user.email consumer.lis_person_name_full = str(userProfile.name) hash = hashlib.md5() hash.update(str(userProfile.user_id)) consumer.user_id = hash.hexdigest() #TODO: check if user is is_staff, student, professor, or staff and set the role appropriately consumer.roles = piazza_role consumer.context_id = course_id consumer.context_title = course.display_name_with_default consumer.context_label = course.number.replace('_', ' ') consumer.tool_consumer_instance_guid = 'lms.cvn.columbia.edu' consumer.tool_consumer_instance_description = 'Columbia University' launch_data = consumer.generate_launch_data() launch_url = consumer.launch_url course = get_course_with_access(request.user, course_id, 'load') staff_access = has_access(request.user, course, 'staff') masq = setup_masquerade( request, staff_access) # allow staff to toggle masquerade on info page return render_to_response( 'courseware/piazza_discussion.html', { 'request': request, 'course_id': course_id, 'cache': None, 'course': course, 'staff_access': staff_access, 'masquerade': masq, 'launch_url': launch_url, 'launch_data': launch_data })
def piazza_discussion(request, course_id): ''' Shows the page under the Discussion tab with an iframe containing Piazza ''' # Create a new tool configuration config = ToolConfig(title = 'Piazza', launch_url = LTI_LAUNCH_URL) # Create tool consumer using LTI! consumer = ToolConsumer(LTI_CONSUMER_KEY, LTI_CONSUMER_SECRET) consumer.set_config(config) #retrieve user and course models user = User.objects.prefetch_related("groups").get(id=request.user.id) userProfile = UserProfile.objects.get(user_id=user.id) course = course_from_id(course_id) #check for permissions to determine what role to pass to Piazza.com through piazza_role = '' if user.groups.filter(name=('instructor_'+course_id)).count() != 0 or request.user.is_staff: piazza_role = 'Instructor' elif user.groups.filter(name=('staff_'+course_id)).count() != 0: piazza_role = 'Staff' else: piazza_role = 'Learner' # Set some launch data from: http://www.imsglobal.org/LTI/v1p1pd/ltiIMGv1p1pd.html#_Toc309649684 consumer.resource_link_id = course_id consumer.lis_person_contact_email_primary = user.email consumer.lis_person_name_full = str(userProfile.name) hash = hashlib.md5() hash.update(str(userProfile.user_id)) consumer.user_id = hash.hexdigest() #TODO: check if user is is_staff, student, professor, or staff and set the role appropriately consumer.roles = piazza_role consumer.context_id = course_id consumer.context_title = course.display_name_with_default consumer.context_label = course.number.replace('_', ' ') consumer.tool_consumer_instance_guid = 'lms.cvn.columbia.edu' consumer.tool_consumer_instance_description = 'Columbia University' launch_data = consumer.generate_launch_data() launch_url = consumer.launch_url course = get_course_with_access(request.user, course_id, 'load') staff_access = has_access(request.user, course, 'staff') masq = setup_masquerade(request, staff_access) # allow staff to toggle masquerade on info page return render_to_response('courseware/piazza_discussion.html', {'request': request, 'course_id': course_id, 'cache': None, 'course': course, 'staff_access': staff_access, 'masquerade': masq, 'launch_url':launch_url, 'launch_data':launch_data})
def piazza_test(request, course_id): # Create a new tool configuration config = ToolConfig(title = 'Piazza', launch_url = LTI_LAUNCH_URL) # Create tool consumer using LTI! consumer = ToolConsumer(LTI_CONSUMER_KEY, LTI_CONSUMER_SECRET) consumer.set_config(config) #retrieve user and course models user = User.objects.prefetch_related("groups").get(id=request.user.id) userProfile = UserProfile.objects.get(user_id=user.id) course = course_from_id(course_id) #check for permissions to determine what role to pass to Piazza.com through piazza_role = '' if user.groups.filter(name=('instructor_'+course_id)).count() != 0 or request.user.is_staff: piazza_role = 'Instructor' elif user.groups.filter(name=('staff_'+course_id)).count() != 0: piazza_role = 'Staff' else: piazza_role = 'Learner' # Set some launch data from: http://www.imsglobal.org/LTI/v1p1pd/ltiIMGv1p1pd.html#_Toc309649684 consumer.resource_link_id = course_id consumer.lis_person_contact_email_primary = user.email consumer.lis_person_name_full = str(userProfile.name) hash = hashlib.md5() hash.update(str(userProfile.user_id)) consumer.user_id = hash.hexdigest() #TODO: check if user is is_staff, student, professor, or staff and set the role appropriately #consumer.roles = 'Learner' consumer.roles = piazza_role consumer.context_id = course_id consumer.context_title = course.display_name_with_default consumer.context_label = course.number.replace('_', ' ') consumer.tool_consumer_instance_guid = 'lms.cvn.columbia.edu' consumer.tool_consumer_instance_description = 'Columbia University' launch_data = consumer.generate_launch_data() launch_url = consumer.launch_url #render a self-submitting form that sends all data to Piazza.com via the LTI standard returnable = '<form id="ltiLaunchFormSubmitArea" action="' + launch_url + '" name="ltiLaunchForm" id="ltiLaunchForm" method="post" encType="application/x-www-form-urlencoded">' for key in launch_data: returnable += '<input type="hidden" name="'+ key +'" value="'+ str(launch_data[key]) + '"/>' returnable += '<input type="submit" value="Go to Piazza"></input>' returnable += '</form>' returnable += '<script language="javascript">document.getElementById("ltiLaunchFormSubmitArea").style.display = "none";document.ltiLaunchForm.submit();</script>' return HttpResponse(returnable)