Ejemplo n.º 1
0
    def test_delete(self):
        """The DELETE method is not allowed to sign in"""
        consumer = LTIConsumerFactory(slug="consumer")
        passport = LTIPassportFactory(title="consumer1_passport1",
                                      consumer=consumer)

        forum_uuid = "8bb319aa-f3cf-4509-952c-c4bd0fb42fd7"
        context_id = "course-v1:testschool+login+0001"

        # Build the LTI launch request
        lti_parameters = {
            "user_id": "643f1625-f240-4a5a-b6eb-89b317807963",
            "lti_message_type": "basic-lti-launch-request",
            "lti_version": "LTI-1p0",
            "resource_link_id": "aaa",
            "context_id": context_id,
            "lis_person_contact_email_primary": "*****@*****.**",
            "lis_person_sourcedid": "testuser",
            "launch_presentation_locale": "en",
            "roles": "Instructor",
        }
        url = f"http://testserver/lti/forum/{forum_uuid}"
        signed_parameters = sign_parameters(passport, lti_parameters, url)

        response = self.client.delete(
            f"/lti/forum/{forum_uuid}",
            data=urlencode(signed_parameters),
            content_type=CONTENT_TYPE,
        )
        self.assertEqual(405, response.status_code)
Ejemplo n.º 2
0
    def test_post_with_an_inactive_user(self):
        """An inactive user should not be allowed to authenticate via a valid LTI request"""

        user = UserFactory(is_active=False)
        passport = LTIPassportFactory(title="consumer1_passport1",
                                      consumer=user.lti_consumer)

        forum_uuid = "8bb319aa-f3cf-4509-952c-c4bd0fb42fd7"
        context_id = "course-v1:testschool+login+0001"

        # Build the LTI launch request
        lti_parameters = {
            "user_id": "643f1625-f240-4a5a-b6eb-89b317807963",
            "lti_message_type": "basic-lti-launch-request",
            "lti_version": "LTI-1p0",
            "resource_link_id": "aaa",
            "context_id": context_id,
            "lis_person_contact_email_primary":
            "*****@*****.**",
            "lis_person_sourcedid": user.public_username,
            "launch_presentation_locale": "en",
            "roles": "Instructor",
        }
        url = f"http://testserver/lti/forum/{forum_uuid}"
        signed_parameters = sign_parameters(passport, lti_parameters, url)

        response = self.client.post(
            f"/lti/forum/{forum_uuid}",
            data=urlencode(signed_parameters),
            content_type=CONTENT_TYPE,
        )

        self.assertEqual(403, response.status_code)
Ejemplo n.º 3
0
 def _authenticate(
     self,
     lti_parameters: dict,
     passport: LTIPassport,
 ):
     url = "http://testserver/lti/launch"
     signed_parameters = sign_parameters(passport, lti_parameters, url)
     request = self.request_factory.post(
         url, data=urlencode(signed_parameters), content_type=CONTENT_TYPE
     )
     lti = LTI(request)
     lti.verify()
     return self._auth_backend.authenticate(request, lti_request=lti)
Ejemplo n.º 4
0
    def test_groups_moderator_created_with_role_student(self):
        """
        Controls that group moderator is initialy created when a user login in the forum
        with the role student
        """
        consumer = LTIConsumerFactory(slug="consumer")
        passport = LTIPassportFactory(title="consumer1_passport1",
                                      consumer=consumer)

        forum_uuid = "8bb319aa-f3cf-4509-952c-c4bd0fb42fd7"
        context_id = "course-v1:testschool+login+0001"
        initial_group_count = Group.objects.count()

        # Build the LTI launch request
        lti_parameters = {
            "user_id": "643f1625-f240-4a5a-b6eb-89b317807963",
            "lti_message_type": "basic-lti-launch-request",
            "lti_version": "LTI-1p0",
            "resource_link_id": "aaa",
            "context_id": context_id,
            "lis_person_contact_email_primary": "*****@*****.**",
            "lis_person_sourcedid": "testuser",
            "launch_presentation_locale": "en",
            "roles": "Student",
        }
        url = f"http://testserver/lti/forum/{forum_uuid}"
        signed_parameters = sign_parameters(passport, lti_parameters, url)

        self.client.post(
            f"/lti/forum/{forum_uuid}",
            data=urlencode(signed_parameters),
            content_type=CONTENT_TYPE,
        )

        # A LTIContext and a Forum should have been created
        context = LTIContext.objects.get(lti_id=context_id)

        # Groups should have been created
        self.assertEqual(initial_group_count + 5, Group.objects.count())
        self.assertEqual(
            [
                f"cg:{context.id}",
                f"cg:{context.id}:role:administrator",
                f"cg:{context.id}:role:instructor",
                f"cg:{context.id}:role:moderator",
                f"cg:{context.id}:role:student",
            ],
            list(
                Group.objects.filter(name__startswith=f"cg:{context.id}").
                order_by("name").values_list("name", flat=True)),
        )
