예제 #1
0
    def test_can_login(self, testapp, app, db):
        app.config['SERVER_NAME'] = 'localhost'
        #app.config['SERVER_PORT'] = 5000
        app.config['PREFERRED_URL_SCHEME'] = 'http'

        consumer = ConsumerFactory()
        consumer.save()
        params = {
            'lti_message_type': 'basic-lti-launch-request',
            'lti_version': 'LTI-1p0',
            'resource_link_id':
            'same.site.org-9fcae62972a240e488ca1de83dc4a6d9',
        }
        tool_consumer = ToolConsumer(consumer_key=consumer.client_key,
                                     consumer_secret=consumer.secret_key,
                                     launch_url=url_for(
                                         'lti_launch.lti_launch',
                                         _external=True),
                                     params=params)

        lti_params = tool_consumer.generate_launch_data()

        #res = testapp.post(url_for('lti_launch.lti_launch', _external=True), lti_params)
        res = testapp.post(url_for('lti_launch.lti_launch', _external=True),
                           lti_params)

        assert res.status_code == 200
예제 #2
0
def test_lti_validation_default_key_unknown_consumer_fail():
    target_path = "/some_path"
    launch_url = "http://testserver{}".format(target_path)
    resource_link_id = "some_string_to_be_the_fake_resource_link_id"
    consumer = ToolConsumer(
        consumer_key="unknown_consumer_key",
        consumer_secret=settings.LTI_SECRET,
        launch_url=launch_url,
        params={
            "lti_message_type": "basic-lti-launch-request",
            "lti_version": "LTI-1p0",
            "resource_link_id": resource_link_id,
            "lis_person_sourcedid": "instructor_1",
            "lis_outcome_service_url": "fake_url",
            "user_id": "instructor_1-anon",
            "roles": ["Instructor", "Administrator"],
            "context_id": "fake_course",
        },
    )
    params = consumer.generate_launch_data()
    for key in params:
        print("****** LTI[{}]: {}".format(key, params[key]))

    factory = RequestFactory()
    request = factory.post(target_path, data=params)

    validator = LTIRequestValidator()
    tool_provider = DjangoToolProvider.from_django_request(request=request)
    request_is_valid = tool_provider.is_valid_request(validator)

    assert not request_is_valid
예제 #3
0
def test_launchLti(random_course_instructor):
    instructor = random_course_instructor["profile"]
    course = random_course_instructor["course"]
    target_path = "/lti_init/launch_lti/"
    launch_url = "http://testserver{}".format(target_path)
    consumer = ToolConsumer(
        consumer_key=settings.CONSUMER_KEY,
        consumer_secret=settings.LTI_SECRET,
        launch_url=launch_url,
        params={
            "lti_message_type": "basic-lti-launch-request",
            "lti_version": "LTI-1p0",
            "resource_link_id": "FakeResourceLinkID",
            "lis_person_sourcedid": instructor.name,
            "lis_outcome_service_url": "fake_url",
            "user_id": instructor.anon_id,
            "roles": ["Instructor"],
            "context_id": course.course_id,
        },
    )
    params = consumer.generate_launch_data()
    # req = consumer.generate_launch_request()

    client = Client(enforce_csrf_checks=False)
    response = client.post(
        target_path,
        data=params,
    )

    assert response.status_code == 403
    assert response.content == "hey"
예제 #4
0
def show_testcase(request, testcase_id):
    '''
    shows a testcase with all parameters.

    Keyword arguments:
        request -- the calling HttpRequest
        testcase_id -- id of the testcase to show
    '''
    testcase = get_object_or_404(Testcase, id=testcase_id)

    lps = {}
    for lp in testcase.launchparam_set.all():
        lps[lp.name] = lp.value

    params = {'testcase': testcase}

    try:
        consumer = ToolConsumer(consumer_key=testcase.consumer_key,
                                consumer_secret=testcase.consumer_secret,
                                launch_url=testcase.launch_url,
                                params=lps)
        params['launch_data'] = consumer.generate_launch_data()
        params['launch_url'] = consumer.launch_url
    except Exception as inst:
        params['error_name'] = str(type(inst).__name__)
        params['error_detail'] = str(inst)

    return render(request, 'consumer/show_testcase.html', params)
