|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 00003 // This file is part of Moodle - http://moodle.org/ 00004 // 00005 // Moodle is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // Moodle is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00017 00033 abstract class backup_check { 00034 00035 public static function check_format_and_type($format, $type) { 00036 global $CFG; 00037 00038 $file = $CFG->dirroot . '/backup/' . $format . '/backup_plan_builder.class.php'; 00039 if (! file_exists($file)) { 00040 throw new backup_controller_exception('backup_check_unsupported_format', $format); 00041 } 00042 require_once($file); 00043 if (!in_array($type, backup_plan_builder::supported_backup_types())) { 00044 throw new backup_controller_exception('backup_check_unsupported_type', $type); 00045 } 00046 00047 require_once($CFG->dirroot . '/backup/moodle2/backup_plan_builder.class.php'); 00048 } 00049 00050 public static function check_id($type, $id) { 00051 global $DB; 00052 switch ($type) { 00053 case backup::TYPE_1ACTIVITY: 00054 // id must exist in course_modules table 00055 if (! $DB->record_exists('course_modules', array('id' => $id))) { 00056 throw new backup_controller_exception('backup_check_module_not_exists', $id); 00057 } 00058 break; 00059 case backup::TYPE_1SECTION: 00060 // id must exist in course_sections table 00061 if (! $DB->record_exists('course_sections', array('id' => $id))) { 00062 throw new backup_controller_exception('backup_check_section_not_exists', $id); 00063 } 00064 break; 00065 case backup::TYPE_1COURSE: 00066 // id must exist in course table 00067 if (! $DB->record_exists('course', array('id' => $id))) { 00068 throw new backup_controller_exception('backup_check_course_not_exists', $id); 00069 } 00070 break; 00071 default: 00072 throw new backup_controller_exception('backup_check_incorrect_type', $type); 00073 } 00074 return true; 00075 } 00076 00077 public static function check_user($userid) { 00078 global $DB; 00079 // userid must exist in user table 00080 if (! $DB->record_exists('user', array('id' => $userid))) { 00081 throw new backup_controller_exception('backup_check_user_not_exists', $userid); 00082 } 00083 return true; 00084 } 00085 00086 public static function check_security($backup_controller, $apply) { 00087 global $DB; 00088 00089 if (! $backup_controller instanceof backup_controller) { 00090 throw new backup_controller_exception('backup_check_security_requires_backup_controller'); 00091 } 00092 $backup_controller->log('checking plan security', backup::LOG_INFO); 00093 00094 // Some handy vars 00095 $type = $backup_controller->get_type(); 00096 $mode = $backup_controller->get_mode(); 00097 $courseid = $backup_controller->get_courseid(); 00098 $coursectx= get_context_instance(CONTEXT_COURSE, $courseid); 00099 $userid = $backup_controller->get_userid(); 00100 $id = $backup_controller->get_id(); // courseid / sectionid / cmid 00101 00102 // Note: all the checks along the function MUST be performed for $userid, that 00103 // is the user who "requested" the course backup, not current $USER at all!! 00104 00105 // First of all, decide which caps/contexts are we going to check 00106 // for common backups (general, automated...) based exclusively 00107 // in the type (course, section, activity). And store them into 00108 // one capability => context array structure 00109 $typecapstocheck = array(); 00110 switch ($type) { 00111 case backup::TYPE_1COURSE : 00112 $DB->get_record('course', array('id' => $id), '*', MUST_EXIST); // course exists 00113 $typecapstocheck['moodle/backup:backupcourse'] = $coursectx; 00114 break; 00115 case backup::TYPE_1SECTION : 00116 $DB->get_record('course_sections', array('course' => $courseid, 'id' => $id), '*', MUST_EXIST); // sec exists 00117 $typecapstocheck['moodle/backup:backupsection'] = $coursectx; 00118 break; 00119 case backup::TYPE_1ACTIVITY : 00120 get_coursemodule_from_id(null, $id, $courseid, false, MUST_EXIST); // cm exists 00121 $modulectx = get_context_instance(CONTEXT_MODULE, $id); 00122 $typecapstocheck['moodle/backup:backupactivity'] = $modulectx; 00123 break; 00124 default : 00125 throw new backup_controller_exception('backup_unknown_backup_type', $type); 00126 } 00127 00128 // Now, if backup mode is hub or import, check userid has permissions for those modes 00129 // other modes will perform common checks only (backupxxxx capabilities in $typecapstocheck) 00130 switch ($mode) { 00131 case backup::MODE_HUB: 00132 if (!has_capability('moodle/backup:backuptargethub', $coursectx, $userid)) { 00133 $a = new stdclass(); 00134 $a->userid = $userid; 00135 $a->courseid = $courseid; 00136 $a->capability = 'moodle/backup:backuptargethub'; 00137 throw new backup_controller_exception('backup_user_missing_capability', $a); 00138 } 00139 break; 00140 case backup::MODE_IMPORT: 00141 if (!has_capability('moodle/backup:backuptargetimport', $coursectx, $userid)) { 00142 $a = new stdclass(); 00143 $a->userid = $userid; 00144 $a->courseid = $courseid; 00145 $a->capability = 'moodle/backup:backuptargetimport'; 00146 throw new backup_controller_exception('backup_user_missing_capability', $a); 00147 } 00148 break; 00149 // Common backup (general, automated...), let's check all the $typecapstocheck 00150 // capability => context pairs 00151 default: 00152 foreach ($typecapstocheck as $capability => $context) { 00153 if (!has_capability($capability, $context, $userid)) { 00154 $a = new stdclass(); 00155 $a->userid = $userid; 00156 $a->courseid = $courseid; 00157 $a->capability = $capability; 00158 throw new backup_controller_exception('backup_user_missing_capability', $a); 00159 } 00160 } 00161 } 00162 00163 // Now, enforce 'moodle/backup:userinfo' to 'users' setting, applying changes if allowed, 00164 // else throwing exception 00165 $userssetting = $backup_controller->get_plan()->get_setting('users'); 00166 $prevvalue = $userssetting->get_value(); 00167 $prevstatus = $userssetting->get_status(); 00168 $hasusercap = has_capability('moodle/backup:userinfo', $coursectx, $userid); 00169 00170 // If setting is enabled but user lacks permission 00171 if (!$hasusercap && $prevvalue) { // If user has not the capability and setting is enabled 00172 // Now analyse if we are allowed to apply changes or must stop with exception 00173 if (!$apply) { // Cannot apply changes, throw exception 00174 $a = new stdclass(); 00175 $a->setting = 'users'; 00176 $a->value = $prevvalue; 00177 $a->capability = 'moodle/backup:userinfo'; 00178 throw new backup_controller_exception('backup_setting_value_wrong_for_capability', $a); 00179 00180 } else { // Can apply changes 00181 $userssetting->set_value(false); // Set the value to false 00182 $userssetting->set_status(base_setting::LOCKED_BY_PERMISSION);// Set the status to locked by perm 00183 } 00184 } 00185 00186 // Now, enforce 'moodle/backup:anonymise' to 'anonymise' setting, applying changes if allowed, 00187 // else throwing exception 00188 $anonsetting = $backup_controller->get_plan()->get_setting('anonymize'); 00189 $prevvalue = $anonsetting->get_value(); 00190 $prevstatus = $anonsetting->get_status(); 00191 $hasanoncap = has_capability('moodle/backup:anonymise', $coursectx, $userid); 00192 00193 // If setting is enabled but user lacks permission 00194 if (!$hasanoncap && $prevvalue) { // If user has not the capability and setting is enabled 00195 // Now analyse if we are allowed to apply changes or must stop with exception 00196 if (!$apply) { // Cannot apply changes, throw exception 00197 $a = new stdclass(); 00198 $a->setting = 'anonymize'; 00199 $a->value = $prevvalue; 00200 $a->capability = 'moodle/backup:anonymise'; 00201 throw new backup_controller_exception('backup_setting_value_wrong_for_capability', $a); 00202 00203 } else { // Can apply changes 00204 $anonsetting->set_value(false); // Set the value to false 00205 $anonsetting->set_status(base_setting::LOCKED_BY_PERMISSION);// Set the status to locked by perm 00206 } 00207 } 00208 00209 // Now, if mode is HUB or IMPORT, and still we are including users in backup, turn them off 00210 // Defaults processing should have handled this, but we need to be 100% sure 00211 if ($mode == backup::MODE_IMPORT || $mode == backup::MODE_HUB) { 00212 $userssetting = $backup_controller->get_plan()->get_setting('users'); 00213 if ($userssetting->get_value()) { 00214 $userssetting->set_value(false); // Set the value to false 00215 $userssetting->set_status(base_setting::LOCKED_BY_PERMISSION);// Set the status to locked by perm 00216 } 00217 } 00218 00219 // Check the user has the ability to configure the backup. If not then we need 00220 // to lock all settings by permission so that no changes can be made. This does 00221 // not apply to the import facility, where the activities must be always enabled 00222 // to be able to pick them 00223 if ($mode != backup::MODE_IMPORT) { 00224 $hasconfigcap = has_capability('moodle/backup:configure', $coursectx, $userid); 00225 if (!$hasconfigcap) { 00226 $settings = $backup_controller->get_plan()->get_settings(); 00227 foreach ($settings as $setting) { 00228 if ($setting->get_name() == 'filename') { 00229 continue; 00230 } 00231 $setting->set_status(base_setting::LOCKED_BY_PERMISSION); 00232 } 00233 } 00234 } 00235 00236 return true; 00237 } 00238 }