Ejemplo n.º 1
0
 def test_consumer(self):
     with self.silo['Consumers'].open() as collection:
         entity = collection.new_entity()
         consumer = lti.ToolConsumer.new_from_values(
             entity, self.cipher, 'default', key="12345",
             secret=ul("secret"))
         self.assertTrue(consumer.entity is entity)
         self.assertTrue(isinstance(consumer, lti.ToolConsumer))
         self.assertTrue(consumer.entity['Handle'].value == 'default')
         self.assertTrue(consumer.entity['Key'].value == '12345')
         self.assertTrue(consumer.entity['Secret'].value ==
                         self.cipher.encrypt(b'secret'))
         # at this stage the entity has not been persisted but
         # the local attributes should be set...
         self.assertTrue(consumer.key == '12345')
         self.assertTrue(consumer.secret == 'secret')
         # now check persistence
         self.assertTrue(len(collection) == 0)
         collection.insert_entity(consumer.entity)
         self.assertTrue(len(collection) == 1)
         check_entity = collection.values()[0]
         check_consuemr = lti.ToolConsumer(check_entity, self.cipher)
         self.assertTrue(check_consuemr.entity['Handle'].value ==
                         'default')
         self.assertTrue(check_consuemr.entity['Key'].value ==
                         '12345')
         self.assertTrue(check_consuemr.entity['Secret'].value ==
                         self.cipher.encrypt(b'secret'))
         self.assertTrue(check_consuemr.key == '12345')
         self.assertTrue(check_consuemr.secret == 'secret')
         # now check the update process
         consumer.update_from_values('updated', 'password')
         self.assertTrue(consumer.entity['Handle'].value == 'updated')
         self.assertTrue(consumer.entity['Key'].value == '12345')
         self.assertTrue(consumer.entity['Secret'].value ==
                         self.cipher.encrypt(b'password'))
         self.assertTrue(consumer.key == '12345')
         self.assertTrue(consumer.secret == 'password')
         self.assertTrue(len(collection) == 1)
         check_entity = collection.values()[0]
         check_consuemr = lti.ToolConsumer(check_entity, self.cipher)
         self.assertTrue(check_consuemr.entity['Handle'].value ==
                         'updated')
         self.assertTrue(check_consuemr.entity['Key'].value ==
                         '12345')
         self.assertTrue(check_consuemr.entity['Secret'].value ==
                         self.cipher.encrypt(b'password'))
         self.assertTrue(check_consuemr.key == '12345')
         self.assertTrue(check_consuemr.secret == 'password')
Ejemplo n.º 2
0
    def test_create_silo_option(self):

        class TPApp(lti.ToolProviderApp):
            private_files = self.d
        p = optparse.OptionParser()
        TPApp.add_options(p)
        options, args = p.parse_args(['-m'])
        # setup should succeed with default metadata
        TPApp.setup(options=options, args=args)
        # in memory database created, no silos
        with TPApp.container['Silos'].open() as collection:
            self.assertTrue(len(collection) == 0)

        class TPApp(lti.ToolProviderApp):
            private_files = self.d
        p = optparse.OptionParser()
        TPApp.add_options(p)
        options, args = p.parse_args(['-m', '--create_silo'])
        TPApp.setup(options=options, args=args)
        # in memory database created, with default silo
        with TPApp.container['Silos'].open() as collection:
            self.assertTrue(len(collection) == 1)
            silo = collection.values()[0]
            self.assertTrue(silo['Slug'].value == 'testing')
        with silo['Consumers'].open() as collection:
            self.assertTrue(len(collection) == 1)
            consumer = collection.values()[0]
            tc = lti.ToolConsumer(consumer, TPApp.new_app_cipher())
            self.assertTrue(tc.key == '12345', tc.key)
            self.assertTrue(tc.secret == 'secret', tc.secret)
