Skip to content

Commit

Permalink
MDL-26838 rating: remove logged in users ability to sidestep rating v…
Browse files Browse the repository at this point in the history
…alidity checks
  • Loading branch information
andyjdavis committed May 1, 2011
1 parent eb9d692 commit 4af7c9d
Show file tree
Hide file tree
Showing 11 changed files with 314 additions and 87 deletions.
1 change: 1 addition & 0 deletions lang/en/rating.php
Expand Up @@ -50,6 +50,7 @@
$string['rate'] = 'Rate';
$string['ratepermissiondenied'] = 'You do not have permission to rate this item';
$string['rating'] = 'Rating';
$string['ratinginvalid'] = 'Rating is invalid';
$string['ratingtime'] = 'Restrict ratings to items with dates in this range:';
$string['ratings'] = 'Ratings';
$string['rolewarning'] = 'Roles with permission to rate';
Expand Down
4 changes: 4 additions & 0 deletions lib/outputrenderers.php
Expand Up @@ -1526,6 +1526,10 @@ function render_rating(rating $rating) {
$attributes = array('type'=>'hidden', 'class'=>'ratinginput', 'name'=>'contextid', 'value'=>$rating->context->id);
$formstart .= html_writer::empty_tag('input', $attributes);

$attributes['name'] = 'component';
$attributes['value'] = $rating->settings->component;
$formstart .= html_writer::empty_tag('input', $attributes);

$attributes['name'] = 'itemid';
$attributes['value'] = $rating->itemid;
$formstart .= html_writer::empty_tag('input', $attributes);
Expand Down
77 changes: 73 additions & 4 deletions mod/data/lib.php
Expand Up @@ -1369,11 +1369,80 @@ 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
* Validates a submitted rating
* @param array $params submitted data
* context => object the context in which the rated items exists [required]
* itemid => int the ID of the object being rated
* scaleid => int the scale from which the user can select a rating. Used for bounds checking. [required]
* rating => int the submitted rating
* rateduserid => int the id of the user whose items have been rated. NOT the user who submitted the ratings. 0 to update all. [required]
* aggregation => int the aggregation method to apply when calculating grades ie RATING_AGGREGATE_AVERAGE [required]
* @return boolean true if the rating is valid
*/
function data_rating_item_check_info() {
return array('data_records','id','userid');
function data_rating_add($params) {
global $DB, $USER;

if (!array_key_exists('itemid', $params) || !array_key_exists('context', $params)) {
debugging('itemid or context not supplied');
return false;
}

$datasql = "SELECT d.id as did, d.course, r.userid as userid, d.approval, r.approved, r.timecreated, d.assesstimestart, d.assesstimefinish, r.groupid
FROM {data_records} r
JOIN {data} d ON r.dataid = d.id
WHERE r.id = :itemid";
$dataparams = array('itemid'=>$params['itemid']);
if (!$info = $DB->get_record_sql($datasql, $dataparams)) {
//item id doesn't exist
return false;
}

if ($info->userid == $USER->id) {
//user is attempting to rate their own glossary entry
return false;
}

if ($info->approval && !$info->approved) {
//database requires approval but this item isnt approved
return false;
}

//check the item we're rating was created in the assessable time window
if (!empty($info->assesstimestart) && !empty($info->assesstimefinish)) {
if ($info->timecreated < $info->assesstimestart || $info->timecreated > $info->assesstimefinish) {
return false;
}
}

$dataid = $info->did;
$groupid = $info->groupid;
$courseid = $info->course;

$cm = get_coursemodule_from_instance('data', $dataid);
if (empty($cm)) {
return false;
}
$context = get_context_instance(CONTEXT_MODULE, $cm->id);

//if the supplied context doesnt match the item's context
if (empty($context) || $context->id != $params['context']->id) {
return false;
}

// Make sure groups allow this user to see the item they're rating
$course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST);
if ($groupid > 0 and $groupmode = groups_get_activity_groupmode($cm, $course)) { // Groups are being used
if (!groups_group_exists($groupid)) { // Can't find group
return false;//something is wrong
}

if (!groups_is_member($groupid) and !has_capability('moodle/site:accessallgroups', $context)) {
// do not allow rating of posts from other groups when in SEPARATEGROUPS or VISIBLEGROUPS
return false;
}
}

return true;
}


Expand Down
3 changes: 1 addition & 2 deletions mod/data/view.php
Expand Up @@ -667,15 +667,14 @@
if ($data->assessed!=RATING_AGGREGATE_NONE) {
$ratingoptions = new stdclass();
$ratingoptions->context = $context;
$ratingoptions->component = 'mod_data';
$ratingoptions->items = $records;
$ratingoptions->aggregate = $data->assessed;//the aggregation method
$ratingoptions->scaleid = $data->scale;
$ratingoptions->userid = $USER->id;
$ratingoptions->returnurl = $CFG->wwwroot.'/mod/data/'.$baseurl;
$ratingoptions->assesstimestart = $data->assesstimestart;
$ratingoptions->assesstimefinish = $data->assesstimefinish;
$ratingoptions->plugintype = 'mod';
$ratingoptions->pluginname = 'data';

$rm = new rating_manager();
$records = $rm->get_ratings($ratingoptions);
Expand Down
95 changes: 88 additions & 7 deletions mod/forum/lib.php
Expand Up @@ -3457,11 +3457,93 @@ 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');
* Validates a submitted rating
* @param array $params submitted data
* context => object the context in which the rated items exists [required]
* itemid => int the ID of the object being rated [required]
* scaleid => int the scale from which the user can select a rating. Used for bounds checking. [required]
* rating => int the submitted rating [required]
* rateduserid => int the id of the user whose items have been rated. NOT the user who submitted the ratings. 0 to update all. [required]
* aggregation => int the aggregation method to apply when calculating grades ie RATING_AGGREGATE_AVERAGE [required]
* @return boolean true if the rating is valid
*/
function forum_rating_add($params) {
global $DB, $USER;

if (!array_key_exists('itemid', $params) || !array_key_exists('context', $params)) {
return false;
}

$forumsql = "SELECT f.id as fid, f.course, d.id as did, p.userid as userid, p.created, f.assesstimestart, f.assesstimefinish, d.groupid
FROM {forum_posts} p
JOIN {forum_discussions} d ON p.discussion = d.id
JOIN {forum} f ON d.forum = f.id
WHERE p.id = :itemid";
$forumparams = array('itemid'=>$params['itemid']);
if (!$info = $DB->get_record_sql($forumsql, $forumparams)) {
//item id doesn't exist
return false;
}

if ($info->userid == $USER->id) {
//user is attempting to rate their own post
return false;
}

//check the item we're rating was created in the assessable time window
if (!empty($info->assesstimestart) && !empty($info->assesstimefinish)) {
if ($info->timecreated < $info->assesstimestart || $info->timecreated > $info->assesstimefinish) {
return false;
}
}

$forumid = $info->fid;
$discussionid = $info->did;
$groupid = $info->groupid;
$courseid = $info->course;

$cm = get_coursemodule_from_instance('forum', $forumid);
if (empty($cm)) {
return false;
}
$context = get_context_instance(CONTEXT_MODULE, $cm->id);

//if the supplied context doesnt match the item's context
if (empty($context) || $context->id != $params['context']->id) {
return false;
}

// Make sure groups allow this user to see the item they're rating
$course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST);
if ($groupid > 0 and $groupmode = groups_get_activity_groupmode($cm, $course)) { // Groups are being used
if (!groups_group_exists($groupid)) { // Can't find group
return false;//something is wrong
}

if (!groups_is_member($groupid) and !has_capability('moodle/site:accessallgroups', $context)) {
// do not allow rating of posts from other groups when in SEPARATEGROUPS or VISIBLEGROUPS
return false;
}
}

//need to load the full objects here as ajax scripts don't like
//the debugging messages produced by forum_user_can_see_post() if you just supply IDs
if (!$forum = $DB->get_record('forum',array('id'=>$forumid))) {
return false;
}
if (!$post = $DB->get_record('forum_posts',array('id'=>$params['itemid']))) {
return false;
}
if (!$discussion = $DB->get_record('forum_discussions',array('id'=>$discussionid))) {
return false;
}

//perform some final capability checks
if( !forum_user_can_see_post($forum, $discussion, $post, $USER, $cm)) {
return false;
}

return true;
}


Expand Down Expand Up @@ -5333,6 +5415,7 @@ function forum_print_discussion($course, $cm, $forum, $discussion, $post, $mode,
if ($forum->assessed!=RATING_AGGREGATE_NONE) {
$ratingoptions = new stdclass();
$ratingoptions->context = $modcontext;
$ratingoptions->component = 'mod_forum';
$ratingoptions->items = $posts;
$ratingoptions->aggregate = $forum->assessed;//the aggregation method
$ratingoptions->scaleid = $forum->scale;
Expand All @@ -5344,8 +5427,6 @@ function forum_print_discussion($course, $cm, $forum, $discussion, $post, $mode,
}
$ratingoptions->assesstimestart = $forum->assesstimestart;
$ratingoptions->assesstimefinish = $forum->assesstimefinish;
$ratingoptions->plugintype = 'mod';
$ratingoptions->pluginname = 'forum';

$rm = new rating_manager();
$posts = $rm->get_ratings($ratingoptions);
Expand Down
1 change: 1 addition & 0 deletions mod/forum/user.php
Expand Up @@ -165,6 +165,7 @@
//load ratings
if ($forum->assessed!=RATING_AGGREGATE_NONE) {
$ratingoptions->context = $forum->context;
$ratingoptions->component = 'mod_forum';
$ratingoptions->items = array($post);
$ratingoptions->aggregate = $forum->assessed;//the aggregation method
$ratingoptions->scaleid = $forum->scale;
Expand Down
63 changes: 58 additions & 5 deletions mod/glossary/lib.php
Expand Up @@ -471,11 +471,64 @@ 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');
* Validates a submitted rating
* @param array $params submitted data
* context => object the context in which the rated items exists [required]
* itemid => int the ID of the object being rated
* scaleid => int the scale from which the user can select a rating. Used for bounds checking. [required]
* rating => int the submitted rating
* rateduserid => int the id of the user whose items have been rated. NOT the user who submitted the ratings. 0 to update all. [required]
* aggregation => int the aggregation method to apply when calculating grades ie RATING_AGGREGATE_AVERAGE [optional]
* @return boolean true if the rating is valid
*/
function glossary_rating_add($params) {
global $DB, $USER;

if (!array_key_exists('itemid', $params) || !array_key_exists('context', $params)) {
return false;
}

$glossarysql = "SELECT g.id as gid, e.userid as userid, e.approved, e.timecreated, g.assesstimestart, g.assesstimefinish
FROM {glossary_entries} e
JOIN {glossary} g ON e.glossaryid = g.id
WHERE e.id = :itemid";
$glossaryparams = array('itemid'=>$params['itemid']);
if (!$info = $DB->get_record_sql($glossarysql, $glossaryparams)) {
//item id doesn't exist
return false;
}

if ($info->userid == $USER->id) {
//user is attempting to rate their own glossary entry
return false;
}

if (!$info->approved) {
//item isnt approved
return false;
}

//check the item we're rating was created in the assessable time window
if (!empty($info->assesstimestart) && !empty($info->assesstimefinish)) {
if ($info->timecreated < $info->assesstimestart || $info->timecreated > $info->assesstimefinish) {
return false;
}
}

$glossaryid = $info->gid;

$cm = get_coursemodule_from_instance('glossary', $glossaryid);
if (empty($cm)) {
return false;
}
$context = get_context_instance(CONTEXT_MODULE, $cm->id);

//if the supplied context doesnt match the item's context
if (empty($context) || $context->id != $params['context']->id) {
return false;
}

return true;
}

/**
Expand Down
3 changes: 1 addition & 2 deletions mod/glossary/view.php
Expand Up @@ -396,15 +396,14 @@
if ($glossary->assessed!=RATING_AGGREGATE_NONE) {
$ratingoptions = new stdclass();
$ratingoptions->context = $context;
$ratingoptions->component = 'mod_glossary';
$ratingoptions->items = $allentries;
$ratingoptions->aggregate = $glossary->assessed;//the aggregation method
$ratingoptions->scaleid = $glossary->scale;
$ratingoptions->userid = $USER->id;
$ratingoptions->returnurl = $CFG->wwwroot.'/mod/glossary/view.php?id='.$cm->id;
$ratingoptions->assesstimestart = $glossary->assesstimestart;
$ratingoptions->assesstimefinish = $glossary->assesstimefinish;
$ratingoptions->plugintype = 'mod';
$ratingoptions->pluginname = 'glossary';

$rm = new rating_manager();
$allentries = $rm->get_ratings($ratingoptions);
Expand Down

0 comments on commit 4af7c9d

Please sign in to comment.