示例#1
0
 /**
  * Execute the request for this resource.
  *
  * @param mod_lti\local\ltiservice\response $response  Response object for this request.
  */
 public function execute($response)
 {
     global $CFG, $DB;
     $params = $this->parse_template();
     $role = optional_param('role', '', PARAM_TEXT);
     $limitnum = optional_param('limit', 0, PARAM_INT);
     $limitfrom = optional_param('from', 0, PARAM_INT);
     if ($limitnum <= 0) {
         $limitfrom = 0;
     }
     try {
         if (!$this->get_service()->check_tool_proxy($params['product_code'])) {
             throw new \Exception(null, 401);
         }
         if (!($course = $DB->get_record('course', array('id' => $params['context_id']), 'id', IGNORE_MISSING))) {
             throw new \Exception(null, 404);
         }
         if (!($context = \context_course::instance($course->id))) {
             throw new \Exception(null, 404);
         }
         if (!($tool = $DB->get_record('lti_types', array('id' => $params['tool_code']), 'toolproxyid,enabledcapability,parameter', IGNORE_MISSING))) {
             throw new \Exception(null, 404);
         }
         $toolproxy = $DB->get_record('lti_tool_proxies', array('id' => $tool->toolproxyid), 'guid', IGNORE_MISSING);
         if (!$toolproxy || $toolproxy->guid !== $this->get_service()->get_tool_proxy()->guid) {
             throw new \Exception(null, 400);
         }
         $json = memberships::get_users_json($this, $context, $course->id, $tool, $role, $limitfrom, $limitnum, null, null);
         $response->set_content_type($this->formats[0]);
         $response->set_body($json);
     } catch (\Exception $e) {
         $response->set_code($e->getCode());
     }
 }
示例#2
0
 /**
  * Execute the request for this resource.
  *
  * @param mod_lti\local\ltiservice\response $response  Response object for this request.
  */
 public function execute($response)
 {
     global $CFG, $DB;
     $params = $this->parse_template();
     $linkid = $params['link_id'];
     $role = optional_param('role', '', PARAM_TEXT);
     $limitnum = optional_param('limit', 0, PARAM_INT);
     $limitfrom = optional_param('from', 0, PARAM_INT);
     if ($limitnum <= 0) {
         $limitfrom = 0;
     }
     try {
         if (empty($linkid)) {
             throw new \Exception(null, 404);
         }
         if (!($lti = $DB->get_record('lti', array('id' => $linkid), 'id,course,typeid,servicesalt', IGNORE_MISSING))) {
             throw new \Exception(null, 404);
         }
         $tool = $DB->get_record('lti_types', array('id' => $lti->typeid));
         $toolproxy = $DB->get_record('lti_tool_proxies', array('id' => $tool->toolproxyid));
         if (!$this->check_tool_proxy($toolproxy->guid, $response->get_request_data())) {
             throw new \Exception(null, 401);
         }
         if (!($course = $DB->get_record('course', array('id' => $lti->course), 'id', IGNORE_MISSING))) {
             throw new \Exception(null, 404);
         }
         if (!($context = \context_course::instance($lti->course))) {
             throw new \Exception(null, 404);
         }
         $modinfo = get_fast_modinfo($course);
         $cm = get_coursemodule_from_instance('lti', $linkid, $lti->course, false, MUST_EXIST);
         $cm = $modinfo->get_cm($cm->id);
         $info = new info_module($cm);
         if ($info->is_available_for_all()) {
             $info = null;
         }
         $json = memberships::get_users_json($this, $context, $lti->course, $tool, $role, $limitfrom, $limitnum, $lti, $info);
         $response->set_content_type($this->formats[0]);
         $response->set_body($json);
     } catch (\Exception $e) {
         $response->set_code($e->getCode());
     }
 }
