Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 310 and 402] [Versions 310 and 403]

   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   * Auth external API
  19   *
  20   * @package    core_auth
  21   * @category   external
  22   * @copyright  2016 Juan Leyva <juan@moodle.com>
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   * @since      Moodle 3.2
  25   */
  26  
  27  defined('MOODLE_INTERNAL') || die;
  28  
  29  require_once($CFG->libdir . '/externallib.php');
  30  require_once($CFG->libdir . '/authlib.php');
  31  
  32  /**
  33   * Auth external functions
  34   *
  35   * @package    core_auth
  36   * @category   external
  37   * @copyright  2016 Juan Leyva <juan@moodle.com>
  38   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  39   * @since      Moodle 3.2
  40   */
  41  class core_auth_external extends external_api {
  42  
  43      /**
  44       * Describes the parameters for confirm_user.
  45       *
  46       * @return external_function_parameters
  47       * @since Moodle 3.2
  48       */
  49      public static function confirm_user_parameters() {
  50          return new external_function_parameters(
  51              array(
  52                  'username' => new external_value(core_user::get_property_type('username'), 'User name'),
  53                  'secret' => new external_value(core_user::get_property_type('secret'), 'Confirmation secret'),
  54              )
  55          );
  56      }
  57  
  58      /**
  59       * Confirm a user account.
  60       *
  61       * @param  string $username user name
  62       * @param  string $secret   confirmation secret (random string) used for validating the confirm request
  63       * @return array warnings and success status (true if the user was confirmed, false if he was already confirmed)
  64       * @since Moodle 3.2
  65       * @throws moodle_exception
  66       */
  67      public static function confirm_user($username, $secret) {
  68          global $PAGE;
  69  
  70          $warnings = array();
  71          $params = self::validate_parameters(
  72              self::confirm_user_parameters(),
  73              array(
  74                  'username' => $username,
  75                  'secret' => $secret,
  76              )
  77          );
  78  
  79          $context = context_system::instance();
  80          $PAGE->set_context($context);
  81  
  82          if (!$authplugin = signup_get_user_confirmation_authplugin()) {
  83              throw new moodle_exception('confirmationnotenabled');
  84          }
  85  
  86          $confirmed = $authplugin->user_confirm($username, $secret);
  87  
  88          if ($confirmed == AUTH_CONFIRM_ALREADY) {
  89              $success = false;
  90              $warnings[] = array(
  91                  'item' => 'user',
  92                  'itemid' => 0,
  93                  'warningcode' => 'alreadyconfirmed',
  94                  'message' => s(get_string('alreadyconfirmed'))
  95              );
  96          } else if ($confirmed == AUTH_CONFIRM_OK) {
  97              $success = true;
  98          } else {
  99              throw new moodle_exception('invalidconfirmdata');
 100          }
 101  
 102          $result = array(
 103              'success' => $success,
 104              'warnings' => $warnings,
 105          );
 106          return $result;
 107      }
 108  
 109      /**
 110       * Describes the confirm_user return value.
 111       *
 112       * @return external_single_structure
 113       * @since Moodle 3.2
 114       */
 115      public static function confirm_user_returns() {
 116  
 117          return new external_single_structure(
 118              array(
 119                  'success' => new external_value(PARAM_BOOL, 'True if the user was confirmed, false if he was already confirmed'),
 120                  'warnings'  => new external_warnings(),
 121              )
 122          );
 123      }
 124  
 125      /**
 126       * Describes the parameters for request_password_reset.
 127       *
 128       * @return external_function_parameters
 129       * @since Moodle 3.4
 130       */
 131      public static function request_password_reset_parameters() {
 132          return new external_function_parameters(
 133              array(
 134                  'username' => new external_value(core_user::get_property_type('username'), 'User name', VALUE_DEFAULT, ''),
 135                  'email' => new external_value(core_user::get_property_type('email'), 'User email', VALUE_DEFAULT, ''),
 136              )
 137          );
 138      }
 139  
 140      /**
 141       * Requests a password reset.
 142       *
 143       * @param  string $username user name
 144       * @param  string $email    user email
 145       * @return array warnings and success status (including notices and errors while processing)
 146       * @since Moodle 3.4
 147       * @throws moodle_exception
 148       */
 149      public static function request_password_reset($username = '', $email = '') {
 150          global $CFG, $PAGE;
 151          require_once($CFG->dirroot . '/login/lib.php');
 152  
 153          $warnings = array();
 154          $params = self::validate_parameters(
 155              self::request_password_reset_parameters(),
 156              array(
 157                  'username' => $username,
 158                  'email' => $email,
 159              )
 160          );
 161  
 162          $context = context_system::instance();
 163          $PAGE->set_context($context);   // Needed by format_string calls.
 164  
 165          // Check if an alternate forgotten password method is set.
 166          if (!empty($CFG->forgottenpasswordurl)) {
 167              throw new moodle_exception('cannotmailconfirm');
 168          }
 169  
 170          $errors = core_login_validate_forgot_password_data($params);
 171          if (!empty($errors)) {
 172              $status = 'dataerror';
 173              $notice = '';
 174  
 175              foreach ($errors as $itemname => $message) {
 176                  $warnings[] = array(
 177                      'item' => $itemname,
 178                      'itemid' => 0,
 179                      'warningcode' => 'fielderror',
 180                      'message' => s($message)
 181                  );
 182              }
 183          } else {
 184              list($status, $notice, $url) = core_login_process_password_reset($params['username'], $params['email']);
 185          }
 186  
 187          return array(
 188              'status' => $status,
 189              'notice' => $notice,
 190              'warnings' => $warnings,
 191          );
 192      }
 193  
 194      /**
 195       * Describes the request_password_reset return value.
 196       *
 197       * @return external_single_structure
 198       * @since Moodle 3.4
 199       */
 200      public static function request_password_reset_returns() {
 201  
 202          return new external_single_structure(
 203              array(
 204                  'status' => new external_value(PARAM_ALPHANUMEXT, 'The returned status of the process:
 205                      dataerror: Error in the sent data (username or email). More information in warnings field.
 206                      emailpasswordconfirmmaybesent: Email sent or not (depends on user found in database).
 207                      emailpasswordconfirmnotsent: Failure, user not found.
 208                      emailpasswordconfirmnoemail: Failure, email not found.
 209                      emailalreadysent: Email already sent.
 210                      emailpasswordconfirmsent: User pending confirmation.
 211                      emailresetconfirmsent: Email sent.
 212                  '),
 213                  'notice' => new external_value(PARAM_RAW, 'Important information for the user about the process.'),
 214                  'warnings'  => new external_warnings(),
 215              )
 216          );
 217      }
 218  
 219      /**
 220       * Describes the parameters for the digital minor check.
 221       *
 222       * @return external_function_parameters
 223       * @since Moodle 3.4
 224       */
 225      public static function is_minor_parameters() {
 226          return new external_function_parameters(
 227              array(
 228                  'age' => new external_value(PARAM_INT, 'Age'),
 229                  'country' => new external_value(PARAM_ALPHA, 'Country of residence'),
 230              )
 231          );
 232      }
 233  
 234      /**
 235       * Requests a check if a user is digital minor.
 236       *
 237       * @param  int $age User age
 238       * @param  string $country Country of residence
 239       * @return array status (true if the user is a minor, false otherwise)
 240       * @since Moodle 3.4
 241       * @throws moodle_exception
 242       */
 243      public static function is_minor($age, $country) {
 244          global $CFG, $PAGE;
 245          require_once($CFG->dirroot . '/login/lib.php');
 246  
 247          $params = self::validate_parameters(
 248              self::is_minor_parameters(),
 249              array(
 250                  'age' => $age,
 251                  'country' => $country,
 252              )
 253          );
 254  
 255          if (!array_key_exists($params['country'], get_string_manager()->get_list_of_countries())) {
 256              throw new invalid_parameter_exception('Invalid value for country parameter (value: '.
 257                  $params['country'] .')');
 258          }
 259  
 260          $context = context_system::instance();
 261          $PAGE->set_context($context);
 262  
 263          // Check if verification of age and location (minor check) is enabled.
 264          if (!\core_auth\digital_consent::is_age_digital_consent_verification_enabled()) {
 265              throw new moodle_exception('nopermissions', 'error', '',
 266                  get_string('agelocationverificationdisabled', 'error'));
 267          }
 268  
 269          $status = \core_auth\digital_consent::is_minor($params['age'], $params['country']);
 270  
 271          return array(
 272              'status' => $status
 273          );
 274      }
 275  
 276      /**
 277       * Describes the is_minor return value.
 278       *
 279       * @return external_single_structure
 280       * @since Moodle 3.4
 281       */
 282      public static function is_minor_returns() {
 283          return new external_single_structure(
 284              array(
 285                  'status' => new external_value(PARAM_BOOL, 'True if the user is considered to be a digital minor,
 286                      false if not')
 287              )
 288          );
 289      }
 290  
 291      /**
 292       * Describes the parameters for is_age_digital_consent_verification_enabled.
 293       *
 294       * @return external_function_parameters
 295       * @since Moodle 3.3
 296       */
 297      public static function is_age_digital_consent_verification_enabled_parameters() {
 298          return new external_function_parameters(array());
 299      }
 300  
 301      /**
 302       * Checks if age digital consent verification is enabled.
 303       *
 304       * @return array status (true if digital consent verification is enabled, false otherwise.)
 305       * @since Moodle 3.3
 306       * @throws moodle_exception
 307       */
 308      public static function is_age_digital_consent_verification_enabled() {
 309          global $PAGE;
 310  
 311          $context = context_system::instance();
 312          $PAGE->set_context($context);
 313  
 314          $status = false;
 315          // Check if verification is enabled.
 316          if (\core_auth\digital_consent::is_age_digital_consent_verification_enabled()) {
 317              $status = true;
 318          }
 319  
 320          return array(
 321              'status' => $status
 322          );
 323      }
 324  
 325      /**
 326       * Describes the is_age_digital_consent_verification_enabled return value.
 327       *
 328       * @return external_single_structure
 329       * @since Moodle 3.3
 330       */
 331      public static function is_age_digital_consent_verification_enabled_returns() {
 332          return new external_single_structure(
 333              array(
 334                  'status' => new external_value(PARAM_BOOL, 'True if digital consent verification is enabled,
 335                      false otherwise.')
 336              )
 337          );
 338      }
 339  
 340      /**
 341       * Describes the parameters for resend_confirmation_email.
 342       *
 343       * @return external_function_parameters
 344       * @since Moodle 3.6
 345       */
 346      public static function resend_confirmation_email_parameters() {
 347          return new external_function_parameters(
 348              array(
 349                  'username' => new external_value(core_user::get_property_type('username'), 'Username.'),
 350                  'password' => new external_value(core_user::get_property_type('password'), 'Plain text password.'),
 351                  'redirect' => new external_value(PARAM_LOCALURL, 'Redirect the user to this site url after confirmation.',
 352                      VALUE_DEFAULT, ''),
 353              )
 354          );
 355      }
 356  
 357      /**
 358       * Requests resend the confirmation email.
 359       *
 360       * @param  string $username user name
 361       * @param  string $password plain text password
 362       * @param  string $redirect redirect the user to this site url after confirmation
 363       * @return array warnings and success status
 364       * @since Moodle 3.6
 365       * @throws moodle_exception
 366       */
 367      public static function resend_confirmation_email($username, $password, $redirect = '') {
 368          global $PAGE;
 369  
 370          $warnings = array();
 371          $params = self::validate_parameters(
 372              self::resend_confirmation_email_parameters(),
 373              array(
 374                  'username' => $username,
 375                  'password' => $password,
 376                  'redirect' => $redirect,
 377              )
 378          );
 379  
 380          $context = context_system::instance();
 381          $PAGE->set_context($context);   // Need by internal APIs.
 382          $username = trim(core_text::strtolower($params['username']));
 383          $password = $params['password'];
 384  
 385          if (is_restored_user($username)) {
 386              throw new moodle_exception('restoredaccountresetpassword', 'webservice');
 387          }
 388  
 389          $user = authenticate_user_login($username, $password);
 390  
 391          if (empty($user)) {
 392              throw new moodle_exception('invalidlogin');
 393          }
 394  
 395          if ($user->confirmed) {
 396              throw new moodle_exception('alreadyconfirmed');
 397          }
 398  
 399          // Check if we should redirect the user once the user is confirmed.
 400          $confirmationurl = null;
 401          if (!empty($params['redirect'])) {
 402              // Pass via moodle_url to fix thinks like admin links.
 403              $redirect = new moodle_url($params['redirect']);
 404  
 405              $confirmationurl = new moodle_url('/login/confirm.php', array('redirect' => $redirect->out()));
 406          }
 407          $status = send_confirmation_email($user, $confirmationurl);
 408  
 409          return array(
 410              'status' => $status,
 411              'warnings' => $warnings,
 412          );
 413      }
 414  
 415      /**
 416       * Describes the resend_confirmation_email return value.
 417       *
 418       * @return external_single_structure
 419       * @since Moodle 3.6
 420       */
 421      public static function resend_confirmation_email_returns() {
 422  
 423          return new external_single_structure(
 424              array(
 425                  'status' => new external_value(PARAM_BOOL, 'True if the confirmation email was sent, false otherwise.'),
 426                  'warnings'  => new external_warnings(),
 427              )
 428          );
 429      }
 430  }