Skip to content

Commit

Permalink
MDL-16658 restore - new restore:createuser cap + pre-check users befo…
Browse files Browse the repository at this point in the history
…re restoring; merged from 19_STABLE
  • Loading branch information
stronk7 committed Dec 30, 2009
1 parent e07a708 commit 5e93489
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 61 deletions.
94 changes: 34 additions & 60 deletions backup/restorelib.php
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,7 @@ function restore_check_user($restore, $user) {
}

// 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))) {
Expand Down Expand Up @@ -950,7 +950,7 @@ function restore_precheck_users($xml_file, $restore, &$problems) {
$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
Expand All @@ -965,13 +965,18 @@ function restore_precheck_users($xml_file, $restore, &$problems) {
$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;
Expand Down Expand Up @@ -2830,25 +2835,17 @@ function restore_create_users($restore,$xml_file) {
$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();
Expand All @@ -2858,9 +2855,22 @@ function restore_create_users($restore,$xml_file) {

/// 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);
Expand Down Expand Up @@ -2908,31 +2918,12 @@ function restore_create_users($restore,$xml_file) {
//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) {
Expand All @@ -2951,21 +2942,6 @@ function restore_create_users($restore,$xml_file) {
}
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;
Expand Down Expand Up @@ -3245,7 +3221,7 @@ function restore_create_users($restore,$xml_file) {
}
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')) {
Expand Down Expand Up @@ -8487,7 +8463,6 @@ function restore_execute(&$restore,$info,$course_header,&$errorstr) {

// 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>';
}
Expand All @@ -8501,7 +8476,6 @@ function restore_execute(&$restore,$info,$course_header,&$errorstr) {
}
return false;
}
*/

//If we've selected to restore into new course
//create it (course)
Expand Down
15 changes: 15 additions & 0 deletions config-dist.php
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,21 @@
// 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;
//
Expand Down
4 changes: 4 additions & 0 deletions lang/en_utf8/moodle.php
Original file line number Diff line number Diff line change
Expand Up @@ -1369,14 +1369,18 @@
$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\"';
$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';
Expand Down
1 change: 1 addition & 0 deletions lang/en_utf8/role.php
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@
$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';
Expand Down
11 changes: 11 additions & 0 deletions lib/db/access.php
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,17 @@
)
),

'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,
Expand Down
2 changes: 1 addition & 1 deletion version.php
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 5e93489

Please sign in to comment.