<script type=\"text/javascript\">
                    window.opener.M.mod_lti.editor.updateToolType({$json});
                    window.close();
                </script>
            </html>
        ";

        echo $script;
        die;
    } else {
        $type->state = LTI_TOOL_STATE_CONFIGURED;
        $type->course = $COURSE->id;

        $id = lti_add_type($type, $data);

        $fromdb = lti_get_type($id);
        $json = json_encode($fromdb);

        // Output script to update the calling window.
        $script = "
            <html>
                <script type=\"text/javascript\">
                    window.opener.M.mod_lti.editor.addToolType({$json});
                    window.close();
                </script>
            </html>
        ";

        echo $script;

        die;
Exemplo n.º 2
0
/**
 * Return the launch data required for opening the external tool.
 *
 * @param  stdClass $instance the external tool activity settings
 * @return array the endpoint URL and parameters (including the signature)
 * @since  Moodle 3.0
 */
function lti_get_launch_data($instance)
{
    global $PAGE, $CFG;
    if (empty($instance->typeid)) {
        $tool = lti_get_tool_by_url_match($instance->toolurl, $instance->course);
        if ($tool) {
            $typeid = $tool->id;
        } else {
            $typeid = null;
        }
    } else {
        $typeid = $instance->typeid;
        $tool = lti_get_type($typeid);
    }
    if ($typeid) {
        $typeconfig = lti_get_type_config($typeid);
    } else {
        // There is no admin configuration for this tool. Use configuration in the lti instance record plus some defaults.
        $typeconfig = (array) $instance;
        $typeconfig['sendname'] = $instance->instructorchoicesendname;
        $typeconfig['sendemailaddr'] = $instance->instructorchoicesendemailaddr;
        $typeconfig['customparameters'] = $instance->instructorcustomparameters;
        $typeconfig['acceptgrades'] = $instance->instructorchoiceacceptgrades;
        $typeconfig['allowroster'] = $instance->instructorchoiceallowroster;
        $typeconfig['forcessl'] = '0';
    }
    // Default the organizationid if not specified.
    if (empty($typeconfig['organizationid'])) {
        $urlparts = parse_url($CFG->wwwroot);
        $typeconfig['organizationid'] = $urlparts['host'];
    }
    if (isset($tool->toolproxyid)) {
        $toolproxy = lti_get_tool_proxy($tool->toolproxyid);
        $key = $toolproxy->guid;
        $secret = $toolproxy->secret;
    } else {
        $toolproxy = null;
        if (!empty($instance->resourcekey)) {
            $key = $instance->resourcekey;
        } else {
            if (!empty($typeconfig['resourcekey'])) {
                $key = $typeconfig['resourcekey'];
            } else {
                $key = '';
            }
        }
        if (!empty($instance->password)) {
            $secret = $instance->password;
        } else {
            if (!empty($typeconfig['password'])) {
                $secret = $typeconfig['password'];
            } else {
                $secret = '';
            }
        }
    }
    $endpoint = !empty($instance->toolurl) ? $instance->toolurl : $typeconfig['toolurl'];
    $endpoint = trim($endpoint);
    // If the current request is using SSL and a secure tool URL is specified, use it.
    if (lti_request_is_using_ssl() && !empty($instance->securetoolurl)) {
        $endpoint = trim($instance->securetoolurl);
    }
    // If SSL is forced, use the secure tool url if specified. Otherwise, make sure https is on the normal launch URL.
    if (isset($typeconfig['forcessl']) && $typeconfig['forcessl'] == '1') {
        if (!empty($instance->securetoolurl)) {
            $endpoint = trim($instance->securetoolurl);
        }
        $endpoint = lti_ensure_url_is_https($endpoint);
    } else {
        if (!strstr($endpoint, '://')) {
            $endpoint = 'http://' . $endpoint;
        }
    }
    $orgid = $typeconfig['organizationid'];
    $course = $PAGE->course;
    $islti2 = isset($tool->toolproxyid);
    $allparams = lti_build_request($instance, $typeconfig, $course, $typeid, $islti2);
    if ($islti2) {
        $requestparams = lti_build_request_lti2($tool, $allparams);
    } else {
        $requestparams = $allparams;
    }
    $requestparams = array_merge($requestparams, lti_build_standard_request($instance, $orgid, $islti2));
    $customstr = '';
    if (isset($typeconfig['customparameters'])) {
        $customstr = $typeconfig['customparameters'];
    }
    $requestparams = array_merge($requestparams, lti_build_custom_parameters($toolproxy, $tool, $instance, $allparams, $customstr, $instance->instructorcustomparameters, $islti2));
    $launchcontainer = lti_get_launch_container($instance, $typeconfig);
    $returnurlparams = array('course' => $course->id, 'launch_container' => $launchcontainer, 'instanceid' => $instance->id, 'sesskey' => sesskey());
    // Add the return URL. We send the launch container along to help us avoid frames-within-frames when the user returns.
    $url = new \moodle_url('/mod/lti/return.php', $returnurlparams);
    $returnurl = $url->out(false);
    if (isset($typeconfig['forcessl']) && $typeconfig['forcessl'] == '1') {
        $returnurl = lti_ensure_url_is_https($returnurl);
    }
    $target = '';
    switch ($launchcontainer) {
        case LTI_LAUNCH_CONTAINER_EMBED:
        case LTI_LAUNCH_CONTAINER_EMBED_NO_BLOCKS:
            $target = 'iframe';
            break;
        case LTI_LAUNCH_CONTAINER_REPLACE_MOODLE_WINDOW:
            $target = 'frame';
            break;
        case LTI_LAUNCH_CONTAINER_WINDOW:
            $target = 'window';
            break;
    }
    if (!empty($target)) {
        $requestparams['launch_presentation_document_target'] = $target;
    }
    $requestparams['launch_presentation_return_url'] = $returnurl;
    // Allow request params to be updated by sub-plugins.
    $plugins = core_component::get_plugin_list('ltisource');
    foreach (array_keys($plugins) as $plugin) {
        $pluginparams = component_callback('ltisource_' . $plugin, 'before_launch', array($instance, $endpoint, $requestparams), array());
        if (!empty($pluginparams) && is_array($pluginparams)) {
            $requestparams = array_merge($requestparams, $pluginparams);
        }
    }
    if (!empty($key) && !empty($secret)) {
        $parms = lti_sign_parameters($requestparams, $endpoint, "POST", $key, $secret);
        $endpointurl = new \moodle_url($endpoint);
        $endpointparams = $endpointurl->params();
        // Strip querystring params in endpoint url from $parms to avoid duplication.
        if (!empty($endpointparams) && !empty($parms)) {
            foreach (array_keys($endpointparams) as $paramname) {
                if (isset($parms[$paramname])) {
                    unset($parms[$paramname]);
                }
            }
        }
    } else {
        // If no key and secret, do the launch unsigned.
        $returnurlparams['unsigned'] = '1';
        $parms = $requestparams;
    }
    return array($endpoint, $parms);
}
Exemplo n.º 3
0
/**
 * Processes the tool provider's response to the ContentItemSelectionRequest and builds the configuration data from the
 * selected content item. This configuration data can be then used when adding a tool into the course.
 *
 * @param int $typeid The tool type ID.
 * @param string $messagetype The value for the lti_message_type parameter.
 * @param string $ltiversion The value for the lti_version parameter.
 * @param string $consumerkey The consumer key.
 * @param string $contentitemsjson The JSON string for the content_items parameter.
 * @return stdClass The array of module information objects.
 * @throws moodle_exception
 * @throws lti\OAuthException
 */
function lti_tool_configuration_from_content_item($typeid, $messagetype, $ltiversion, $consumerkey, $contentitemsjson)
{
    $tool = lti_get_type($typeid);
    // Validate parameters.
    if (!$tool) {
        throw new moodle_exception('errortooltypenotfound', 'mod_lti');
    }
    // Check lti_message_type. Show debugging if it's not set to ContentItemSelection.
    // No need to throw exceptions for now since lti_message_type does not seem to be used in this processing at the moment.
    if ($messagetype !== 'ContentItemSelection') {
        debugging("lti_message_type is invalid: {$messagetype}. It should be set to 'ContentItemSelection'.", DEBUG_DEVELOPER);
    }
    $typeconfig = lti_get_type_config($typeid);
    if (isset($tool->toolproxyid)) {
        $islti2 = true;
        $toolproxy = lti_get_tool_proxy($tool->toolproxyid);
        $key = $toolproxy->guid;
        $secret = $toolproxy->secret;
    } else {
        $islti2 = false;
        $toolproxy = null;
        if (!empty($typeconfig['resourcekey'])) {
            $key = $typeconfig['resourcekey'];
        } else {
            $key = '';
        }
        if (!empty($typeconfig['password'])) {
            $secret = $typeconfig['password'];
        } else {
            $secret = '';
        }
    }
    // Check LTI versions from our side and the response's side. Show debugging if they don't match.
    // No need to throw exceptions for now since LTI version does not seem to be used in this processing at the moment.
    $expectedversion = LTI_VERSION_1;
    if ($islti2) {
        $expectedversion = LTI_VERSION_2;
    }
    if ($ltiversion !== $expectedversion) {
        debugging("lti_version from response does not match the tool's configuration. Tool: {$expectedversion}," . " Response: {$ltiversion}", DEBUG_DEVELOPER);
    }
    if ($consumerkey !== $key) {
        throw new moodle_exception('errorincorrectconsumerkey', 'mod_lti');
    }
    $store = new lti\TrivialOAuthDataStore();
    $store->add_consumer($key, $secret);
    $server = new lti\OAuthServer($store);
    $method = new lti\OAuthSignatureMethod_HMAC_SHA1();
    $server->add_signature_method($method);
    $request = lti\OAuthRequest::from_request();
    try {
        $server->verify_request($request);
    } catch (lti\OAuthException $e) {
        throw new lti\OAuthException("OAuth signature failed: " . $e->getMessage());
    }
    $items = json_decode($contentitemsjson);
    if (empty($items)) {
        throw new moodle_exception('errorinvaliddata', 'mod_lti', '', $contentitemsjson);
    }
    if ($items->{'@context'} !== 'http://purl.imsglobal.org/ctx/lti/v1/ContentItem') {
        throw new moodle_exception('errorinvalidmediatype', 'mod_lti', '', $items->{'@context'});
    }
    if (!isset($items->{'@graph'}) || !is_array($items->{'@graph'}) || count($items->{'@graph'}) > 1) {
        throw new moodle_exception('errorinvalidresponseformat', 'mod_lti');
    }
    $config = null;
    if (!empty($items->{'@graph'})) {
        $item = $items->{'@graph'}[0];
        $config = new stdClass();
        $config->name = '';
        if (isset($item->title)) {
            $config->name = $item->title;
        }
        if (empty($config->name)) {
            $config->name = $tool->name;
        }
        if (isset($item->text)) {
            $config->introeditor = ['text' => $item->text, 'format' => FORMAT_PLAIN];
        }
        if (isset($item->icon->{'@id'})) {
            $iconurl = new moodle_url($item->icon->{'@id'});
            // Assign item's icon URL to secureicon or icon depending on its scheme.
            if (strtolower($iconurl->get_scheme()) === 'https') {
                $config->secureicon = $iconurl->out(false);
            } else {
                $config->icon = $iconurl->out(false);
            }
        }
        if (isset($item->url)) {
            $url = new moodle_url($item->url);
            // Assign item URL to securetoolurl or toolurl depending on its scheme.
            if (strtolower($url->get_scheme()) === 'https') {
                $config->securetoolurl = $url->out(false);
            } else {
                $config->toolurl = $url->out(false);
            }
            $config->typeid = 0;
        } else {
            $config->typeid = $typeid;
        }
        $config->instructorchoicesendname = LTI_SETTING_NEVER;
        $config->instructorchoicesendemailaddr = LTI_SETTING_NEVER;
        $config->instructorchoiceacceptgrades = LTI_SETTING_NEVER;
        $config->launchcontainer = LTI_LAUNCH_CONTAINER_DEFAULT;
        if (isset($item->placementAdvice->presentationDocumentTarget)) {
            if ($item->placementAdvice->presentationDocumentTarget === 'window') {
                $config->launchcontainer = LTI_LAUNCH_CONTAINER_WINDOW;
            } else {
                if ($item->placementAdvice->presentationDocumentTarget === 'frame') {
                    $config->launchcontainer = LTI_LAUNCH_CONTAINER_EMBED_NO_BLOCKS;
                } else {
                    if ($item->placementAdvice->presentationDocumentTarget === 'iframe') {
                        $config->launchcontainer = LTI_LAUNCH_CONTAINER_EMBED;
                    }
                }
            }
        }
        if (isset($item->custom)) {
            $customparameters = [];
            foreach ($item->custom as $key => $value) {
                $customparameters[] = "{$key}={$value}";
            }
            $config->instructorcustomparameters = implode("\n", $customparameters);
        }
    }
    return $config;
}
Exemplo n.º 4
0
 /**
  * Delete a tool type.
  *
  * @param int $id The id of the tool type to be deleted
  * @return array deleted tool type
  * @since Moodle 3.1
  * @throws moodle_exception
  */
 public static function delete_tool_type($id)
 {
     $params = self::validate_parameters(self::delete_tool_type_parameters(), array('id' => $id));
     $id = $params['id'];
     $context = context_system::instance();
     self::validate_context($context);
     require_capability('moodle/site:config', $context);
     $type = lti_get_type($id);
     if (!empty($type)) {
         lti_delete_type($id);
         // If this is the last type for this proxy then remove the proxy
         // as well so that it isn't orphaned.
         $types = lti_get_lti_types_from_proxy_id($type->toolproxyid);
         if (empty($types)) {
             lti_delete_tool_proxy($type->toolproxyid);
         }
     }
     return array('id' => $id);
 }
Exemplo n.º 5
0
 public function test_mod_lti_delete_tool_type_without_capability()
 {
     $type = mod_lti_external::create_tool_type($this->getExternalTestFileUrl('/ims_cartridge_basic_lti_link.xml'), '', '');
     $this->assertNotEmpty(lti_get_type($type['id']));
     $this->expectException('required_capability_exception');
     self::setUser($this->teacher);
     $type = mod_lti_external::delete_tool_type($type['id']);
 }