예제 #5
0
def get_lti_url(course, user_id, task_id):
    config = syllabus.get_config()
    inginious_config = config['courses'][course]['inginious']
    consumer = ToolConsumer(
        consumer_key=inginious_config['lti']['consumer_key'],
        consumer_secret=inginious_config['lti']['consumer_secret'],
        launch_url='%s/lti/%s/%s' %
        (inginious_config['url'], inginious_config['course_id'], task_id),
        params={
            'lti_message_type': 'basic-lti-launch-request',
            'lti_version': "1.1",
            'resource_link_id': "syllabus_{}_{}".format(course, task_id),
            'user_id': user_id,
        })

    d = consumer.generate_launch_data()
    data = parse.urlencode(d).encode()

    req = urllib_request.Request(
        '%s/lti/%s/%s' %
        (inginious_config['url'], inginious_config['course_id'], task_id),
        data=data)
    resp = urllib_request.urlopen(req)

    task_url = resp.geturl()

    lti_url_regex = re.compile("%s/@[0-9a-fA-F]+@/lti/task/?" %
                               inginious_config['url'])
    if not lti_url_regex.match(task_url):
        pass
        #raise Exception("INGInious returned the wrong url: %s vs %s" % (task_url, str(lti_url_regex)))
    return task_url
예제 #6
0
def test_launchLti_from_LTIdict_wrong_secret(
    lti_path,
    lti_launch_url,
    course_instructor_factory,
):
    course, user = course_instructor_factory()
    consumer = ToolConsumer(
        consumer_key=settings.CONSUMER_KEY,
        consumer_secret=settings.TEST_COURSE_LTI_SECRET,
        launch_url=lti_launch_url,
        params={
            "lti_message_type": "basic-lti-launch-request",
            "lti_version": "LTI-1p0",
            "resource_link_id": "FakeResourceLinkID",
            "lis_person_sourcedid": user.name,
            "lis_outcome_service_url": "fake_url",
            "user_id": user.anon_id,
            "roles": ["Instructor"],
            "context_id": course.course_id,
        },
    )
    params = consumer.generate_launch_data()

    client = Client(enforce_csrf_checks=False)
    response = client.post(
        lti_path,
        data=params,
    )
    assert response.status_code == 403
예제 #7
0
def test_launchLti_from_LTIdict_ok(
    lti_path,
    lti_launch_url,
    course_instructor_factory,
):
    course, user = course_instructor_factory()
    course.course_id = settings.TEST_COURSE  # force context_id
    resource_link_id = "FakeResourceLinkID"
    consumer = ToolConsumer(
        consumer_key=settings.CONSUMER_KEY,
        consumer_secret=settings.TEST_COURSE_LTI_SECRET,
        launch_url=lti_launch_url,
        params={
            "lti_message_type": "basic-lti-launch-request",
            "lti_version": "LTI-1p0",
            "resource_link_id": resource_link_id,
            "lis_person_sourcedid": user.name,
            "lis_outcome_service_url": "fake_url",
            "user_id": user.anon_id,
            "roles": ["Instructor"],
            "context_id": course.course_id,
        },
    )
    params = consumer.generate_launch_data()

    client = Client(enforce_csrf_checks=False)
    response = client.post(
        lti_path,
        data=params,
    )
    assert response.status_code == 302
    expected_url = (reverse("hx_lti_initializer:course_admin_hub") +
                    f"?resource_link_id={resource_link_id}" +
                    f"&utm_source={client.session.session_key}")
    assert response.url == expected_url
예제 #8
0
def test_lti_validation_from_ltidict_ok():
    target_path = reverse("hx_lti_initializer:launch_lti")
    launch_url = "http://testserver{}".format(target_path)
    resource_link_id = "some_string_to_be_the_fake_resource_link_id"
    consumer = ToolConsumer(
        consumer_key=settings.CONSUMER_KEY,
        consumer_secret=settings.TEST_COURSE_LTI_SECRET,
        launch_url=launch_url,
        params={
            "lti_message_type": "basic-lti-launch-request",
            "lti_version": "LTI-1p0",
            "resource_link_id": resource_link_id,
            "lis_person_sourcedid": "instructor_1",
            "lis_outcome_service_url": "fake_url",
            "user_id": "instructor_1-anon",
            "roles": ["Instructor", "Administrator"],
            "context_id": settings.TEST_COURSE,
        },
    )
    params = consumer.generate_launch_data()
    for key in params:
        print("****** LTI[{}]: {}".format(key, params[key]))

    factory = RequestFactory()
    request = factory.post(target_path, data=params)

    validator = LTIRequestValidator()
    tool_provider = DjangoToolProvider.from_django_request(request=request)
    request_is_valid = tool_provider.is_valid_request(validator)

    assert request_is_valid
