MDL-63742 auth: New WS core_auth_resend_confirmation_email
authorJuan Leyva <juanleyvadelgado@gmail.com>
Tue, 23 Oct 2018 14:09:47 +0000 (16:09 +0200)
committerJuan Leyva <juanleyvadelgado@gmail.com>
Mon, 29 Oct 2018 10:04:02 +0000 (11:04 +0100)
auth/classes/external.php
auth/tests/external_test.php
lib/db/services.php
version.php

index 7c08349..2cb651d 100644 (file)
@@ -336,4 +336,95 @@ class core_auth_external extends external_api {
             )
         );
     }
+
+    /**
+     * Describes the parameters for resend_confirmation_email.
+     *
+     * @return external_function_parameters
+     * @since Moodle 3.6
+     */
+    public static function resend_confirmation_email_parameters() {
+        return new external_function_parameters(
+            array(
+                'username' => new external_value(core_user::get_property_type('username'), 'Username.'),
+                'password' => new external_value(core_user::get_property_type('password'), 'Plain text password.'),
+                'redirect' => new external_value(PARAM_LOCALURL, 'Redirect the user to this site url after confirmation.',
+                    VALUE_DEFAULT, ''),
+            )
+        );
+    }
+
+    /**
+     * Requests resend the confirmation email.
+     *
+     * @param  string $username user name
+     * @param  string $password plain text password
+     * @param  string $redirect redirect the user to this site url after confirmation
+     * @return array warnings and success status
+     * @since Moodle 3.6
+     * @throws moodle_exception
+     */
+    public static function resend_confirmation_email($username, $password, $redirect = '') {
+        global $PAGE;
+
+        $warnings = array();
+        $params = self::validate_parameters(
+            self::resend_confirmation_email_parameters(),
+            array(
+                'username' => $username,
+                'password' => $password,
+                'redirect' => $redirect,
+            )
+        );
+
+        $context = context_system::instance();
+        $PAGE->set_context($context);   // Need by internal APIs.
+        $username = trim(core_text::strtolower($params['username']));
+        $password = $params['password'];
+
+        if (is_restored_user($username)) {
+            throw new moodle_exception('restoredaccountresetpassword', 'webservice');
+        }
+
+        $user = authenticate_user_login($username, $password);
+
+        if (empty($user)) {
+            throw new moodle_exception('invalidlogin');
+        }
+
+        if ($user->confirmed) {
+            throw new moodle_exception('alreadyconfirmed');
+        }
+
+        // Check if we should redirect the user once the user is confirmed.
+        $confirmationurl = null;
+        if (!empty($params['redirect'])) {
+            // Pass via moodle_url to fix thinks like admin links.
+            $redirect = new moodle_url($params['redirect']);
+
+            $confirmationurl = new moodle_url('/login/confirm.php', array('redirect' => $redirect->out()));
+        }
+        $status = send_confirmation_email($user, $confirmationurl);
+
+        return array(
+            'status' => $status,
+            'warnings' => $warnings,
+        );
+    }
+
+    /**
+     * Describes the resend_confirmation_email return value.
+     *
+     * @return external_single_structure
+     * @since Moodle 3.6
+     */
+    public static function resend_confirmation_email_returns() {
+
+        return new external_single_structure(
+            array(
+                'status' => new external_value(PARAM_BOOL, 'True if the confirmation email was sent, false otherwise.'),
+                'warnings'  => new external_warnings(),
+            )
+        );
+    }
 }
