MDL-44484 admin: Theme can be null and create user
authorMathew May <mathewm@hotmail.co.nz>
Mon, 8 Apr 2019 07:35:24 +0000 (15:35 +0800)
committerMathew May <mathewm@hotmail.co.nz>
Wed, 8 May 2019 02:44:30 +0000 (14:44 +1200)
admin/tool/uploaduser/classes/local/field_value_validators.php [new file with mode: 0644]
admin/tool/uploaduser/index.php
admin/tool/uploaduser/lang/en/tool_uploaduser.php
admin/tool/uploaduser/tests/behat/upload_users.feature
admin/tool/uploaduser/tests/field_value_validators_test.php [new file with mode: 0644]
lang/en/error.php
lib/tests/fixtures/upload_users_themes.csv [new file with mode: 0644]

diff --git a/admin/tool/uploaduser/classes/local/field_value_validators.php b/admin/tool/uploaduser/classes/local/field_value_validators.php
new file mode 100644 (file)
index 0000000..dd14677
--- /dev/null
@@ -0,0 +1,79 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * File containing the field_value_validators class.
+ *
+ * @package    tool_uploaduser
+ * @copyright  2019 Mathew May
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace tool_uploaduser\local;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Field validator class.
+ *
+ * @package    tool_uploaduser
+ * @copyright  2019 Mathew May
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class field_value_validators {
+
+    /**
+     * List of valid and compatible themes.
+     *
+     * @return array
+     */
+    protected static $themescache;
+
+    /**
+     * Validates the value provided for the theme field.
+     *
+     * @param string $value The value for the theme field.
+     * @return array Contains the validation status and message.
+     */
+    public static function validate_theme($value) {
+        global $CFG;
+
+        $status = 'normal';
+        $message = '';
+
+        // Validate if user themes are allowed.
+        if (!$CFG->allowuserthemes) {
+            $status = 'warning';
+            $message = get_string('userthemesnotallowed', 'tool_uploaduser');
+        } else {
+            // Cache list of themes if not yet set.
+            if (!isset(self::$themescache)) {
+                self::$themescache = get_list_of_themes();
+            }
+
+            // Check if we have a valid theme.
+            if (empty($value)) {
+                $status = 'warning';
+                $message = get_string('notheme', 'tool_uploaduser');
+            } else if (!isset(self::$themescache[$value])) {
+                $status = 'warning';
+                $message = get_string('invalidtheme', 'tool_uploaduser', s($value));
+            }
+        }
+
+        return [$status, $message];
+    }
+}
index 80336c4..2bc1206 100644 (file)
@@ -32,6 +32,8 @@ require_once($CFG->dirroot.'/group/lib.php');
 require_once($CFG->dirroot.'/cohort/lib.php');
 require_once('locallib.php');
 require_once('user_form.php');
+require_once('classes/local/field_value_validators.php');
+use tool_uploaduser\local\field_value_validators;
 
 $iid         = optional_param('iid', '', PARAM_INT);
 $previewrows = optional_param('previewrows', 10, PARAM_INT);
@@ -71,8 +73,6 @@ $struserauthunsupported     = get_string('userauthunsupported', 'error');
 $stremailduplicate          = get_string('useremailduplicate', 'error');
 
 $strinvalidpasswordpolicy   = get_string('invalidpasswordpolicy', 'error');
-$strinvalidtheme            = get_string('invalidtheme', 'error');
-
 $errorstr                   = get_string('error');
 
 $stryes                     = get_string('yes');
