[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/login/ -> token.php (source)

   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   * Return token
  19   * @package    moodlecore
  20   * @copyright  2011 Dongsheng Cai <dongsheng@moodle.com>
  21   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  22   */
  23  
  24  define('AJAX_SCRIPT', true);
  25  define('REQUIRE_CORRECT_ACCESS', true);
  26  define('NO_MOODLE_COOKIES', true);
  27  
  28  require_once(__DIR__ . '/../config.php');
  29  
  30  // Allow CORS requests.
  31  header('Access-Control-Allow-Origin: *');
  32  
  33  $username = required_param('username', PARAM_USERNAME);
  34  $password = required_param('password', PARAM_RAW);
  35  $serviceshortname  = required_param('service',  PARAM_ALPHANUMEXT);
  36  
  37  echo $OUTPUT->header();
  38  
  39  if (!$CFG->enablewebservices) {
  40      throw new moodle_exception('enablewsdescription', 'webservice');
  41  }
  42  $username = trim(core_text::strtolower($username));
  43  if (is_restored_user($username)) {
  44      throw new moodle_exception('restoredaccountresetpassword', 'webservice');
  45  }
  46  $user = authenticate_user_login($username, $password);
  47  if (!empty($user)) {
  48  
  49      //Non admin can not authenticate if maintenance mode
  50      $hassiteconfig = has_capability('moodle/site:config', context_system::instance(), $user);
  51      if (!empty($CFG->maintenance_enabled) and !$hassiteconfig) {
  52          throw new moodle_exception('sitemaintenance', 'admin');
  53      }
  54  
  55      if (isguestuser($user)) {
  56          throw new moodle_exception('noguest');
  57      }
  58      if (empty($user->confirmed)) {
  59          throw new moodle_exception('usernotconfirmed', 'moodle', '', $user->username);
  60      }
  61      // check credential expiry
  62      $userauth = get_auth_plugin($user->auth);
  63      if (!empty($userauth->config->expiration) and $userauth->config->expiration == 1) {
  64          $days2expire = $userauth->password_expire($user->username);
  65          if (intval($days2expire) < 0 ) {
  66              throw new moodle_exception('passwordisexpired', 'webservice');
  67          }
  68      }
  69  
  70      // Check whether the user should be changing password.
  71      if (get_user_preferences('auth_forcepasswordchange', false, $user)) {
  72          if ($userauth->can_change_password()) {
  73              throw new moodle_exception('forcepasswordchangenotice');
  74          } else {
  75              throw new moodle_exception('nopasswordchangeforced', 'auth');
  76          }
  77      }
  78  
  79      // let enrol plugins deal with new enrolments if necessary
  80      enrol_check_plugins($user);
  81  
  82      // setup user session to check capability
  83      \core\session\manager::set_user($user);
  84  
  85      //check if the service exists and is enabled
  86      $service = $DB->get_record('external_services', array('shortname' => $serviceshortname, 'enabled' => 1));
  87      if (empty($service)) {
  88          // will throw exception if no token found
  89          throw new moodle_exception('servicenotavailable', 'webservice');
  90      }
  91  
  92      //check if there is any required system capability
  93      if ($service->requiredcapability and !has_capability($service->requiredcapability, context_system::instance(), $user)) {
  94          throw new moodle_exception('missingrequiredcapability', 'webservice', '', $service->requiredcapability);
  95      }
  96  
  97      //specific checks related to user restricted service
  98      if ($service->restrictedusers) {
  99          $authoriseduser = $DB->get_record('external_services_users',
 100              array('externalserviceid' => $service->id, 'userid' => $user->id));
 101  
 102          if (empty($authoriseduser)) {
 103              throw new moodle_exception('usernotallowed', 'webservice', '', $serviceshortname);
 104          }
 105  
 106          if (!empty($authoriseduser->validuntil) and $authoriseduser->validuntil < time()) {
 107              throw new moodle_exception('invalidtimedtoken', 'webservice');
 108          }
 109  
 110          if (!empty($authoriseduser->iprestriction) and !address_in_subnet(getremoteaddr(), $authoriseduser->iprestriction)) {
 111              throw new moodle_exception('invalidiptoken', 'webservice');
 112          }
 113      }
 114  
 115      //Check if a token has already been created for this user and this service
 116      //Note: this could be an admin created or an user created token.
 117      //      It does not really matter we take the first one that is valid.
 118      $tokenssql = "SELECT t.id, t.sid, t.token, t.validuntil, t.iprestriction
 119                FROM {external_tokens} t
 120               WHERE t.userid = ? AND t.externalserviceid = ? AND t.tokentype = ?
 121            ORDER BY t.timecreated ASC";
 122      $tokens = $DB->get_records_sql($tokenssql, array($user->id, $service->id, EXTERNAL_TOKEN_PERMANENT));
 123  
 124      //A bit of sanity checks
 125      foreach ($tokens as $key=>$token) {
 126  
 127          /// Checks related to a specific token. (script execution continue)
 128          $unsettoken = false;
 129          //if sid is set then there must be a valid associated session no matter the token type
 130          if (!empty($token->sid)) {
 131              if (!\core\session\manager::session_exists($token->sid)){
 132                  //this token will never be valid anymore, delete it
 133                  $DB->delete_records('external_tokens', array('sid'=>$token->sid));
 134                  $unsettoken = true;
 135              }
 136          }
 137  
 138          //remove token if no valid anymore
 139          //Also delete this wrong token (similar logic to the web service servers
 140          //    /webservice/lib.php/webservice_server::authenticate_by_token())
 141          if (!empty($token->validuntil) and $token->validuntil < time()) {
 142              $DB->delete_records('external_tokens', array('token'=>$token->token, 'tokentype'=> EXTERNAL_TOKEN_PERMANENT));
 143              $unsettoken = true;
 144          }
 145  
 146          // remove token if its ip not in whitelist
 147          if (isset($token->iprestriction) and !address_in_subnet(getremoteaddr(), $token->iprestriction)) {
 148              $unsettoken = true;
 149          }
 150  
 151          if ($unsettoken) {
 152              unset($tokens[$key]);
 153          }
 154      }
 155  
 156      // if some valid tokens exist then use the most recent
 157      if (count($tokens) > 0) {
 158          $token = array_pop($tokens);
 159      } else {
 160          if ( ($serviceshortname == MOODLE_OFFICIAL_MOBILE_SERVICE and has_capability('moodle/webservice:createmobiletoken', context_system::instance()))
 161                  //Note: automatically token generation is not available to admin (they must create a token manually)
 162                  or (!is_siteadmin($user) && has_capability('moodle/webservice:createtoken', context_system::instance()))) {
 163              // if service doesn't exist, dml will throw exception
 164              $service_record = $DB->get_record('external_services', array('shortname'=>$serviceshortname, 'enabled'=>1), '*', MUST_EXIST);
 165  
 166              // Create a new token.
 167              $token = new stdClass;
 168              $token->token = md5(uniqid(rand(), 1));
 169              $token->userid = $user->id;
 170              $token->tokentype = EXTERNAL_TOKEN_PERMANENT;
 171              $token->contextid = context_system::instance()->id;
 172              $token->creatorid = $user->id;
 173              $token->timecreated = time();
 174              $token->externalserviceid = $service_record->id;
 175              // MDL-43119 Token valid for 3 months (12 weeks).
 176              $token->validuntil = $token->timecreated + 12 * WEEKSECS;
 177              $token->id = $DB->insert_record('external_tokens', $token);
 178  
 179              $params = array(
 180                  'objectid' => $token->id,
 181                  'relateduserid' => $user->id,
 182                  'other' => array(
 183                      'auto' => true
 184                  )
 185              );
 186              $event = \core\event\webservice_token_created::create($params);
 187              $event->add_record_snapshot('external_tokens', $token);
 188              $event->trigger();
 189          } else {
 190              throw new moodle_exception('cannotcreatetoken', 'webservice', '', $serviceshortname);
 191          }
 192      }
 193  
 194      // log token access
 195      $DB->set_field('external_tokens', 'lastaccess', time(), array('id'=>$token->id));
 196  
 197      $params = array(
 198          'objectid' => $token->id,
 199      );
 200      $event = \core\event\webservice_token_sent::create($params);
 201      $event->add_record_snapshot('external_tokens', $token);
 202      $event->trigger();
 203  
 204      $usertoken = new stdClass;
 205      $usertoken->token = $token->token;
 206      echo json_encode($usertoken);
 207  } else {
 208      throw new moodle_exception('invalidlogin');
 209  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1