index 84ffa1f..237852c 100644 (file)
@@ -40,6 +40,9 @@ require_once($CFG->dirroot . '/webservice/tests/helpers.php');
  */
 class core_auth_external_testcase extends externallib_advanced_testcase {
 
+    /** @var string Original error log */
+    protected $oldlog;
+
     /**
      * Set up for every test
      */
@@ -48,6 +51,18 @@ class core_auth_external_testcase extends externallib_advanced_testcase {
 
         $this->resetAfterTest(true);
         $CFG->registerauth = 'email';
+
+        // Discard error logs.
+        $this->oldlog = ini_get('error_log');
+        ini_set('error_log', "$CFG->dataroot/testlog.log");
+    }
+
+    /**
+     * Tear down to restore old logging..
+     */
+    protected function tearDown() {
+        ini_set('error_log', $this->oldlog);
+        parent::tearDown();
     }
 
     /**
@@ -115,4 +130,105 @@ class core_auth_external_testcase extends externallib_advanced_testcase {
             core_auth_external::is_age_digital_consent_verification_enabled_returns(), $result);
         $this->assertTrue($result['status']);
     }
+
+    /**
+     * Test resend_confirmation_email.
+     */
+    public function test_resend_confirmation_email() {
+        global $DB;
+
+        $username = 'pepe';
+        $password = 'abcdefAª.ªª!!3';
+        $firstname = 'Pepe';
+        $lastname = 'Pérez';
+        $email = 'myemail@no.zbc';
+
+        // Create new user.
+        $result = auth_email_external::signup_user($username, $password, $firstname, $lastname, $email);
+        $result = external_api::clean_returnvalue(auth_email_external::signup_user_returns(), $result);
+        $this->assertTrue($result['success']);
+        $this->assertEmpty($result['warnings']);
+
+        $result = core_auth_external::resend_confirmation_email($username, $password);
+        $result = external_api::clean_returnvalue(core_auth_external::resend_confirmation_email_returns(), $result);
+        $this->assertTrue($result['status']);
+        $this->assertEmpty($result['warnings']);
+        $confirmed = $DB->get_field('user', 'confirmed', array('username' => $username));
+        $this->assertEquals(0, $confirmed);
+    }
+
+    /**
+     * Test resend_confirmation_email invalid username.
+     */
+    public function test_resend_confirmation_email_invalid_username() {
+
+        $username = 'pepe';
+        $password = 'abcdefAª.ªª!!3';
+        $firstname = 'Pepe';
+        $lastname = 'Pérez';
+        $email = 'myemail@no.zbc';
+
+        // Create new user.
+        $result = auth_email_external::signup_user($username, $password, $firstname, $lastname, $email);
+        $result = external_api::clean_returnvalue(auth_email_external::signup_user_returns(), $result);
+        $this->assertTrue($result['success']);
+        $this->assertEmpty($result['warnings']);
+
+        $_SERVER['HTTP_USER_AGENT'] = 'no browser'; // Hack around missing user agent in CLI scripts.
+        $this->expectException('moodle_exception');
+        $this->expectExceptionMessage('error/invalidlogin');
+        $result = core_auth_external::resend_confirmation_email('abc', $password);
+    }
+
+    /**
+     * Test resend_confirmation_email invalid password.
+     */
+    public function test_resend_confirmation_email_invalid_password() {
+
+        $username = 'pepe';
+        $password = 'abcdefAª.ªª!!3';
+        $firstname = 'Pepe';
+        $lastname = 'Pérez';
+        $email = 'myemail@no.zbc';
+
+        // Create new user.
+        $result = auth_email_external::signup_user($username, $password, $firstname, $lastname, $email);
+        $result = external_api::clean_returnvalue(auth_email_external::signup_user_returns(), $result);
+        $this->assertTrue($result['success']);
+        $this->assertEmpty($result['warnings']);
+
+        $_SERVER['HTTP_USER_AGENT'] = 'no browser'; // Hack around missing user agent in CLI scripts.
+        $this->expectException('moodle_exception');
+        $this->expectExceptionMessage('error/invalidlogin');
+        $result = core_auth_external::resend_confirmation_email($username, 'abc');
+    }
+
+    /**
+     * Test resend_confirmation_email already confirmed user.
+     */
+    public function test_resend_confirmation_email_already_confirmed_user() {
+        global $DB;
+
+        $username = 'pepe';
+        $password = 'abcdefAª.ªª!!3';
+        $firstname = 'Pepe';
+        $lastname = 'Pérez';
+        $email = 'myemail@no.zbc';
+
+        // Create new user.
+        $result = auth_email_external::signup_user($username, $password, $firstname, $lastname, $email);
+        $result = external_api::clean_returnvalue(auth_email_external::signup_user_returns(), $result);
+        $this->assertTrue($result['success']);
+        $this->assertEmpty($result['warnings']);
+        $secret = $DB->get_field('user', 'secret', array('username' => $username));
+
+        // Confirm the user.
+        $result = core_auth_external::confirm_user($username, $secret);
+        $result = external_api::clean_returnvalue(core_auth_external::confirm_user_returns(), $result);
+        $this->assertTrue($result['success']);
+
+        $this->expectException('moodle_exception');
+        $this->expectExceptionMessage('error/alreadyconfirmed');
+        core_auth_external::resend_confirmation_email($username, $password);
+    }
 }
index f9e1185..1c4a37f 100644 (file)
@@ -66,6 +66,14 @@ $functions = array(
         'ajax'          => true,
         'loginrequired' => false,
     ),
+    'core_auth_resend_confirmation_email' => array(
+        'classname'   => 'core_auth_external',
+        'methodname'  => 'resend_confirmation_email',
+        'description' => 'Resend confirmation email.',
+        'type'        => 'write',
+        'ajax'          => true,
+        'loginrequired' => false,
+    ),
     'core_badges_get_user_badges' => array(
         'classname'     => 'core_badges_external',
         'methodname'    => 'get_user_badges',
index 3b66a8e..46c8bda 100644 (file)
@@ -29,7 +29,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$version  = 2018102700.00;              // YYYYMMDD      = weekly release date of this DEV branch.
+$version  = 2018102700.01;              // YYYYMMDD      = weekly release date of this DEV branch.
                                         //         RR    = release increments - 00 in DEV branches.
                                         //           .XX = incremental changes.