예제 #9
0
def test_wsauth_ok():
    ###
    # prep to create lti session
    instructor_name = "sylvia_plath"
    instructor_edxid = "{}{}".format(randint(1000, 65534),
                                     randint(1000, 65534))
    course_id = "hx+FancierCourse+TermCode+Year"
    clean_course_id = re.sub(r"[\W_]", "-", course_id)
    target_path = reverse("hx_lti_initializer:launch_lti")
    launch_url = "http://testserver{}".format(target_path)
    resource_link_id = "some_string_to_be_THE_fake_resource_link_id"
    consumer = ToolConsumer(
        consumer_key=settings.CONSUMER_KEY,
        consumer_secret=settings.LTI_SECRET,
        launch_url=launch_url,
        params={
            "lti_message_type": "basic-lti-launch-request",
            "lti_version": "LTI-1p0",
            "resource_link_id": resource_link_id,
            "lis_person_sourcedid": instructor_name,
            "lis_outcome_service_url": "fake_url",
            "user_id": instructor_edxid,
            "roles": ["Instructor", "Administrator"],
            "context_id": course_id,
            "context_title": "{}+title".format(course_id),
        },
    )
    params = consumer.generate_launch_data()

    client = Client(enforce_csrf_checks=False)
    response = client.post(
        target_path,
        data=params,
    )
    utm_source = response.cookies.get("sessionid").value
    # prep to create lti session
    ###

    application = URLRouter([
        re_path(r"^ws/notification/(?P<room_name>[^/]+)/$",
                NotificationConsumer),
    ])
    mut = SessionAuthMiddleware(application)

    mock_scope = {
        "type":
        "websocket",
        "path":
        "/ws/notification/{}--ad10b1d2--1/".format(clean_course_id),
        "query_string":
        "utm_source={}&resource_link_id={}".format(
            utm_source, resource_link_id).encode("utf-8"),
        "headers": [],
        "subprotocols": [],
    }
    inner_consumer = mut.__call__(scope=mock_scope)

    assert "hxat_auth" in mock_scope
    assert mock_scope["hxat_auth"] == "authenticated"
예제 #10
0
async def test_wsconn_ok():
    ###
    # prep to create lti session
    instructor_name = "sylvia_plath"
    instructor_edxid = "{}{}".format(randint(1000, 65534),
                                     randint(1000, 65534))
    course_id = "hx+FancierCourse+TermCode+Year"
    clean_course_id = re.sub(r"[\W_]", "-", course_id)
    target_path = reverse("hx_lti_initializer:launch_lti")
    launch_url = "http://testserver{}".format(target_path)
    resource_link_id = "some_string_to_be_THE_fake_resource_link_id"
    consumer = ToolConsumer(
        consumer_key=settings.CONSUMER_KEY,
        consumer_secret=settings.LTI_SECRET,
        launch_url=launch_url,
        params={
            "lti_message_type": "basic-lti-launch-request",
            "lti_version": "LTI-1p0",
            "resource_link_id": resource_link_id,
            "lis_person_sourcedid": instructor_name,
            "lis_outcome_service_url": "fake_url",
            "user_id": instructor_edxid,
            "roles": ["Instructor", "Administrator"],
            "context_id": course_id,
            "context_title": "{}+title".format(course_id),
        },
    )
    params = consumer.generate_launch_data()

    client = Client(enforce_csrf_checks=False)
    response = client.post(
        target_path,
        data=params,
    )
    utm_source = response.cookies.get("sessionid").value
    # prep to create lti session
    ###

    application = SessionAuthMiddleware(
        URLRouter([
            re_path(r"^ws/notification/(?P<room_name>[^/]+)/$",
                    NotificationConsumer),
        ]))
    path = "/ws/notification/{}--dvorak--1/?utm_source={}&resource_link_id={}".format(
        clean_course_id, utm_source, resource_link_id)

    communicator = WebsocketCommunicator(application, path)
    connected, subprotocol = await communicator.connect()

    assert connected
    # not sure receive_nothing() is needed
    # it might be good to have some resp from server at application level
    await communicator.receive_nothing()
    await communicator.disconnect()