示例#3
0
 /**
  * Execute the request for this resource.
  *
  * @param mod_lti\local\ltiservice\response $response  Response object for this request.
  */
 public function execute($response)
 {
     $params = $this->parse_template();
     $contexttype = $params['context_type'];
     $contextid = $params['context_id'];
     $vendorcode = $params['vendor_code'];
     $productcode = $params['product_code'];
     $bubble = optional_param('bubble', '', PARAM_ALPHA);
     $ok = !empty($contexttype) && !empty($contextid) && !empty($vendorcode) && !empty($productcode) && $this->check_tool_proxy($productcode, $response->get_request_data());
     if (!$ok) {
         $response->set_code(401);
     }
     $contenttype = $response->get_accept();
     $simpleformat = !empty($contenttype) && $contenttype == $this->formats[1];
     if ($ok) {
         $ok = (empty($bubble) || ($bubble == 'distinct' || $bubble == 'all')) && (!$simpleformat || empty($bubble) || $bubble != 'all') && (empty($bubble) || $response->get_request_method() == 'GET');
     }
     if (!$ok) {
         $response->set_code(404);
     } else {
         $systemsetting = null;
         $contextsettings = lti_get_tool_settings($this->get_service()->get_tool_proxy()->id, $contextid);
         if (!empty($bubble)) {
             $systemsetting = new systemsettings($this->get_service());
             $systemsetting->params['tool_proxy_id'] = $productcode;
             $systemsettings = lti_get_tool_settings($this->get_service()->get_tool_proxy()->id);
             if ($bubble == 'distinct') {
                 toolsettings::distinct_settings($systemsettings, $contextsettings, null);
             }
         } else {
             $systemsettings = null;
         }
         if ($response->get_request_method() == 'GET') {
             $json = '';
             if ($simpleformat) {
                 $response->set_content_type($this->formats[1]);
                 $json .= "{";
             } else {
                 $response->set_content_type($this->formats[0]);
                 $json .= "{\n  \"@context\":\"http://purl.imsglobal.org/ctx/lti/v2/ToolSettings\",\n  \"@graph\":[\n";
             }
             $settings = toolsettings::settings_to_json($systemsettings, $simpleformat, 'ToolProxy', $systemsetting);
             $json .= $settings;
             $isfirst = strlen($settings) <= 0;
             $settings = toolsettings::settings_to_json($contextsettings, $simpleformat, 'ToolProxyBinding', $this);
             if (strlen($settings) > 0 && !$isfirst) {
                 $json .= ",";
             }
             $json .= $settings;
             if ($simpleformat) {
                 $json .= "\n}";
             } else {
                 $json .= "\n  ]\n}";
             }
             $response->set_body($json);
         } else {
             // PUT.
             $settings = null;
             if ($response->get_content_type() == $this->formats[0]) {
                 $json = json_decode($response->get_request_data());
                 $ok = !empty($json);
                 if ($ok) {
                     $ok = isset($json->{"@graph"}) && is_array($json->{"@graph"}) && count($json->{"@graph"}) == 1 && $json->{"@graph"}[0]->{"@type"} == 'ToolProxyBinding';
                 }
                 if ($ok) {
                     $settings = $json->{"@graph"}[0]->custom;
                 }
             } else {
                 // Simple JSON.
                 $json = json_decode($response->get_request_data(), true);
                 $ok = !empty($json);
                 if ($ok) {
                     $ok = is_array($json);
                 }
                 if ($ok) {
                     $settings = $json;
                 }
             }
             if ($ok) {
                 lti_set_tool_settings($settings, $this->get_service()->get_tool_proxy()->id, $contextid);
             } else {
                 $response->set_code(406);
             }
         }
     }
 }
