diff --git a/grade/classes/grades/grader/gradingpanel/scale/external/fetch.php b/grade/classes/grades/grader/gradingpanel/scale/external/fetch.php index 8f3bb48db43..3501e31a629 100644 --- a/grade/classes/grades/grader/gradingpanel/scale/external/fetch.php +++ b/grade/classes/grades/grader/gradingpanel/scale/external/fetch.php @@ -127,7 +127,12 @@ class fetch extends external_api { throw new moodle_exception("The {$itemname} item in {$component}/{$contextid} is not configured for grading with scales"); } - $gradeduser = \core_user::get_user($gradeduserid); + $gradeduser = \core_user::get_user($gradeduserid, '*', MUST_EXIST); + + // One can access its own grades. Others just if they're graders. + if ($gradeduserid != $USER->id) { + $gradeitem->require_user_can_grade($gradeduser, $USER); + } // Set up some items we need to return on other interfaces. $gradegrade = \grade_grade::fetch(['itemid' => $gradeitem->get_grade_item()->id, 'userid' => $gradeduser->id]); diff --git a/grade/tests/grades_grader_gradingpanel_scale_external_fetch_test.php b/grade/tests/grades_grader_gradingpanel_scale_external_fetch_test.php index cd5de19f158..9a8ec1d0543 100644 --- a/grade/tests/grades_grader_gradingpanel_scale_external_fetch_test.php +++ b/grade/tests/grades_grader_gradingpanel_scale_external_fetch_test.php @@ -189,14 +189,75 @@ class fetch_test extends advanced_testcase { $course = $forum->get_course_record(); $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher'); $student = $this->getDataGenerator()->create_and_enrol($course, 'student'); - $this->setUser($teacher); + + $this->execute_and_assert_fetch($forum, $options, $scale, $teacher, $teacher, $student); + } + + /** + * Class mates should not get other's grades. + */ + public function test_execute_fetch_does_not_return_data_to_other_students(): void { + $this->resetAfterTest(); + + $options = [ + 'A', + 'B', + 'C' + ]; + $scale = $this->getDataGenerator()->create_scale(['scale' => implode(',', $options)]); + + $forum = $this->get_forum_instance([ + // Negative numbers mean a scale. + 'grade_forum' => -1 * $scale->id + ]); + $course = $forum->get_course_record(); + $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher'); + $student = $this->getDataGenerator()->create_and_enrol($course, 'student'); + $evilstudent = $this->getDataGenerator()->create_and_enrol($course, 'student'); + + $this->expectException(\required_capability_exception::class); + $this->execute_and_assert_fetch($forum, $options, $scale, $evilstudent, $teacher, $student); + } + + /** + * Grades can be returned to graded user. + */ + public function test_execute_fetch_return_data_to_graded_user(): void { + $this->resetAfterTest(); + + $options = [ + 'A', + 'B', + 'C' + ]; + $scale = $this->getDataGenerator()->create_scale(['scale' => implode(',', $options)]); + + $forum = $this->get_forum_instance([ + // Negative numbers mean a scale. + 'grade_forum' => -1 * $scale->id + ]); + $course = $forum->get_course_record(); + $teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher'); + $student = $this->getDataGenerator()->create_and_enrol($course, 'student'); + + $this->execute_and_assert_fetch($forum, $options, $scale, $student, $teacher, $student); + } + + /** + * Executes the fetch method with the given users and returns the result. + */ + private function execute_and_assert_fetch ($forum, $options, $scale, $fetcheruser, $grader, $gradeduser) { + + $this->setUser($grader); $gradeitem = component_gradeitem::instance('mod_forum', $forum->get_context(), 'forum'); - $gradeitem->store_grade_from_formdata($student, $teacher, (object) [ + $gradeitem->store_grade_from_formdata($gradeduser, $grader, (object) [ 'grade' => 2, ]); - $result = fetch::execute('mod_forum', (int) $forum->get_context()->id, 'forum', (int) $student->id); + $this->setUser($fetcheruser); + + $result = fetch::execute('mod_forum', (int) $forum->get_context()->id, 'forum', (int) $gradeduser->id); $result = external_api::clean_returnvalue(fetch::execute_returns(), $result); $this->assertIsArray($result); @@ -204,7 +265,7 @@ class fetch_test extends advanced_testcase { $this->assertEquals('core_grades/grades/grader/gradingpanel/scale', $result['templatename']); - $result = fetch::execute('mod_forum', (int) $forum->get_context()->id, 'forum', (int) $student->id); + $result = fetch::execute('mod_forum', (int) $forum->get_context()->id, 'forum', (int) $gradeduser->id); $result = external_api::clean_returnvalue(fetch::execute_returns(), $result); $this->assertIsArray($result); @@ -232,7 +293,7 @@ class fetch_test extends advanced_testcase { $this->assertEquals(3, $result['grade']['maxgrade']); $this->assertArrayHasKey('gradedby', $result['grade']); - $this->assertEquals(fullname($teacher), $result['grade']['gradedby']); + $this->assertEquals(fullname($grader), $result['grade']['gradedby']); $this->assertArrayHasKey('options', $result['grade']); $this->assertCount(count($options), $result['grade']['options']);