$url = new moodle_url('/mod/lti/request_tool.php', array('instanceid' => $instanceid)); $PAGE->set_url($url); $pagetitle = strip_tags($course->shortname); $PAGE->set_title($pagetitle); $PAGE->set_heading($course->fullname); $PAGE->set_pagelayout('incourse'); echo $OUTPUT->header(); echo $OUTPUT->heading(format_string($lti->name, true, array('context' => $context))); // Add a tool type if one does not exist already. if (!lti_get_tool_by_url_match($lti->toolurl, $lti->course, LTI_TOOL_STATE_ANY)) { // There are no tools (active, pending, or rejected) for the launch URL. Create a new pending tool. $tooltype = new stdClass(); $toolconfig = new stdClass(); $toolconfig->lti_toolurl = lti_get_domain_from_url($lti->toolurl); $toolconfig->lti_typename = $toolconfig->lti_toolurl; lti_add_type($tooltype, $toolconfig); echo get_string('lti_tool_request_added', 'lti'); } else { echo get_string('lti_tool_request_existing', 'lti'); } echo $OUTPUT->footer();
} } if (lti_request_is_using_ssl() && !empty($type->lti_secureicon)) { $type->oldicon = $type->lti_secureicon; } else { $type->oldicon = $type->lti_icon; } $form = new mod_lti_edit_types_form($pageurl, (object) array('isadmin' => true, 'istool' => true)); if ($data = $form->get_data()) { $type = new stdClass(); if (!empty($id)) { $type->id = $id; lti_update_type($type, $data); } else { $type->state = LTI_TOOL_STATE_CONFIGURED; lti_add_type($type, $data); } redirect($redirect); } else { if ($form->is_cancelled()) { redirect($redirect); } } $PAGE->set_title(format_string($SITE->shortname) . ': ' . get_string('toolsetup', 'lti')); $PAGE->navbar->add(get_string('lti_administration', 'lti'), $CFG->wwwroot . '/' . $CFG->admin . '/settings.php?section=modsettinglti'); echo $OUTPUT->header(); echo $OUTPUT->heading(get_string('toolsetup', 'lti')); echo $OUTPUT->box_start('generalbox'); if ($action == 'update') { $form->set_data($type); }
/** * Creates a tool type. * * @param string $cartridgeurl Url of the xml cartridge representing the LTI tool * @param string $key The consumer key to identify this consumer * @param string $secret The secret * @return array created tool type * @since Moodle 3.1 * @throws moodle_exception If the tool type could not be created */ public static function create_tool_type($cartridgeurl, $key, $secret) { $params = self::validate_parameters(self::create_tool_type_parameters(), array('cartridgeurl' => $cartridgeurl, 'key' => $key, 'secret' => $secret)); $cartridgeurl = $params['cartridgeurl']; $key = $params['key']; $secret = $params['secret']; $context = context_system::instance(); self::validate_context($context); require_capability('moodle/site:config', $context); $id = null; if (!empty($cartridgeurl)) { $type = new stdClass(); $data = new stdClass(); $type->state = LTI_TOOL_STATE_CONFIGURED; $data->lti_coursevisible = 1; $data->lti_sendname = LTI_SETTING_DELEGATE; $data->lti_sendemailaddr = LTI_SETTING_DELEGATE; $data->lti_acceptgrades = LTI_SETTING_DELEGATE; $data->lti_forcessl = 0; if (!empty($key)) { $data->lti_resourcekey = $key; } if (!empty($secret)) { $data->lti_password = $secret; } lti_load_type_from_cartridge($cartridgeurl, $data); if (empty($data->lti_toolurl)) { throw new moodle_exception('unabletocreatetooltype', 'mod_lti'); } else { $id = lti_add_type($type, $data); } } if (!empty($id)) { $type = lti_get_type($id); return serialise_tool_type($type); } else { throw new moodle_exception('unabletocreatetooltype', 'mod_lti'); } }
/** * Execute the request for this resource. * * @param mod_lti\local\ltiservice\response $response Response object for this request. */ public function execute($response) { $ok = $this->check_tool_proxy(null, $response->get_request_data()); if ($ok) { $toolproxy = $this->get_service()->get_tool_proxy(); } else { $toolproxy = null; $response->set_code(401); } $tools = array(); // Ensure all required elements are present in the Tool Proxy. if ($ok) { $toolproxyjson = json_decode($response->get_request_data()); $ok = !empty($toolproxyjson); if (!$ok) { debugging('Tool proxy is not properly formed JSON'); } else { $ok = isset($toolproxyjson->tool_profile->product_instance->product_info->product_family->vendor->code); $ok = $ok && isset($toolproxyjson->security_contract->shared_secret); $ok = $ok && isset($toolproxyjson->tool_profile->resource_handler); if (!$ok) { debugging('One or more missing elements from tool proxy: vendor code, shared secret or resource handlers'); } } } // Check all capabilities requested were offered. if ($ok) { $offeredcapabilities = explode("\n", $toolproxy->capabilityoffered); $resources = $toolproxyjson->tool_profile->resource_handler; $errors = array(); foreach ($resources as $resource) { if (isset($resource->message)) { foreach ($resource->message as $message) { if (!in_array($message->message_type, $offeredcapabilities)) { $errors[] = $message->message_type; } else { if (isset($resource->parameter)) { foreach ($message->parameter as $parameter) { if (isset($parameter->variable) && !in_array($parameter->variable, $offeredcapabilities)) { $errors[] = $parameter->variable; } } } } } } } if (count($errors) > 0) { $ok = false; debugging('Tool proxy contains capabilities which were not offered: ' . implode(', ', $errors)); } } // Check all services requested were offered (only tool services currently supported). if ($ok && isset($toolproxyjson->security_contract->tool_service)) { $contexts = lti_get_contexts($toolproxyjson); $profileservice = lti_get_service_by_name('profile'); $profileservice->set_tool_proxy($toolproxy); $context = $profileservice->get_service_path() . $profileservice->get_resources()[0]->get_path() . '#'; $offeredservices = explode("\n", $toolproxy->serviceoffered); $services = lti_get_services(); $tpservices = $toolproxyjson->security_contract->tool_service; $errors = array(); foreach ($tpservices as $service) { $fqid = lti_get_fqid($contexts, $service->service); if (substr($fqid, 0, strlen($context)) !== $context) { $errors[] = $service->service; } else { $id = explode('#', $fqid, 2); $aservice = lti_get_service_by_resource_id($services, $id[1]); $classname = explode('\\', get_class($aservice)); if (empty($aservice) || !in_array($classname[count($classname) - 1], $offeredservices)) { $errors[] = $service->service; } } } if (count($errors) > 0) { $ok = false; debugging('Tool proxy contains services which were not offered: ' . implode(', ', $errors)); } } // Extract all launchable tools from the resource handlers. if ($ok) { $resources = $toolproxyjson->tool_profile->resource_handler; foreach ($resources as $resource) { $found = false; $tool = new \stdClass(); foreach ($resource->message as $message) { if ($message->message_type == 'basic-lti-launch-request') { $found = true; $tool->path = $message->path; $tool->enabled_capability = $message->enabled_capability; $tool->parameter = $message->parameter; break; } } if (!$found) { continue; } $tool->name = $resource->resource_name->default_value; $tools[] = $tool; } $ok = count($tools) > 0; if (!$ok) { debugging('No launchable messages found in tool proxy'); } } // Add tools and custom parameters. if ($ok) { $baseurl = ''; if (isset($toolproxyjson->tool_profile->base_url_choice[0]->default_base_url)) { $baseurl = $toolproxyjson->tool_profile->base_url_choice[0]->default_base_url; } $securebaseurl = ''; if (isset($toolproxyjson->tool_profile->base_url_choice[0]->secure_base_url)) { $securebaseurl = $toolproxyjson->tool_profile->base_url_choice[0]->secure_base_url; } foreach ($tools as $tool) { $config = new \stdClass(); $config->lti_toolurl = "{$baseurl}{$tool->path}"; $config->lti_typename = $tool->name; $config->lti_coursevisible = 1; $config->lti_forcessl = 0; $type = new \stdClass(); $type->state = LTI_TOOL_STATE_PENDING; $type->toolproxyid = $toolproxy->id; $type->enabledcapability = implode("\n", $tool->enabled_capability); $type->parameter = self::lti_extract_parameters($tool->parameter); if (isset($resource->icon_info[0]->default_location->path)) { $iconpath = $resource->icon_info[0]->default_location->path; $type->icon = "{$baseurl}{$iconpath}"; if (!empty($securebaseurl)) { $type->secureicon = "{$securebaseurl}{$iconpath}"; } } $ok = $ok && lti_add_type($type, $config) !== false; } if (isset($toolproxyjson->custom)) { lti_set_tool_settings($toolproxyjson->custom, $toolproxy->id); } } if (!empty($toolproxy)) { if ($ok) { // If all went OK accept the tool proxy. $toolproxy->state = LTI_TOOL_PROXY_STATE_ACCEPTED; $toolproxy->toolproxy = $response->get_request_data(); $toolproxy->secret = $toolproxyjson->security_contract->shared_secret; $toolproxy->vendorcode = $toolproxyjson->tool_profile->product_instance->product_info->product_family->vendor->code; $url = $this->get_endpoint(); $body = <<<EOD { "@context" : "http://purl.imsglobal.org/ctx/lti/v2/ToolProxyId", "@type" : "ToolProxy", "@id" : "{$url}", "tool_proxy_guid" : "{$toolproxy->guid}" } EOD; $response->set_code(201); $response->set_content_type('application/vnd.ims.lti.v2.toolproxy.id+json'); $response->set_body($body); } else { // Otherwise reject the tool proxy. $toolproxy->state = LTI_TOOL_PROXY_STATE_REJECTED; $response->set_code(400); } lti_update_tool_proxy($toolproxy); } else { $response->set_code(400); } }
public function test_mod_lti_get_tool_types() { // Create a tool proxy. $proxy = mod_lti_external::create_tool_proxy('Test proxy', $this->getExternalTestFileUrl('/test.html'), array(), array()); // Create a tool type, associated with that proxy. $type = new stdClass(); $data = new stdClass(); $type->state = LTI_TOOL_STATE_CONFIGURED; $type->name = "Test tool"; $type->description = "Example description"; $type->toolproxyid = $proxy->id; $type->baseurl = $this->getExternalTestFileUrl('/test.html'); $typeid = lti_add_type($type, $data); $types = mod_lti_external::get_tool_types($proxy->id); $this->assertEquals(1, count($types)); $type = $types[0]; $this->assertEquals('Test tool', $type['name']); $this->assertEquals('Example description', $type['description']); }
/** * Test for lti_build_content_item_selection_request() with invalid presentation targets parameter. */ public function test_lti_build_content_item_selection_request_invalid_presentationtargets() { $this->resetAfterTest(); $this->setAdminUser(); // Create a tool type, associated with that proxy. $type = new stdClass(); $data = new stdClass(); $data->lti_contentitem = true; $type->state = LTI_TOOL_STATE_CONFIGURED; $type->name = "Test tool"; $type->description = "Example description"; $type->baseurl = $this->getExternalTestFileUrl('/test.html'); $typeid = lti_add_type($type, $data); $course = $this->getDataGenerator()->create_course(); $returnurl = new moodle_url('/'); // Should throw coding_exception on non-array presentation targets. $targets = 'frame,iframe'; $this->expectException('coding_exception'); lti_build_content_item_selection_request($typeid, $course, $returnurl, '', '', [], $targets); }
public function execute($response) { $ok = $this->get_service()->check_tool_proxy(null, $response->get_request_data()); $toolproxy = $this->get_service()->get_tool_proxy(); if ($ok) { $toolproxyjson = json_decode($response->get_request_data()); $ok = !is_null($toolproxyjson); $ok = $ok && isset($toolproxyjson->tool_profile->product_instance->product_info->product_family->vendor->code); $ok = $ok && isset($toolproxyjson->security_contract->shared_secret); $ok = $ok && isset($toolproxyjson->tool_profile->resource_handler); } if ($ok) { $baseurl = ''; if (isset($toolproxyjson->tool_profile->base_url_choice[0]->default_base_url)) { $baseurl = $toolproxyjson->tool_profile->base_url_choice[0]->default_base_url; } $securebaseurl = ''; if (isset($toolproxyjson->tool_profile->base_url_choice[0]->secure_base_url)) { $securebaseurl = $toolproxyjson->tool_profile->base_url_choice[0]->secure_base_url; } $resources = $toolproxyjson->tool_profile->resource_handler; foreach ($resources as $resource) { $icon = new \stdClass(); if (isset($resource->icon_info[0]->default_location->path)) { $icon->path = $resource->icon_info[0]->default_location->path; } $tool = new \stdClass(); $tool->name = $resource->resource_name->default_value; $messages = $resource->message; foreach ($messages as $message) { if ($message->message_type == 'basic-lti-launch-request') { $tool->path = $message->path; $tool->enabled_capability = $message->enabled_capability; $tool->parameter = $message->parameter; } } $config = new \stdClass(); $config->lti_toolurl = "{$baseurl}{$tool->path}"; $config->lti_typename = $tool->name; $config->lti_coursevisible = 1; $config->lti_forcessl = 0; $type = new \stdClass(); $type->state = LTI_TOOL_STATE_PENDING; $type->toolproxyid = $toolproxy->id; $type->enabledcapability = implode("\n", $tool->enabled_capability); $type->parameter = self::lti_extract_parameters($tool->parameter); if (!empty($icon->path)) { $type->icon = "{$baseurl}{$icon->path}"; if (!empty($securebaseurl)) { $type->secureicon = "{$securebaseurl}{$icon->path}"; } } $ok = (lti_add_type($type, $config) !== false); } if (isset($toolproxyjson->custom)) { lti_set_tool_settings($toolproxyjson->custom, $toolproxy->id); } } if ($ok) { $toolproxy->state = LTI_TOOL_PROXY_STATE_ACCEPTED; $toolproxy->toolproxy = $response->get_request_data(); $toolproxy->secret = $toolproxyjson->security_contract->shared_secret; $toolproxy->vendorcode = $toolproxyjson->tool_profile->product_instance->product_info->product_family->vendor->code; $url = $this->get_endpoint(); $body = <<< EOD { "@context" : "http://purl.imsglobal.org/ctx/lti/v2/ToolProxyId", "@type" : "ToolProxy", "@id" : "{$url}", "tool_proxy_guid" : "{$toolproxy->guid}" } EOD; $response->set_code(201); $response->set_content_type('application/vnd.ims.lti.v2.toolproxy.id+json'); $response->set_body($body); } else { $toolproxy->state = LTI_TOOL_PROXY_STATE_REJECTED; $response->set_code(400); } lti_update_tool_proxy($toolproxy); }