Ejemplo n.º 5
0
    def test_post_with_valid_lti_launch_request(self):
        """A user should be able to authenticate via a LTI launch request signed by
        a trusted consumer and passport."""

        consumer = LTIConsumerFactory(slug="consumer")
        passport = LTIPassportFactory(title="consumer1_passport1",
                                      consumer=consumer)

        forum_uuid = "8bb319aa-f3cf-4509-952c-c4bd0fb42fd7"
        context_id = "course-v1:testschool+login+0001"

        # Build the LTI launch request
        lti_parameters = {
            "user_id": "643f1625-f240-4a5a-b6eb-89b317807963",
            "lti_message_type": "basic-lti-launch-request",
            "lti_version": "LTI-1p0",
            "resource_link_id": "aaa",
            "context_id": context_id,
            "lis_person_contact_email_primary": "*****@*****.**",
            "lis_person_sourcedid": "testuser",
            "launch_presentation_locale": "en",
            "roles": "Instructor",
        }
        url = f"http://testserver/lti/forum/{forum_uuid}"
        signed_parameters = sign_parameters(passport, lti_parameters, url)

        response = self.client.post(
            f"/lti/forum/{forum_uuid}",
            data=urlencode(signed_parameters),
            content_type=CONTENT_TYPE,
        )

        # A LTIContext and a Forum should have been created
        context = LTIContext.objects.get(lti_id=context_id)
        forum = Forum.objects.get(lti_id=forum_uuid)

        # The response should be a redirection to the forum URL
        self.assertEqual(302, response.status_code)
        self.assertEqual(f"/forum/forum/{forum.slug}-{forum.id}/",
                         response.url)

        # Our current LTIContext id should have been injected in the user session
        self.assertEqual(context.id,
                         self.client.session.get(SESSION_LTI_CONTEXT_ID))

        # The launch_presentation_locale should be set in the language cookie
        self.assertEqual(
            "en", response.client.cookies[settings.LANGUAGE_COOKIE_NAME].value)
Ejemplo n.º 6
0
    def _connects(self,
                  role,
                  forum_uuid=None,
                  uuid=None,
                  lis_person_sourcedid=None):
        """
        Utils not to repeat the connection of an instructor or
        a student
        """
        consumer = LTIConsumerFactory(slug="consumer")
        passport = LTIPassportFactory(title="consumer1_passport1",
                                      consumer=consumer)

        if not forum_uuid:
            forum_uuid = self.forum_uuid

        # Build the LTI launch request
        lti_parameters = {
            "user_id":
            "643f1625-f240-4a5a-b6eb-89b317807963" if not uuid else uuid,
            "lti_message_type": "basic-lti-launch-request",
            "lti_version": "LTI-1p0",
            "resource_link_id": "aaa",
            "context_id": self.context_id,
            "lis_person_contact_email_primary": "*****@*****.**",
            "lis_person_sourcedid":
            "testuser" if not lis_person_sourcedid else lis_person_sourcedid,
            "launch_presentation_locale": "en",
            "roles": role.capitalize(),
        }

        url = f"http://testserver/lti/forum/{forum_uuid}"
        signed_parameters = sign_parameters(passport, lti_parameters, url)

        self.client.post(
            f"/lti/forum/{forum_uuid}",
            data=urlencode(signed_parameters),
            content_type=CONTENT_TYPE,
        )

        forum = Forum.objects.get(
            lti_id=forum_uuid,
            lti_contexts__id=LTIContext.objects.get(
                lti_id=self.context_id, lti_consumer_id=passport.consumer).id,
        )

        return forum