示例#4
0
 /**
  * Execute the request for this resource.
  *
  * @param mod_lti\local\ltiservice\response $response  Response object for this request.
  */
 public function execute($response)
 {
     global $DB, $COURSE;
     $params = $this->parse_template();
     $linkid = $params['link_id'];
     $bubble = optional_param('bubble', '', PARAM_ALPHA);
     $contenttype = $response->get_accept();
     $simpleformat = !empty($contenttype) && $contenttype == $this->formats[1];
     $ok = (empty($bubble) || ($bubble == 'distinct' || $bubble == 'all')) && (!$simpleformat || empty($bubble) || $bubble != 'all') && (empty($bubble) || $response->get_request_method() == 'GET');
     if (!$ok) {
         $response->set_code(406);
     }
     $systemsetting = null;
     $contextsetting = null;
     if ($ok) {
         $ok = !empty($linkid);
         if ($ok) {
             $lti = $DB->get_record('lti', array('id' => $linkid), 'course,typeid', MUST_EXIST);
             $ltitype = $DB->get_record('lti_types', array('id' => $lti->typeid));
             $toolproxy = $DB->get_record('lti_tool_proxies', array('id' => $ltitype->toolproxyid));
             $ok = $this->check_tool_proxy($toolproxy->guid, $response->get_request_data());
         }
         if (!$ok) {
             $response->set_code(401);
         }
     }
     if ($ok) {
         $linksettings = lti_get_tool_settings($this->get_service()->get_tool_proxy()->id, $lti->course, $linkid);
         if (!empty($bubble)) {
             $contextsetting = new contextsettings($this->get_service());
             if ($COURSE == 'site') {
                 $contextsetting->params['context_type'] = 'Group';
             } else {
                 $contextsetting->params['context_type'] = 'CourseSection';
             }
             $contextsetting->params['context_id'] = $lti->course;
             $contextsetting->params['vendor_code'] = $this->get_service()->get_tool_proxy()->vendorcode;
             $contextsetting->params['product_code'] = $this->get_service()->get_tool_proxy()->id;
             $contextsettings = lti_get_tool_settings($this->get_service()->get_tool_proxy()->id, $lti->course);
             $systemsetting = new systemsettings($this->get_service());
             $systemsetting->params['tool_proxy_id'] = $this->get_service()->get_tool_proxy()->id;
             $systemsettings = lti_get_tool_settings($this->get_service()->get_tool_proxy()->id);
             if ($bubble == 'distinct') {
                 toolsettings::distinct_settings($systemsettings, $contextsettings, $linksettings);
             }
         } else {
             $contextsettings = null;
             $systemsettings = null;
         }
         if ($response->get_request_method() == 'GET') {
             $json = '';
             if ($simpleformat) {
                 $response->set_content_type($this->formats[1]);
                 $json .= "{";
             } else {
                 $response->set_content_type($this->formats[0]);
                 $json .= "{\n  \"@context\":\"http://purl.imsglobal.org/ctx/lti/v2/ToolSettings\",\n  \"@graph\":[\n";
             }
             $settings = toolsettings::settings_to_json($systemsettings, $simpleformat, 'ToolProxy', $systemsetting);
             $json .= $settings;
             $isfirst = strlen($settings) <= 0;
             $settings = toolsettings::settings_to_json($contextsettings, $simpleformat, 'ToolProxyBinding', $contextsetting);
             if (strlen($settings) > 0) {
                 if (!$isfirst) {
                     $json .= ",";
                     if (!$simpleformat) {
                         $json .= "\n";
                     }
                 }
                 $isfirst = false;
             }
             $json .= $settings;
             $settings = toolsettings::settings_to_json($linksettings, $simpleformat, 'LtiLink', $this);
             if (strlen($settings) > 0 && !$isfirst) {
                 $json .= ",";
                 if (!$simpleformat) {
                     $json .= "\n";
                 }
             }
             $json .= $settings;
             if ($simpleformat) {
                 $json .= "\n}";
             } else {
                 $json .= "\n  ]\n}";
             }
             $response->set_body($json);
         } else {
             // PUT.
             $settings = null;
             if ($response->get_content_type() == $this->formats[0]) {
                 $json = json_decode($response->get_request_data());
                 $ok = !empty($json);
                 if ($ok) {
                     $ok = isset($json->{"@graph"}) && is_array($json->{"@graph"}) && count($json->{"@graph"}) == 1 && $json->{"@graph"}[0]->{"@type"} == 'LtiLink';
                 }
                 if ($ok) {
                     $settings = $json->{"@graph"}[0]->custom;
                 }
             } else {
                 // Simple JSON.
                 $json = json_decode($response->get_request_data(), true);
                 $ok = !empty($json);
                 if ($ok) {
                     $ok = is_array($json);
                 }
                 if ($ok) {
                     $settings = $json;
                 }
             }
             if ($ok) {
                 lti_set_tool_settings($settings, $this->get_service()->get_tool_proxy()->id, $lti->course, $linkid);
             } else {
                 $response->set_code(406);
             }
         }
     }
 }
示例#5
0
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
/**
 * This file contains a controller for receiving LTI service requests
 *
 * @package    mod_lti
 * @copyright  2014 Vital Source Technologies http://vitalsource.com
 * @author     Stephen Vickers
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
define('NO_DEBUG_DISPLAY', true);
define('NO_MOODLE_COOKIES', true);
require_once dirname(__FILE__) . '/../../config.php';
require_once $CFG->dirroot . '/mod/lti/locallib.php';
$response = new \mod_lti\local\ltiservice\response();
$isget = $response->get_request_method() == 'GET';
if ($isget) {
    $response->set_accept(isset($_SERVER['HTTP_ACCEPT']) ? $_SERVER['HTTP_ACCEPT'] : '');
} else {
    $response->set_content_type(isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : '');
}
$ok = false;
$path = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '';
$accept = $response->get_accept();
$services = lti_get_services();
foreach ($services as $service) {
    $resources = $service->get_resources();
    foreach ($resources as $resource) {
        if ($isget && !empty($accept) && strpos($accept, '*/*') === false && !in_array($accept, $resource->get_formats()) || !$isget && !in_array($response->get_content_type(), $resource->get_formats())) {
            continue;
