diff --git a/contentbank/classes/contentbank.php b/contentbank/classes/contentbank.php index 1e5c93415bb..9152067264d 100644 --- a/contentbank/classes/contentbank.php +++ b/contentbank/classes/contentbank.php @@ -36,6 +36,10 @@ use context; * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class contentbank { + + /** @var array All the context levels allowed in the content bank */ + private const ALLOWED_CONTEXT_LEVELS = [CONTEXT_SYSTEM, CONTEXT_COURSECAT, CONTEXT_COURSE]; + /** @var array Enabled content types. */ private $enabledcontenttypes = null; @@ -348,4 +352,14 @@ class contentbank { $contentclass = "\\$record->contenttype\\content"; return new $contentclass($record); } + + /** + * Whether the context is allowed. + * + * @param context $context Context to check. + * @return bool + */ + public function is_context_allowed(context $context): bool { + return in_array($context->contextlevel, self::ALLOWED_CONTEXT_LEVELS); + } } diff --git a/contentbank/edit.php b/contentbank/edit.php index cdddcd4fd78..6d0c58d9643 100644 --- a/contentbank/edit.php +++ b/contentbank/edit.php @@ -30,6 +30,12 @@ $contextid = required_param('contextid', PARAM_INT); $pluginname = required_param('plugin', PARAM_PLUGIN); $id = optional_param('id', null, PARAM_INT); $context = context::instance_by_id($contextid, MUST_EXIST); + +$cb = new \core_contentbank\contentbank(); +if (!$cb->is_context_allowed($context)) { + print_error('contextnotallowed', 'core_contentbank'); +} + require_capability('moodle/contentbank:access', $context); $returnurl = new \moodle_url('/contentbank/view.php', ['id' => $id]); diff --git a/contentbank/index.php b/contentbank/index.php index 33eff295d36..c4d22428d9f 100644 --- a/contentbank/index.php +++ b/contentbank/index.php @@ -30,6 +30,11 @@ $contextid = optional_param('contextid', \context_system::instance()->id, PAR $search = optional_param('search', '', PARAM_CLEAN); $context = context::instance_by_id($contextid, MUST_EXIST); +$cb = new \core_contentbank\contentbank(); +if (!$cb->is_context_allowed($context)) { + print_error('contextnotallowed', 'core_contentbank'); +} + require_capability('moodle/contentbank:access', $context); $statusmsg = optional_param('statusmsg', '', PARAM_ALPHANUMEXT); @@ -47,7 +52,6 @@ $PAGE->set_heading($title); $PAGE->set_pagetype('contentbank'); // Get all contents managed by active plugins where the user has permission to render them. -$cb = new \core_contentbank\contentbank(); $contenttypes = []; $enabledcontenttypes = $cb->get_enabled_content_types(); foreach ($enabledcontenttypes as $contenttypename) { diff --git a/contentbank/tests/contentbank_test.php b/contentbank/tests/contentbank_test.php index 3d6a703a77f..9ca729a12ca 100644 --- a/contentbank/tests/contentbank_test.php +++ b/contentbank/tests/contentbank_test.php @@ -631,4 +631,76 @@ class core_contentbank_testcase extends advanced_testcase { $this->expectException(Exception::class); $cb->get_content_from_id(0); } + + /** + * Test the behaviour of is_context_allowed(). + * + * @dataProvider context_provider + * @param \Closure $getcontext Get the context to check. + * @param bool $expectedresult Expected result. + * + * @covers ::is_context_allowed + */ + public function test_is_context_allowed(\Closure $getcontext, bool $expectedresult): void { + $this->resetAfterTest(); + + $cb = new contentbank(); + $context = $getcontext(); + $this->assertEquals($expectedresult, $cb->is_context_allowed($context)); + } + + /** + * Data provider for test_is_context_allowed(). + * + * @return array + */ + public function context_provider(): array { + + return [ + 'System context' => [ + function (): \context { + return \context_system::instance(); + }, + true, + ], + 'User context' => [ + function (): \context { + $user = $this->getDataGenerator()->create_user(); + return \context_user::instance($user->id); + }, + false, + ], + 'Course category context' => [ + function (): \context { + $coursecat = $this->getDataGenerator()->create_category(); + return \context_coursecat::instance($coursecat->id); + }, + true, + ], + 'Course context' => [ + function (): \context { + $course = $this->getDataGenerator()->create_course(); + return \context_course::instance($course->id); + }, + true, + ], + 'Module context' => [ + function (): \context { + $course = $this->getDataGenerator()->create_course(); + $module = $this->getDataGenerator()->create_module('page', ['course' => $course->id]); + return \context_module::instance($module->cmid); + }, + false, + ], + 'Block context' => [ + function (): \context { + $course = $this->getDataGenerator()->create_course(); + $coursecontext = context_course::instance($course->id); + $block = $this->getDataGenerator()->create_block('online_users', ['parentcontextid' => $coursecontext->id]); + return \context_block::instance($block->id); + }, + false, + ], + ]; + } } diff --git a/contentbank/upload.php b/contentbank/upload.php index 4410de44a25..81a7870d044 100644 --- a/contentbank/upload.php +++ b/contentbank/upload.php @@ -32,9 +32,12 @@ require_login(); $contextid = optional_param('contextid', \context_system::instance()->id, PARAM_INT); $context = context::instance_by_id($contextid, MUST_EXIST); -require_capability('moodle/contentbank:upload', $context); - $cb = new \core_contentbank\contentbank(); +if (!$cb->is_context_allowed($context)) { + print_error('contextnotallowed', 'core_contentbank'); +} + +require_capability('moodle/contentbank:upload', $context); $id = optional_param('id', null, PARAM_INT); if ($id) { diff --git a/lang/en/contentbank.php b/lang/en/contentbank.php index 4e073a6a939..acbfc0df190 100644 --- a/lang/en/contentbank.php +++ b/lang/en/contentbank.php @@ -33,6 +33,7 @@ $string['contentrenamed'] = 'The content has been renamed.'; $string['contentsmoved'] = 'Content bank contents moved to {$a}.'; $string['contenttypenoaccess'] = 'You cannot view this {$a} instance.'; $string['contenttypenoedit'] = 'You can not edit this content'; +$string['contextnotallowed'] = 'Context is not allowed'; $string['emptynamenotallowed'] = 'Empty name is not allowed'; $string['eventcontentcreated'] = 'Content created'; $string['eventcontentdeleted'] = 'Content deleted';