Ejemplo n.º 7
0
    def test_post_with_lti_uuid_multiple_forum_existing_in_another_context(
            self):
        """
        Forums can have an identical `lti_id` and be accessed from the same LTI
        launch URL but from different LTI contexts. A new forum is created for
        each LTI context. The title for the forum created is set by default to the
        class name of the forum created last having the same `lti_id` (this enables
        quick copy and paste). We check that the default name used is from the last
        forum created.
        """

        passport = LTIPassportFactory(consumer=LTIConsumerFactory())
        forum_uuid = "8bb319aa-f3cf-4509-952c-c4bd0fb42fd7"
        context1_id = "course-v1:testschool+login+0001"

        # Build the LTI launch request
        lti_parameters = {
            "user_id": "643f1625-f240-4a5a-b6eb-89b317807963",
            "lti_message_type": "basic-lti-launch-request",
            "lti_version": "LTI-1p0",
            "resource_link_id": "aaa",
            "context_id": context1_id,
            "lis_person_contact_email_primary": "*****@*****.**",
            "lis_person_sourcedid": "testuser",
            "launch_presentation_locale": "en",
            "roles": "Instructor",
        }
        url = f"http://testserver/lti/forum/{forum_uuid}"
        self.client.post(
            f"/lti/forum/{forum_uuid}",
            data=urlencode(sign_parameters(passport, lti_parameters, url)),
            content_type=CONTENT_TYPE,
            follow=True,
        )
        # A new forum has been created
        forum1 = Forum.objects.get(
            lti_id=forum_uuid,
            lti_contexts__id=LTIContext.objects.get(
                lti_id=context1_id, lti_consumer_id=passport.consumer).id,
        )
        forum1.name = "An original title"
        forum1.save()
        forum1.refresh_from_db()

        # We use the same lti_parameters except the context
        context2_id = "course-v1:testschool+login+0002"
        lti_parameters2 = {
            "user_id": "643f1625-f240-4a5a-b6eb-89b317807963",
            "lti_message_type": "basic-lti-launch-request",
            "lti_version": "LTI-1p0",
            "resource_link_id": "aaa",
            "context_id": context2_id,
            "lis_person_contact_email_primary": "*****@*****.**",
            "lis_person_sourcedid": "testuser",
            "launch_presentation_locale": "en",
            "roles": "Instructor",
        }
        # We request the same LTI launch source url
        self.client.post(
            f"/lti/forum/{forum_uuid}",
            data=urlencode(sign_parameters(passport, lti_parameters2, url)),
            content_type=CONTENT_TYPE,
            follow=True,
        )
        # A new forum has been created
        forum2 = Forum.objects.get(
            lti_id=forum_uuid,
            lti_contexts__id=LTIContext.objects.get(
                lti_id=context2_id, lti_consumer_id=passport.consumer).id,
        )
        # Forum name should be the same as the previous forum
        self.assertEqual(forum2.name, forum1.name)
        forum2.name = "A new original title"
        forum2.save()
        forum2.refresh_from_db()

        # We use the same lti_parameters except the context
        context3_id = "course-v3:testschool+login+0002"
        lti_parameters3 = {
            "user_id": "643f1625-f240-4a5a-b6eb-89b317807963",
            "lti_message_type": "basic-lti-launch-request",
            "lti_version": "LTI-1p0",
            "resource_link_id": "aaa",
            "context_id": context3_id,
            "lis_person_contact_email_primary": "*****@*****.**",
            "lis_person_sourcedid": "testuser",
            "launch_presentation_locale": "en",
            "roles": "Instructor",
        }
        # We request the same LTI launch source url
        self.client.post(
            f"/lti/forum/{forum_uuid}",
            data=urlencode(sign_parameters(passport, lti_parameters3, url)),
            content_type=CONTENT_TYPE,
            follow=True,
        )
        # A new forum has been created
        forum3 = Forum.objects.get(
            lti_id=forum_uuid,
            lti_contexts__id=LTIContext.objects.get(
                lti_id=context3_id, lti_consumer_id=passport.consumer).id,
        )
        # Forum name should be the same as the previous forum, the last created
        self.assertEqual(forum3.name, forum2.name)