示例#6
0
    /**
     * 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);
        }
    }
示例#7
0
    /**
     * Execute the request for this resource.
     *
     * @param mod_lti\local\ltiservice\response $response  Response object for this request.
     */
    public function execute($response)
    {
        global $CFG;
        $version = service_base::LTI_VERSION2P0;
        $params = $this->parse_template();
        $ok = $this->get_service()->check_tool_proxy($params['tool_proxy_id']);
        if (!$ok) {
            $response->set_code(404);
        } else {
            if (optional_param('lti_version', '', PARAM_ALPHANUMEXT) != $version) {
                $response->set_code(400);
            } else {
                $toolproxy = $this->get_service()->get_tool_proxy();
                $response->set_content_type($this->formats[0]);
                $servicepath = $this->get_service()->get_service_path();
                $id = $servicepath . $this->get_path();
                $now = date('Y-m-d\\TH:iO');
                $capabilityofferedarr = explode("\n", $toolproxy->capabilityoffered);
                $serviceofferedarr = explode("\n", $toolproxy->serviceoffered);
                $serviceoffered = '';
                $sep = '';
                $services = \core_component::get_plugin_list('ltiservice');
                foreach ($services as $name => $location) {
                    if (in_array($name, $serviceofferedarr)) {
                        $classname = "\\ltiservice_{$name}\\local\\service\\{$name}";
                        $service = new $classname();
                        $service->set_tool_proxy($toolproxy);
                        $resources = $service->get_resources();
                        foreach ($resources as $resource) {
                            $formats = implode("\", \"", $resource->get_formats());
                            $methods = implode("\", \"", $resource->get_methods());
                            $capabilityofferedarr = array_merge($capabilityofferedarr, $resource->get_variables());
                            $path = $servicepath . preg_replace('/\\{?.*\\}$/', '', $resource->get_path());
                            $serviceoffered .= <<<EOD
{$sep}
    {
      "@type":"{$resource->get_type()}",
      "@id":"tcp:{$resource->get_id()}",
      "endpoint":"{$path}",
      "format":["{$formats}"],
      "action":["{$methods}"]
    }
EOD;
                            $sep = ',';
                        }
                    }
                }
                $capabilityoffered = implode("\",\n    \"", $capabilityofferedarr);
                if (strlen($capabilityoffered) > 0) {
                    $capabilityoffered = "\n    \"{$capabilityoffered}\"";
                }
                $urlparts = parse_url($CFG->wwwroot);
                $orgid = $urlparts['host'];
                $name = 'Moodle';
                $code = 'moodle';
                $vendorname = 'Moodle.org';
                $vendorcode = 'mdl';
                $prodversion = strval($CFG->version);
                if (!empty($CFG->mod_lti_institution_name)) {
                    $consumername = $CFG->mod_lti_institution_name;
                    $consumerdesc = '';
                } else {
                    $consumername = get_site()->fullname;
                    $consumerdesc = strip_tags(get_site()->summary);
                }
                $profile = <<<EOD
{
  "@context":[
    "http://purl.imsglobal.org/ctx/lti/v2/ToolConsumerProfile",
    {
      "tcp":"{$id}#"
    }
  ],
  "@type":"ToolConsumerProfile",
  "@id":"{$id}",
  "lti_version":"{$version}",
  "guid":"{$toolproxy->guid}",
  "product_instance":{
    "guid":"{$orgid}",
    "product_info":{
      "product_name":{
        "default_value":"{$name}",
        "key":"product.name"
      },
      "product_version":"{$prodversion}",
      "product_family":{
        "code":"{$code}",
        "vendor":{
          "code":"{$vendorcode}",
          "vendor_name":{
            "default_value":"{$vendorname}",
            "key":"product.vendor.name"
          },
          "timestamp":"{$now}"
        }
      }
    },
    "service_owner":{
      "@id":"ServiceOwner",
      "service_owner_name":{
        "default_value":"{$consumername}",
        "key":"service_owner.name"
      },
      "description":{
        "default_value":"{$consumerdesc}",
        "key":"service_owner.description"
      }
    }
  },
  "capability_offered":[{$capabilityoffered}
  ],
  "service_offered":[{$serviceoffered}
  ]
}
EOD;
                $response->set_body($profile);
            }
        }
    }