From 106f3b6779528c6e91130c3cc5f2219376fcc526 Mon Sep 17 00:00:00 2001 From: skodak Date: Mon, 8 Sep 2008 23:16:48 +0000 Subject: [PATCH] MDL-16394 user profile browsing and serving improvements --- lang/en_utf8/repository.php | 1 + lib/file/file_browser.php | 67 +++++++++++++++++++++++++++---- lib/file/file_info_user.php | 15 ++++++- pluginfile.php | 80 +++++++++++++++++++++++++++++-------- userfile.php | 45 +++++++++------------ 5 files changed, 156 insertions(+), 52 deletions(-) diff --git a/lang/en_utf8/repository.php b/lang/en_utf8/repository.php index beec7452f4..231f9b9fed 100644 --- a/lang/en_utf8/repository.php +++ b/lang/en_utf8/repository.php @@ -9,6 +9,7 @@ $string['areacourseintro'] = 'Course introduction'; $string['arearoot'] = 'System'; $string['areauserdraft'] = 'Drafts'; $string['areauserpersonal'] = 'Personal'; +$string['areauserprofile'] = 'Profile'; $string['attachment'] = 'Attachment'; $string['back'] = '< Back'; $string['cacheexpire'] = 'Cache expire'; diff --git a/lib/file/file_browser.php b/lib/file/file_browser.php index bb3aa7f015..ce6a314247 100644 --- a/lib/file/file_browser.php +++ b/lib/file/file_browser.php @@ -36,20 +36,36 @@ class file_browser { //TODO: question files browsing } else if ($context->contextlevel == CONTEXT_USER) { - // access control: only own files - if ($context->instanceid != $USER->id) { + + if ($context->instanceid == $USER->id) { + $user = $USER; + } else { + $user = $DB->get_record('user', array('id'=>$context->instanceid)); + } + + if (isguestuser($user)) { return null; } - if (!is_null($filearea) and !in_array($filearea, array('user_private', 'user_draft'))) { - // file area does not exist, sorry + if ($user->deleted) { return null; } if (is_null($filearea)) { + // access control: list areas only for myself + if ($context->instanceid != $USER->id) { + return null; + } + return new file_info_user($this, $context); + } else { if ($filearea == 'user_private') { + // access control: only my files for now, nobody else + if ($context->instanceid != $USER->id) { + return null; + } + if (is_null($itemid)) { return new file_info_user($this, $context); } @@ -67,9 +83,46 @@ class file_browser { $urlbase = $CFG->wwwroot.'/userfile.php'; return new file_info_stored($this, $context, $storedfile, $urlbase, get_string('areauserpersonal', 'repository'), false, true, true); + } else if ($filearea == 'user_profile') { + if (is_null($itemid)) { + return new file_info_user($this, $context); + } + + // access controll here must match user edit forms + if ($user->id == $USER->id) { + if (!has_capability('moodle/user:editownprofile', get_context_instance(CONTEXT_SYSTEM))) { + return null; + } + } else { + if (!has_capability('moodle/user:editprofile', $context) and !has_capability('moodle/user:update', $context)) { + return null; + } + } + + $filepath = is_null($filepath) ? '/' : $filepath; + $filename = is_null($filename) ? '.' : $filename; + + if (!$storedfile = $fs->get_file($context->id, $filearea, 0, $filepath, $filename)) { + if ($filepath === '/' and $filename === '.') { + $storedfile = new virtual_root_file($context->id, $filearea, 0); + } else { + // not found + return null; + } + } + $urlbase = $CFG->wwwroot.'/userfile.php'; + return new file_info_stored($this, $context, $storedfile, $urlbase, get_string('areauserprofile', 'repository'), false, true, true); + + } else if ($filearea == 'user_draft') { + // access control: only my files + if ($context->instanceid != $USER->id) { + return null; + } + if (empty($itemid)) { - return new file_info_user($this, $context); + // do not browse itemids - you most know the draftid to see what is there + return null; } $urlbase = $CFG->wwwroot.'/draftfile.php'; if (!$storedfile = $fs->get_file($context->id, $filearea, $itemid, $filepath, $filename)) { @@ -232,9 +285,9 @@ class file_browser { } if (is_null($filearea) or is_null($itemid)) { return new file_info_module($this, $course, $cm, $context, $areas); - + } else if (!isset($areas[$filearea])) { - return null; + return null; } else if ($filearea === $modname.'_intro') { if (!has_capability('moodle/course:managefiles', $context)) { diff --git a/lib/file/file_info_user.php b/lib/file/file_info_user.php index b212529e43..f26e9d3e10 100644 --- a/lib/file/file_info_user.php +++ b/lib/file/file_info_user.php @@ -41,8 +41,19 @@ class file_info_user extends file_info { public function get_children() { global $USER, $CFG; - // only current user for now - return array($this->browser->get_file_info(get_context_instance(CONTEXT_USER, $USER->id), 'user_private', 0)); + $children = array(); + + if ($child = $this->browser->get_file_info(get_context_instance(CONTEXT_USER, $USER->id), 'user_private', 0)) { + $children[] = $child; + } + + if ($child = $this->browser->get_file_info(get_context_instance(CONTEXT_USER, $USER->id), 'user_profile', 0)) { + $children[] = $child; + } + + // do not list user_draft here - it is browsable only if you know the draft itemid ;-) + + return $children; } public function get_parent() { diff --git a/pluginfile.php b/pluginfile.php index 06dc3cb845..3e5aac164f 100644 --- a/pluginfile.php +++ b/pluginfile.php @@ -87,7 +87,7 @@ } else if ($context->contextlevel == CONTEXT_COURSECAT) { - if ($filearea !== 'intro') { + if ($filearea !== 'coursecat_intro') { send_file_not_found(); } @@ -97,7 +97,7 @@ } $relativepath = '/'.implode('/', $args); - $fullpath = $context->id.'intro0'.$relativepath; + $fullpath = $context->id.'coursecat_intro0'.$relativepath; if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->get_filename() == '.') { send_file_not_found(); @@ -108,36 +108,82 @@ } else if ($context->contextlevel == CONTEXT_COURSE) { - if ($filearea !== 'intro' and $filearea !== 'backup') { - send_file_not_found(); - } - if (!$course = $DB->get_record('course', array('id'=>$context->instanceid))) { print_error('invalidcourseid'); } - if ($filearea === 'backup') { + if ($filearea === 'course_backup') { require_login($course); require_capability('moodle/site:backupdownload', $context); - } else { + + $relativepath = '/'.implode('/', $args); + $fullpath = $context->id.'course_backup0'.$relativepath; + + if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { + send_file_not_found(); + } + + session_write_close(); // unlock session during fileserving + send_stored_file($file, 0, 0, true); + + } else if ($filearea === 'course_intro') { if ($CFG->forcelogin) { require_login(); } - } - $relativepath = '/'.implode('/', $args); - $fullpath = $context->id.'intro0'.$relativepath; + $relativepath = '/'.implode('/', $args); + $fullpath = $context->id.'course_intro0'.$relativepath; - if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { - send_file_not_found(); - } + if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { + send_file_not_found(); + } - session_write_close(); // unlock session during fileserving - send_stored_file($file, 60*60, 0, $forcedownload); + session_write_close(); // unlock session during fileserving + send_stored_file($file, 60*60, 0, false); // TODO: change timeout? + } else if ($filearea === 'user_profile') { + $userid = (int)array_shift($args); + $usercontext = get_context_instance(CONTEXT_USER, $userid); + + if (!empty($CFG->forceloginforprofiles)) { + require_login(); + if (isguestuser()) { + print_error('noguest'); + } + + if (!isteacherinanycourse() + and !isteacherinanycourse($userid) + and !has_capability('moodle/user:viewdetails', $usercontext)) { + print_error('usernotavailable'); + } + if (!has_capability('moodle/user:viewdetails', $context) && + !has_capability('moodle/user:viewdetails', $usercontext)) { + print_error('cannotviewprofile'); + } + if (!has_capability('moodle/course:view', $context, $userid, false)) { + print_error('notenrolledprofile'); + } + if (groups_get_course_groupmode($course) == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) { + print_error('groupnotamember'); + } + } + + $relativepath = '/'.implode('/', $args); + $fullpath = $usercontext->id.'user_profile0'.$relativepath; + + if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { + send_file_not_found(); + } + + session_write_close(); // unlock session during fileserving + send_stored_file($file, 0, 0, true); // must force download - security! + + } else { + send_file_not_found(); + } } else if ($context->contextlevel == CONTEXT_MODULE) { - + if (!$coursecontext = get_context_instance_by_id(get_parent_contextid($context))) { send_file_not_found(); } diff --git a/userfile.php b/userfile.php index 3d7a68c1e9..9b80068e36 100644 --- a/userfile.php +++ b/userfile.php @@ -32,47 +32,40 @@ } $userid = $context->instanceid; - if ($USER->id != $userid) { - print_error('invaliduserid'); - } switch ($filearea) { case 'user_profile': - if (!empty($CFG->forceloginforprofiles)) { - require_login(); - if (isguestuser()) { - print_error('noguest'); - } - $user = $DB->get_record("user", array("id"=>$userid)); - $usercontext = get_context_instance(CONTEXT_USER, $user->id); - if (!isteacherinanycourse() - and !isteacherinanycourse($user->id) - and !has_capability('moodle/user:viewdetails', $usercontext)) { - print_error('usernotavailable'); + require_login(); + if (isguestuser()) { + print_error('noguest'); + } + + // access controll here must match user edit forms + if ($userid == $USER->id) { + if (!has_capability('moodle/user:editownprofile', get_context_instance(CONTEXT_SYSTEM))) { + send_file_not_found(); + } + } else { + if (!has_capability('moodle/user:editprofile', $context) and !has_capability('moodle/user:update', $context)) { + send_file_not_found(); } - //TODO: find a way to get $coursecontext .. or equivalent check. - //if (!has_capability('moodle/user:viewdetails', $coursecontext) && - // !has_capability('moodle/user:viewdetails', $usercontext)) { - // print_error('cannotviewprofile'); - //} - //if (!has_capability('moodle/course:view', $coursecontext, $user->id, false)) { - // print_error('notenrolledprofile'); - //} - //if (groups_get_course_groupmode($course) == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $coursecontext)) { - // print_error('groupnotamember'); - //} } $itemid = 0; $forcedownload = true; break; + case 'user_private': require_login(); if (isguestuser()) { - print_error('noguest'); + send_file_not_found(); + } + if ($USER->id != $userid) { + send_file_not_found(); } $itemid = 0; $forcedownload = true; break; + default: send_file_not_found(); } -- 2.39.5