Skip to:
Content

bbPress.org


Ignore:
Timestamp:
01/28/2020 10:12:13 PM (5 years ago)
Author:
johnjamesjacoby
Message:

BuddyPress: explicitly validate IDs when editing Group forum topics & replies.

This commit adds methods to validate that the forum IDs and reply-to IDs for topics & replies are within the accepted ranges for the specific Group Forum they are being edited inside of.

In addition, the moderate_forum mapped meta capability is removed, and the broader moderate capability will continue to cover its use case. This capability was not intended to be used directly, and doing so incorrectly would trigger unintended and infinite recursion.

For 2.7, trunk

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/includes/extend/buddypress/groups.php

    r7057 r7060  
    8686        // Remove group forum cap map when view is done
    8787        add_action( 'bbp_after_group_forum_display',  array( $this, 'remove_group_forum_meta_cap_map' ) );
     88
     89        // Validate group forum IDs when editing topics & replies
     90        add_action( 'bbp_edit_topic_pre_extras',      array( $this, 'validate_topic_forum_id' ) );
     91        add_action( 'bbp_edit_reply_pre_extras',      array( $this, 'validate_reply_to_id'    ) );
    8892
    8993        // Check if group-forum status should be changed
     
    279283
    280284            // If user is a group mod ar admin, map to participate cap.
    281             case 'moderate'     :
    282             case 'edit_topic'   :
    283             case 'edit_reply'   :
    284             case 'view_trash'   :
     285            case 'moderate'            :
     286            case 'edit_topic'          :
     287            case 'edit_reply'          :
     288            case 'view_trash'          :
    285289            case 'edit_others_replies' :
    286290            case 'edit_others_topics'  :
     
    310314    public function remove_group_forum_meta_cap_map() {
    311315        remove_filter( 'bbp_map_meta_caps', array( $this, 'map_group_forum_meta_caps' ), 99, 4 );
     316    }
     317
     318    /**
     319     * Validate the forum ID for a topic in a group forum.
     320     *
     321     * This method ensures that when a topic is saved, it is only allowed to be
     322     * saved to a forum that is either:
     323     *
     324     * - A forum in the current group
     325     * - A forum the current user can moderate outside of this group
     326     *
     327     * If all checks fail, an error gets added to prevent the topic from saving.
     328     *
     329     * @since 2.6.14
     330     *
     331     * @param int $topic_id
     332     */
     333    public function validate_topic_forum_id( $topic_id = 0 ) {
     334
     335        // Bail if no topic
     336        if ( empty( $topic_id ) ) {
     337            return;
     338        }
     339
     340        // Get current forum ID
     341        $forum_id = bbp_get_topic_forum_id( $topic_id );
     342
     343        // Bail if not a group forum
     344        if ( ! bbp_is_forum_group_forum( $forum_id ) ) {
     345            return;
     346        }
     347
     348        // Get current group ID
     349        $group_id = bp_get_current_group_id();
     350
     351        // Bail if unknown group ID
     352        if ( empty( $group_id ) ) {
     353            return;
     354        }
     355
     356        // Get group forum IDs
     357        $forum_ids = bbp_get_group_forum_ids( $group_id );
     358
     359        // Get posted forum ID
     360        $new_forum_id = ! empty( $_POST['bbp_forum_id'] )
     361            ? absint( $_POST['bbp_forum_id'] )
     362            : 0;
     363
     364        // Bail if new forum ID is a forum in this group
     365        if ( in_array( $new_forum_id, $forum_ids, true ) ) {
     366            return;
     367        }
     368
     369        // Get the current user ID
     370        $user_id = bbp_get_current_user_id();
     371
     372        // Bail if current user can moderate the new forum ID
     373        if ( bbp_is_user_forum_moderator( $user_id, $new_forum_id ) ) {
     374            return;
     375        }
     376
     377        // If everything else has failed, then something is wrong and we need
     378        // to add an error to prevent this topic from saving.
     379        bbp_add_error( 'bbp_topic_forum_id', __( '<strong>ERROR</strong>: Forum ID is invalid.', 'bbpress' ) );
     380    }
     381
     382    /**
     383     * Validate the reply to for a reply in a group forum.
     384     *
     385     * This method ensures that when a reply to is saved, it is only allowed to
     386     * be saved to the current topic.
     387     *
     388     * If all checks fail, an error gets added to prevent the reply from saving.
     389     *
     390     * @since 2.6.14
     391     *
     392     * @param int $reply_id
     393     */
     394    public function validate_reply_to_id( $reply_id = 0 ) {
     395
     396        // Bail if no reply
     397        if ( empty( $reply_id ) ) {
     398            return;
     399        }
     400
     401        // Get posted reply to
     402        $new_reply_to = ! empty( $_POST['bbp_reply_to'] )
     403            ? absint( $_POST['bbp_reply_to'] )
     404            : 0;
     405
     406        // Bail if no reply to (assumes topic ID)
     407        if ( empty( $new_reply_to ) ) {
     408            return;
     409        }
     410
     411        // Get current forum ID
     412        $forum_id = bbp_get_reply_forum_id( $reply_id );
     413
     414        // Bail if not a group forum
     415        if ( ! bbp_is_forum_group_forum( $forum_id ) ) {
     416            return;
     417        }
     418
     419        // Get current group ID
     420        $group_id = bp_get_current_group_id();
     421
     422        // Bail if unknown group ID
     423        if ( empty( $group_id ) ) {
     424            return;
     425        }
     426
     427        // Get current topic ID
     428        $topic_id = bbp_get_reply_topic_id( $reply_id );
     429
     430        // Get topic reply IDs
     431        $reply_ids = bbp_get_public_child_ids( $topic_id, bbp_get_reply_post_type() );
     432
     433        // Avoid recursion
     434        unset( $reply_ids[ $reply_id ] );
     435
     436        // Bail if new reply parent ID is in this topic
     437        if ( in_array( $new_reply_to, $reply_ids, true ) ) {
     438            return;
     439        }
     440
     441        // Add an error to prevent this reply from saving.
     442        bbp_add_error( 'bbp_reply_to_id', __( '<strong>ERROR</strong>: Reply To is invalid.', 'bbpress' ) );
    312443    }
    313444
Note: See TracChangeset for help on using the changeset viewer.