From df7264331b97d3f3aee67b0a1232eae89b94c9dc Mon Sep 17 00:00:00 2001 From: Eloy Lafuente Date: Sun, 5 Sep 2010 21:49:34 +0000 Subject: [PATCH] MDL-23437 backup - restore security checks --- backup/util/checks/restore_check.class.php | 106 ++++++++++++++++++++- 1 file changed, 105 insertions(+), 1 deletion(-) diff --git a/backup/util/checks/restore_check.class.php b/backup/util/checks/restore_check.class.php index b08065ef33c..3e6252ec0b5 100644 --- a/backup/util/checks/restore_check.class.php +++ b/backup/util/checks/restore_check.class.php @@ -51,8 +51,112 @@ abstract class restore_check { } public static function check_security($restore_controller, $apply) { + global $DB; + + if (! $restore_controller instanceof restore_controller) { + throw new restore_controller_exception('restore_check_security_requires_restore_controller'); + } + $restore_controller->log('checking plan security', backup::LOG_INFO); + + // Some handy vars + $type = $restore_controller->get_type(); + $mode = $restore_controller->get_mode(); + $courseid = $restore_controller->get_courseid(); + $coursectx= get_context_instance(CONTEXT_COURSE, $courseid); + $userid = $restore_controller->get_userid(); + + // Note: all the checks along the function MUST be performed for $userid, that + // is the user who "requested" the course restore, not current $USER at all!! + + // First of all, check the main restore[course|section|activity] principal caps + // Lacking the corresponding one makes this to break with exception always + switch ($type) { + case backup::TYPE_1COURSE : + if (!has_capability('moodle/restore:restorecourse', $coursectx, $userid)) { + $a = new stdclass(); + $a->userid = $userid; + $a->courseid = $courseid; + $a->capability = 'moodle/restore:restorecourse'; + throw new restore_controller_exception('restore_user_missing_capability', $a); + } + break; + case backup::TYPE_1SECTION : + if (!has_capability('moodle/restore:restoresection', $coursectx, $userid)) { + $a = new stdclass(); + $a->userid = $userid; + $a->courseid = $courseid; + $a->capability = 'moodle/restore:restoresection'; + throw new restore_controller_exception('restore_user_missing_capability', $a); + } + break; + case backup::TYPE_1ACTIVITY : + if (!has_capability('moodle/restore:restoreactivity', $coursectx, $userid)) { + $a = new stdclass(); + $a->userid = $userid; + $a->courseid = $courseid; + $a->capability = 'moodle/restore:restoreactivity'; + throw new restore_controller_exception('restore_user_missing_capability', $a); + } + break; + default : + print_error('unknownrestoretype'); + } + + // Now, if restore mode is hub or import, check userid has permissions for those modes + switch ($mode) { + case backup::MODE_HUB: + if (!has_capability('moodle/restore:restoretargethub', $coursectx, $userid)) { + $a = new stdclass(); + $a->userid = $userid; + $a->courseid = $courseid; + $a->capability = 'moodle/restore:restoretargethub'; + throw new restore_controller_exception('restore_user_missing_capability', $a); + } + break; + case backup::MODE_IMPORT: + if (!has_capability('moodle/restore:restoretargetimport', $coursectx, $userid)) { + $a = new stdclass(); + $a->userid = $userid; + $a->courseid = $courseid; + $a->capability = 'moodle/restore:restoretargetimport'; + throw new restore_controller_exception('restore_user_missing_capability', $a); + } + break; + } + + // Now, enforce 'moodle/restore:userinfo' to 'users' setting, applying changes if allowed, + // else throwing exception + $userssetting = $restore_controller->get_plan()->get_setting('users'); + $prevvalue = $userssetting->get_value(); + $prevstatus = $userssetting->get_status(); + $hasusercap = has_capability('moodle/restore:userinfo', $coursectx, $userid); + + // If setting is enabled but user lacks permission + if (!$hasusercap && $prevvalue) { // If user has not the capability and setting is enabled + // Now analyse if we are allowed to apply changes or must stop with exception + if (!$apply) { // Cannot apply changes, throw exception + $a = new stdclass(); + $a->setting = 'users'; + $a->value = $prevvalue; + $a->capability = 'moodle/restore:userinfo'; + throw new restore_controller_exception('restore_setting_value_wrong_for_capability', $a); + + } else { // Can apply changes + $userssetting->set_value(false); // Set the value to false + $userssetting->set_status(base_setting::LOCKED_BY_PERMISSION);// Set the status to locked by perm + } + } + + // Now, if mode is HUB or IMPORT, and still we are including users in restore, turn them off + // Defaults processing should have handled this, but we need to be 100% sure + if ($mode == backup::MODE_IMPORT || $mode == backup::MODE_HUB) { + $userssetting = $restore_controller->get_plan()->get_setting('users'); + if ($userssetting->get_value()) { + $userssetting->set_value(false); // Set the value to false + $userssetting->set_status(base_setting::LOCKED_BY_PERMISSION);// Set the status to locked by perm + } + } - debugging('TODO: Not applying security yet!', DEBUG_DEVELOPER); // TODO: Add once plan is complete return true; } } -- 2.43.0