예제 #11
0
def hxat_lti_launch(locust):
    target_path = "/lti_init/launch_lti/"
    consumer = ToolConsumer(
        consumer_key=locust.hxat_client.consumer_key,
        consumer_secret=locust.hxat_client.secret_key,
        launch_url="{}{}".format(locust.host, target_path),
        params={
            "lti_message_type": "basic-lti-launch-request",
            "lti_version": "LTI-1p0",
            "resource_link_id": locust.hxat_client.resource_link_id,
            "lis_person_sourcedid": locust.hxat_client.user_name,
            # lis_outcome_service_url sets graded assignment
            # "lis_outcome_service_url": os.environ.get('LIS_OUTCOME_SERVICE_URL', 'fake_url'),
            "user_id": locust.hxat_client.user_id,
            "roles": locust.hxat_client.user_roles,
            "context_id": locust.hxat_client.context_id,
            "context_title": locust.hxat_client.context_title,
            "custom_collection_id": locust.hxat_client.collection_id,
            "custom_object_id": locust.hxat_client.target_source_id,
        },
    )
    headers = {
        "Content-Type": "application/x-www-form-urlencoded",
    }
    params = consumer.generate_launch_data()
    response = locust.client.post(
        target_path,
        catch_response=True,
        name="/lti_launch/",
        headers=headers,
        data=params,
        verify=locust.ssl_verify,
    )

    if response.status_code == requests.codes.ok:
        if response.content == "":
            response.failure("no data")
            return False
        else:

            # locust.log('*..*..*..*..*..*..*..*..*..*..*..*..*..*..*..*..*..*..*..*..*')
            # locust.log(response.content)

            cookie_sid = response.cookies.get("sessionid", None)
            if not cookie_sid:
                response.failure("missing session-id cookies")
                return False
            else:
                locust.hxat_client.utm_source = cookie_sid
                response.success()
                return True
    else:
        response.failure("status code: {}".format(response.status_code))
        return False
예제 #12
0
 def test_generate_launch_data_with_empty_value(self):
     launch_params = {
         'lti_version': 'abc',
         'lti_message_type': 'def',
         'resource_link_id': '123',
         'custom_test_value': '',
     }
     tc = ToolConsumer('client_key',
                       'client_secret',
                       launch_url='http://example.edu/',
                       params=launch_params)
     got = tc.generate_launch_data(nonce='wxyz7890', timestamp='2345678901')
     self.assertEqual(got['custom_test_value'], '')
예제 #13
0
 def test_generate_launch_data_with_empty_value(self):
     launch_params = {
         'lti_version': 'abc',
         'lti_message_type': 'def',
         'resource_link_id': '123',
         'custom_test_value': '',
     }
     tc = ToolConsumer('client_key', 'client_secret',
                       launch_url='http://example.edu/',
                       params=launch_params)
     got = tc.generate_launch_data(nonce='wxyz7890',
                                   timestamp='2345678901')
     self.assertEqual(got['custom_test_value'], '')
예제 #14
0
def hxat_lti_launch(locust):

    target_path = '/lti_init/launch_lti/'
    consumer = ToolConsumer(
        consumer_key=os.environ.get('HXAT_CONSUMER', 'fake_consumer_key'),
        consumer_secret=os.environ.get('HXAT_SECRET', 'fake_secret_key'),
        launch_url='{}{}'.format(locust.host, target_path),
        params={
            "lti_message_type":
            "basic-lti-launch-request",
            "lti_version":
            "LTI-1p0",
            "resource_link_id":
            RESOURCE_LINK_ID,
            "lis_person_sourcedid":
            os.environ.get('LIS_PERSON_SOURCEDID', 'fake_person'),
            "lis_outcome_service_url":
            os.environ.get('LIS_OUTCOME_SERVICE_URL', 'fake_url'),
            "user_id":
            USER_ID,
            "roles":
            os.environ.get('USER_ROLES', 'fake_role'),
            "context_id":
            CONTEXT_ID,
        },
    )
    headers = {
        'Content-Type': 'application/x-www-form-urlencoded',
    }
    params = consumer.generate_launch_data()
    response = locust.client.post(
        target_path,
        catch_response=True,
        name='/lti_launch/',
        headers=headers,
        data=params,
        verify=locust.verify,
    )
    if response.content == '':
        response.failure('no data')
    else:
        cookie_csrf = response.cookies.get('csrftoken', None)
        cookie_sid = response.cookies.get('sessionid', None)
        if not cookie_csrf or not cookie_sid:
            response.failure('missing csrf and/or session-id cookies')
            return False
        else:
            locust.cookies['UTM_SOURCE'] = cookie_sid
            locust.cookies['CSRF_TOKEN'] = cookie_csrf
            response.success()
            return True
