Uploaded image for project: 'Moodle'
  1. Moodle
  2. MDL-51969

LTI registration: Missing Tool Proxy GUID in 'tc_profile_url'

    XMLWordPrintable

Details

    • MOODLE_29_STABLE, MOODLE_31_STABLE, MOODLE_33_STABLE, MOODLE_34_STABLE, MOODLE_35_STABLE
    • MOODLE_34_STABLE, MOODLE_35_STABLE
    • MDL-51969-master
    • Hide

      Steps to reproduce

      1. Install Moodle behind nginx with configuration as described here. The problem depends on how the server handles the PATH_INFO environment variable, it might not occur in a different setting.
      2. Go to Site Administration -> Plugins -> Activity Modules -> LTI -> Manage external tool registrations.
      3. Configure a new external tool registration. Set the registration URL to 'http://lti.tools/test/tp.php'. It does not matter what you enter for the other parameters.
      4. Register the tool and inspect the 'tc_profile_url' parameter.

      Expected result

      The 'tc_profile_url' parameter should look something like this:

      tc_profile_url=http://example.com/moodle/mod/lti/services.php/profile/Acb6GQ5BGM5N0VM?lti_version=LTI-2p0
      

      Actual result

      The tool proxy GUID is missing in the 'tc_profile_url' parameter:

      tc_profile_url=http://example.com/moodle/mod/lti/services.php/profile/?lti_version=LTI-2p0
      

       

      Show
      Steps to reproduce Install Moodle behind nginx with configuration as described here . The problem depends on how the server handles the PATH_INFO environment variable, it might not occur in a different setting. Go to Site Administration -> Plugins -> Activity Modules -> LTI -> Manage external tool registrations. Configure a new external tool registration. Set the registration URL to 'http://lti.tools/test/tp.php'. It does not matter what you enter for the other parameters. Register the tool and inspect the 'tc_profile_url' parameter. Expected result The 'tc_profile_url' parameter should look something like this: tc_profile_url=http://example.com/moodle/mod/lti/services.php/profile/Acb6GQ5BGM5N0VM?lti_version=LTI-2p0 Actual result The tool proxy GUID is missing in the 'tc_profile_url' parameter: tc_profile_url=http://example.com/moodle/mod/lti/services.php/profile/?lti_version=LTI-2p0  

    Description

      Explanation

      The 'tc_profile_url' is determined by the get_endpoint() function in mod/lti/classes/local/ltiservice/service_base.php:

          public function get_endpoint() {
       
              $this->parse_template();
              $url = $this->get_service()->get_service_path() . $this->get_template();
              foreach ($this->params as $key => $value) {
                  $url = str_replace('{' . $key . '}', $value, $url);
              }
              $toolproxy = $this->get_service()->get_tool_proxy();
              if (!empty($toolproxy)) {
                  $url = str_replace('{tool_proxy_id}', $toolproxy->guid, $url);
              }
       
              return $url;
       
          }
      

      The function calls parse_template() which determines the '{tool_proxy_id}' parameter from the PATH_INFO environment variable. If not set the '{tool_proxy_id}' parameter is set to the guid of the tool proxy.

      Now look at the parse_template() function:

          protected function parse_template() {
       
              if (empty($this->params)) {
                  $this->params = array();
                  if (isset($_SERVER['PATH_INFO'])) {
                      $path = explode('/', $_SERVER['PATH_INFO']);
                      $parts = explode('/', $this->get_template());
                      for ($i = 0; $i < count($parts); $i++) {
                          if ((substr($parts[$i], 0, 1) == '{') && (substr($parts[$i], -1) == '}')) {
                              $value = '';
                              if ($i < count($path)) {
                                  $value = $path[$i];
                              }
                              $this->params[substr($parts[$i], 1, -1)] = $value;
                          }
                      }
                  }
              }
       
              return $this->params;
       
          }
      

      If the PATH_INFO variable is not set the function returns an empty array. But if the PATH_INFO variable is an empty string the function sets all parameters to an empty string. As a result the '{tool_proxy_id}' parameter is set to an empty string and won't be replaced with the tool proxy guid by get_endpoint() anymore.

      Workaround/ProposedFix

      Check in parse_template() if the PATH_INFO variable is empty:

      $ git diff
      diff --git a/mod/lti/classes/local/ltiservice/resource_base.php b/mod/lti/classes/local/ltiservice/resource_base.php
      index 4d617fe..60c7327 100644
      --- a/mod/lti/classes/local/ltiservice/resource_base.php
      +++ b/mod/lti/classes/local/ltiservice/resource_base.php
      @@ -255,7 +255,7 @@ abstract class resource_base {
       
               if (empty($this->params)) {
                   $this->params = array();
      -            if (isset($_SERVER['PATH_INFO'])) {
      +            if (isset($_SERVER['PATH_INFO']) && !empty($_SERVER['PATH_INFO'])) {
                       $path = explode('/', $_SERVER['PATH_INFO']);
                       $parts = explode('/', $this->get_template());
                       for ($i = 0; $i < count($parts); $i++) {
      

      Note that according to RFC 3875, section 4.1.5, an empty PATH_INFO variable is perfectly correct:

      PATH_INFO = "" | ( "/" path )

      Attachments

        Activity

          People

            dmitriim Dmitrii Metelkin
            mkemmerling Markus Kemmerling
            Mark Nelson Mark Nelson
            David Monllaó David Monllaó
            Peter Dias Peter Dias
            Adrian Greeve, Jake Dallimore, Mathew May, Mihail Geshoski, Sujith Haridasan
            Votes:
            3 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:
              12/Nov/18