Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.

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