diff --git a/mod/data/lib.php b/mod/data/lib.php index 8659fd9d675..b3a572d8103 100755 --- a/mod/data/lib.php +++ b/mod/data/lib.php @@ -1359,6 +1359,14 @@ function data_rating_permissions($options) { } } +/** + * Returns the names of the table and columns necessary to check items for ratings + * @return array an array containing the item table, item id and user id columns + */ +function data_rating_item_check_info() { + return array('data_records','id','userid'); +} + /** * function that takes in the current data, number of items per page, diff --git a/mod/forum/lib.php b/mod/forum/lib.php index 6045ffdf51c..d1575ebae2b 100644 --- a/mod/forum/lib.php +++ b/mod/forum/lib.php @@ -3410,6 +3410,14 @@ function forum_rating_permissions($contextid) { } } +/** + * Returns the names of the table and columns necessary to check items for ratings + * @return array an array containing the item table, item id and user id columns + */ +function forum_rating_item_check_info() { + return array('forum_posts','id','userid'); +} + /** * This function prints the overview of a discussion in the forum listing. diff --git a/mod/glossary/lib.php b/mod/glossary/lib.php index 4fc6fd71d33..fc519cadaaf 100644 --- a/mod/glossary/lib.php +++ b/mod/glossary/lib.php @@ -474,6 +474,14 @@ function glossary_rating_permissions($options) { } } +/** + * Returns the names of the table and columns necessary to check items for ratings + * @return array an array containing the item table, item id and user id columns + */ +function glossary_rating_item_check_info() { + return array('glossary_entries','id','userid'); +} + /** * Update activity grades * diff --git a/rating/lib.php b/rating/lib.php index b392d347a4c..111a2a5a6d9 100644 --- a/rating/lib.php +++ b/rating/lib.php @@ -557,6 +557,13 @@ class rating_manager { return $aggregatestr; } + /** + * Looks for a callback and retrieves permissions from the plugin whose items are being rated + * @param int $contextid The current context id + * @param string plugintype the type of plugin ie 'mod' + * @param string pluginname the name of the plugin ie 'forum' + * @return array rating related permissions + */ public function get_plugin_permissions_array($contextid, $plugintype=null, $pluginname=null) { $pluginpermissionsarray = null; $defaultpluginpermissions = array('rate'=>true,'view'=>true,'viewany'=>true,'viewall'=>true);//all true == rely on system level permissions if no plugin callback is defined @@ -567,4 +574,29 @@ class rating_manager { } return $pluginpermissionsarray; } + + /** + * Checks if the item exists and is NOT owned by the current owner. Uses a callback to find out what table to look in. + * @param string plugintype the type of plugin ie 'mod' + * @param string pluginname the name of the plugin ie 'forum' + * @return boolean True if the callback doesn't exist. True if the item exists and doesn't belong to the current user. False otherwise. + */ + public function check_item_and_owner($plugintype, $pluginname, $itemid) { + global $DB, $USER; + + list($tablename,$itemidcol,$useridcol) = plugin_callback($plugintype, $pluginname, 'rating', 'item_check_info'); + + if (!empty($tablename)) { + $item = $DB->get_record($tablename, array($itemidcol=>$itemid), $useridcol); + if ($item) { + if ($item->userid!=$USER->id) { + return true; + } + } + + return false;//item doesn't exist or belongs to the current user + } else { + return true;//callback doesn't exist + } + } }//end rating_manager class definition diff --git a/rating/rate.php b/rating/rate.php index 84045408bbc..cf33c70ee6e 100644 --- a/rating/rate.php +++ b/rating/rate.php @@ -58,6 +58,11 @@ if ($context->contextlevel==CONTEXT_MODULE) { $rm = new rating_manager(); $pluginpermissionsarray = $rm->get_plugin_permissions_array($context->id, $plugintype, $pluginname); $pluginrateallowed = $pluginpermissionsarray['rate']; + + if ($pluginrateallowed) { + //check the item exists and isn't owned by the current user + $pluginrateallowed = $rm->check_item_and_owner($plugintype, $pluginname, $itemid); + } } if (!$pluginrateallowed || !has_capability('moodle/rating:rate',$context)) { @@ -67,8 +72,6 @@ if (!$pluginrateallowed || !has_capability('moodle/rating:rate',$context)) { die(); } -$userid = $USER->id; - $PAGE->set_url('/lib/rate.php', array( 'contextid'=>$context->id )); @@ -77,7 +80,7 @@ $ratingoptions = new stdclass; $ratingoptions->context = $context; $ratingoptions->itemid = $itemid; $ratingoptions->scaleid = $scaleid; -$ratingoptions->userid = $userid; +$ratingoptions->userid = $USER->id; $rating = new rating($ratingoptions); $rating->update_rating($userrating); diff --git a/rating/rate_ajax.php b/rating/rate_ajax.php index 1221ef20a59..61602b4568c 100644 --- a/rating/rate_ajax.php +++ b/rating/rate_ajax.php @@ -66,6 +66,11 @@ if ($context->contextlevel==CONTEXT_MODULE) { $rm = new rating_manager(); $pluginpermissionsarray = $rm->get_plugin_permissions_array($context->id, $plugintype, $pluginname); $pluginrateallowed = $pluginpermissionsarray['rate']; + + if ($pluginrateallowed) { + //check the item exists and isn't owned by the current user + $pluginrateallowed = $rm->check_item_and_owner($plugintype, $pluginname, $itemid); + } } if (!$pluginrateallowed || !has_capability('moodle/rating:rate',$context)) { @@ -136,8 +141,8 @@ if($rating->scaleid < 0 ) { //if its a scale (not numeric) //See if the user has permission to see the rating aggregate //we could do this check as "if $userid==$rateduserid" but going to the database to determine item owner id seems more secure //if we accept the item owner user id from the http request a user could alter the URL and erroneously get access to the rating aggregate -if (($userid==$items[0]->rating->itemuserid && has_capability('moodle/rating:view',$context) && $pluginpermissionsarray['view']) - || ($userid!=$items[0]->rating->itemuserid && has_capability('moodle/rating:viewany',$context) && $pluginpermissionsarray['viewany'])) { +if (($USER->id==$items[0]->rating->itemuserid && has_capability('moodle/rating:view',$context) && $pluginpermissionsarray['view']) + || ($USER->id!=$items[0]->rating->itemuserid && has_capability('moodle/rating:viewany',$context) && $pluginpermissionsarray['viewany'])) { $result->aggregate = $aggregatetoreturn; $result->count = $items[0]->rating->count; $result->itemid = $rating->itemid;