From f6459d125e63e3c8196e5566b6ea4926cbad801d Mon Sep 17 00:00:00 2001 From: Eloy Lafuente Date: Fri, 20 Nov 2009 00:32:16 +0000 Subject: [PATCH] MDL-20849 moodle/restore:userinfo - new cababilty to allow/deny permissions to restore any (users, messages, modulesactivity...) user-level information. Merged from 19_STABLE --- backup/backup_form.html | 2 +- backup/restore_check.html | 32 ++++++ backup/restore_form.html | 200 ++++++++++++++++++++------------------ backup/restorelib.php | 4 +- lang/en_utf8/moodle.php | 1 + lang/en_utf8/role.php | 2 + lib/db/access.php | 15 ++- version.php | 2 +- 8 files changed, 157 insertions(+), 101 deletions(-) diff --git a/backup/backup_form.html b/backup/backup_form.html index e13e31cd98..87025650f9 100644 --- a/backup/backup_form.html +++ b/backup/backup_form.html @@ -288,7 +288,7 @@ function selectItemInCheckboxByName(formId, checkName, checked ) { } // do you want grade histories to be backed up? - if (empty($CFG->disablegradehistory)) { + if (empty($to) and $backupuserinfo and empty($CFG->disablegradehistory)) { echo ""; echo ""; echo ''; diff --git a/backup/restore_check.html b/backup/restore_check.html index 98e5edfa6a..1be9cff6d7 100644 --- a/backup/restore_check.html +++ b/backup/restore_check.html @@ -200,15 +200,21 @@ $loginurl = get_login_url(); + //Init restoreuserinfo + $restoreuserinfo = false; + + //Check admin if (!empty($id)) { if (!has_capability('moodle/site:restore', get_context_instance(CONTEXT_COURSE, $id))) { print_error("cannotuseadminadminorteacher", '', $loginurl); } + $restoreuserinfo = has_capability('moodle/restore:userinfo', get_context_instance(CONTEXT_COURSE, $id)); } else { if (!has_capability('moodle/site:restore', get_context_instance(CONTEXT_SYSTEM))) { print_error("cannotuseadmin", '', $loginurl); } + $restoreuserinfo = has_capability('moodle/restore:userinfo', get_context_instance(CONTEXT_SYSTEM)); } //Check site @@ -320,6 +326,32 @@ } } + // Re-enforce moodle/restore:userinfo capability + if (!$restoreuserinfo) { + $userinfocheck = true; + // Confirm that all the settings are properly set to no users + // if anything is wrong, message and stop + // First global settings + if ($restore->users != 2 or $restore->user_files or $restore->messages or $restore->blogs) { + $userinfocheck = false; + + // Now all modules userinfo flag + } else { + $mods = $restore->mods; + foreach ($mods as $mod) { + if ($mod->userinfo) { + $userinfocheck = false; + } + } + } + + if (!$userinfocheck) { // Something was wrong + $messages[] = get_string('restoreuserinfofailed'); + $show_continue_button = false; + } + } + + /// 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 diff --git a/backup/restore_form.html b/backup/restore_form.html index d201873c5c..3976a6ebb8 100644 --- a/backup/restore_form.html +++ b/backup/restore_form.html @@ -27,15 +27,20 @@ $loginurl = get_login_url(); + //Init restoreuserinfo + $restoreuserinfo = false; + //Check admin if (!empty($id)) { if (!has_capability('moodle/site:restore', get_context_instance(CONTEXT_COURSE, $id))) { print_error('cannotuseadminadminorteacher', '', $loginurl); } + $restoreuserinfo = has_capability('moodle/restore:userinfo', get_context_instance(CONTEXT_COURSE, $id)); } else { if (!has_capability('moodle/site:restore', get_context_instance(CONTEXT_SYSTEM))) { print_error('cannotuseadmin', '', $loginurl); } + $restoreuserinfo = has_capability('moodle/restore:userinfo', get_context_instance(CONTEXT_SYSTEM)); } //Check site @@ -64,8 +69,10 @@ } //Check include user info $var = "restore_user_info_".$modname; - if (!isset($$var)) { + if (!isset($$var) && $restoreuserinfo) { $$var = 1; + } else { + $$var = 0; } } } @@ -324,14 +331,18 @@ function selectItemInCheckboxByName(formId, checkName, checked ) { echo "". get_string("none").""; echo ""; - echo ""; - echo ' '; - echo ""; - echo "". - get_string("all")."/"; - echo "". - get_string("none").""; - echo ""; + if ($restoreuserinfo) { + echo ""; + echo ' '; + echo ""; + echo "". + get_string("all")."/"; + echo "". + get_string("none").""; + echo ""; + } else { + echo " "; + } echo ""; echo "
"; $currentrow = 0; @@ -359,7 +370,7 @@ function selectItemInCheckboxByName(formId, checkName, checked ) { //without user data echo " "; echo ""; - if ($info->mods[$modname]->userinfo == "true") { + if ($info->mods[$modname]->userinfo == "true" && $restoreuserinfo) { $restore_user_options[1] = get_string("yes"); $restore_user_options[0] = get_string("no"); print_checkbox($user_info_var, $$user_info_var, $$user_info_var, get_string("userdata"),'','selectItemInCheckboxByName(\'form1\',\'restore_user_info_'.$modname.'\',this.checked)'); @@ -382,7 +393,7 @@ function selectItemInCheckboxByName(formId, checkName, checked ) { echo ' '; $var = 'restore_user_info_'.$modname.'_instance_'.$instance->id; $$var = optional_param($var,1, PARAM_CLEAN); - if (!empty($info->mods[$modname]->instances) && ($info->mods[$modname]->instances[$instance->id]->userinfo == 'true')) { + if (!empty($info->mods[$modname]->instances) && ($info->mods[$modname]->instances[$instance->id]->userinfo == 'true') && $restoreuserinfo) { print_checkbox($var,$$var,$$var,get_string('userdata'),'','this.form.elements[\'restore_user_info_'.$modname.'\'].checked=1;'); } else { echo ''; @@ -433,7 +444,7 @@ function selectItemInCheckboxByName(formId, checkName, checked ) { echo ''; echo "
"; //If some user is present in the backup file - if ($info->backup_users == "all" or $info->backup_users == "course") { + if (($info->backup_users == "all" or $info->backup_users == "course") and $restoreuserinfo) { $user_options = array(); //If all users are in the backup file if ($info->backup_users == "all") { @@ -453,23 +464,17 @@ function selectItemInCheckboxByName(formId, checkName, checked ) { echo ""; echo ""; $helplink = $OUTPUT->help_icon(moodle_help_icon::make('grouprestore', get_string('groups'))); + echo ''.$helplink; + echo ""; if (empty($CFG->enablegroupings)) { - echo ''.$helplink; - echo ""; $group_options[RESTORE_GROUPS_NONE] = get_string('no'); $group_options[RESTORE_GROUPS_ONLY] = get_string('yes'); } else { - echo ''.$helplink; - echo ""; $group_options[RESTORE_GROUPS_NONE] = get_string('none'); $group_options[RESTORE_GROUPS_ONLY] = get_string('groupsonly', 'group'); $group_options[RESTORE_GROUPINGS_ONLY] = get_string('groupingsonly', 'group'); $group_options[RESTORE_GROUPS_GROUPINGS] = get_string('groupsgroupings', 'group'); //all. - - } /*else { - echo get_string('none'); - echo ""; - }*/ + } echo $OUTPUT->select(html_select::make($group_options, 'restore_groups', $restore_groups, false)); echo ""; @@ -479,7 +484,7 @@ function selectItemInCheckboxByName(formId, checkName, checked ) { echo ''; echo ""; //If logs are in the backup file, show menu, else fixed to no - if ($info->backup_logs == "true") { + if ($info->backup_logs == "true" and $restoreuserinfo) { $log_options = array(); $log_options[0] = get_string("no"); $log_options[1] = get_string("yes"); @@ -496,7 +501,7 @@ function selectItemInCheckboxByName(formId, checkName, checked ) { echo ''; echo ""; //If user files are in the backup file, show menu, else fixed to no - if ($info->backup_user_files == "true") { + if ($info->backup_user_files == "true" and $restoreuserinfo) { $user_file_options = array(); $user_file_options[0] = get_string("no"); $user_file_options[1] = get_string("yes"); @@ -545,7 +550,7 @@ function selectItemInCheckboxByName(formId, checkName, checked ) { echo ""; // do you want grade histories to be restored? - if (empty($CFG->disablegradehistory)) { + if (empty($CFG->disablegradehistory) and $restoreuserinfo) { echo ""; echo ""; echo ''; @@ -568,7 +573,7 @@ function selectItemInCheckboxByName(formId, checkName, checked ) { //we haven't messages is the backup, to avoid confusions to users. //If messages are in the backup file, show menu, else fixed to no and show nothing //Also, messaging must be enabled in the destination site - if (isset($info->backup_messages) && $info->backup_messages == "true" && !empty($CFG->messaging)) { + if (isset($info->backup_messages) && $info->backup_messages == "true" && !empty($CFG->messaging) and $restoreuserinfo) { echo ""; echo ""; echo ''; @@ -586,7 +591,7 @@ function selectItemInCheckboxByName(formId, checkName, checked ) { //we haven't blogs is the backup, to avoid confusions to users. //If blogs are in the backup file, show menu, else fixed to no and show nothing //Also, blogs must be enabled in the destination site - if (isset($info->backup_blogs) && $info->backup_blogs == "true" && !empty($CFG->bloglevel)) { + if (isset($info->backup_blogs) && $info->backup_blogs == "true" && !empty($CFG->bloglevel) and $restoreuserinfo) { echo ""; echo ""; echo ''; @@ -606,100 +611,106 @@ function selectItemInCheckboxByName(formId, checkName, checked ) {
heading(get_string('rolemappings')); + $xml_file = $CFG->dataroot."/temp/backup/".$backup_unique_code."/moodle.xml"; -echo $OUTPUT->heading(get_string('rolemappings')); -$xml_file = $CFG->dataroot."/temp/backup/".$backup_unique_code."/moodle.xml"; + $info = restore_read_xml_info($xml_file); -$info = restore_read_xml_info($xml_file); + // fix for MDL-9068, front page course is just a normal course + $siterolesarray = get_assignable_roles (get_context_instance(CONTEXT_COURSE, $course->id), "shortname", ROLENAME_ORIGINAL); + $siterolesnamearray = get_assignable_roles (get_context_instance(CONTEXT_COURSE, $course->id), "name", ROLENAME_ORIGINAL); + $allroles = get_records('role'); -// fix for MDL-9068, front page course is just a normal course -$siterolesarray = get_assignable_roles(get_context_instance(CONTEXT_COURSE, $course->id), ROLENAME_ORIGINALANDSHORT); -$allroles = get_all_roles(); + echo (''); + echo (''); -echo ('
'.get_string('sourcerole').''.get_string('targetrole').'
'); -echo (''); + if ($info->backup_moodle_version < 2006092801) { + // 1.6 and below backup -if ($info->backup_moodle_version < 2006092801) { - // 1.6 and below backup + /// Editting teacher + echo (''); - $editteacher = reset($roles); - echo $OUTPUT->select(html_select::make ($siterolesarray, "defaultteacheredit", $editteacher->id, 'new role')); - echo (''); + /// Non-editting teacher + echo (''); - echo $OUTPUT->select(html_select::make ($siterolesarray, "defaultteacher", $teacher->id, 'new role')); - echo (''); + /// Student + echo (''); - echo $OUTPUT->select(html_select::make ($siterolesarray, "defaultstudent", $studentrole->id, 'new role')); - echo (''); + } else { + // 1.7 and above backup + $roles = restore_read_xml_roles($xml_file); -} else { - // 1.7 and above backup - $roles = restore_read_xml_roles($xml_file); + if (!empty($roles->roles)) { // possible to have course with no roles + foreach ($siterolesarray as $siteroleid=>$siteroleshortname) { + $siteroleschoicearray[$siteroleid] = $siterolesnamearray[$siteroleid]." (". $siterolesarray[$siteroleid].")"; + } - if (!empty($roles->roles)) { // possible to have course with no roles - foreach ($roles->roles as $roleid=>$role) { + foreach ($roles->roles as $roleid=>$role) { - $mappableroles = $siterolesarray; + $mappableroles = $siteroleschoicearray; - echo (''); } - echo $OUTPUT->select(html_select::make ($mappableroles, "roles_".$roleid, $matchrole, 'new role')); - echo (''); } - } -} // end else - -echo ('
'.get_string('sourcerole').''.get_string('targetrole').'
'); + echo ''; + echo (''); - /// Editting teacher - echo ('
'); - echo ''; - echo (''); + // get the first teacheredit legacy + $roles = get_roles_with_capability('moodle/legacy:editingteacher', CAP_ALLOW, get_context_instance(CONTEXT_SYSTEM)); - // get the first teacheredit legacy - $roles = get_roles_with_capability('moodle/legacy:editingteacher', CAP_ALLOW, get_context_instance(CONTEXT_SYSTEM)); + $editteacher = reset($roles); + echo $OUTPUT->select(html_select::make ($siterolesarray, "defaultteacheredit", $editteacher->id, 'new role')); + echo ('
'); + echo ''; + print_string('noneditingteacher'); + echo (''); - /// Non-editting teacher - echo ('
'); - echo ''; - print_string('noneditingteacher'); - echo (''); + // get the first teacheredit legacy + $roles = get_roles_with_capability('moodle/legacy:teacher', CAP_ALLOW, get_context_instance(CONTEXT_SYSTEM)); + $teacher = reset($roles); - // get the first teacheredit legacy - $roles = get_roles_with_capability('moodle/legacy:teacher', CAP_ALLOW, get_context_instance(CONTEXT_SYSTEM)); - $teacher = reset($roles); + echo $OUTPUT->select(html_select::make ($siterolesarray, "defaultteacher", $teacher->id, 'new role')); + echo ('
'); + echo ''; + echo (''); - /// Student - echo ('
'); - echo ''; - echo (''); + // get the first teacheredit legacy + $roles = get_roles_with_capability('moodle/legacy:student', CAP_ALLOW, get_context_instance(CONTEXT_SYSTEM)); + $studentrole = array_shift($roles); - // get the first teacheredit legacy - $roles = get_roles_with_capability('moodle/legacy:student', CAP_ALLOW, get_context_instance(CONTEXT_SYSTEM)); - $studentrole = array_shift($roles); + echo $OUTPUT->select(html_select::make ($siterolesarray, "defaultstudent", $studentrole->id, 'new role')); + echo ('
'); - echo ''; - echo (''); + echo ('
'); + echo ''; + echo (''); - /// first, we see if any exact role definition is found - /// if found, that is the only option of restoring to + /// first, we see if any exact role definition is found + /// if found, that is the only option of restoring to - if ($samerole = restore_samerole($roleid, $role)) { - $matchrole = $samerole->id; - // if an exact role is found, it does not matter whether this user can assign this role or not, - // this will be presented as a valid option regardless - $mappableroles[$samerole->id] = format_string($allroles[$samerole->id]->name)." (". $allroles[$samerole->id]->shortname.")"; - } else { - // no exact role found, let's try to match shortname - // this is useful in situations where basic roles differ slightly in definition - $matchrole = 0; - foreach ($siterolesarray as $siteroleid => $notused) { - if ($siteroleshortname == $allroles[$siteroleid]->shortname) { - $matchrole = $siteroleid; - break; + if ($samerole = restore_samerole($roleid, $role)) { + $matchrole = $samerole->id; + // if an exact role is found, it does not matter whether this user can assign this role or not, + // this will be presented as a valid option regardless + $mappableroles[$samerole->id] = format_string($allroles[$samerole->id]->name)." (". $allroles[$samerole->id]->shortname.")"; + } else { + // no exact role found, let's try to match shortname + // this is useful in situations where basic roles differ slightly in definition + $matchrole = 0; + foreach ($siterolesarray as $siteroleid=>$siteroleshortname) { + if ($siteroleshortname == $role->shortname) { + $matchrole = $siteroleid; + break; + } } } + echo $OUTPUT->select(html_select::make ($mappableroles, "roles_".$roleid, $matchrole, 'new role')); + echo ('
'); // end of role mappings table + } // end else + echo (''); // end of role mappings table +} ?>
@@ -720,7 +731,6 @@ echo (''); // end of role mappings table restore->importing); // there should not be a way to import old backups, but anyway ;-) - if ($importing) { + if ($importing || $restore->users == 2) { $restoreall = false; } else { @@ -1664,7 +1664,7 @@ define('RESTORE_GROUPS_GROUPINGS', 3); $restoreall = true; // set to false if any grade_item is not selected/restored or already exist $importing = !empty($SESSION->restore->importing); - if ($importing) { + if ($importing || $restore->users == 2) { $restoreall = false; } else { diff --git a/lang/en_utf8/moodle.php b/lang/en_utf8/moodle.php index 99dbc09dad..d57d2f05a5 100644 --- a/lang/en_utf8/moodle.php +++ b/lang/en_utf8/moodle.php @@ -1371,6 +1371,7 @@ $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['restoreuserinfofailed'] = 'Warning: To be able to restore any user data (in activities, files, messages...) the \"moodle/restore:userinfo\" capability is required and you are missing it. Restore process stopped.'; $string['restricted'] = 'Restricted'; $string['restrictmodules'] = 'Restrict activity modules?'; $string['returntooriginaluser'] = 'Return to $a'; diff --git a/lang/en_utf8/role.php b/lang/en_utf8/role.php index 58dcf52d68..094f02c7fb 100644 --- a/lang/en_utf8/role.php +++ b/lang/en_utf8/role.php @@ -24,6 +24,7 @@ $string['assignglobalroles'] = 'Assign system roles'; $string['assignmentcontext'] = 'Assignment context'; $string['assignmentoptions'] = 'Assignment options'; $string['backtoallroles'] = 'Back to the list of all roles'; +$string['backup:userinfo'] = 'Backup user data'; $string['blog:associatecourse'] = 'Associate blog entries with courses'; $string['blog:associatemodule'] = 'Associate blog entries with activity modules'; $string['blog:create'] = 'Create new blog entries'; @@ -199,6 +200,7 @@ $string['resetrolenolegacy'] = 'Clear permissions'; $string['resetrolesure'] = 'Are you sure that you want to reset role \"$a->name ($a->shortname)\" to defaults?

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:userinfo'] = 'Restore user data'; $string['risks'] = 'Risks'; $string['role:assign'] = 'Assign roles to users'; $string['role:manage'] = 'Create and manage roles'; diff --git a/lib/db/access.php b/lib/db/access.php index a67b6f232a..fad8f7c161 100644 --- a/lib/db/access.php +++ b/lib/db/access.php @@ -195,9 +195,9 @@ $capabilities = array( 'moodle/backup:userinfo' => array( - 'riskbitmask' => RISK_PERSONAL | RISK_CONFIG, + 'riskbitmask' => RISK_PERSONAL, - 'captype' => 'write', + 'captype' => 'read', 'contextlevel' => CONTEXT_COURSE, 'legacy' => array( 'admin' => CAP_ALLOW @@ -216,6 +216,17 @@ $capabilities = array( ) ), + 'moodle/restore:userinfo' => array( + + 'riskbitmask' => RISK_SPAM | RISK_PERSONAL | RISK_XSS | RISK_CONFIG, + + 'captype' => 'write', + 'contextlevel' => CONTEXT_COURSE, + 'legacy' => array( + 'admin' => CAP_ALLOW + ) + ), + 'moodle/restore:rolldates' => array( 'captype' => 'write', diff --git a/version.php b/version.php index e0ad2b46a7..6b29470a4e 100644 --- a/version.php +++ b/version.php @@ -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 = 2009111800; // YYYYMMDD = date of the last version bump + $version = 2009112000; // YYYYMMDD = date of the last version bump // XX = daily increments $release = '2.0 dev (Build: 20091117)'; // Human-friendly version name -- 2.39.5