]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-16658 restore - new restore:createuser cap + pre-check users before restoring...
authorEloy Lafuente <stronk7@moodle.org>
Wed, 30 Dec 2009 17:35:36 +0000 (17:35 +0000)
committerEloy Lafuente <stronk7@moodle.org>
Wed, 30 Dec 2009 17:35:36 +0000 (17:35 +0000)
backup/restorelib.php
config-dist.php
lang/en_utf8/moodle.php
lang/en_utf8/role.php
lib/db/access.php
version.php

index 7908e3422dc733ab9ae435e05684df49ebcb88d6..aac97521edcf6c1e3bd1b7c0a73c709e7ac61181 100644 (file)
@@ -742,7 +742,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
         }
 
         // Handle checks from same site backups
-        if (backup_is_same_site($restore)) {
+        if (backup_is_same_site($restore) && empty($CFG->forcedifferentsitecheckingusersonrestore)) {
 
             // 1A - If match by id and username and mnethost => ok, return target user
             if ($rec = $DB->get_record('user', array('id'=>$user->id, 'username'=>$user->username, 'mnethostid'=>$user->mnethostid))) {
@@ -950,7 +950,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
             $user = $rec->info;
 
             // Find the correct mnethostid for user before performing any further check
-            if (empty($user->mnethosturl) || $user->mnethosturl===$CFG->wwwroot) {
+            if (empty($user->mnethosturl) || $user->mnethosturl === $CFG->wwwroot) {
                 $user->mnethostid = $CFG->mnet_localhost_id;
             } else {
                 // fast url-to-id lookups
@@ -965,13 +965,18 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
             $usercheck = restore_check_user($restore, $user);
 
             if (is_object($usercheck)) { // No problem, we have found one user in DB to be mapped to
+                // Annotate it, for later process by restore_create_users(). Set new_id to mapping user->id
+                backup_putid($restore->backup_unique_code, 'user', $userid, $usercheck->id, $user);
 
             } else if ($usercheck === false) { // Found conflict, report it as problem
                 $problems[] = get_string('restoreuserconflict', '', $user->username);
                 $status = false;
 
             } else if ($usercheck === true) { // User needs to be created, check if we are able
-                if (!$cancreateuser) { // Cannot create, report as problem
+                if ($cancreateuser) { // Can create user, annotate it, for later process by restore_create_users(). Set new_id to 0
+                    backup_putid($restore->backup_unique_code, 'user', $userid, 0, $user);
+
+                } else { // Cannot create user, report it as problem
 
                     $problems[] = get_string('restorecannotcreateuser', '', $user->username);
                     $status = false;
@@ -2830,25 +2835,17 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
         $authcache = array(); // Cache to get some bits from authentication plugins
 
         $status = true;
-        //Check it exists
-        if (!file_exists($xml_file)) {
-            $status = false;
-        }
-        //Get info from xml
-        if ($status) {
-            //info will contain the old_id of every user
-            //in backup_ids->info will be the real info (serialized)
-            $info = restore_read_xml_users($restore,$xml_file);
-        }
 
-        //Now, get evey user_id from $info and user data from $backup_ids
-        //and create the necessary db structures
+        // Users have already been checked by restore_precheck_users() so they are loaded
+        // in backup_ids table. They don't need to be loaded (parsed) from XML again. Also, note
+        // the same function has performed the needed modifications in the $user->mnethostid field
+        // so we don't need to do it again here at all. Just some checks.
 
-        if (!empty($info->users)) {
+        // Get users ids from backup_ids table
+        $userids = $DB->get_fieldset_select('backup_ids', 'old_id', 'backup_code = ? AND table_name = ?', array($restore->backup_unique_code, 'user'));
 
-        /// Grab mnethosts keyed by wwwroot, to map to id
-            $mnethosts = $DB->get_records('mnet_host', null,
-                                     'wwwroot', 'wwwroot, id');
+        // Have users to process, proceed with them
+        if (!empty($userids)) {
 
         /// Get languages for quick search later
             $languages = get_list_of_languages();
@@ -2858,9 +2855,22 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
 
         /// Init trailing messages
             $messages = array();
-            foreach ($info->users as $userid) {
-                $rec = backup_getid($restore->backup_unique_code,"user",$userid);
-                $user = $rec->info;
+            foreach ($userids as $userid) {
+                // Defaults
+                $user_exists = false; // By default user does not exist
+                $newid = null;        // By default, there is not newid
+
+                // Get record from backup_ids
+                $useridsdbrec = backup_getid($restore->backup_unique_code, 'user', $userid);
+
+                // Based in restore_precheck_users() calculations, if the user exists
+                // new_id must contain the id of the matching user
+                if (!empty($useridsdbrec->new_id)) {
+                    $user_exists = true;
+                    $newid = $useridsdbrec->new_id;
+                }
+
+                $user = $useridsdbrec->info;
                 foreach (array_keys(get_object_vars($user)) as $field) {
                     if (!is_array($user->$field)) {
                         $user->$field = backup_todb($user->$field);
@@ -2908,31 +2918,12 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
                 //Has role teacher or student or needed
                 $is_course_user = ($is_teacher or $is_student or $is_needed);
 
-                // in case we are restoring to same server, look for user by id and username
-                // it should return record always, but in sites rebuilt from scratch
-                // and being reconstructed using course backups
-                $user_data = false;
-                if (backup_is_same_site($restore)) {
-                    $user_data = $DB->get_record('user', array('id'=>$user->id, 'username'=>$user->username));
-                }
-
                 // Only try to perform mnethost/auth modifications if restoring to another server
                 // or if, while restoring to same server, the user doesn't exists yet (rebuilt site)
                 //
                 // So existing user data in same server *won't be modified by restore anymore*,
                 // under any circumpstance. If somehting is wrong with existing data, it's server fault.
-                if (!backup_is_same_site($restore) || (backup_is_same_site($restore) && !$user_data)) {
-                    //Calculate mnethostid
-                    if (empty($user->mnethosturl) || $user->mnethosturl===$CFG->wwwroot) {
-                        $user->mnethostid = $CFG->mnet_localhost_id;
-                    } else {
-                        // fast url-to-id lookups
-                        if (isset($mnethosts[$user->mnethosturl])) {
-                            $user->mnethostid = $mnethosts[$user->mnethosturl]->id;
-                        } else {
-                            $user->mnethostid = $CFG->mnet_localhost_id;
-                        }
-                    }
+                if (!backup_is_same_site($restore) || (backup_is_same_site($restore) && !$user_exists)) {
                     //Arriving here, any user with mnet auth and using $CFG->mnet_localhost_id is wrong
                     //as own server cannot be accesed over mnet. Change auth to manual and inform about the switch
                     if ($user->auth == 'mnet' && $user->mnethostid == $CFG->mnet_localhost_id) {
@@ -2951,21 +2942,6 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
                 }
                 unset($user->mnethosturl);
 
-                //To store user->id along all the iteration
-                $newid=null;
-                //check if it exists (by username) and get its id
-                $user_exists = true;
-                if (!backup_is_same_site($restore) || !$user_data) { /// Restoring to another server, or rebuilding site (failed id&
-                                                                     /// login search above), look for existing user based on fields
-                    $user_data = $DB->get_record('user', array('username'=>$user->username, 'mnethostid'=>$user->mnethostid));
-                }
-
-                if (!$user_data) {
-                    $user_exists = false;
-                } else {
-                    $newid = $user_data->id;
-                }
-
                 //Flags to see what parts are we going to restore
                 $create_user = true;
                 $create_roles = true;
@@ -3245,7 +3221,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
                     }
                     backup_flush(300);
                 }
-            } /// End of loop over all the users loaded from xml
+            } /// End of loop over all the users loaded from backup_ids table
 
         /// Inform about all the messages geerated while restoring users
             if (!defined('RESTORE_SILENTLY')) {
@@ -8487,7 +8463,6 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
 
         // Precheck the users section, detecting various situations that can lead to problems, so
         // we stop restore before performing any further action
-        /*
         if (!defined('RESTORE_SILENTLY')) {
             echo '<li>'.get_string('restoreusersprecheck').'</li>';
         }
@@ -8501,7 +8476,6 @@ define('RESTORE_GROUPS_GROUPINGS', 3);
             }
             return false;
         }
-        */
 
         //If we've selected to restore into new course
         //create it (course)
index 94d8ab0310bf1113797b1440ccb305b36916088f..5ad939e961ef8d2ba66624d572f84501de09f3dd 100644 (file)
@@ -180,6 +180,21 @@ $CFG->admin = 'admin';
 // shared out from your site/institution!
 //      $CFG->includeuserpasswordsinbackup = true;
 //
+// Completely disable user creation on restore, bypassing any right granted
+// via roles/capabilities. By enabling this setting any restore process
+// requiring users to be created will be stopped before any further action.
+//     $CFG->disableusercreationonrestore = true;
+//
+// Modify the restore process in order to force the "user checks" to assume
+// that the backup was originated in a different site so detection of matching
+// users is performed with some different (more "relaxed") rules. *Only* useful
+// if the backup file has been generated with Moodle < 1.9.4 and the site has
+// been rebuilt from scratch using backup files (not the best way, btw). If you
+// are getting user conflicts on restore, try to restore the backup to a different
+// site, backup it again and then restore on target server instead of enabling this
+// setting permanently!
+//    $CFG->forcedifferentsitecheckingusersonrestore = true;
+//
 // Prevent stats processing and hide the GUI
 //      $CFG->disablestatsprocessing = true;
 //
index 638ff34da39e12e0130302b6d9bdd6242c94af6e..7e4a3a14daad94f92aa81f27cb8e5b45d3b8852b 100644 (file)
@@ -1369,6 +1369,7 @@ $string['resource'] = 'Resource';
 $string['resources'] = 'Resources';
 $string['restore'] = 'Restore';
 $string['restorecancelled'] = 'Restore canceled';
+$string['restorecannotcreateuser'] = 'restore needs to create user \'$a\' from backup file and you are not allowed to do that';
 $string['restorecoursenow'] = 'Restore this course now!';
 $string['restoredaccount'] = 'Restored account';
 $string['restoredaccountinfo'] = 'This account was imported from another server and the password has been lost. To set a new password by email, please click \"Continue\"';
@@ -1376,7 +1377,10 @@ $string['restorefinished'] = 'Restore completed successfully';
 $string['restoreto'] = 'Restore to';
 $string['restoretositeadding'] = 'Warning: You are about to restore to the site front page, adding data to it!';
 $string['restoretositedeleting'] = 'Warning: You are about to restore to the site front page, deleting data from it first!';
+$string['restoreuserconflict'] = 'trying to restore user \'$a\' from backup file will cause conflict';
 $string['restoreuserinfofailed'] = 'The restore process has stopped because you don\'t have permission to restore user data.';
+$string['restoreusersprecheck'] = 'Checking user information';
+$string['restoreusersprecheckerror'] = 'Some problems were detected checking user information';
 $string['restricted'] = 'Restricted';
 $string['restrictmodules'] = 'Restrict activity modules?';
 $string['returntooriginaluser'] = 'Return to $a';
index 094f02c7fb496184370b71aab22cc3c0f9373a2c..7a6b3ebe3f4277990b849cad0c24878f404b977b 100644 (file)
@@ -200,6 +200,7 @@ $string['resetrolenolegacy'] = 'Clear permissions';
 $string['resetrolesure'] = 'Are you sure that you want to reset role \"$a->name ($a->shortname)\" to defaults?<p></p>The defaults are taken from the selected legacy capability ($a->legacytype).';
 $string['resetrolesurenolegacy'] = 'Are you sure that you want to clear all permissions defined in this role \"$a->name ($a->shortname)\"?';
 $string['restore:rolldates'] = 'Allowed to roll activity configuration dates on restore';
+$string['restore:createuser'] = 'Create users on restore';
 $string['restore:userinfo'] = 'Restore user data';
 $string['risks'] = 'Risks';
 $string['role:assign'] = 'Assign roles to users';
index fad8f7c16120f315dd131d56cd0968cd6fd41240..db1548f32a8e65580cd80d28af8e49cc6ebd482e 100644 (file)
@@ -216,6 +216,17 @@ $capabilities = array(
         )
     ),
 
+    'moodle/restore:createuser' => array(
+
+        'riskbitmask' => RISK_SPAM | RISK_PERSONAL,
+
+        'captype' => 'write',
+        'contextlevel' => CONTEXT_SYSTEM,
+        'legacy' => array(
+            'admin' => CAP_ALLOW
+        )
+    ),
+
     'moodle/restore:userinfo' => array(
 
         'riskbitmask' => RISK_SPAM | RISK_PERSONAL | RISK_XSS | RISK_CONFIG,
index d624093448ca9e8a8f44e4f4ba8b1b6cd4338b63..7bb4d335c5b743a672ff972ac522f98e746d1a46 100644 (file)
@@ -6,7 +6,7 @@
 // This is compared against the values stored in the database to determine
 // whether upgrades should be performed (see lib/db/*.php)
 
-    $version = 2009122500;  // YYYYMMDD   = date of the last version bump
+    $version = 2009123000;  // YYYYMMDD   = date of the last version bump
                             //         XX = daily increments
 
     $release = '2.0 dev (Build: 20091230)';  // Human-friendly version name