diff --git a/admin/user/user_bulk_message.php b/admin/user/user_bulk_message.php index 83161a7d554..008367b6b26 100644 --- a/admin/user/user_bulk_message.php +++ b/admin/user/user_bulk_message.php @@ -9,7 +9,7 @@ $confirm = optional_param('confirm', 0, PARAM_BOOL); require_login(); admin_externalpage_setup('userbulk'); -require_capability('moodle/site:readallmessages', context_system::instance()); +require_capability('moodle/site:manageallmessaging', context_system::instance()); $return = $CFG->wwwroot.'/'.$CFG->admin.'/user/user_bulk.php'; diff --git a/lang/en/role.php b/lang/en/role.php index 27b8921b0ea..4fb431c4f76 100644 --- a/lang/en/role.php +++ b/lang/en/role.php @@ -394,6 +394,7 @@ $string['site:doclinks'] = 'Show links to offsite docs'; $string['site:forcelanguage'] = 'Override course language'; $string['site:import'] = 'Import other courses into a course'; $string['site:maintenanceaccess'] = 'Allowed access when maintenance mode is enabled.'; +$string['site:manageallmessaging'] = 'Can perform all messaging actions on site'; $string['site:manageblocks'] = 'Manage blocks on a page'; $string['site:mnetloginfromremote'] = 'Login from a remote application via MNet'; $string['site:mnetlogintoremote'] = 'Roam to a remote application via MNet'; diff --git a/lib/db/access.php b/lib/db/access.php index f371558d77e..4f529bdf483 100644 --- a/lib/db/access.php +++ b/lib/db/access.php @@ -77,6 +77,17 @@ $capabilities = array( ) ), + 'moodle/site:manageallmessaging' => array( + + 'riskbitmask' => RISK_PERSONAL, + + 'captype' => 'write', + 'contextlevel' => CONTEXT_SYSTEM, + 'archetypes' => array( + 'manager' => CAP_ALLOW + ) + ), + 'moodle/site:deleteanymessage' => array( 'riskbitmask' => RISK_DATALOSS, diff --git a/message/externallib.php b/message/externallib.php index a22831c389a..994ab4a952b 100644 --- a/message/externallib.php +++ b/message/externallib.php @@ -214,13 +214,26 @@ class core_message_external extends external_api { * @since Moodle 2.5 */ public static function create_contacts($userids, $userid = 0) { - global $CFG; + global $CFG, $USER; // Check if messaging is enabled. if (empty($CFG->messaging)) { throw new moodle_exception('disabled', 'message'); } + if (empty($userid)) { + $userid = $USER->id; + } + + // Validate context. + $context = context_system::instance(); + self::validate_context($context); + + $capability = 'moodle/site:manageallmessaging'; + if (($USER->id != $userid) && !has_capability($capability, $context)) { + throw new required_capability_exception($context, $capability, 'nopermissions', ''); + } + $params = array('userids' => $userids, 'userid' => $userid); $params = self::validate_parameters(self::create_contacts_parameters(), $params); @@ -276,13 +289,26 @@ class core_message_external extends external_api { * @since Moodle 2.5 */ public static function delete_contacts($userids, $userid = 0) { - global $CFG; + global $CFG, $USER; // Check if messaging is enabled. if (empty($CFG->messaging)) { throw new moodle_exception('disabled', 'message'); } + if (empty($userid)) { + $userid = $USER->id; + } + + // Validate context. + $context = context_system::instance(); + self::validate_context($context); + + $capability = 'moodle/site:manageallmessaging'; + if (($USER->id != $userid) && !has_capability($capability, $context)) { + throw new required_capability_exception($context, $capability, 'nopermissions', ''); + } + $params = array('userids' => $userids, 'userid' => $userid); $params = self::validate_parameters(self::delete_contacts_parameters(), $params); @@ -331,13 +357,26 @@ class core_message_external extends external_api { * @since Moodle 2.5 */ public static function block_contacts($userids, $userid = 0) { - global $CFG; + global $CFG, $USER; // Check if messaging is enabled. if (empty($CFG->messaging)) { throw new moodle_exception('disabled', 'message'); } + if (empty($userid)) { + $userid = $USER->id; + } + + // Validate context. + $context = context_system::instance(); + self::validate_context($context); + + $capability = 'moodle/site:manageallmessaging'; + if (($USER->id != $userid) && !has_capability($capability, $context)) { + throw new required_capability_exception($context, $capability, 'nopermissions', ''); + } + $params = array('userids' => $userids, 'userid' => $userid); $params = self::validate_parameters(self::block_contacts_parameters(), $params); @@ -393,13 +432,26 @@ class core_message_external extends external_api { * @since Moodle 2.5 */ public static function unblock_contacts($userids, $userid = 0) { - global $CFG; + global $CFG, $USER; // Check if messaging is enabled. if (empty($CFG->messaging)) { throw new moodle_exception('disabled', 'message'); } + if (empty($userid)) { + $userid = $USER->id; + } + + // Validate context. + $context = context_system::instance(); + self::validate_context($context); + + $capability = 'moodle/site:manageallmessaging'; + if (($USER->id != $userid) && !has_capability($capability, $context)) { + throw new required_capability_exception($context, $capability, 'nopermissions', ''); + } + $params = array('userids' => $userids, 'userid' => $userid); $params = self::validate_parameters(self::unblock_contacts_parameters(), $params); @@ -1679,8 +1731,9 @@ class core_message_external extends external_api { core_user::require_active_user($user); // Check if we have permissions for retrieve the information. - if ($userid != $USER->id and !has_capability('moodle/site:readallmessages', $context)) { - throw new moodle_exception('accessdenied', 'admin'); + $capability = 'moodle/site:manageallmessaging'; + if (($USER->id != $userid) && !has_capability($capability, $context)) { + throw new required_capability_exception($context, $capability, 'nopermissions', ''); } // Now, we can get safely all the blocked users. diff --git a/message/tests/externallib_test.php b/message/tests/externallib_test.php index e8584b1bf93..2d0678aa616 100644 --- a/message/tests/externallib_test.php +++ b/message/tests/externallib_test.php @@ -161,6 +161,11 @@ class core_message_externallib_testcase extends externallib_advanced_testcase { $return = array_pop($return); $this->assertEquals($return['warningcode'], 'contactnotcreated'); $this->assertEquals($return['itemid'], 99999); + + // Try to add a contact to another user, should throw an exception. + // All assertions must be added before this point. + $this->expectException('required_capability_exception'); + core_message_external::create_contacts(array($user2->id), $user3->id); } /** @@ -198,6 +203,11 @@ class core_message_externallib_testcase extends externallib_advanced_testcase { // Removing mixed valid and invalid data. $return = core_message_external::delete_contacts(array($user6->id, 99999)); $this->assertNull($return); + + // Try to delete a contact of another user contact list, should throw an exception. + // All assertions must be added before this point. + $this->expectException('required_capability_exception'); + core_message_external::delete_contacts(array($user2->id), $user3->id); } /** @@ -244,6 +254,11 @@ class core_message_externallib_testcase extends externallib_advanced_testcase { $return = array_pop($return); $this->assertEquals($return['warningcode'], 'contactnotblocked'); $this->assertEquals($return['itemid'], 99999); + + // Try to block a contact of another user contact list, should throw an exception. + // All assertions must be added before this point. + $this->expectException('required_capability_exception'); + core_message_external::block_contacts(array($user2->id), $user3->id); } /** @@ -282,6 +297,10 @@ class core_message_externallib_testcase extends externallib_advanced_testcase { $return = core_message_external::unblock_contacts(array($user6->id, 99999)); $this->assertNull($return); + // Try to unblock a contact of another user contact list, should throw an exception. + // All assertions must be added before this point. + $this->expectException('required_capability_exception'); + core_message_external::unblock_contacts(array($user2->id), $user3->id); } /** diff --git a/version.php b/version.php index abc3bda27fe..5ccdc4e444f 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2016102700.00; // YYYYMMDD = weekly release date of this DEV branch. +$version = 2016102700.01; // YYYYMMDD = weekly release date of this DEV branch. // RR = release increments - 00 in DEV branches. // .XX = incremental changes.