From d61f7b7641ce47a684350586b3e959f2677225f1 Mon Sep 17 00:00:00 2001 From: tjhunt Date: Tue, 20 Jan 2009 03:16:30 +0000 Subject: [PATCH] backup/restore: MDL-16614 more reliable test for when we are restoring a backup that was made of the same site that we are restoring to. * Use this to fix a question restore bug. * Replace older code that does something similar with the new test. * Refactor initialisation of $CFG->siteidentifier into a function. There were about 4 copies of this code ;-) --- admin/index.php | 2 -- admin/register.php | 8 ++------ backup/backuplib.php | 2 ++ backup/lib.php | 19 +++++++++++++++++++ backup/restore_check.html | 2 +- backup/restore_execute.html | 4 ++++ backup/restorelib.php | 22 +++++++++++++++++----- lang/en_utf8/moodle.php | 1 + lib/moodlelib.php | 20 ++++++++++++++------ question/restorelib.php | 24 ++++++++++++++++++++++-- 10 files changed, 82 insertions(+), 22 deletions(-) diff --git a/admin/index.php b/admin/index.php index ccc581c8df..ae7794d17d 100644 --- a/admin/index.php +++ b/admin/index.php @@ -343,7 +343,6 @@ upgrade_log_finish('upgradesettings.php'); } - // Turn xmlstrictheaders back on now. $CFG->xmlstrictheaders = $origxmlstrictheaders; unset($origxmlstrictheaders); @@ -363,7 +362,6 @@ } /// Check if we are returning from moodle.org registration and if so, we mark that fact to remove reminders - if (!empty($id) and $id == $CFG->siteidentifier) { set_config('registered', time()); } diff --git a/admin/register.php b/admin/register.php index e4217f023a..5acb8d8256 100644 --- a/admin/register.php +++ b/admin/register.php @@ -23,18 +23,14 @@ $admin->country = $CFG->country; } - if (empty($CFG->siteidentifier)) { // Unique site identification code - set_config('siteidentifier', random_string(32).$_SERVER['HTTP_HOST']); - } - /// Print the header stuff admin_externalpage_print_header(); /// Print headings - $stradministration = get_string("administration"); $strregistration = get_string("registration"); $strregistrationinfo = get_string("registrationinfo"); + $navlinks = array(); $navlinks[] = array('name' => $stradministration, 'link' => "../$CFG->admin/index.php", 'type' => 'misc'); $navlinks[] = array('name' => $strregistration, 'link' => null, 'type' => 'misc'); @@ -55,7 +51,7 @@ echo "\n"; echo "\n"; echo "wwwroot\" />\n"; - echo "siteidentifier\" />\n"; + echo "\n"; echo "\n"; echo "\n"; diff --git a/backup/backuplib.php b/backup/backuplib.php index e03e4d3306..655244ec63 100644 --- a/backup/backuplib.php +++ b/backup/backuplib.php @@ -473,6 +473,8 @@ fwrite ($bf,full_tag("DATE",2,false,$preferences->backup_unique_code)); //The original site wwwroot fwrite ($bf,full_tag("ORIGINAL_WWWROOT",2,false,$CFG->wwwroot)); + //The original site identifier. MD5 hashed for security. + fwrite ($bf,full_tag("ORIGINAL_SITE_IDENTIFIER_HASH",2,false,md5(get_site_identifier()))); //Indicate if it includes external MNET users $sql = "SELECT b.old_id FROM {backup_ids} b diff --git a/backup/lib.php b/backup/lib.php index e6c668bb0f..43f781bccb 100644 --- a/backup/lib.php +++ b/backup/lib.php @@ -297,6 +297,25 @@ // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + /** + * Are we restoring a backup that was made on the same site that we are restoring to? + * This relies on some information that was only added to backup files in January 2009. + * For older backup files, fall back to guessing based on wwwroot. MDL-16614 explains + * when this guess could give the wrong answer. + * @return boolean true if the backup was made on the same site we are restoring to. + */ + function backup_is_same_site(&$restore) { + global $CFG; + static $hashedsiteid = null; + if (is_null($hashedsiteid)) { + $hashedsiteid = md5(get_site_identifier()); + } + if (!empty($restore->original_siteidentifier)) { + return $restore->original_siteidentifier == $hashedsiteid; + } else { + return $restore->original_wwwroot == $CFG->wwwroot; + } + } //This function is used to insert records in the backup_ids table //If the info field is greater than max_db_storage, then its info diff --git a/backup/restore_check.html b/backup/restore_check.html index 871febb379..f6d6df0eb0 100644 --- a/backup/restore_check.html +++ b/backup/restore_check.html @@ -297,7 +297,7 @@ /// If restoring users and backup has mnet remote users and we are restoring to different site, forbid restore to non-admins. MDL-17009 if ($restore->users != 2 && /// If restoring users !empty($info->mnet_remoteusers) && $info->mnet_remoteusers === 'true' && /// and backup contains remote users - $info->original_wwwroot !== $CFG->wwwroot) { /// and backup is being restored to different site + !backup_is_same_site($info)) { /// and backup is being restored to different site /// If user is admin (by 'moodle/user:create' cap), warn about conversion to local auth if missing mnet hosts and continue restore if (has_capability('moodle/user:create', get_context_instance(CONTEXT_SYSTEM))) { diff --git a/backup/restore_execute.html b/backup/restore_execute.html index 4c10580c15..e80b29e297 100644 --- a/backup/restore_execute.html +++ b/backup/restore_execute.html @@ -13,6 +13,10 @@ //Add info->original_wwwroot to $restore to be able to use it in all the restore process //(mainly when decoding internal links) $restore->original_wwwroot = $info->original_wwwroot; + // Copy $info->original_siteidentifier, is present, so backup_is_same_site can work. + if (isset($info->original_siteidentifier)) { + $restore->original_siteidentifier = $info->original_siteidentifier; + } //Add info->backup_version to $restore to be able to detect versions in the restore process //(to decide when to convert wiki texts to markdown...) $restore->backup_version = $info->backup_backup_version; diff --git a/backup/restorelib.php b/backup/restorelib.php index dbf1e820f7..d88370cbd3 100644 --- a/backup/restorelib.php +++ b/backup/restorelib.php @@ -487,6 +487,15 @@ define('RESTORE_GROUPS_GROUPINGS', 3); //The backup date $tab[3][0] = "".get_string("backupdate").":"; $tab[3][1] = userdate($info->backup_date); + //Is this the same Moodle install? + if (!empty($info->original_siteidentifier)) { + $tab[4][0] = "".get_string("backupfromthissite").":"; + if (backup_is_same_site($info)) { + $tab[4][1] = get_string('yes'); + } else { + $tab[4][1] = get_string('no'); + } + } //Print title print_heading(get_string("backup").":"); $table->data = $tab; @@ -1332,7 +1341,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3); $dbmetacourse = false; //Check if child course exists in destination server //(by id in the same server or by idnumber and shortname in other server) - if ($restore->original_wwwroot == $CFG->wwwroot) { + if (backup_is_same_site($restore)) { //Same server, lets see by id $dbcourse = $DB->get_record('course', array('id'=>$child->id)); } else { @@ -1364,7 +1373,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3); $dbmetacourse = false; //Check if parent course exists in destination server //(by id in the same server or by idnumber and shortname in other server) - if ($restore->original_wwwroot == $CFG->wwwroot) { + if (backup_is_same_site($restore)) { //Same server, lets see by id $dbcourse = $DB->get_record('course', array('id'=>$parent->id)); } else { @@ -2632,7 +2641,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3); // - if the destination site is different (by wwwroot) reset it. // - if the destination site is the same (by wwwroot), leave it unmodified - if ($restore->original_wwwroot != $CFG->wwwroot) { + if (!backup_is_same_site($restore)) { $user->policyagreed = 0; } else { //Nothing to do, we are in the same server @@ -2697,7 +2706,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3); // - if we are in the same server (by wwwroot), maintain it unmodified. if (empty($user->roles['teacher']->enrol)) { $user->roles['teacher']->enrol = $CFG->enrol; - } else if ($restore->original_wwwroot != $CFG->wwwroot) { + } else if (!backup_is_same_site($restore)) { $user->roles['teacher']->enrol = $CFG->enrol; } else { //Nothing to do. Leave it unmodified @@ -2743,7 +2752,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3); // - if we are in the same server (by wwwroot), maintain it unmodified. if (empty($user->roles['student']->enrol)) { $user->roles['student']->enrol = $CFG->enrol; - } else if ($restore->original_wwwroot != $CFG->wwwroot) { + } else if (!backup_is_same_site($restore)) { $user->roles['student']->enrol = $CFG->enrol; } else { //Nothing to do. Leave it unmodified @@ -5035,6 +5044,9 @@ define('RESTORE_GROUPS_GROUPINGS', 3); case "ORIGINAL_WWWROOT": $this->info->original_wwwroot = $this->getContents(); break; + case "ORIGINAL_SITE_IDENTIFIER_HASH": + $this->info->original_siteidentifier = $this->getContents(); + break; case "MNET_REMOTEUSERS": $this->info->mnet_remoteusers = $this->getContents(); break; diff --git a/lang/en_utf8/moodle.php b/lang/en_utf8/moodle.php index cf7d87315d..bd2928e238 100644 --- a/lang/en_utf8/moodle.php +++ b/lang/en_utf8/moodle.php @@ -151,6 +151,7 @@ $string['backupexecuteathelp'] = 'Choose what time automated backups should run $string['backupfailed'] = 'Some of your courses weren\'t saved!!'; $string['backupfilename'] = 'backup'; $string['backupfinished'] = 'Backup completed successfully'; +$string['backupfromthissite'] = 'Backup was made on this site?'; $string['backupgradebookhistoryhelp'] = 'If enabled then gradebook history will be included in automated backups. Note that grade history must not be disabled in server settings (disablegradehistory) in order for this to work'; $string['backupincludemoduleshelp'] = 'Choose whether you want to include course modules, with or without user data, in automated backups'; $string['backupincludemoduleuserdatahelp'] = 'Choose whether you want to include module user data in automated backups.'; diff --git a/lib/moodlelib.php b/lib/moodlelib.php index d98fbb615b..67b663b14a 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -3916,15 +3916,10 @@ function reset_course_userdata($data) { function generate_email_processing_address($modid,$modargs) { global $CFG; - if (empty($CFG->siteidentifier)) { // Unique site identification code - set_config('siteidentifier', random_string(32)); - } - $header = $CFG->mailprefix . substr(base64_encode(pack('C',$modid)),0,2).$modargs; - return $header . substr(md5($header.$CFG->siteidentifier),0,16).'@'.$CFG->maildomain; + return $header . substr(md5($header.get_site_identifier()),0,16).'@'.$CFG->maildomain; } - function moodle_process_email($modargs,$body) { global $DB; @@ -8305,5 +8300,18 @@ function is_primary_admin($userid){ } } +/** + * @return string $CFG->siteidentifier, first making sure it is properly initialised. + */ +function get_site_identifier() { + global $CFG; + // Check to see if it is missing. If so, initialise it. + if (empty($CFG->siteidentifier)) { + set_config('siteidentifier', random_string(32) . $_SERVER['HTTP_HOST']); + } + // Return it. + return $CFG->siteidentifier; +} + // vim:autoindent:expandtab:shiftwidth=4:tabstop=4:tw=140: ?> diff --git a/question/restorelib.php b/question/restorelib.php index 8f528a7a9c..7e9bd2b9fd 100644 --- a/question/restorelib.php +++ b/question/restorelib.php @@ -337,8 +337,28 @@ $question->hidden = backup_todb($que_info['#']['HIDDEN']['0']['#']); $question->timecreated = backup_todb_optional_field($que_info, 'TIMECREATED', 0); $question->timemodified = backup_todb_optional_field($que_info, 'TIMEMODIFIED', 0); - $question->createdby = backup_todb_optional_field($que_info, 'CREATEDBY', null); - $question->modifiedby = backup_todb_optional_field($que_info, 'MODIFIEDBY', null); + + // Set the createdby field, if the user was in the backup, or if we are on the same site. + $createdby = backup_todb_optional_field($que_info, 'CREATEDBY', null); + if (!empty($createdby)) { + $user = backup_getid($restore->backup_unique_code, 'user', $createdby); + if ($user) { + $question->createdby = $user->new_id; + } else if (backup_is_same_site($restore)) { + $question->createdby = $createdby; + } + } + + // Set the modifiedby field, if the user was in the backup, or if we are on the same site. + $modifiedby = backup_todb_optional_field($que_info, 'MODIFIEDBY', null); + if (!empty($createdby)) { + $user = backup_getid($restore->backup_unique_code, 'user', $modifiedby); + if ($user) { + $question->modifiedby = $user->new_id; + } else if (backup_is_same_site($restore)) { + $question->modifiedby = $modifiedby; + } + } if ($restore->backup_version < 2006032200) { // The qtype was an integer that now needs to be converted to the name -- 2.39.5