Merge branch 'w41_MDL-29602_m22_accesslib' of git://github.com/skodak/moodle

This commit is contained in:
Eloy Lafuente (stronk7) 2011-10-18 13:15:13 +02:00
commit c2551ed593
26 changed files with 4859 additions and 3124 deletions

View File

@ -65,13 +65,15 @@ if ($requestedqtype) {
// Get the question counts, and all the context information, for each
// context. That is, rows of these results can be used as $context objects.
$ctxpreload = context_helper::get_preload_record_columns_sql('con');
$ctxgroupby = implode(',', array_keys(context_helper::get_preload_record_columns('con')));
$counts = $DB->get_records_sql("
SELECT qc.contextid, count(1) as numquestions, sum(hidden) as numhidden, con.id, con.contextlevel, con.instanceid, con.path, con.depth
SELECT qc.contextid, count(1) as numquestions, sum(hidden) as numhidden, $ctxpreload
FROM {question} q
JOIN {question_categories} qc ON q.category = qc.id
JOIN {context} con ON con.id = qc.contextid
$sqlqtypetest
GROUP BY contextid, con.id, con.contextlevel, con.instanceid, con.path, con.depth
GROUP BY qc.contextid, $ctxgroupby
ORDER BY numquestions DESC, numhidden ASC, con.contextlevel ASC, con.id ASC", $params);
// Print the report heading.
@ -94,8 +96,10 @@ if ($requestedqtype) {
$totalhidden = 0;
foreach ($counts as $count) {
// Work out a link for editing questions in this context.
$contextname = print_context_name($count);
$url = question_edit_url($count);
context_helper::preload_from_record($count);
$context = context::instance_by_id($count->contextid);
$contextname = $context->get_context_name();
$url = question_edit_url($context);
if ($url) {
$contextname = '<a href="' . $url . '" title="' .
get_string('editquestionshere', 'report_questioninstances') .

View File

@ -96,7 +96,8 @@ foreach ($contexts as $conid => $con) {
/// Put the contexts into a tree structure.
foreach ($contexts as $conid => $con) {
$parentcontextid = get_parent_contextid($con);
$context = context::instance_by_id($conid);
$parentcontextid = get_parent_contextid($context);
if ($parentcontextid) {
$contexts[$parentcontextid]->children[] = $conid;
}
@ -156,13 +157,13 @@ function print_report_tree($contextid, $contexts, $systemcontext, $fullname) {
}
// Pull the current context into an array for convinience.
$context = $contexts[$contextid];
$context = context::instance_by_id($contextid);
// Print the context name.
echo $OUTPUT->heading(print_context_name($contexts[$contextid]), 4, 'contextname');
echo $OUTPUT->heading($context->get_context_name(), 4, 'contextname');
// If there are any role assignments here, print them.
foreach ($context->roleassignments as $ra) {
foreach ($contexts[$contextid]->roleassignments as $ra) {
$value = $ra->contextid . ',' . $ra->roleid;
$inputid = 'unassign' . $value;

View File

@ -138,7 +138,8 @@ if ($capability) {
// Put the contexts into a tree structure.
foreach ($contexts as $conid => $con) {
$parentcontextid = get_parent_contextid($con);
$context = context::instance_by_id($conid);
$parentcontextid = get_parent_contextid($context);
if ($parentcontextid) {
$contexts[$parentcontextid]->children[] = $conid;
}
@ -196,7 +197,8 @@ function print_report_tree($contextid, $contexts, $allroles) {
$url = "$CFG->wwwroot/$CFG->admin/roles/override.php?contextid=$contextid";
$title = get_string('changeoverrides', 'tool_capability');
}
echo '<h3><a href="' . $url . '" title="' . $title . '">', print_context_name($contexts[$contextid]), '</a></h3>';
$context = context::instance_by_id($contextid);
echo '<h3><a href="' . $url . '" title="' . $title . '">', $context->get_context_name(), '</a></h3>';
// If there are any role overrides here, print them.
if (!empty($contexts[$contextid]->rolecapabilities)) {

View File

@ -39,7 +39,9 @@
if ($shibbolethauth->user_login($frm->username, $frm->password)) {
$USER = authenticate_user_login($frm->username, $frm->password);
$user = authenticate_user_login($frm->username, $frm->password);
enrol_check_plugins($user);
session_set_user($user);
$USER->loggedin = true;
$USER->site = $CFG->wwwroot; // for added security, store the site in the
@ -75,9 +77,6 @@
}
}
enrol_check_plugins($USER);
load_all_capabilities(); /// This is what lets the user do anything on the site :-)
redirect($urltogo);
exit;

10
auth/upgrade.txt Normal file
View File

@ -0,0 +1,10 @@
This files describes API changes in /auth/* - plugins,
information provided here is intended especially for developers.
=== 2.2 ===
required changes in code:
* the correct sequence to set up global $USER is:
$user = get_complete_user_data('username', $username); // or $user = authenticate_user_login()
enrol_check_plugins($user);
session_set_user($user);

View File

@ -143,9 +143,9 @@ if (!empty($entry->id)) {
if ($CFG->useblogassociations && ($blogassociations = $DB->get_records('blog_association', array('blogid' => $entry->id)))) {
foreach ($blogassociations as $assocrec) {
$contextrec = $DB->get_record('context', array('id' => $assocrec->contextid));
$context = get_context_instance_by_id($assocrec->contextid);
switch ($contextrec->contextlevel) {
switch ($context->contextlevel) {
case CONTEXT_COURSE:
$entry->courseassoc = $assocrec->contextid;
break;

View File

@ -95,7 +95,7 @@ class blog_edit_form extends moodleform {
$a->modname = $mod->name;
$context = get_context_instance(CONTEXT_MODULE, $modid);
} else {
$context = $DB->get_record('context', array('id' => $entry->modassoc));
$context = get_context_instance_by_id($entry->modassoc);
$cm = $DB->get_record('course_modules', array('id' => $context->instanceid));
$a = new stdClass();
$a->modtype = $DB->get_field('modules', 'name', array('id' => $cm->module));
@ -134,7 +134,7 @@ class blog_edit_form extends moodleform {
// validate course association
if (!empty($data['courseassoc']) && has_capability('moodle/blog:associatecourse', $sitecontext)) {
$coursecontext = $DB->get_record('context', array('id' => $data['courseassoc'], 'contextlevel' => CONTEXT_COURSE));
$coursecontext = get_context_instance(CONTEXT_COURSE, $data['courseassoc']);
if ($coursecontext) {
if (!is_enrolled($coursecontext) and !is_viewing($coursecontext)) {
@ -149,12 +149,12 @@ class blog_edit_form extends moodleform {
if (!empty($data['modassoc'])) {
$modcontextid = $data['modassoc'];
$modcontext = $DB->get_record('context', array('id' => $modcontextid, 'contextlevel' => CONTEXT_MODULE));
$modcontext = get_context_instance(CONTEXT_MODULE, $modcontextid);
if ($modcontext) {
// get context of the mod's course
$path = explode('/', $modcontext->path);
$coursecontext = $DB->get_record('context', array('id' => $path[(count($path) - 2)]));
$coursecontext = get_context_instance_by_id($path[(count($path) - 2)]);
// ensure only one course is associated
if (!empty($data['courseassoc'])) {

View File

@ -247,10 +247,10 @@ class blog_entry {
// First find and show the associated course
foreach ($blogassociations as $assocrec) {
$contextrec = $DB->get_record('context', array('id' => $assocrec->contextid));
if ($contextrec->contextlevel == CONTEXT_COURSE) {
$assocurl = new moodle_url('/course/view.php', array('id' => $contextrec->instanceid));
$text = $DB->get_field('course', 'shortname', array('id' => $contextrec->instanceid)); //TODO: performance!!!!
$context = get_context_instance_by_id($assocrec->contextid);
if ($context->contextlevel == CONTEXT_COURSE) {
$assocurl = new moodle_url('/course/view.php', array('id' => $context->instanceid));
$text = $DB->get_field('course', 'shortname', array('id' => $context->instanceid)); //TODO: performance!!!!
$assocstr .= $OUTPUT->action_icon($assocurl, new pix_icon('i/course', $text), null, array(), true);
$hascourseassocs = true;
$assoctype = get_string('course');
@ -259,15 +259,15 @@ class blog_entry {
// Now show mod association
foreach ($blogassociations as $assocrec) {
$contextrec = $DB->get_record('context', array('id' => $assocrec->contextid));
$context = get_context_instance_by_id($assocrec->contextid);
if ($contextrec->contextlevel == CONTEXT_MODULE) {
if ($context->contextlevel == CONTEXT_MODULE) {
if ($hascourseassocs) {
$assocstr .= ', ';
$hascourseassocs = false;
}
$modinfo = $DB->get_record('course_modules', array('id' => $contextrec->instanceid));
$modinfo = $DB->get_record('course_modules', array('id' => $context->instanceid));
$modname = $DB->get_field('modules', 'name', array('id' => $modinfo->module));
$assocurl = new moodle_url('/mod/'.$modname.'/view.php', array('id' => $modinfo->id));

View File

@ -77,7 +77,7 @@ class enrol_guest_plugin extends enrol_plugin {
if (empty($instance->password)) {
// Temporarily assign them some guest role for this context
$context = get_context_instance(CONTEXT_COURSE, $instance->courseid);
$USER->access = load_temp_role($context, $CFG->guestroleid, $USER->access);
load_temp_course_role($context, $CFG->guestroleid);
return ENROL_REQUIRE_LOGIN_CACHE_PERIOD + time();
}
@ -131,7 +131,7 @@ class enrol_guest_plugin extends enrol_plugin {
// add guest role
$context = get_context_instance(CONTEXT_COURSE, $instance->courseid);
$USER->access = load_temp_role($context, $CFG->guestroleid, $USER->access);
load_temp_course_role($context, $CFG->guestroleid);
// go to the originally requested page
if (!empty($SESSION->wantsurl)) {

View File

@ -38,9 +38,6 @@ $context = get_context_instance(CONTEXT_COURSE, $course->id, MUST_EXIST);
require_login();
// Refreshing enrolment data in the USER session
load_all_capabilities();
if ($SESSION->wantsurl) {
$destination = $SESSION->wantsurl;
unset($SESSION->wantsurl);

8
enrol/upgrade.txt Normal file
View File

@ -0,0 +1,8 @@
This files describes API changes in /enrol/* - plugins,
information provided here is intended especially for developers.
=== 2.2 ===
required changes in code:
* load_temp_role() is deprecated, use load_temp_course_role() instead, temp role not loaded
* remove_temp_role() is deprecated, use remove_temp_course_roles() instead

File diff suppressed because it is too large Load Diff

View File

@ -1014,7 +1014,11 @@ function fix_course_sortorder() {
// now fix the paths and depths in context table if needed
if ($fixcontexts) {
rebuild_contexts($fixcontexts);
foreach ($fixcontexts as $fixcontext) {
$fixcontext->reset_paths(false);
}
context_helper::build_all_paths(false);
unset($fixcontexts);
}
// release memory

View File

@ -29,14 +29,17 @@ defined('MOODLE_INTERNAL') || die();
function xmldb_main_install() {
global $CFG, $DB, $SITE;
/// make sure system context exists
$syscontext = get_system_context(false);
if ($syscontext->id != 1) {
/// Make sure system context exists
$syscontext = context_system::instance(0, MUST_EXIST, false);
if ($syscontext->id != SYSCONTEXTID) {
throw new moodle_exception('generalexceptionmessage', 'error', '', 'Unexpected new system context id!');
}
/// create site course
/// Create site course
if ($DB->record_exists('course', array())) {
throw new moodle_exception('generalexceptionmessage', 'error', '', 'Can not create frontpage course, courses already exist.');
}
$newsite = new stdClass();
$newsite->fullname = '';
$newsite->shortname = '';
@ -48,18 +51,38 @@ function xmldb_main_install() {
$newsite->timecreated = time();
$newsite->timemodified = $newsite->timecreated;
$newsite->id = $DB->insert_record('course', $newsite);
if (defined('SITEID')) {
$newsite->id = SITEID;
$DB->import_record('course', $newsite);
$DB->get_manager()->reset_sequence('course');
} else {
$newsite->id = $DB->insert_record('course', $newsite);
define('SITEID', $newsite->id);
}
$SITE = get_site();
if ($newsite->id != 1 or $SITE->id != 1) {
if ($newsite->id != $SITE->id) {
throw new moodle_exception('generalexceptionmessage', 'error', '', 'Unexpected new site course id!');
}
// Make sure site course context exists
context_course::instance($SITE->id);
// Update the global frontpage cache
$SITE = $DB->get_record('course', array('id'=>$newsite->id), '*', MUST_EXIST);
/// make sure site course context exists
get_context_instance(CONTEXT_COURSE, $SITE->id);
/// Create default course category
if ($DB->record_exists('course_categories', array())) {
throw new moodle_exception('generalexceptionmessage', 'error', '', 'Can not create default course category, categories already exist.');
}
$cat = new stdClass();
$cat->name = get_string('miscellaneous');
$cat->depth = 1;
$cat->sortorder = MAX_COURSES_IN_CATEGORY;
$cat->timemodified = time();
$catid = $DB->insert_record('course_categories', $cat);
$DB->set_field('course_categories', 'path', '/'.$catid, array('id'=>$catid));
// Make sure category context exists
context_coursecat::instance($catid);
/// create default course category
$cat = get_course_category();
$defaults = array(
'rolesactive' => '0', // marks fully set up system
@ -82,7 +105,7 @@ function xmldb_main_install() {
}
/// bootstrap mnet
/// Bootstrap mnet
$mnethost = new stdClass();
$mnethost->wwwroot = $CFG->wwwroot;
$mnethost->name = '';
@ -137,7 +160,10 @@ function xmldb_main_install() {
$mnetallhosts->id = $DB->insert_record('mnet_host', $mnetallhosts, true);
set_config('mnet_all_hosts_id', $mnetallhosts->id);
/// Create guest record - do not assign any role, guest user get's the default guest role automatically on the fly
/// Create guest record - do not assign any role, guest user gets the default guest role automatically on the fly
if ($DB->record_exists('user', array())) {
throw new moodle_exception('generalexceptionmessage', 'error', '', 'Can not create default users, users already exist.');
}
$guest = new stdClass();
$guest->auth = 'manual';
$guest->username = 'guest';
@ -156,6 +182,8 @@ function xmldb_main_install() {
}
// Store guest id
set_config('siteguest', $guest->id);
// Make sure user context exists
context_user::instance($guest->id);
/// Now create admin user
@ -176,8 +204,10 @@ function xmldb_main_install() {
if ($admin->id != 2) {
throw new moodle_exception('generalexceptionmessage', 'error', '', 'Unexpected new admin user id!');
}
/// Store list of admins
// Store list of admins
set_config('siteadmins', $admin->id);
// Make sure user context exists
context_user::instance($admin->id);
/// Install the roles system.
@ -264,17 +294,16 @@ function xmldb_main_install() {
require_once($CFG->libdir . '/licenselib.php');
license_manager::install_licenses();
/// Add two lines of data into this new table
// Init profile pages defaults
if ($DB->record_exists('my_pages', array())) {
throw new moodle_exception('generalexceptionmessage', 'error', '', 'Can not create default profile pages, records already exist.');
}
$mypage = new stdClass();
$mypage->userid = NULL;
$mypage->name = '__default';
$mypage->private = 0;
$mypage->sortorder = 0;
if (!$DB->record_exists('my_pages', array('userid'=>NULL, 'private'=>0))) {
$DB->insert_record('my_pages', $mypage);
}
$DB->insert_record('my_pages', $mypage);
$mypage->private = 1;
if (!$DB->record_exists('my_pages', array('userid'=>NULL, 'private'=>1))) {
$DB->insert_record('my_pages', $mypage);
}
$DB->insert_record('my_pages', $mypage);
}

View File

@ -280,28 +280,28 @@ function isteacher() {
* @deprecated
*/
function isteacherinanycourse() {
error('Function isteacherinanycourse() was removed, please use capabilities instead!');
throw new coding_Exception('Function isteacherinanycourse() was removed, please use capabilities instead!');
}
/**
* @deprecated
*/
function get_guest() {
error('Function get_guest() was removed, please use capabilities instead!');
throw new coding_Exception('Function get_guest() was removed, please use capabilities instead!');
}
/**
* @deprecated
*/
function isguest() {
error('Function isguest() was removed, please use capabilities instead!');
throw new coding_Exception('Function isguest() was removed, please use capabilities instead!');
}
/**
* @deprecated
*/
function get_teacher() {
error('Function get_teacher() was removed, please use capabilities instead!');
throw new coding_Exception('Function get_teacher() was removed, please use capabilities instead!');
}
/**
@ -371,15 +371,7 @@ function get_recent_enrolments($courseid, $timestart) {
* @return object
*/
function make_context_subobj($rec) {
$ctx = new StdClass;
$ctx->id = $rec->ctxid; unset($rec->ctxid);
$ctx->path = $rec->ctxpath; unset($rec->ctxpath);
$ctx->depth = $rec->ctxdepth; unset($rec->ctxdepth);
$ctx->contextlevel = $rec->ctxlevel; unset($rec->ctxlevel);
$ctx->instanceid = $rec->id;
$rec->context = $ctx;
return $rec;
throw new coding_Exception('make_context_subobj() was removed, use new context preloading');
}
/**
@ -395,10 +387,7 @@ function make_context_subobj($rec) {
* for this thing.
*/
function is_context_subobj_valid($rec, $contextlevel) {
return isset($rec->context) && isset($rec->context->id) &&
isset($rec->context->path) && isset($rec->context->depth) &&
isset($rec->context->contextlevel) && isset($rec->context->instanceid) &&
$rec->context->contextlevel == $contextlevel && $rec->context->instanceid == $rec->id;
throw new coding_Exception('is_context_subobj_valid() was removed, use new context preloading');
}
/**
@ -415,9 +404,7 @@ function is_context_subobj_valid($rec, $contextlevel) {
* @param integer $contextlevel the type of thing $rec is, one of the CONTEXT_... constants.
*/
function ensure_context_subobj_present(&$rec, $contextlevel) {
if (!is_context_subobj_valid($rec, $contextlevel)) {
$rec->context = get_context_instance($contextlevel, $rec->id);
}
throw new coding_Exception('ensure_context_subobj_present() was removed, use new context preloading');
}
########### FROM weblib.php ##########################################################################

View File

@ -188,7 +188,9 @@ function enrol_is_enabled($enrol) {
* Check all the login enrolment information for the given user object
* by querying the enrolment plugins
*
* @param object $user
* This function may be very slow, use only once after log-in or login-as.
*
* @param stdClass $user
* @return void
*/
function enrol_check_plugins($user) {
@ -201,7 +203,7 @@ function enrol_check_plugins($user) {
if (is_siteadmin()) {
// no sync for admin user, please use admin accounts only for admin tasks like the unix root user!
// if plugin fails on sync admins need to be able to log in
// if plugin fails on sync admins need to be able to log in and fix the settings
return;
}
@ -1150,7 +1152,7 @@ abstract class enrol_plugin {
}
if (isset($USER->enrol['tempguest'][$courseid])) {
unset($USER->enrol['tempguest'][$courseid]);
$USER->access = remove_temp_roles($context, $USER->access);
remove_temp_course_roles($context);
}
}
}
@ -1272,7 +1274,7 @@ abstract class enrol_plugin {
}
if (isset($USER->enrol['tempguest'][$courseid])) {
unset($USER->enrol['tempguest'][$courseid]);
$USER->access = remove_temp_roles($context, $USER->access);
remove_temp_course_roles($context);
}
}
}

View File

@ -2790,7 +2790,7 @@ function require_login($courseorid = NULL, $autologinguest = true, $cm = NULL, $
} else {
//expired
unset($USER->enrol['tempguest'][$course->id]);
$USER->access = remove_temp_roles($coursecontext, $USER->access);
remove_temp_course_roles($coursecontext);
}
}
@ -2817,7 +2817,7 @@ function require_login($courseorid = NULL, $autologinguest = true, $cm = NULL, $
$access = true;
// remove traces of previous temp guest access
$USER->access = remove_temp_roles($coursecontext, $USER->access);
remove_temp_course_roles($coursecontext);
} else {
$instances = $DB->get_records('enrol', array('courseid'=>$course->id, 'status'=>ENROL_INSTANCE_ENABLED), 'sortorder, id ASC');
@ -2831,7 +2831,7 @@ function require_login($courseorid = NULL, $autologinguest = true, $cm = NULL, $
$until = $enrols[$instance->enrol]->try_autoenrol($instance);
if ($until !== false) {
$USER->enrol['enrolled'][$course->id] = $until;
$USER->access = remove_temp_roles($coursecontext, $USER->access);
remove_temp_course_roles($coursecontext);
$access = true;
break;
}
@ -3031,6 +3031,7 @@ function require_user_key_login($script, $instance=null) {
}
/// emulate normal session
enrol_check_plugins($user);
session_set_user($user);
/// note we are not using normal login
@ -3882,12 +3883,15 @@ function complete_user_login($user) {
// this helps prevent session fixation attacks from the same domain
session_regenerate_id(true);
// let enrol plugins deal with new enrolments if necessary
enrol_check_plugins($user);
// check enrolments, load caps and setup $USER object
session_set_user($user);
// reload preferences from DB
unset($user->preference);
check_user_preferences_loaded($user);
unset($USER->preference);
check_user_preferences_loaded($USER);
// update login times
update_user_login_times();

View File

@ -2868,7 +2868,7 @@ class settings_navigation extends navigation_node {
$context = $this->context;
if ($context->contextlevel == CONTEXT_BLOCK) {
$this->load_block_settings();
$context = $DB->get_record_sql('SELECT ctx.* FROM {block_instances} bi LEFT JOIN {context} ctx ON ctx.id=bi.parentcontextid WHERE bi.id=?', array($context->instanceid));
$context = $context->get_parent_context();
}
switch ($context->contextlevel) {

View File

@ -894,7 +894,8 @@ function get_moodle_cookie() {
/**
* Setup $USER object - called during login, loginas, etc.
* Preloads capabilities and checks enrolment plugins
*
* Call sync_user_enrolments() manually after log-in, or log-in-as.
*
* @param stdClass $user full user record object
* @return void
@ -902,11 +903,6 @@ function get_moodle_cookie() {
function session_set_user($user) {
$_SESSION['USER'] = $user;
unset($_SESSION['USER']->description); // conserve memory
if (!isset($_SESSION['USER']->access)) {
// check enrolments and load caps only once
enrol_check_plugins($_SESSION['USER']);
load_all_capabilities();
}
sesskey(); // init session key
}
@ -950,6 +946,10 @@ function session_loginas($userid, $context) {
$user = get_complete_user_data('id', $userid);
$user->realuser = $_SESSION['REALUSER']->id;
$user->loginascontext = $context;
// let enrol plugins deal with new enrolments if necessary
enrol_check_plugins($user);
// set up global $USER
session_set_user($user);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,382 +0,0 @@
<?php
/**
* Unit tests for (some of) ../accesslib.php.
*
* @copyright &copy; 2006 The Open University
* @author T.J.Hunt@open.ac.uk
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package moodlecore
*/
if (!defined('MOODLE_INTERNAL')) {
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
}
class accesslib_test extends UnitTestCaseUsingDatabase {
public static $includecoverage = array('lib/accesslib.php');
function test_get_parent_contexts() {
$context = get_context_instance(CONTEXT_SYSTEM);
$this->assertEqual(get_parent_contexts($context), array());
$context = new stdClass;
$context->path = '/1/25';
$this->assertEqual(get_parent_contexts($context), array(1));
$context = new stdClass;
$context->path = '/1/123/234/345/456';
$this->assertEqual(get_parent_contexts($context), array(345, 234, 123, 1));
}
function test_get_parent_contextid() {
$context = get_context_instance(CONTEXT_SYSTEM);
$this->assertFalse(get_parent_contextid($context));
$context = new stdClass;
$context->path = '/1/25';
$this->assertEqual(get_parent_contextid($context), 1);
$context = new stdClass;
$context->path = '/1/123/234/345/456';
$this->assertEqual(get_parent_contextid($context), 345);
}
function test_get_users_by_capability() {
global $CFG;
$tablenames = array('capabilities', 'context', 'role', 'role_capabilities',
'role_allow_assign', 'role_allow_override', 'role_assignments', 'role_context_levels',
'user', 'groups_members', 'cache_flags', 'events_handlers', 'user_lastaccess', 'course');
$this->create_test_tables($tablenames, 'lib');
accesslib_clear_all_caches_for_unit_testing();
$this->switch_to_test_db();
$this->switch_to_test_cfg();
$course = new stdClass();
$course->category = 0;
$this->testdb->insert_record('course', $course);
$syscontext = get_system_context(false);
/// Install the roles system.
$coursecreatorrole = create_role(get_string('coursecreators'), 'coursecreator',
get_string('coursecreatorsdescription'), 'coursecreator');
$editteacherrole = create_role(get_string('defaultcourseteacher'), 'editingteacher',
get_string('defaultcourseteacherdescription'), 'editingteacher');
$noneditteacherrole = create_role(get_string('noneditingteacher'), 'teacher',
get_string('noneditingteacherdescription'), 'teacher');
$studentrole = create_role(get_string('defaultcoursestudent'), 'student',
get_string('defaultcoursestudentdescription'), 'student');
$guestrole = create_role(get_string('guest'), 'guest',
get_string('guestdescription'), 'guest');
$userrole = create_role(get_string('authenticateduser'), 'user',
get_string('authenticateduserdescription'), 'user');
/// Now is the correct moment to install capabilities - after creation of legacy roles, but before assigning of roles
update_capabilities('moodle');
update_capabilities('mod_forum');
update_capabilities('mod_quiz');
// Create some nested contexts. instanceid does not matter for this. Just
// ensure we don't violate any unique keys by using an unlikely number.
// We will fix paths in a second.
$contexts = $this->load_test_data('context',
array('contextlevel', 'instanceid', 'path', 'depth'), array(
1 => array(40, 666, '', 2),
2 => array(50, 666, '', 3),
3 => array(70, 666, '', 4),
));
$contexts[0] = $syscontext;
$contexts[1]->path = $contexts[0]->path . '/' . $contexts[1]->id;
$this->testdb->set_field('context', 'path', $contexts[1]->path, array('id' => $contexts[1]->id));
$contexts[2]->path = $contexts[1]->path . '/' . $contexts[2]->id;
$this->testdb->set_field('context', 'path', $contexts[2]->path, array('id' => $contexts[2]->id));
$contexts[3]->path = $contexts[2]->path . '/' . $contexts[3]->id;
$this->testdb->set_field('context', 'path', $contexts[3]->path, array('id' => $contexts[3]->id));
// Now make some test users.
$users = $this->load_test_data('user',
array('username', 'confirmed', 'deleted'), array(
'a' => array('a', 1, 0),
'cc' => array('cc', 1, 0),
't1' => array('t1', 1, 0),
's1' => array('s1', 1, 0),
's2' => array('s2', 1, 0),
'del' => array('del', 1, 1),
'unc' => array('unc', 0, 0),
));
// Get some of the standard roles.
$creator = $this->testdb->get_record('role', array('shortname' => 'coursecreator'));
$teacher = $this->testdb->get_record('role', array('shortname' => 'editingteacher'));
$student = $this->testdb->get_record('role', array('shortname' => 'student'));
$authuser = $this->testdb->get_record('role', array('shortname' => 'user'));
// And some role assignments.
$ras = $this->load_test_data('role_assignments',
array('userid', 'roleid', 'contextid'), array(
'cc' => array($users['cc']->id, $creator->id, $contexts[1]->id),
't1' => array($users['t1']->id, $teacher->id, $contexts[2]->id),
's1' => array($users['s1']->id, $student->id, $contexts[2]->id),
's2' => array($users['s2']->id, $student->id, $contexts[2]->id),
));
// And make user a into admin
$CFG->siteadmins = $users['a']->id;
$CFG->defaultuserroleid = $userrole;
// And some group memebership.
$gms = $this->load_test_data('groups_members',
array('userid', 'groupid'), array(
array($users['t1']->id, 666),
array($users['s1']->id, 666),
array($users['s2']->id, 667),
));
// Test some simple cases - check that looking in coruse and module contextlevel gives the same answer.
foreach (array(2, 3) as $conindex) {
$results = get_users_by_capability($contexts[$conindex], 'mod/forum:replypost');
// note: admin accounts are never returned, so no admin return here
$this->assert(new ArraysHaveSameValuesExpectation(
array($users['t1']->id, $users['s1']->id, $users['s2']->id)),
array_map(create_function('$o', 'return $o->id;'),
$results));
// Paging.
$firstuser = reset($results);
$this->assertEqual(array($firstuser->id => $firstuser), get_users_by_capability($contexts[$conindex], 'mod/forum:replypost', '', '', 0, 1));
$seconduser = next($results);
$this->assertEqual(array($seconduser->id => $seconduser), get_users_by_capability($contexts[$conindex], 'mod/forum:replypost', '', '', 1, 1));
// $doanything = false (ignored now)
$this->assert(new ArraysHaveSameValuesExpectation(
array($users['t1']->id, $users['s1']->id, $users['s2']->id)),
array_map(create_function('$o', 'return $o->id;'),
get_users_by_capability($contexts[$conindex], 'mod/forum:replypost', '', '', '', '', '', '', false)));
// group
$this->assert(new ArraysHaveSameValuesExpectation(
array($users['t1']->id, $users['s1']->id)),
array_map(create_function('$o', 'return $o->id;'),
get_users_by_capability($contexts[$conindex], 'mod/forum:replypost', '', '', '', '', 666)));
// exceptions
$this->assert(new ArraysHaveSameValuesExpectation(
array($users['s1']->id, $users['s2']->id)),
array_map(create_function('$o', 'return $o->id;'),
get_users_by_capability($contexts[$conindex], 'mod/forum:replypost', '', '', '', '', '', array($users['t1']->id))));
$this->assert(new ArraysHaveSameValuesExpectation(
array($users['s1']->id)),
array_map(create_function('$o', 'return $o->id;'),
get_users_by_capability($contexts[$conindex], 'mod/forum:replypost', '', '', '', '', 666, array($users['t1']->id))));
// $useviewallgroups
$this->assert(new ArraysHaveSameValuesExpectation(
array($users['t1']->id, $users['s2']->id)),
array_map(create_function('$o', 'return $o->id;'),
get_users_by_capability($contexts[$conindex], 'mod/forum:replypost', '', '', '', '', 667, '', false, false, true)));
// More than one capability.
$this->assert(new ArraysHaveSameValuesExpectation(
array($users['s1']->id, $users['s2']->id)),
array_map(create_function('$o', 'return $o->id;'),
get_users_by_capability($contexts[$conindex], array('mod/quiz:attempt', 'mod/quiz:reviewmyattempts'))));
}
// For reference: get_users_by_capability argument order:
// $context, $capability, $fields='', $sort='', $limitfrom='', $limitnum='',
// $groups='', $exceptions='', $doanything=true, $view=false, $useviewallgroups=false
// Now add some role overrides.
$rcs = $this->load_test_data('role_capabilities',
array('capability', 'roleid', 'contextid', 'permission'), array(
array('mod/forum:replypost', $student->id, $contexts[1]->id, CAP_PREVENT),
array('mod/forum:replypost', $student->id, $contexts[3]->id, CAP_ALLOW),
array('mod/quiz:attempt', $student->id, $contexts[2]->id, CAP_PREVENT),
array('mod/forum:startdiscussion', $student->id, $contexts[1]->id, CAP_PROHIBIT),
array('mod/forum:startdiscussion', $student->id, $contexts[3]->id, CAP_ALLOW),
array('mod/forum:viewrating', $authuser->id, $contexts[1]->id, CAP_PROHIBIT),
array('mod/forum:createattachment', $authuser->id, $contexts[3]->id, CAP_PREVENT),
));
// Now test the overridden cases.
// Students prevented at category level, with and without doanything.
$this->assert(new ArraysHaveSameValuesExpectation(
array($users['t1']->id)),
array_map(create_function('$o', 'return $o->id;'),
get_users_by_capability($contexts[2], 'mod/forum:replypost')));
$this->assert(new ArraysHaveSameValuesExpectation(
array($users['t1']->id)),
array_map(create_function('$o', 'return $o->id;'),
get_users_by_capability($contexts[2], 'mod/forum:replypost', '', '', '', '', '', '', false)));
// Students prevented at category level, but re-allowed at module level, with and without doanything.
$this->assert(new ArraysHaveSameValuesExpectation(
array($users['t1']->id, $users['s1']->id, $users['s2']->id)),
array_map(create_function('$o', 'return $o->id;'),
get_users_by_capability($contexts[3], 'mod/forum:replypost', '', '', '', '', '', '', false)));
$this->assert(new ArraysHaveSameValuesExpectation(
array($users['t1']->id, $users['s1']->id, $users['s2']->id)),
array_map(create_function('$o', 'return $o->id;'),
get_users_by_capability($contexts[3], 'mod/forum:replypost')));
// Students prohibited at category level, re-allowed at module level should have no effect.
$this->assert(new ArraysHaveSameValuesExpectation(
array($users['t1']->id)),
array_map(create_function('$o', 'return $o->id;'),
get_users_by_capability($contexts[2], 'mod/forum:startdiscussion')));
$this->assert(new ArraysHaveSameValuesExpectation(
array($users['t1']->id)),
array_map(create_function('$o', 'return $o->id;'),
get_users_by_capability($contexts[3], 'mod/forum:startdiscussion')));
// Prevent on logged-in user should be overridden by student allow.
$this->assert(new ArraysHaveSameValuesExpectation(
array($users['t1']->id, $users['s1']->id, $users['s2']->id)),
array_map(create_function('$o', 'return $o->id;'),
get_users_by_capability($contexts[3], 'mod/forum:createattachment')));
// Prohibit on logged-in user should trump student/teacher allow.
$this->assert(new ArraysHaveSameValuesExpectation(
array()),
array_map(create_function('$o', 'return $o->id;'),
get_users_by_capability($contexts[3], 'mod/forum:viewrating')));
// More than one capability, where students have one, but not the other.
$this->assert(new ArraysHaveSameValuesExpectation(
array($users['s1']->id, $users['s2']->id)),
array_map(create_function('$o', 'return $o->id;'),
get_users_by_capability($contexts[3], array('mod/quiz:attempt', 'mod/quiz:reviewmyattempts'), '', '', '', '', '', '', false)));
}
function test_get_switchable_roles() {
global $USER;
$tablenames = array('role' , 'role_capabilities', 'role_assignments', 'role_allow_switch',
'capabilities', 'context', 'role_names');
$this->create_test_tables($tablenames, 'lib');
$this->switch_to_test_db();
$this->switch_to_test_cfg();
// Ensure SYSCONTEXTID is set.
get_context_instance(CONTEXT_SYSTEM);
$contexts = $this->load_test_data('context',
array('contextlevel', 'instanceid', 'path', 'depth'), array(
'sys' => array(CONTEXT_SYSTEM, 0, '/' . SYSCONTEXTID, 1),
'cat' => array(CONTEXT_COURSECAT, 66, '/' . SYSCONTEXTID . '/' . (SYSCONTEXTID + 1), 2),
'cou' => array(CONTEXT_COURSE, 666, '/' . SYSCONTEXTID . '/' . (SYSCONTEXTID + 1) . '/' . (SYSCONTEXTID + 2), 3),
'fp' => array(CONTEXT_COURSE, SITEID, '/' . SYSCONTEXTID . '/' . SITEID, 2)));
$this->testdb->set_field('context', 'id', SYSCONTEXTID, array('id' => $contexts['sys']->id));
$this->testdb->set_field('context', 'id', SYSCONTEXTID + 1, array('id' => $contexts['cat']->id));
$this->testdb->set_field('context', 'id', SYSCONTEXTID + 2, array('id' => $contexts['cou']->id));
$syscontext = $contexts['sys'];
$syscontext->id = SYSCONTEXTID;
$context = $contexts['cou'];
$context->id = SYSCONTEXTID + 2;
$roles = $this->load_test_data('role',
array( 'name', 'shortname', 'description', 'sortorder'), array(
'r1' => array( 'r1', 'r1', 'not null', 2),
'r2' => array( 'r2', 'r2', 'not null', 3),
'funny' => array('funny', 'funny', 'not null', 4)));
$r1id = $roles['r1']->id;
$r2id = $roles['r2']->id;
$funnyid = $roles['funny']->id; // strange role
// Note that get_switchable_roles requires at least one capability for
// each role. I am not really clear why it was implemented that way
// but this makes the test work.
$roles = $this->load_test_data('role_capabilities',
array('roleid', 'capability'), array(
array($r1id, 'moodle/say:hello'),
array($r2id, 'moodle/say:hello'),
array($funnyid, 'moodle/say:hello'),
));
$this->load_test_data('role_assignments',
array('userid', 'contextid', 'roleid'), array(
array( 2, SYSCONTEXTID + 1 , $r1id),
array( 3, SYSCONTEXTID + 2 , $r2id)));
$this->load_test_data('role_allow_switch',
array('roleid', 'allowswitch'), array(
array( $r1id , $r2id),
array( $r2id , $r1id),
array( $r2id , $r2id),
array( $r2id , $funnyid)));
// r1 should be able to switch to r2, but this user only has r1 in $context, not $syscontext.
$this->switch_global_user_id(2);
accesslib_clear_all_caches_for_unit_testing();
$this->assert(new ArraysHaveSameValuesExpectation(array()), array_keys(get_switchable_roles($syscontext)));
$this->assert(new ArraysHaveSameValuesExpectation(array($r2id)), array_keys(get_switchable_roles($context)));
$this->revert_global_user_id();
// The table says r2 should be able to switch to all of r1, r2 and funny;
// this used to be restricted further beyond the switch table (for example
// to prevent you switching to roles with doanything) but is not any more
// (for example because doanything does not exist).
$this->switch_global_user_id(3);
accesslib_clear_all_caches_for_unit_testing();
$this->assert(new ArraysHaveSameValuesExpectation(array()), array_keys(get_switchable_roles($syscontext)));
$this->assert(new ArraysHaveSameValuesExpectation(array($r2id, $r1id, $funnyid)), array_keys(get_switchable_roles($context)));
}
function test_context_cache() {
// Create cache, empty
$cache = new context_cache();
$this->assertEqual(0, $cache->get_approx_count());
// Put context in cache
$context = (object)array('id'=>37,'contextlevel'=>50,'instanceid'=>13);
$cache->add($context);
$this->assertEqual(1, $cache->get_approx_count());
// Get context out of cache
$this->assertEqual($context, $cache->get(50, 13));
$this->assertEqual($context, $cache->get_by_id(37));
// Try to get context that isn't there
$this->assertEqual(false, $cache->get(50, 99));
$this->assertEqual(false, $cache->get(99, 13));
$this->assertEqual(false, $cache->get_by_id(99));
// Remove context from cache
$cache->remove($context);
$this->assertEqual(0, $cache->get_approx_count());
$this->assertEqual(false, $cache->get(50, 13));
$this->assertEqual(false, $cache->get_by_id(37));
// Add a stack of contexts to cache
for($i=0; $i<context_cache::MAX_SIZE; $i++) {
$context = (object)array('id'=>$i, 'contextlevel'=>50,
'instanceid'=>$i+1);
$cache->add($context);
}
$this->assertEqual(context_cache::MAX_SIZE, $cache->get_approx_count());
// Get a random sample from the middle
$sample = (object)array(
'id'=>174, 'contextlevel'=>50, 'instanceid'=>175);
$this->assertEqual($sample, $cache->get(50, 175));
$this->assertEqual($sample, $cache->get_by_id(174));
// Now add one more; should result in size being reduced
$context = (object)array('id'=>99999, 'contextlevel'=>50,
'instanceid'=>99999);
$cache->add($context);
$this->assertEqual(context_cache::MAX_SIZE - context_cache::REDUCE_SIZE + 1,
$cache->get_approx_count());
// Check that the first ones are no longer there
$this->assertEqual(false, $cache->get(50, 175));
$this->assertEqual(false, $cache->get_by_id(174));
// Check that the last ones are still there
$bigid = context_cache::MAX_SIZE - 10;
$sample = (object)array(
'id'=>$bigid, 'contextlevel'=>50, 'instanceid'=>$bigid+1);
$this->assertEqual($sample, $cache->get(50, $bigid+1));
$this->assertEqual($sample, $cache->get_by_id($bigid));
// Reset the cache
$cache->reset();
$this->assertEqual(0, $cache->get_approx_count());
$this->assertEqual(false, $cache->get(50, $bigid+1));
}
}

View File

@ -1417,11 +1417,11 @@ function upgrade_core($version, $verbose) {
purge_all_caches();
// Clean up contexts - more and more stuff depends on existence of paths and contexts
cleanup_contexts();
create_contexts();
build_context_path();
$syscontext = get_context_instance(CONTEXT_SYSTEM);
mark_context_dirty($syscontext->path);
context_helper::cleanup_instances();
context_helper::create_instances(null, false);
context_helper::build_all_paths(false);
$syscontext = context_system::instance();
$syscontext->mark_dirty();
print_upgrade_part_end('moodle', false, $verbose);
} catch (Exception $ex) {

View File

@ -56,6 +56,9 @@ if (!empty($user)) {
}
}
// let enrol plugins deal with new enrolments if necessary
enrol_check_plugins($user);
// setup user session to check capability
session_set_user($user);

View File

@ -16,9 +16,9 @@
/**
* rss/file.php - entry point to serve rss streams
*
*
* This script simply checks the parameters to construct a $USER
* then finds and calls a function in the relevant component to
* then finds and calls a function in the relevant component to
* actually check security and create the RSS stream
*
* @package moodlecore
@ -81,7 +81,7 @@ if ($token==="$inttoken") {
if (!isset($modinfo->instances[$componentname])) {
$modinfo->instances[$componentname] = array();
}
foreach ($modinfo->instances[$componentname] as $modinstanceid=>$cm) {
if ($modinstanceid==$instanceid) {
$context = get_context_instance(CONTEXT_MODULE, $cm->id);
@ -122,6 +122,10 @@ if ($token==="$inttoken") {
}
$user = get_complete_user_data('id', $userid);
// let enrol plugins deal with new enrolments if necessary
enrol_check_plugins($user);
session_set_user($user); //for login and capability checks
// Check the context actually exists

View File

@ -654,6 +654,7 @@ abstract class webservice_server implements webservice_server_interface {
}
// now fake user login, the session is completely empty too
enrol_check_plugins($user);
session_set_user($user);
$this->userid = $user->id;

View File

@ -66,6 +66,8 @@ $user = $DB->get_record('user', array('id'=>$token->userid, 'deleted'=>0), '*',
// log token access
$DB->set_field('external_tokens', 'lastaccess', time(), array('id'=>$token->id));
// let enrol plugins deal with new enrolments if necessary
enrol_check_plugins($user);
session_set_user($user);
$context = get_context_instance(CONTEXT_USER, $USER->id);
require_capability('moodle/user:manageownfiles', $context);