Ejemplo n.º 3
0
    def test_set_launch_user(self):

        class TPApp(lti.ToolProviderApp):
            private_files = self.d
        p = optparse.OptionParser()
        TPApp.add_options(p)
        options, args = p.parse_args(['-m', '--create_silo'])
        TPApp.setup(options=options, args=args)
        with TPApp.container['Silos'].open() as collection:
            silo = collection.values()[0]
        with silo['Consumers'].open() as collection:
            consumer = collection.values()[0]
            tc = lti.ToolConsumer(consumer, TPApp.new_app_cipher())
        app = TPApp()
        req = MockRequest()
        context = lti.ToolProviderContext(req.environ, req.start_response)
        context.session = wsgi.CookieSession()
        context.session.establish()
        context.consumer = tc
        # parameters will be empty, so no launch user
        app.set_launch_user(context)
        self.assertTrue(context.user is None)
        with TPApp.container['Users'].open() as collection:
            self.assertTrue(len(collection) == 0)
        # add a user to the parameters
        context.parameters['user_id'] = '123456'
        context.parameters['lis_person_name_given'] = 'Jane'
        context.parameters['lis_person_name_family'] = 'Doe'
        context.parameters['lis_person_name_full'] = 'Jane Doe'
        context.parameters['lis_person_contact_email_primary'] = \
            '*****@*****.**'
        app.set_launch_user(context)
        with TPApp.container['Users'].open() as collection:
            self.assertTrue(len(collection) == 1)
            user = collection.values()[0]
            self.assertTrue(user['UserID'].value == "123456")
            self.assertTrue(user['GivenName'].value == "Jane")
            self.assertTrue(user['FamilyName'].value == "Doe")
            self.assertTrue(user['FullName'].value == "Jane Doe")
            self.assertTrue(user['Email'].value == "*****@*****.**")
            uconsumer = user['Consumer'].get_entity()
            # check it is associated with the consumer we created
            self.assertTrue(uconsumer == consumer)
            # and no visits
            with user['Visits'].open() as vcollection:
                self.assertTrue(len(vcollection) == 0)
        self.assertTrue(context.user == user)
Ejemplo n.º 4
0
    def test_set_launch_group(self):

        class TPApp(lti.ToolProviderApp):
            private_files = self.d
        p = optparse.OptionParser()
        TPApp.add_options(p)
        options, args = p.parse_args(['-m', '--create_silo'])
        TPApp.setup(options=options, args=args)
        with TPApp.container['Silos'].open() as collection:
            silo = collection.values()[0]
        with silo['Consumers'].open() as collection:
            consumer = collection.values()[0]
            tc = lti.ToolConsumer(consumer, TPApp.new_app_cipher())
        app = TPApp()
        req = MockRequest()
        context = lti.ToolProviderContext(req.environ, req.start_response)
        context.session = wsgi.CookieSession()
        context.session.establish()
        context.consumer = tc
        # parameters will be empty, so no launch group
        app.set_launch_group(context)
        self.assertTrue(context.group is None)
        with TPApp.container['Contexts'].open() as collection:
            self.assertTrue(len(collection) == 0)
        # add in group parameters
        context.parameters['context_id'] = "gid"
        context.parameters['context_type'] = "Group"
        context.parameters['context_title'] = "Group101"
        context.parameters['context_label'] = "G101"
        app.set_launch_group(context)
        # now check that we have a group in the data store
        with TPApp.container['Contexts'].open() as collection:
            self.assertTrue(len(collection) == 1)
            group = collection.values()[0]
            self.assertTrue(group['ContextID'].value == "gid")
            self.assertTrue(group['Title'].value == "Group101")
            self.assertTrue(group['Label'].value == "G101")
            self.assertTrue(
                group['Types'].value == "urn:lti:context-type:ims/lis/Group")
            gconsumer = group['Consumer'].get_entity()
            # check it is associated with the consumer we created
            self.assertTrue(gconsumer == consumer)
            # and there are no resources
            with group['Resources'].open() as rcollection:
                self.assertTrue(len(rcollection) == 0)
        self.assertTrue(context.group == group)