Ejemplo n.º 8
0
    def test_post_with_lti_uuid_forum_existing_in_another_context(self):
        """
        Two forums can have an identical `lti_id` and be accessed from the same LTI
        launch URL but from two different LTI contexts. A new forum is created for
        each LTI context. The title for the forum created is set by default to the
        class name of the last forum having the same `lti_id` (this enables quick
        copy and paste)
        """

        passport = LTIPassportFactory(consumer=LTIConsumerFactory())

        forum_uuid = "8bb319aa-f3cf-4509-952c-c4bd0fb42fd7"
        context1_id = "course-v1:testschool+login+0001"

        # Build the LTI launch request
        lti_parameters = {
            "user_id": "643f1625-f240-4a5a-b6eb-89b317807963",
            "lti_message_type": "basic-lti-launch-request",
            "lti_version": "LTI-1p0",
            "resource_link_id": "aaa",
            "context_id": context1_id,
            "lis_person_contact_email_primary": "*****@*****.**",
            "lis_person_sourcedid": "testuser",
            "launch_presentation_locale": "en",
            "roles": "Instructor",
        }
        url = f"http://testserver/lti/forum/{forum_uuid}"
        # we sign the request
        initial_forum_count = Forum.objects.count()
        initial_lticontext_count = LTIContext.objects.count()
        response = self.client.post(
            f"/lti/forum/{forum_uuid}",
            data=urlencode(sign_parameters(passport, lti_parameters, url)),
            content_type=CONTENT_TYPE,
            follow=True,
        )

        # A LTIContext and a Forum should have been created
        context1 = LTIContext.objects.get(lti_id=context1_id,
                                          lti_consumer_id=passport.consumer)
        forum1 = Forum.objects.get(lti_id=forum_uuid,
                                   lti_contexts__id=context1.id)
        forum1.name = "An original title"
        self.assertEqual(LTIContext.objects.count(),
                         initial_lticontext_count + 1)
        self.assertEqual(Forum.objects.count(), initial_forum_count + 1)

        # The response should be a redirection to the forum URL
        self.assertRedirects(response,
                             f"/forum/forum/{forum1.slug}-{forum1.id}/")
        forum1.save()
        forum1.refresh_from_db()

        # We use the same lti_parameters except the context
        context2_id = "course-v1:testschool+login+0002"
        lti_parameters2 = {
            "user_id": "643f1625-f240-4a5a-b6eb-89b317807963",
            "lti_message_type": "basic-lti-launch-request",
            "lti_version": "LTI-1p0",
            "resource_link_id": "aaa",
            "context_id": context2_id,
            "lis_person_contact_email_primary": "*****@*****.**",
            "lis_person_sourcedid": "testuser",
            "launch_presentation_locale": "en",
            "roles": "Instructor",
        }
        # We request the same LTI launch source url
        response = self.client.post(
            f"/lti/forum/{forum_uuid}",
            data=urlencode(sign_parameters(passport, lti_parameters2, url)),
            content_type=CONTENT_TYPE,
            follow=True,
        )
        # A new lti context should have been created
        self.assertEqual(LTIContext.objects.count(),
                         initial_lticontext_count + 2)
        # A new forum should have been created
        self.assertEqual(Forum.objects.count(), initial_forum_count + 2)
        # The response should be a redirection to the forum URL
        context2 = LTIContext.objects.get(lti_id=context2_id,
                                          lti_consumer_id=passport.consumer)
        forum2 = Forum.objects.get(lti_id=forum_uuid,
                                   lti_contexts__id=context2.id)
        # Forum name should be the same as the previous forum
        self.assertEqual(forum2.name, forum1.name)

        self.assertRedirects(response,
                             f"/forum/forum/{forum2.slug}-{forum2.id}/")

        # we resign the request for context1
        response = self.client.post(
            f"/lti/forum/{forum_uuid}",
            data=urlencode(sign_parameters(passport, lti_parameters, url)),
            content_type=CONTENT_TYPE,
            follow=True,
        )
        # No new lti context should have been created
        self.assertEqual(LTIContext.objects.count(),
                         initial_lticontext_count + 2)
        # No new forum should have been created
        self.assertEqual(Forum.objects.count(), initial_forum_count + 2)
        # The response should be a redirection to the forum URL
        self.assertRedirects(response,
                             f"/forum/forum/{forum1.slug}-{forum1.id}/")