MDL-23437 backup - restore security checks
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user