Ejemplo n.º 5
0
 def consumers_page(self, context):
     page_context = self.new_page_context(context)
     # add errors
     errors = set(('duplicate_key', ))
     query = context.get_query()
     error = query.get('error', '')
     for e in errors:
         page_context[e] = (e == error)
     owner = context.session.get_owner()
     if owner is None:
         # we require an owner to be logged in
         raise wsgi.PageNotAuthorized
     page_context['user_name'] = owner['FullName'].value
     silo = owner['Silo'].get_entity()
     page_context['silo'] = silo
     consumer_list = []
     with silo['Consumers'].open() as collection:
         collection.set_orderby(
             odata.Parser('Handle asc').parse_orderby_option())
         for consumer in collection.itervalues():
             citem = {}
             consumer = lti.ToolConsumer(consumer, self.app_cipher)
             query = urllib.urlencode({
                 'cid':
                 odata.ODataURI.format_literal(consumer.entity['ID'])
             })
             citem['consumer'] = consumer
             citem['cedit_link'] = xml.escape_char_data7(
                 'edit?' + query, True)
             citem['cdel_link'] = xml.escape_char_data7(
                 'del?' + query, True)
             consumer_list.append(citem)
         query = urllib.urlencode(
             {'silo': odata.ODataURI.format_literal(silo['ID'])})
         page_context['cadd_link'] = xml.escape_char_data7(
             'add?' + query, True)
     page_context['consumers'] = consumer_list
     page_context[self.csrf_token] = context.session.sid()
     data = self.render_template(context, 'consumers/index.html',
                                 page_context)
     context.set_status(200)
     return self.html_response(context, data)
Ejemplo n.º 6
0
    def test_constructor(self):

        class TPApp(lti.ToolProviderApp):
            private_files = self.d
        p = optparse.OptionParser()
        TPApp.add_options(p)
        options, args = p.parse_args(['-m', '--create_silo'])
        TPApp.setup(options=options, args=args)
        with TPApp.container['Silos'].open() as collection:
            self.assertTrue(len(collection) == 1)
            silo = collection.values()[0]
        with silo['Consumers'].open() as collection:
            consumer = collection.values()[0]
            lti.ToolConsumer(consumer, TPApp.new_app_cipher())
        # ready to test the app
        app = TPApp()
        self.assertTrue(isinstance(app.provider, lti.ToolProvider))
        # now test the App logic, initially no visits
        with TPApp.container['Visits'].open() as collection:
            self.assertTrue(len(collection) == 0)
Ejemplo n.º 7
0
 def consumer_edit_action(self, context):
     if context.environ['REQUEST_METHOD'].upper() != 'POST':
         raise wsgi.MethodNotAllowed
     owner = context.session.get_owner()
     if owner is None:
         # we require an owner to be logged in
         raise wsgi.PageNotAuthorized
     silo = owner['Silo'].GetEntity()
     try:
         cid = context.get_form_long('cid')
         key = context.get_form_string('key', 80)
         secret = context.get_form_string('secret', 80)
         with silo['Consumers'].OpenCollection() as collection:
             consumer = lti.ToolConsumer(collection[cid], self.app_cipher)
             # we never change the handle
             consumer.update_from_values(key, secret)
     except ValueError:
         raise wsgi.BadRequest
     except KeyError:
         raise wsgi.PageNotAuthorized
     link = URI.from_octets("./").resolve(context.get_url())
     return self.redirect_page(context, link, 303)
