This commit is contained in:
Eloy Lafuente (stronk7) 2021-12-01 17:13:22 +01:00
commit 74f126770d
2 changed files with 68 additions and 13 deletions

View File

@ -126,18 +126,34 @@ class customfield extends \core_search\base {
/**
* Whether the user can access the document or not.
*
* @param int $id The course instance id.
* @param int $id The custom field data ID
* @return int
*/
public function check_access($id) {
global $DB;
$course = $DB->get_record('course', array('id' => $id));
$coursesql = '
SELECT c.*
FROM {course} c
JOIN {customfield_data} d ON d.instanceid = c.id
WHERE d.id = :dataid';
// Verify both the course and data record still exist.
$course = $DB->get_record_sql($coursesql, ['dataid' => $id]);
if (!$course) {
return \core_search\manager::ACCESS_DELETED;
}
if (\core_course_category::can_view_course_info($course)) {
// Check whether user is enrolled and the course is visible, or user can view it while hidden.
$context = \context_course::instance($course->id);
$userenrolled = is_enrolled($context) &&
($course->visible || has_capability('moodle/course:viewhiddencourses', $context));
// Grant access if user is considered enrolled, or they can otherwise see the course info.
if ($userenrolled || \core_course_category::can_view_course_info($course)) {
return \core_search\manager::ACCESS_GRANTED;
}
return \core_search\manager::ACCESS_DENIED;
}

View File

@ -542,6 +542,8 @@ class course_search_testcase extends advanced_testcase {
* Document accesses for customfield area.
*/
public function test_customfield_access() {
global $DB;
$this->resetAfterTest();
// Returns the instance as long as the area is supported.
@ -550,25 +552,62 @@ class course_search_testcase extends advanced_testcase {
$user1 = self::getDataGenerator()->create_user();
$user2 = self::getDataGenerator()->create_user();
$course1 = self::getDataGenerator()->create_course();
$course2 = self::getDataGenerator()->create_course(array('visible' => 0));
$course3 = self::getDataGenerator()->create_course();
// Create our custom field.
$customfieldcategory = $this->getDataGenerator()->create_custom_field_category([]);
$customfield = $this->getDataGenerator()->create_custom_field([
'categoryid' => $customfieldcategory->get('id'),
'type' => 'text',
'shortname' => 'myfield',
]);
// Create courses, each containing our custom field.
$course1 = $this->getDataGenerator()->create_course(['customfield_myfield' => 'Lionel']);
$course2 = $this->getDataGenerator()->create_course(['customfield_myfield' => 'Rick', 'visible' => 0]);
$course3 = $this->getDataGenerator()->create_course(['customfield_myfield' => 'Jack']);
$this->getDataGenerator()->enrol_user($user1->id, $course1->id, 'teacher');
$this->getDataGenerator()->enrol_user($user2->id, $course1->id, 'student');
$this->getDataGenerator()->enrol_user($user1->id, $course2->id, 'teacher');
$this->getDataGenerator()->enrol_user($user2->id, $course2->id, 'student');
$this->setUser($user1);
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course1->id));
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course2->id));
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course3->id));
// Prevent users viewing course lists.
$userrole = $DB->get_field('role', 'id', ['shortname' => 'user'], MUST_EXIST);
assign_capability('moodle/category:viewcourselist', CAP_PREVENT, $userrole, context_system::instance()->id, true);
// The following assertions check whether each user can view the indexed customfield data record.
$course1data = \core_customfield\data::get_record([
'fieldid' => $customfield->get('id'),
'instanceid' => $course1->id,
]);
$course2data = \core_customfield\data::get_record([
'fieldid' => $customfield->get('id'),
'instanceid' => $course2->id,
]);
$course3data = \core_customfield\data::get_record([
'fieldid' => $customfield->get('id'),
'instanceid' => $course3->id,
]);
// Admin user should see all present custom fields.
$this->setAdminUser();
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course1data->get('id')));
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course2data->get('id')));
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course3data->get('id')));
$this->assertEquals(\core_search\manager::ACCESS_DELETED, $searcharea->check_access(-123));
// First user (teacher) should see all those in the courses they are teaching.
$this->setUser($user1);
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course1data->get('id')));
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course2data->get('id')));
$this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($course3data->get('id')));
$this->assertEquals(\core_search\manager::ACCESS_DELETED, $searcharea->check_access(-123));
// Second user (student) should see all those in visible courses they are studying.
$this->setUser($user2);
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course1->id));
$this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($course2->id));
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course3->id));
$this->assertEquals(\core_search\manager::ACCESS_GRANTED, $searcharea->check_access($course1data->get('id')));
$this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($course2data->get('id')));
$this->assertEquals(\core_search\manager::ACCESS_DENIED, $searcharea->check_access($course3data->get('id')));
$this->assertEquals(\core_search\manager::ACCESS_DELETED, $searcharea->check_access(-123));
}
/**