MDL-53832 enrol_lti: Add interface for proxies

This commit is contained in:
John Okely 2016-09-23 13:46:32 +08:00
parent a1f3821ee0
commit 9a709cd5a5
9 changed files with 342 additions and 10 deletions

View File

@ -435,6 +435,18 @@ class helper {
return trim(html_to_text($description));
}
/**
* Returns the icon of the tool.
*
* @param stdClass $tool The lti tool
* @return moodle_url A url to the icon of the tool
* @since Moodle 3.2
*/
public static function get_icon($tool) {
global $OUTPUT;
return $OUTPUT->favicon();
}
/**
* Returns the url to the cartridge representing the tool.
*
@ -464,6 +476,34 @@ class helper {
return $url;
}
/**
* Returns the url to the tool proxy registration url.
*
* If you have slash arguments enabled, this will be a nice url ending in cartridge.xml.
* If not it will be a php page with some parameters passed.
*
* @param stdClass $tool The lti tool
* @return string The url to the cartridge representing the tool
*/
public static function get_proxy_url($tool) {
global $CFG;
$url = null;
$id = $tool->id;
$token = self::generate_tool_token($tool->id);
if ($CFG->slasharguments) {
$url = new \moodle_url('/enrol/lti/proxy.php/' . $id . '/' . $token . '/');
} else {
$url = new \moodle_url('/enrol/lti/proxy.php',
array(
'id' => $id,
'token' => $token
)
);
}
return $url;
}
/**
* Returns a unique hash for this site and this enrolment instance.
*
@ -500,7 +540,7 @@ class helper {
* @since Moodle 3.2
*/
protected static function get_cartridge_parameters($toolid) {
global $OUTPUT, $PAGE, $SITE;
global $PAGE, $SITE;
$PAGE->set_context(\context_system::instance());
// Get the tool.
@ -510,8 +550,7 @@ class helper {
$title = self::get_name($tool);
$launchurl = self::get_launch_url($toolid);
$launchurl = $launchurl->out();
$icon = $OUTPUT->favicon();
$icon = $icon->out();
$icon = self::get_icon($tool);
$securelaunchurl = null;
$secureicon = null;
$vendorurl = new \moodle_url('/');

View File

@ -69,14 +69,16 @@ class manage_table extends \table_sql {
$this->define_columns(array(
'name',
'url',
'cartridge_url',
'secret',
'proxy_url',
'edit'
));
$this->define_headers(array(
get_string('name'),
get_string('url'),
get_string('cartridgeurl', 'enrol_lti'),
get_string('secret', 'enrol_lti'),
get_string('proxyurl', 'enrol_lti'),
get_string('edit')
));
$this->collapsible(false);
@ -102,17 +104,29 @@ class manage_table extends \table_sql {
}
/**
* Generate the URL column.
* Generate the cartridge URL column.
*
* @param \stdClass $tool event data.
* @return string
*/
public function col_url($tool) {
public function col_cartridge_url($tool) {
$url = helper::get_cartridge_url($tool);
return $this->get_copyable_text($tool, $url);
}
/**
* Generate the proxy URL column.
*
* @param \stdClass $tool event data.
* @return string
*/
public function col_proxy_url($tool) {
$url = helper::get_proxy_url($tool);
return $this->get_copyable_text($tool, $url);
}
/**
* Generate the secret column.
*

View File

@ -0,0 +1,182 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Extends the IMS Tool provider library for the LTI enrolment.
*
* @package enrol_lti
* @copyright 2016 John Okely <john@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace enrol_lti;
defined('MOODLE_INTERNAL') || die;
use IMSGlobal\LTI\Profile;
use IMSGlobal\LTI\ToolProvider;
use IMSGlobal\LTI\ToolProvider\DataConnector;
/**
* Extends the IMS Tool provider library for the LTI enrolment.
*
* @package enrol_lti
* @copyright 2016 John Okely <john@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class tool_provider extends ToolProvider\ToolProvider {
private function stripBaseUrl($url) {
if (substr($url, 0, strlen($this->baseUrl)) == $this->baseUrl) {
return substr($url, strlen($this->baseUrl));
}
# TODO Oh no this will break!!
print_object($icon);
print_object($this->baseUrl);
print_object("no good!!");
die;
return null;
}
function __construct($toolid) {
global $CFG, $SITE;
$token = \enrol_lti\helper::generate_tool_token($toolid);
$this->debugMode = $CFG->debugdeveloper;
$tool = \enrol_lti\helper::get_lti_tool($toolid);
$dataconnector = new data_connector();
parent::__construct($dataconnector);
#$this->baseUrl = $CFG->wwwroot . '/enrol/lti/proxy.php';
$this->baseUrl = $CFG->wwwroot;
$toolpath = $this->stripBaseUrl(\enrol_lti\helper::get_proxy_url($tool));
$vendorid = $SITE->shortname;
$vendorname = $SITE->fullname;
$vendordescription = trim(html_to_text($SITE->summary));
$this->vendor = new Profile\Item($vendorid, $vendorname, $vendordescription, $CFG->wwwroot);
$name = \enrol_lti\helper::get_name($tool);
$description = \enrol_lti\helper::get_description($tool);
$icon = \enrol_lti\helper::get_icon($tool)->out();
// Strip the baseUrl off the icon path.
$icon = $this->stripBaseUrl($icon);
$this->product = new Profile\Item(
$token,
$name,
$description,
\enrol_lti\helper::get_proxy_url($tool),
'1.0'
);
$requiredmessages = array(
new Profile\Message(
'basic-lti-launch-request',
$toolpath,
array(
'Context.id',
'CourseSection.title',
'CourseSection.label',
'CourseSection.sourcedId',
'CourseSection.longDescription',
'CourseSection.timeFrame.begin',
'ResourceLink.id',
'ResourceLink.title',
'ResourceLink.description',
'User.id',
'User.username',
'Person.name.full',
'Person.name.given',
'Person.name.family',
'Person.email.primary',
'Person.sourcedId',
'Person.name.middle',
'Person.address.street1',
'Person.address.locality',
'Person.address.country',
'Person.address.timezone',
'Person.phone.primary',
'Person.phone.mobile',
'Person.webaddress',
'Membership.role',
'Result.sourcedId',
'Result.autocreate'
)
)
);
$optionalmessages = array(
#new Profile\Message('ContentItemSelectionRequest', $toolpath, array('User.id', 'Membership.role')),
#new Profile\Message('DashboardRequest', $toolpath, array('User.id'), array('a' => 'User.id'), array('b' => 'User.id'))
);
$this->resourceHandlers[] = new Profile\ResourceHandler(
new Profile\Item(
$token,
\enrol_lti\helper::get_name($tool),
$description
),
$icon,
$requiredmessages,
$optionalmessages
);
$this->requiredServices[] = new Profile\ServiceDefinition(array('application/vnd.ims.lti.v2.toolproxy+json'), array('POST'));
# TODO should the other requests be here?
$this->setParameterConstraint('oauth_consumer_key', TRUE, 50, array('basic-lti-launch-request', 'ContentItemSelectionRequest', 'DashboardRequest'));
$this->setParameterConstraint('resource_link_id', TRUE, 50, array('basic-lti-launch-request'));
$this->setParameterConstraint('user_id', TRUE, 50, array('basic-lti-launch-request'));
$this->setParameterConstraint('roles', TRUE, NULL, array('basic-lti-launch-request'));
}
function onError() {
error_log("onError()");
error_log($this->reason);
$message = $this->message;
if ($this->debugMode && !empty($this->reason)) {
$message = $this->reason;
}
$this->errorOutput = ''; # TODO remove this
\core\notification::error($message); # TODO is it better to have a generic, yet translatable error?
}
function onLaunch() {
error_log("onLaunch()");
// TODO Launching tool. Basically tool.php code needs to go here.
echo "This is a tool";
}
function onRegister() {
global $OUTPUT;
$returnurl = $_POST['launch_presentation_return_url'];
if (strpos($returnurl, '?') === false) {
$separator = '?';
} else {
$separator = '&';
}
$guid = $this->consumer->getKey();
$returnurl = $returnurl . $separator . 'lti_msg=Successful+registration';
$returnurl = $returnurl . '&status=success';
$returnurl = $returnurl . "&tool_proxy_guid=$guid";
$ok = $this->doToolProxyService($_POST['tc_profile_url']); # TODO only do this right before registering.
echo $OUTPUT->render_from_template("enrol_lti/proxy_registration", array("returnurl" => $returnurl)); # TODO move out output
}
}

View File

@ -8,6 +8,7 @@ require_once($CFG->dirroot . '/enrol/lti/ims-blti/TrivialOAuthDataStore.php');
function is_basic_lti_request() {
$good_message_type = $_REQUEST["lti_message_type"] == "basic-lti-launch-request";
$good_lti_version = ($_REQUEST["lti_version"] == "LTI-1p0" or $_REQUEST["lti_version"] == "LTI-1.0");
$good_lti_version = $good_lti_version || ($_REQUEST["lti_version"] == "LTI-2p0" or $_REQUEST["lti_version"] == "LTI-2.0");
$resource_link_id = $_REQUEST["resource_link_id"];
if ($good_message_type and $good_lti_version and isset($resource_link_id) ) return(true);
return false;

View File

@ -24,6 +24,7 @@
$string['allowframeembedding'] = 'Note: It is recommended that the site administration setting \'Allow frame embedding\' is enabled, so that tools are displayed within a frame rather than in a new window.';
$string['authltimustbeenabled'] = 'Note: This plugin requires the LTI authentication plugin to be enabled too.';
$string['cartridgeurl'] = 'Cartridge URL';
$string['enrolenddate'] = 'End date';
$string['enrolenddate_help'] = 'If enabled, users can access until this date only.';
$string['enrolenddateerror'] = 'Enrolment end date cannot be earlier than start date';
@ -54,6 +55,8 @@ $string['lti:unenrol'] = 'Unenrol users from the course';
$string['opentool'] = 'Open tool';
$string['pluginname'] = 'Publish as LTI tool';
$string['pluginname_desc'] = 'The \'Publish as LTI tool\' plugin, together with the LTI authentication plugin, allows remote users to access selected courses and activities. In other words, Moodle functions as an LTI tool provider.';
$string['proxyurl'] = 'Proxy URL';
$string['registration'] = 'Published tool registration';
$string['remotesystem'] = 'Remote system';
$string['requirecompletion'] = 'Require course or activity completion prior to grade synchronisation';
$string['roleinstructor'] = 'Role for teacher';

60
enrol/lti/proxy.php Normal file
View File

@ -0,0 +1,60 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Tool proxy.
*
* @package enrol_lti
* @copyright 2016 John Okely <john@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . '/../../config.php');
$toolid = null;
$token = null;
$filearguments = get_file_argument();
$arguments = explode('/', trim($filearguments, '/'));
if (count($arguments) == 2) {
list($toolid, $token) = $arguments;
}
$toolid = optional_param('id', $toolid, PARAM_INT);
$token = optional_param('token', $token, PARAM_BASE64);
$messagetype = optional_param('lti_message_type', '', PARAM_TEXT);
$userid = optional_param('user_id', null, PARAM_INT);
$roles = optional_param('roles', null, PARAM_TEXT);
$tcprofileurl = optional_param('tc_profile_url', '', PARAM_URL);
$regkey = optional_param('reg_key', '', PARAM_URL);
$regpassword = optional_param('reg_password', '', PARAM_URL);
$launchpresentationreturnurl = optional_param('launch_presentation_return_url', '', PARAM_URL);
$PAGE->set_context(context_system::instance());
$url = new moodle_url('/enrol/lti/tp.php');
$PAGE->set_url($url);
$PAGE->set_pagelayout('popup');
$PAGE->set_title(get_string('registration', 'enrol_lti'));
// Only show the cartridge if the token parameter is correct.
// If we do not compare with a shared secret, someone could very easily
// guess an id for the enrolment.
\enrol_lti\helper::verify_tool_token($toolid, $token);
$toolprovider = new \enrol_lti\tool_provider($toolid);
$toolprovider->handleRequest();
echo $OUTPUT->header();
echo $OUTPUT->footer();

View File

@ -1,4 +1,3 @@
.copy_box {
width: 100%;
max-width: 350px;
max-width: 15vw;
}

View File

@ -0,0 +1,34 @@
{{!
This file is part of Moodle - http://moodle.org/
Moodle is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Moodle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@template enrol_lti/proxy_registration
The content to display when editing a tool.
Classes required for JS:
* none
Data attributes required for JS:
* none
Context variables required for this template:
* returnurl The url to return the page to.
Example context (json):
{}
}}
Would you like to register this tool? <a href="{{{returnurl}}}">Register</a> <!-- TODO language strings -->

View File

@ -24,6 +24,6 @@
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2016052301; // The current plugin version (Date: YYYYMMDDXX).
$plugin->version = 2016052302; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2016051900; // Requires this Moodle version (3.1)
$plugin->component = 'enrol_lti'; // Full name of the plugin (used for diagnostics).