Ejemplo n.º 8
0
 def consumer_edit_page(self, context):
     page_context = self.new_page_context(context)
     owner = context.session.get_owner()
     if owner is None:
         # we require an owner to be logged in
         raise wsgi.PageNotAuthorized
     page_context['owner'] = owner
     silo = owner['Silo'].GetEntity()
     page_context['silo'] = silo
     query = context.get_query()
     cid = odata.ParseURILiteral(query.get('cid', '')).value
     with silo['Consumers'].OpenCollection() as collection:
         try:
             consumer = lti.ToolConsumer(collection[cid], self.app_cipher)
         except KeyError:
             raise wsgi.PageNotAuthorized
     page_context['consumer'] = consumer
     page_context['cid_attr'] = xml.EscapeCharData7(str(cid), True)
     page_context[self.csrf_token] = context.session.sid()
     data = self.render_template(context, 'consumers/edit_form.html',
                                 page_context)
     context.set_status(200)
     return self.html_response(context, data)
Ejemplo n.º 9
0
    def test_new_visit(self):

        class TPApp(lti.ToolProviderApp):
            private_files = self.d
        p = optparse.OptionParser()
        TPApp.add_options(p)
        options, args = p.parse_args(['-m', '--create_silo'])
        TPApp.setup(options=options, args=args)
        with TPApp.container['Silos'].open() as collection:
            silo = collection.values()[0]
        with silo['Consumers'].open() as collection:
            consumer = collection.values()[0]
            tc = lti.ToolConsumer(consumer, TPApp.new_app_cipher())
        app = TPApp()
        req = MockRequest()
        context = lti.ToolProviderContext(req.environ, req.start_response)
        context.session = wsgi.CookieSession()
        unestablished_id = context.session.sid
        context.consumer = tc
        context.parameters['resource_link_id'] = 'rlink'
        context.parameters['resource_link_title'] = 'A Resource'
        context.parameters['resource_link_description'] = 'About the resource'
        app.set_launch_resource(context)
        # create a new visit in this unestablished session
        app.new_visit(context)
        with TPApp.container['Visits'].open() as collection:
            self.assertTrue(len(collection) == 1)
            visit = collection.values()[0]
            self.assertTrue(visit['Session'].value == unestablished_id)
        self.assertTrue(visit == context.visit)
        # now check that when we establish the session we're updated
        app.establish_session(context)
        self.assertTrue(context.session.established)
        established_id = context.session.sid
        self.assertTrue(unestablished_id != established_id)
        with TPApp.container['Visits'].open() as collection:
            self.assertTrue(len(collection) == 1)
            visit = collection.values()[0]
            self.assertTrue(visit['Session'].value == established_id)
        # but it should still be the same visit
        self.assertTrue(visit == context.visit)
        # now check that a new visit replaces an old one
        first_visit = visit
        context.parameters['user_id'] = '123456'
        context.parameters['lis_person_name_given'] = 'Jane'
        context.parameters['lis_person_name_family'] = 'Doe'
        context.parameters['lis_person_name_full'] = 'Jane Doe'
        context.parameters['lis_person_contact_email_primary'] = \
            '*****@*****.**'
        app.set_launch_user(context)
        app.new_visit(context)
        self.assertFalse(first_visit == context.visit)
        self.assertTrue(context.visit['Session'].value == established_id)
        with TPApp.container['Visits'].open() as collection:
            self.assertTrue(len(collection) == 2)
            # reload the first visit
            first_visit = collection[first_visit.key()]
            # this visit should no longer be associated with a session
            self.assertTrue(first_visit['Session'].value is None)
        # now check that a new visit with a different user orphans
        # visits from the old user (even when resource doesn't match)
        janes_visit = context.visit
        context.parameters['resource_link_id'] = 'rlink2'
        context.parameters['resource_link_title'] = 'Another Resource'
        context.parameters['resource_link_description'] = 'Details'
        app.set_launch_resource(context)
        context.parameters['user_id'] = '123457'
        context.parameters['lis_person_name_given'] = 'John'
        context.parameters['lis_person_name_family'] = 'Doe'
        context.parameters['lis_person_name_full'] = 'John Doe'
        context.parameters['lis_person_contact_email_primary'] = \
            '*****@*****.**'
        app.set_launch_user(context)
        app.new_visit(context)
        self.assertFalse(janes_visit == context.visit)
        with TPApp.container['Visits'].open() as collection:
            self.assertTrue(len(collection) == 3)
            # reload jane's visit
            janes_visit = collection[janes_visit.key()]
            # this visit should no longer be associated with a session
            self.assertTrue(janes_visit['Session'].value is None)
        # check that a login to a different resource with the same
        # user support multiple visits
        johns_first_visit = context.visit
        context.parameters['resource_link_id'] = 'rlink3'
        context.parameters['resource_link_title'] = 'Yet Another Resource'
        context.parameters['resource_link_description'] = 'More Details'
        app.set_launch_resource(context)
        app.new_visit(context)
        self.assertFalse(johns_first_visit == context.visit)
        with TPApp.container['Visits'].open() as collection:
            self.assertTrue(len(collection) == 4)
            # reload john's first visit
            johns_first_visit = collection[johns_first_visit.key()]
            # this visit should still be associated with the session
            self.assertTrue(
                johns_first_visit['Session'].value == established_id)