예제 #15
0
    def test_lti_launch_correct_query(self, role, mock_learner_flow):
        """
        Test for checking LTI query.

        :param role: String identifier for role in platform
        :param mock_learner_flow: mocking method of bridge_lti.provider.learner_flow
        :param mock_instructor_flow: mocking method of bridge_lti.provider.instructor_flow
        """
        mock_learner_flow.return_value = HttpResponse(status=200)
        consumer_prams = {
            'consumer_key':
            self.lti_provider.consumer_key,
            'consumer_secret':
            self.lti_provider.consumer_secret,
            'launch_url':
            f"http://{settings.BRIDGE_HOST}" +
            reverse('lti:launch',
                    kwargs={
                        'collection_slug': self.collection1.slug,
                        'group_slug': str(self.test_cg.slug)
                    }),
            'params': {
                # Required parameters
                'lti_message_type': 'basic-lti-launch-request',
                'lti_version': 'LTI-1p0',
                # The random value is used for the test purpose
                'resource_link_id': '-523523423423423423423423423',
                # Recommended parameters
                'user_id': 'bridge_user',
                'roles': role,
                'oauth_callback': 'about:blank',
                'context_id': 'bridge_collection'
            },
        }
        # Check read-only user do not exists
        read_only_user = BridgeUser.objects.filter(username='******')
        self.assertFalse(read_only_user)

        consumer = ToolConsumer(**consumer_prams)
        response = self.client.post(
            consumer.launch_url,
            HTTP_HOST=settings.BRIDGE_HOST,
            data=consumer.generate_launch_data(),
            headers={'Content-Type': 'application/x-www-form-urlencoded'})

        if role in ['Instructor', 'Administrator']:
            read_only_user = BridgeUser.objects.filter(username='******')
            self.assertTrue(read_only_user)
            self.assertEqual(response.status_code, 302)
        else:
            self.assertEqual(response.status_code, 200)
예제 #16
0
    def test_wrong_lti_credentials(self):
        url = "http://testserver/assignments/%s/lti/" % self.open_assignment.pk

        consumer = ToolConsumer(
            consumer_key="awilfhawilejfhcbawiehjbcfaliejkwf",
            consumer_secret="awhlöfhjawköfjhawökefhjwaölkefrk",
            launch_url=url,
            params={
                'lti_message_type': 'basic-lti-launch-request',
                'resource_link_id': 1
            })

        response = self.c.post(url, consumer.generate_launch_data())
        self.assertEqual(403, response.status_code)
    def test_wrong_lti_credentials(self):
        url = "http://testserver/lti/"

        consumer = ToolConsumer(consumer_key="foo",
                                consumer_secret="bar",
                                launch_url=url,
                                params={
                                    'lti_message_type':
                                    'basic-lti-launch-request',
                                    'resource_link_id': 1
                                })

        response = self.c.post(url, consumer.generate_launch_data())
        self.assertEqual(403, response.status_code)
예제 #18
0
def source_preview(request):
    """View to render Source content block shared through LTI."""
    log.debug("Got request.GET: %s", request.GET)

    content_source_id = request.GET.get('content_source_id')
    # pass source_id to get only on content source

    consumer_prams = {
        'consumer_key': '',
        'consumer_secret': '',
        'params': {
            # Required parameters
            'lti_message_type': 'basic-lti-launch-request',
            'lti_version': 'LTI-1p0',
            'resource_link_id': 'reaource_link_id',
            # Recommended parameters
            'user_id': 'bridge_user',
            'roles': 'Learner',
            'oauth_callback': 'about:blank',
            'context_id': 'bridge_collection'
        },
    }

    # Default impersonal consumer parameters are used for getting problem's preview from the Source via LTI
    sequence_item_id = request.GET.get('sequence_item_id')
    if content_source_id:
        # staff flow
        content_provider = get_content_providers(request,
                                                 content_source_id).first()

        if not content_provider:
            return render(request, 'bridge_lti/stub.html')

        consumer_prams['consumer_key'] = content_provider.provider_key
        consumer_prams['consumer_secret'] = content_provider.provider_secret

    source_name, source_lti_url, consumer_prams = create_lti_launch_params(
        request, sequence_item_id, consumer_prams)

    consumer_prams.update({'launch_url': source_lti_url})
    log.debug("Sending parameters are: {}".format(consumer_prams))
    consumer = ToolConsumer(**consumer_prams)
    return render(
        request, 'bridge_lti/content-source.html', {
            'launch_data': consumer.generate_launch_data(),
            'launch_url': consumer.launch_url,
            'source_name': source_name,
        })