@@ -104,7 +104,6 @@ $STD_FIELDS = array('id', 'username', 'email',
 $STD_FIELDS = array_merge($STD_FIELDS, get_all_user_name_fields());
 
 $PRF_FIELDS = array();
-
 if ($proffields = $DB->get_records('user_info_field')) {
     foreach ($proffields as $key => $proffield) {
         $profilefieldname = 'profile_field_'.$proffield->shortname;
@@ -211,8 +210,6 @@ if ($formdata = $mform2->is_cancelled()) {
     $cir->init();
     $linenum = 1; //column header is first line
 
-    $themes = get_list_of_themes();
-
     // init upload progress tracker
     $upt = new uu_progress_tracker();
     $upt->start(); // start table
@@ -360,21 +357,13 @@ if ($formdata = $mform2->is_cancelled()) {
             $upt->track('username', s($user->username), 'normal', false);
         }
 
-        // Validate theme.
-        if (!$CFG->allowuserthemes) {
-            $upt->track('status', get_string('invalidtheme', 'error', 'theme'), 'error');
-            $upt->track('theme', $errorstr, 'error');
-            $userserrors++;
-            continue;
-        }
-
+        // Verify if the theme is valid and allowed to be set.
         if (isset($user->theme)) {
-            if (!isset($themes[$user->theme])) {
-                $user->theme = '';
-                $upt->track('status', get_string('invalidfieldvalue', 'error', 'theme'), 'error');
-                $upt->track('theme', $errorstr, 'error');
-                $userserrors++;
-                continue;
+            list($status, $message) = field_value_validators::validate_theme($user->theme);
+            if ($status !== 'normal' && !empty($message)) {
+                $upt->track('status', $message, $status);
+                // Unset the theme when validation fails.
+                unset($user->theme);
             }
         }
 
@@ -659,6 +648,15 @@ if ($formdata = $mform2->is_cancelled()) {
                     }
                 }
             }
+            // Verify if the theme is valid and allowed to be set.
+            if (isset($existinguser->theme)) {
+                list($status, $message) = field_value_validators::validate_theme($existinguser->theme);
+                if ($status !== 'normal' && !empty($message)) {
+                     $upt->track('status', $message, $status);
+                    // Unset the theme when validation fails.
+                    unset($existinguser->theme);
+                }
+            }
 
             // changing of passwords is a special case
             // do not force password changes for external auth plugins!
@@ -1234,6 +1232,14 @@ while ($linenum <= $previewrows and $fields = $cir->next()) {
     if (isset($rowcols['city'])) {
         $rowcols['city'] = $rowcols['city'];
     }
+
+    if (isset($rowcols['theme'])) {
+        list($status, $message) = field_value_validators::validate_theme($rowcols['theme']);
+        if ($status !== 'normal' && !empty($message)) {
+            $rowcols['status'][] = $message;
+        }
+    }
+
     // Check if rowcols have custom profile field with correct data and update error state.
     $noerror = uu_check_custom_profile_data($rowcols) && $noerror;
     $rowcols['status'] = implode('<br />', $rowcols['status']);
index 3823bec..e94ba5e 100644 (file)
@@ -35,12 +35,15 @@ $string['errormnetadd'] = 'Can not add remote users';
 $string['errors'] = 'Errors';
 $string['invalidupdatetype'] = 'This option cannot be selected with the chosen upload type.';
 $string['invaliduserdata'] = 'Invalid data detected for user {$a} and it has been automatically cleaned.';
+$string['invalidtheme'] = 'Theme "{$a}" is not installed and will be ignored.';
 $string['nochanges'] = 'No changes';
+$string['notheme'] = 'No theme is defined for this user.';
 $string['pluginname'] = 'User upload';
 $string['renameerrors'] = 'Rename errors';
 $string['requiredtemplate'] = 'Required. You may use template syntax here (%l = lastname, %f = firstname, %u = username). See help for details and examples.';
 $string['rowpreviewnum'] = 'Preview rows';
 $string['unassignedsysrole'] = 'Unassigned system role {$a}';
+$string['userthemesnotallowed'] = 'User themes are not enabled, so any included in the upload users file will be ignored.';
 $string['uploadpicture_baduserfield'] = 'The user attribute specified is not valid. Please, try again.';
 $string['uploadpicture_cannotmovezip'] = 'Cannot move zip file to temporary directory.';
 $string['uploadpicture_cannotprocessdir'] = 'Cannot process unzipped files.';
index e7d88a3..ffd9140 100644 (file)
@@ -84,3 +84,64 @@ Feature: Upload users
     And I should see "Super field"
     And I should see "The big guy"
     And I log out
+
+  @javascript
+  Scenario: Upload users setting their user theme
+    Given the following "courses" exist:
+      | fullname | shortname | category |
+      | Maths    | math102   | 0        |
+    # We need to do a bit of setup here.
+    And I change window size to "large"
+    And I log in as "admin"
+    And I navigate to "Security > Site security settings" in site administration
+    And I click on "Password policy" "checkbox"
+    And I click on "Save changes" "button"
+    And I navigate to "Appearance > Themes > Theme settings" in site administration
+    And I click on "Allow user themes" "checkbox"
+    And I click on "Save changes" "button"
+    # Upload the users.
+    And I navigate to "Users > Accounts > Upload users" in site administration
+    When I upload "lib/tests/fixtures/upload_users_themes.csv" file to "File" filemanager
+    And I press "Upload users"
+    Then I should see "Upload users preview"
+    And I should see "boost"
+    And I should see "classic"
+    And I should see "No theme is defined for this user."
+    And I should see "Theme \"somefaketheme\" is not installed and will be ignored."
+    And I press "Upload users"
+    And I should see "Users created: 4"
+    And I press "Continue"
+    And I log out
+    # Boost check.
+    And I log in as "jonest"
+    And I am on "Maths" course homepage
+    And "Turn editing on" "button" should not exist
+    And I log out
+    # Classic check.
+    And I log in as "reznor"
+    And I am on "Maths" course homepage
+    And "Turn editing on" "button" should exist
+
+  @javascript
+  Scenario: Upload users setting their user theme when allowuserthemes is false
+    Given the following "courses" exist:
+      | fullname | shortname | category |
+      | Maths    | math102   | 0        |
+    # We need to do a bit of setup here.
+    And I change window size to "large"
+    And I log in as "admin"
+    And I navigate to "Security > Site security settings" in site administration
+    And I click on "Password policy" "checkbox"
+    And I click on "Save changes" "button"
+    # Upload the users.
+    And I navigate to "Users > Accounts > Upload users" in site administration
+    When I upload "lib/tests/fixtures/upload_users_themes.csv" file to "File" filemanager
+    And I press "Upload users"
+    Then I should see "Upload users preview"
+    And I should see "boost"
+    And I should see "classic"
+    And I press "Upload users"
+    And I should see "User themes are not enabled, so any included in the upload users file will be ignored."
+    And I should see "Users created: 4"
+    And I press "Continue"
+    And I log out
diff --git a/admin/tool/uploaduser/tests/field_value_validators_test.php b/admin/tool/uploaduser/tests/field_value_validators_test.php
new file mode 100644 (file)
index 0000000..e74dbe2
--- /dev/null
@@ -0,0 +1,82 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Tests for field value validators of tool_uploaduser.
+ *
+ * @package    tool_uploaduser
+ * @copyright  2019 Jun Pataleta
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+use tool_uploaduser\local\field_value_validators;
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+
+/**
+ * Tests for field value validators of tool_uploaduser.
+ *
+ * @package    tool_uploaduser
+ * @copyright  2019 Jun Pataleta
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class field_value_validators_testcase extends advanced_testcase {
+
+    /**
+     * Data provider for \field_value_validators_testcase::test_validate_theme().
+     */
+    public function themes_provider() {
+        return [
+            'User themes disabled' => [
+                false, 'boost', 'warning', get_string('userthemesnotallowed', 'tool_uploaduser')
+            ],
+            'User themes enabled, empty theme' => [
+                true, '', 'warning', get_string('notheme', 'tool_uploaduser')
+            ],
+            'User themes enabled, invalid theme' => [
+                true, 'badtheme', 'warning', get_string('invalidtheme', 'tool_uploaduser', 'badtheme')
+            ],
+            'User themes enabled, valid theme' => [
+                true, 'boost', 'normal', ''
+            ],
+        ];
+    }
+
+    /**
+     * Unit test for \tool_uploaduser\local\field_value_validators::validate_theme()
+     *
+     * @dataProvider themes_provider
+     * @param boolean $userthemesallowed Whether to allow user themes.
+     * @param string $themename The theme name to be tested.
+     * @param string $expectedstatus The expected status.
+     * @param string $expectedmessage The expected validation message.
+     */
+    public function test_validate_theme($userthemesallowed, $themename, $expectedstatus, $expectedmessage) {
+        $this->resetAfterTest();
+
+        // Set value for $CFG->allowuserthemes.
+        set_config('allowuserthemes', $userthemesallowed);
+
+        // Validate the theme.
+        list($status, $message) = field_value_validators::validate_theme($themename);
+
+        // Check the status and validation message.
+        $this->assertEquals($expectedstatus, $status);
+        $this->assertEquals($expectedmessage, $message);
+    }
+}
index 1400732..ef172e2 100644 (file)
@@ -326,7 +326,6 @@ $string['invalidentry'] = 'This is not valid entry!';
 $string['invalidevent'] = 'Invalid event';
 $string['invalidfieldname'] = '"{$a}" is not a valid field name';
 $string['invalidfiletype'] = '"{$a}" is not a valid file type';
-$string['invalidfieldvalue'] = 'Field "{$a}" has an invalid value';
 $string['invalidformatpara'] = 'Incorrect format for choose parameter';
 $string['invalidformdata'] = 'Incorrect form data';
 $string['invalidfunction'] = 'Incorrect function';
@@ -360,7 +359,6 @@ $string['invalidsesskey'] = 'Your session has most likely timed out. Please log
 $string['invalidshortname'] = 'That\'s an invalid short course name';
 $string['invalidstatedetected'] = 'Something has gone wrong: {$a}. This should never normally happen.';
 $string['invalidsourcefield'] = 'Draft file\'s source field is invalid';
-$string['invalidtheme'] = 'Invalid theme column found. User themes are disabled.';
 $string['invalidurl'] = 'Invalid URL';
 $string['invaliduser'] = 'Invalid user';
 $string['invaliduserid'] = 'Invalid user id';
diff --git a/lib/tests/fixtures/upload_users_themes.csv b/lib/tests/fixtures/upload_users_themes.csv
new file mode 100644 (file)
index 0000000..c05f125
--- /dev/null
@@ -0,0 +1,5 @@
+username,password,firstname,lastname,email,course1,role1,theme
+jonest,jonest,Tom,Jones,jonest@example.com,math102,3,boost
+reznor,reznor,Trent,Reznor,reznor@example.com,math102,3,classic
+troy,troy,Troy,Barnes,troy@greendale.com,math102,3,
+donald,donald,Donald,Barnes,donald@greendale.com,math102,3,somefaketheme