Ejemplo n.º 10
0
    def test_set_launch_resource(self):

        class TPApp(lti.ToolProviderApp):
            private_files = self.d
        p = optparse.OptionParser()
        TPApp.add_options(p)
        options, args = p.parse_args(['-m', '--create_silo'])
        TPApp.setup(options=options, args=args)
        with TPApp.container['Silos'].open() as collection:
            silo = collection.values()[0]
        with silo['Consumers'].open() as collection:
            consumer = collection.values()[0]
            tc = lti.ToolConsumer(consumer, TPApp.new_app_cipher())
        app = TPApp()
        req = MockRequest()
        context = lti.ToolProviderContext(req.environ, req.start_response)
        context.session = wsgi.CookieSession()
        context.session.establish()
        context.consumer = tc
        # parameters will be empty, so no launch resource: error
        try:
            app.set_launch_resource(context)
            self.fail("resource_link_id is required")
        except lti.LTIProtocolError:
            pass
        with TPApp.container['Resources'].open() as collection:
            self.assertTrue(len(collection) == 0)
        # add a resource link to the parameters
        context.parameters['resource_link_id'] = 'rlink'
        context.parameters['resource_link_title'] = 'A Resource'
        context.parameters['resource_link_description'] = 'About the resource'
        app.set_launch_resource(context)
        with TPApp.container['Resources'].open() as collection:
            self.assertTrue(len(collection) == 1)
            resource = collection.values()[0]
            self.assertTrue(resource['LinkID'].value == "rlink")
            self.assertTrue(resource['Title'].value == "A Resource")
            self.assertTrue(
                resource['Description'].value == "About the resource")
            rconsumer = resource['Consumer'].get_entity()
            # check it is associated with the consumer we created
            self.assertTrue(rconsumer == consumer)
            # and there are is no context
            self.assertTrue(resource['Context'].get_entity() is None)
            # and no visits
            with resource['Visits'].open() as vcollection:
                self.assertTrue(len(vcollection) == 0)
        self.assertTrue(context.resource == resource)
        # now check contexts too
        context.parameters['context_id'] = "gid"
        context.parameters['context_type'] = "Group"
        context.parameters['context_title'] = "Group101"
        context.parameters['context_label'] = "G101"
        context.parameters['resource_link_id'] = 'rlink2'
        context.parameters['resource_link_title'] = 'Another Resource'
        context.parameters['resource_link_description'] = 'Resource & context'
        app.set_launch_group(context)
        app.set_launch_resource(context)
        self.assertTrue(context.resource['LinkID'].value == 'rlink2')
        self.assertTrue(
            context.resource['Context'].get_entity() == context.group)