예제 #19
0
def get_lti_data(course, user_id, task_id):
    inginious_config = syllabus.get_config()['courses'][course]['inginious']
    consumer = ToolConsumer(
        consumer_key=inginious_config['lti']['consumer_key'],
        consumer_secret=inginious_config['lti']['consumer_secret'],
        launch_url='%s/lti/%s/%s' %
        (inginious_config['url'], inginious_config['course_id'], task_id),
        params={
            'lti_message_type': 'basic-lti-launch-request',
            'lti_version': "1.1",
            'resource_link_id': "syllabus_%s" % task_id,
            'user_id': user_id,
        })

    d = consumer.generate_launch_data()
    return d, consumer.launch_url
예제 #20
0
def test_launchLti_starting_resource(random_assignment_target):
    course = random_assignment_target["course"]
    assignment = random_assignment_target["assignment"]
    target_object = random_assignment_target["target_object"]
    assignment_target = random_assignment_target["assignment_target"]
    instructor = random_assignment_target["profile"]

    course_id = course.course_id
    resource_link_id = "FakeResourceLinkIDStartingResource"
    target_path = "/lti_init/launch_lti/"
    launch_url = "http://testserver{}".format(target_path)

    lti_resource_link_config = LTIResourceLinkConfig.objects.create(
        resource_link_id=resource_link_id,
        assignment_target=assignment_target,
    )

    consumer = ToolConsumer(
        consumer_key=settings.CONSUMER_KEY,
        consumer_secret=settings.LTI_SECRET,
        launch_url=launch_url,
        params={
            "lti_message_type": "basic-lti-launch-request",
            "lti_version": "LTI-1p0",
            "resource_link_id": resource_link_id,
            "lis_person_sourcedid": instructor.name,
            "lis_outcome_service_url": "fake_url",
            "user_id": instructor.anon_id,
            "roles": ["Instructor"],
            "context_id": course_id,
            "context_title": "{}-title".format(course_id),
        },
    )
    params = consumer.generate_launch_data()

    client = Client(enforce_csrf_checks=False)
    response = client.post(
        target_path,
        data=params,
    )
    assert response.status_code == 302
    expected_url = (reverse(
        "hx_lti_initializer:access_annotation_target",
        args=[course_id, assignment.assignment_id, target_object.pk],
    ) + f"?resource_link_id={resource_link_id}" +
                    f"&utm_source={client.session.session_key}")
    assert response.url == expected_url
    def test_working_lti_credentials(self):

        self.course.lti_key = 'foo'
        self.course.lti_secret = 'bar'
        self.course.save()

        url = "http://testserver/lti/"

        consumer = ToolConsumer(consumer_key=self.course.lti_key,
                                consumer_secret=self.course.lti_secret,
                                launch_url=url,
                                params={
                                    'lti_message_type':
                                    'basic-lti-launch-request',
                                    'resource_link_id': 1
                                })

        response = self.c.post(url, consumer.generate_launch_data())
        self.assertEqual(302, response.status_code)
