Search moodle.org's
Developer Documentation

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.
  • /mod/lti/ -> auth.php (source)

    Differences Between: [Versions 310 and 311] [Versions 37 and 311] [Versions 38 and 311] [Versions 39 and 311]

       1  <?php
       2  // This file is part of Moodle - http://moodle.org/
       3  //
       4  // Moodle is free software: you can redistribute it and/or modify
       5  // it under the terms of the GNU General Public License as published by
       6  // the Free Software Foundation, either version 3 of the License, or
       7  // (at your option) any later version.
       8  //
       9  // Moodle is distributed in the hope that it will be useful,
      10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
      11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12  // GNU General Public License for more details.
      13  //
      14  // You should have received a copy of the GNU General Public License
      15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
      16  
      17  /**
      18   * This file responds to a login authentication request
      19   *
      20   * @package    mod_lti
      21   * @copyright  2019 Stephen Vickers
      22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
      23   */
      24  
      25  require_once(__DIR__ . '/../../config.php');
      26  require_once($CFG->dirroot . '/mod/lti/locallib.php');
      27  global $_POST, $_SERVER;
      28  
      29  if (!isloggedin() && empty($_POST['repost'])) {
      30      header_remove("Set-Cookie");
      31      $PAGE->set_pagelayout('popup');
      32      $PAGE->set_context(context_system::instance());
      33      $output = $PAGE->get_renderer('mod_lti');
      34      $page = new \mod_lti\output\repost_crosssite_page($_SERVER['REQUEST_URI'], $_POST);
      35      echo $output->header();
      36      echo $output->render($page);
      37      echo $output->footer();
      38      return;
      39  }
      40  
      41  $scope = optional_param('scope', '', PARAM_TEXT);
      42  $responsetype = optional_param('response_type', '', PARAM_TEXT);
      43  $clientid = optional_param('client_id', '', PARAM_TEXT);
      44  $redirecturi = optional_param('redirect_uri', '', PARAM_URL);
      45  $loginhint = optional_param('login_hint', '', PARAM_TEXT);
      46  $ltimessagehint = optional_param('lti_message_hint', 0, PARAM_INT);
      47  $state = optional_param('state', '', PARAM_TEXT);
      48  $responsemode = optional_param('response_mode', '', PARAM_TEXT);
      49  $nonce = optional_param('nonce', '', PARAM_TEXT);
      50  $prompt = optional_param('prompt', '', PARAM_TEXT);
      51  
      52  $ok = !empty($scope) && !empty($responsetype) && !empty($clientid) &&
      53        !empty($redirecturi) && !empty($loginhint) &&
      54        !empty($nonce) && !empty($SESSION->lti_message_hint);
      55  
      56  if (!$ok) {
      57      $error = 'invalid_request';
      58  }
      59  if ($ok && ($scope !== 'openid')) {
      60      $ok = false;
      61      $error = 'invalid_scope';
      62  }
      63  if ($ok && ($responsetype !== 'id_token')) {
      64      $ok = false;
      65      $error = 'unsupported_response_type';
      66  }
      67  if ($ok) {
      68      list($courseid, $typeid, $id, $titleb64, $textb64) = explode(',', $SESSION->lti_message_hint, 5);
      69      $ok = ($id !== $ltimessagehint);
      70      if (!$ok) {
      71          $error = 'invalid_request';
      72      } else {
      73          $config = lti_get_type_type_config($typeid);
      74          $ok = ($clientid === $config->lti_clientid);
      75          if (!$ok) {
      76              $error = 'unauthorized_client';
      77          }
      78      }
      79  }
      80  if ($ok && ($loginhint !== $USER->id)) {
      81      $ok = false;
      82      $error = 'access_denied';
      83  }
      84  
      85  // If we're unable to load up config; we cannot trust the redirect uri for POSTing to.
      86  if (empty($config)) {
      87      throw new moodle_exception('invalidrequest', 'error');
      88  } else {
      89      $uris = array_map("trim", explode("\n", $config->lti_redirectionuris));
      90      if (!in_array($redirecturi, $uris)) {
      91          throw new moodle_exception('invalidrequest', 'error');
      92      }
      93  }
      94  if ($ok) {
      95      if (isset($responsemode)) {
      96          $ok = ($responsemode === 'form_post');
      97          if (!$ok) {
      98              $error = 'invalid_request';
      99              $desc = 'Invalid response_mode';
     100          }
     101      } else {
     102          $ok = false;
     103          $error = 'invalid_request';
     104          $desc = 'Missing response_mode';
     105      }
     106  }
     107  if ($ok && !empty($prompt) && ($prompt !== 'none')) {
     108      $ok = false;
     109      $error = 'invalid_request';
     110      $desc = 'Invalid prompt';
     111  }
     112  
     113  if ($ok) {
     114      $course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
     115      if ($id) {
     116          $cm = get_coursemodule_from_id('lti', $id, 0, false, MUST_EXIST);
     117          $context = context_module::instance($cm->id);
     118          require_login($course, true, $cm);
     119          require_capability('mod/lti:view', $context);
     120          $lti = $DB->get_record('lti', array('id' => $cm->instance), '*', MUST_EXIST);
     121          $lti->cmid = $cm->id;
     122          list($endpoint, $params) = lti_get_launch_data($lti, $nonce);
     123      } else {
     124          require_login($course);
     125          $context = context_course::instance($courseid);
     126          require_capability('moodle/course:manageactivities', $context);
     127          require_capability('mod/lti:addcoursetool', $context);
     128          // Set the return URL. We send the launch container along to help us avoid frames-within-frames when the user returns.
     129          $returnurlparams = [
     130              'course' => $courseid,
     131              'id' => $typeid,
     132              'sesskey' => sesskey()
     133          ];
     134          $returnurl = new \moodle_url('/mod/lti/contentitem_return.php', $returnurlparams);
     135          // Prepare the request.
     136          $title = base64_decode($titleb64);
     137          $text = base64_decode($textb64);
     138          $request = lti_build_content_item_selection_request($typeid, $course, $returnurl, $title, $text,
     139                                                              [], [], false, true, false, false, false, $nonce);
     140          $endpoint = $request->url;
     141          $params = $request->params;
     142      }
     143  } else {
     144      $params['error'] = $error;
     145      if (!empty($desc)) {
     146          $params['error_description'] = $desc;
     147      }
     148  }
     149  if (isset($state)) {
     150      $params['state'] = $state;
     151  }
     152  unset($SESSION->lti_message_hint);
     153  $r = '<form action="' . $redirecturi . "\" name=\"ltiAuthForm\" id=\"ltiAuthForm\" " .
     154       "method=\"post\" enctype=\"application/x-www-form-urlencoded\">\n";
     155  if (!empty($params)) {
     156      foreach ($params as $key => $value) {
     157          $key = htmlspecialchars($key);
     158          $value = htmlspecialchars($value);
     159          $r .= "  <input type=\"hidden\" name=\"{$key}\" value=\"{$value}\"/>\n";
     160      }
     161  }
     162  $r .= "</form>\n";
     163  $r .= "<script type=\"text/javascript\">\n" .
     164      "//<![CDATA[\n" .
     165      "document.ltiAuthForm.submit();\n" .
     166      "//]]>\n" .
     167      "</script>\n";
     168  echo $r;