def test_valid_nonce(self):
     """
     Verify that check_nonce succeeds with a key of maximum length
     """
     nonce = '0123456789012345678901234567890123456789012345678901234567890123'
     self.assertTrue(
         SignatureValidator(self.lti_consumer).check_nonce(nonce))
 def test_valid_client_key(self):
     """
     Verify that check_client_key succeeds with a valid key
     """
     key = self.lti_consumer.consumer_key
     self.assertTrue(
         SignatureValidator(self.lti_consumer).check_client_key(key))
Exemple #3
0
def lti_launch(request, course_id, usage_id):
    """
    Endpoint for all requests to embed edX content via the LTI protocol. This
    endpoint will be called by a POST message that contains the parameters for
    an LTI launch (we support version 1.2 of the LTI specification):
        http://www.imsglobal.org/lti/ltiv1p2/ltiIMGv1p2.html

    An LTI launch is successful if:
        - The launch contains all the required parameters
        - The launch data is correctly signed using a known client key/secret
          pair
    """
    if not settings.FEATURES['ENABLE_LTI_PROVIDER']:
        return HttpResponseForbidden()

    # Check the LTI parameters, and return 400 if any required parameters are
    # missing
    params = get_required_parameters(request.POST)
    if not params:
        return HttpResponseBadRequest()
    params.update(get_optional_parameters(request.POST))

    # Get the consumer information from either the instance GUID or the consumer
    # key
    try:
        lti_consumer = LtiConsumer.get_or_supplement(
            params.get('tool_consumer_instance_guid', None),
            params['oauth_consumer_key']
        )
    except LtiConsumer.DoesNotExist:
        return HttpResponseForbidden()

    # Check the OAuth signature on the message
    if not SignatureValidator(lti_consumer).verify(request):
        return HttpResponseForbidden()

    # Add the course and usage keys to the parameters array
    try:
        course_key, usage_key = parse_course_and_usage_keys(course_id, usage_id)
    except InvalidKeyError:
        log.error(
            u'Invalid course key %s or usage key %s from request %s',
            course_id,
            usage_id,
            request
        )
        raise Http404()  # lint-amnesty, pylint: disable=raise-missing-from
    params['course_key'] = course_key
    params['usage_key'] = usage_key

    # Create an edX account if the user identifed by the LTI launch doesn't have
    # one already, and log the edX account into the platform.
    authenticate_lti_user(request, params['user_id'], lti_consumer)

    # Store any parameters required by the outcome service in order to report
    # scores back later. We know that the consumer exists, since the record was
    # used earlier to verify the oauth signature.
    store_outcome_parameters(params, request.user, lti_consumer)

    return render_courseware(request, params['usage_key'])
Exemple #4
0
 def test_get_existing_client_secret(self):
     """
     Verify that get_client_secret returns the right value for the correct
     key
     """
     key = self.lti_consumer.consumer_key
     secret = SignatureValidator(self.lti_consumer).get_client_secret(
         key, None)
     assert secret == self.lti_consumer.consumer_secret
Exemple #5
0
 def test_verification_parameters(self, verify_mock):
     """
     Verify that the signature validaton library method is called using the
     correct parameters derived from the HttpRequest.
     """
     body = 'oauth_signature_method=HMAC-SHA1&oauth_version=1.0'
     content_type = 'application/x-www-form-urlencoded'
     request = RequestFactory().post('/url',
                                     body,
                                     content_type=content_type)
     headers = {'Content-Type': content_type}
     SignatureValidator(self.lti_consumer).verify(request)
     verify_mock.assert_called_once_with(request.build_absolute_uri(),
                                         'POST', body.encode('utf-8'),
                                         headers)
Exemple #6
0
 def test_invalid_nonce(self, nonce):
     """
     Verify that check_nonce fails with badly formatted nonce
     """
     assert not SignatureValidator(self.lti_consumer).check_nonce(nonce)
Exemple #7
0
 def test_invalid_client_key(self, key):
     """
     Verify that check_client_key fails with a disallowed key
     """
     assert not SignatureValidator(self.lti_consumer).check_client_key(key)