예제 #22
0
def launch(assignment_id: AnyIDType) -> RequestResultType:
    if (str(current_app.config.get("ENABLE_DEBUG_LAUNCHER")).lower() == "true"
            and str(current_app.config.get("PRODUCTION")).lower() == "false"):
        public_url = current_app.config.get("PUBLIC_URL")
        url = url_for("provider.start")
        if None in [public_url, url]:
            raise ConfigurationErrorException(
                f"Cannot create launch URL from PUBLIC_URL={public_url} and PATH={url}"
            )
        params = dict(
            lti_message_type="basic-lti-launch-request",
            lti_version="lti_version",
            resource_link_id=assignment_id,
            context_id="Open HPI",
            user_id="max",
            roles=["student"],
            context_title="Open HPI Mooc Neural Networks 2019",
            context_label="Open HPI NN 2019",
            lis_person_name_full="Max Mustermann",
            lis_outcome_service_url="http://localhost:8080/savegrade",
        )

        # Custom args MUST start with custom_
        params[current_app.config.get("LAUNCH_ASSIGNMENT_ID_PARAM")
               or "custom_x-assignment-id"] = assignment_id
        consumer = ToolConsumer(
            consumer_key=current_app.config.get("CONSUMER_KEY"),
            consumer_secret=current_app.config.get("CONSUMER_KEY_SECRET"),
            launch_url=slash_join(str(public_url), str(url)),
            params=params,
        )
        return (
            render_template(
                current_app.config.get("TEMPLATE_PREFIX", "") + "launch.html",
                launch_data=consumer.generate_launch_data(),
                launch_url=consumer.launch_url,
            ),
            200,
            MIME.html,
        )
    else:
        return jsonify(dict(error="The launcher is disabled")), 200, MIME.json
예제 #23
0
 def createParams(self, key, secret, launch_url, resource_link_id, user_id,
                  lis_person_name_full, lis_person_name_given,
                  lis_person_name_family, lis_person_contact_email_primary):
     params = {}
     params['lti_message_type'] = 'basic-lti-launch-request'
     params['lti_version'] = 'LTI-1p0'
     params['resource_link_id'] = resource_link_id
     params['user_id'] = user_id
     params['lis_person_name_full'] = lis_person_name_full
     params['lis_person_name_given'] = lis_person_name_given
     params['lis_person_name_family'] = lis_person_name_family
     params[
         'lis_person_contact_email_primary'] = lis_person_contact_email_primary
     consumer = ToolConsumer(consumer_key=key,
                             consumer_secret=secret,
                             launch_url=launch_url,
                             params=params)
     params['launch_data'] = consumer.generate_launch_data()
     params['launch_url'] = consumer.launch_url
     return params
예제 #24
0
    def _params_factory(
        course_id,
        user_name,
        user_id,
        user_roles,
        resource_link_id,
        launch_url,
        course_name=None,
        with_grade=False,
        consumer_key=None,
        consumer_secret=None,
        tool_consumer_instance_guid=None,
    ):
        params = {
            "lti_message_type": "basic-lti-launch-request",
            "lti_version": "LTI-1p0",
            "resource_link_id": resource_link_id,
            "lis_person_sourcedid": user_name,
            "user_id": user_id,
            "roles": user_roles,
            "context_id": course_id,
        }
        if course_name:
            params["context_title"] = course_name
        if with_grade:
            params["lis_outcome_service_url"] = "http://fake_url.com/"
            params["lis_result_sourcedid"] = "{}:{}:123".format(
                course_id, resource_link_id)
        if tool_consumer_instance_guid:
            params["tool_consumer_instance_guid"] = tool_consumer_instance_guid

        consumer = ToolConsumer(
            consumer_key=consumer_key
            if consumer_key else settings.CONSUMER_KEY,
            consumer_secret=consumer_secret
            if consumer_secret else settings.LTI_SECRET,
            launch_url=launch_url,
            params=params,
        )
        lti_params = consumer.generate_launch_data()
        return lti_params
예제 #25
0
 def test_generate_launch_data(self):
     launch_params = {
         'lti_version': 'abc',
         'lti_message_type': 'def',
         'resource_link_id': '123'
     }
     tc = ToolConsumer('client_key',
                       'client_secret',
                       launch_url='http://example.edu/',
                       params=launch_params)
     got = tc.generate_launch_data(nonce='wxyz7890', timestamp='2345678901')
     correct = launch_params.copy()
     correct.update({
         'oauth_nonce': 'wxyz7890',
         'oauth_timestamp': '2345678901',
         'oauth_version': '1.0',
         'oauth_signature_method': 'HMAC-SHA1',
         'oauth_consumer_key': 'client_key',
         'oauth_signature': 'gXIAk60dLsrh6YQGT5ZGK6tHDGY=',
     })
     self.assertEqual(got, correct)
예제 #26
0
 def test_generate_launch_data(self):
     launch_params = {
         'lti_version': 'abc',
         'lti_message_type': 'def',
         'resource_link_id': '123'
     }
     tc = ToolConsumer('client_key', 'client_secret',
                       launch_url='http://example.edu/',
                       params=launch_params)
     got = tc.generate_launch_data(nonce='wxyz7890',
                                   timestamp='2345678901')
     correct = launch_params.copy()
     correct.update({
         'oauth_nonce': 'wxyz7890',
         'oauth_timestamp': '2345678901',
         'oauth_version': '1.0',
         'oauth_signature_method': 'HMAC-SHA1',
         'oauth_consumer_key': 'client_key',
         'oauth_signature': 'gXIAk60dLsrh6YQGT5ZGK6tHDGY=',
         })
     self.assertEqual(got, correct)
예제 #27
0
def get_lti_data(course, user_id, task_id):
    course_config = syllabus.get_config()['courses'][course]
    inginious_config = course_config['inginious']
    lti_config = inginious_config['lti']
    consumer = ToolConsumer(
        consumer_key=inginious_config['lti']['consumer_key'],
        consumer_secret=inginious_config['lti']['consumer_secret'],
        launch_url='%s/lti/%s/%s' % (inginious_config['url'], inginious_config['course_id'], task_id),
        params={
            'lti_message_type': 'basic-lti-launch-request',
            'lti_version': "1.1",
            'resource_link_id': "syllabus_%s" % task_id,
            'tool_consumer_instance_name': 'Interactive syllabus (%s)' % course_config['title'],
            'tool_consumer_instance_url': lti_config.get('tool_url', None),
            'tool_consumer_instance_description': lti_config.get('tool_description', None),
            'context_id': lti_config.get('tool_context_id', None),
            'context_label': lti_config.get('tool_context_label', None),
            'context_title': lti_config.get('tool_context_title', None),
            'user_id': user_id,
        }
    )

    d = consumer.generate_launch_data()
    return d, consumer.launch_url
예제 #28
0
class TODViewsTests(TestCase):
    def setUp(self):
        """
        1. Creates a test course.
        2. Creates a test Assignment.
        3. Creates a fake Target Object record.
        4. Starts the LTI tool consumer and makes a data launch request.
        """

        user = User(username="******", email="dfslkjfijeflkj")
        user.save()
        lti_profile = LTIProfile.objects.create(
            user=user, name=user.username, anon_id="luis123"
        )
        lti_profile.save()

        course = LTICourse(course_name="Fake Course", course_id="BlueMonkeyFake")
        course.save()
        course.course_admins.add(lti_profile)

        self.assignment = Assignment(
            assignment_name="Test", pagination_limit=10, course=course
        )
        self.assignment.save()

        self.tod = TargetObject(
            target_title="TObj2",
            target_author="Test Author",
            target_content="Fake Content2",
            target_citation="Fake Citation2",
            target_type="tx",
        )
        self.tod.save()

        self.aTarget = AssignmentTargets(
            assignment=self.assignment,
            target_object=self.tod,
            order=1,
            target_external_css="",
            target_instructions="Fake Instructions",
            target_external_options="",
        )

        self.target_path = reverse("hx_lti_initializer:launch_lti")
        self.launch_url = "http://testserver{}".format(self.target_path)
        self.resource_link_id = "some_string_to_be_the_fake_resource_link_id"
        self.consumer = ToolConsumer(
            consumer_key=settings.CONSUMER_KEY,
            consumer_secret=settings.LTI_SECRET,
            launch_url=self.launch_url,
            params={
                "lti_message_type": "basic-lti-launch-request",
                "lti_version": "LTI-1p0",
                "resource_link_id": self.resource_link_id,
                "lis_person_sourcedid": lti_profile.name,
                "lis_outcome_service_url": "fake_url",
                "user_id": lti_profile.anon_id,
                "roles": ["Learner"],
                "context_id": course.course_id,
            },
        )
        self.lti_params = self.consumer.generate_launch_data()

    def tearDown(self):
        del self.assignment
        del self.tod

    def test_call_view_loads(self):
        lti_params = self.consumer.generate_launch_data()
        response0 = self.client.post(self.target_path, lti_params)

        self.assertTrue(response0.status_code == 302)

        target_url = reverse(
            "target_object_database:open_target_object",
            kwargs={"collection_id": self.assignment.id, "target_obj_id": self.tod.id,},
        )
        response = self.client.get(target_url)
        self.assertTrue(response.status_code == 200)

        target_url = reverse(
            "target_object_database:open_target_object",
            kwargs={"collection_id": self.assignment.id, "target_obj_id": "987654321",},
        )
        response = self.client.get(target_url)
        self.assertTrue(response.status_code == 404)

    '''