Skip to content

Commit

Permalink
Merge pull request #509 from buddypress/feature/9163
Browse files Browse the repository at this point in the history
Admin cannot be demoted or removed from a group when he's the only one left
  • Loading branch information
renatonascalves authored Jun 18, 2024
2 parents 89ded5b + 3113a42 commit 0c65053
Show file tree
Hide file tree
Showing 2 changed files with 918 additions and 418 deletions.
215 changes: 96 additions & 119 deletions includes/bp-groups/classes/class-bp-rest-group-membership-endpoint.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,6 @@ public function register_routes() {
$this->namespace,
'/' . $this->rest_base . '/(?P<group_id>[\d]+)/members',
array(
'args' => array(
'group_id' => array(
'description' => __( 'A unique numeric ID for the Group.', 'buddypress' ),
'type' => 'integer',
),
),
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_items' ),
Expand All @@ -84,16 +78,6 @@ public function register_routes() {
$this->namespace,
'/' . $this->rest_base . '/(?P<group_id>[\d]+)/members/(?P<user_id>[\d]+)',
array(
'args' => array(
'group_id' => array(
'description' => __( 'A unique numeric ID for the Group.', 'buddypress' ),
'type' => 'integer',
),
'user_id' => array(
'description' => __( 'A unique numeric ID for the Group Member.', 'buddypress' ),
'type' => 'integer',
),
),
array(
'methods' => WP_REST_Server::EDITABLE,
'callback' => array( $this, 'update_item' ),
Expand Down Expand Up @@ -320,18 +304,14 @@ public function create_item_permissions_check( $request ) {
$retval = new WP_Error(
'bp_rest_authorization_required',
__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),
array(
'status' => rest_authorization_required_code(),
)
array( 'status' => rest_authorization_required_code() )
);

if ( ! is_user_logged_in() ) {
$retval = new WP_Error(
'bp_rest_authorization_required',
__( 'Sorry, you need to be logged in to join a group.', 'buddypress' ),
array(
'status' => rest_authorization_required_code(),
)
array( 'status' => rest_authorization_required_code() )
);
} else {
$user = bp_rest_get_user( $request->get_param( 'user_id' ) );
Expand All @@ -341,9 +321,7 @@ public function create_item_permissions_check( $request ) {
$retval = new WP_Error(
'bp_rest_group_member_invalid_id',
__( 'Invalid group member ID.', 'buddypress' ),
array(
'status' => 404,
)
array( 'status' => 404 )
);
} else {
$group = $this->groups_endpoint->get_group_object( $request->get_param( 'group_id' ) );
Expand All @@ -352,19 +330,15 @@ public function create_item_permissions_check( $request ) {
$retval = new WP_Error(
'bp_rest_group_invalid_id',
__( 'Invalid group ID.', 'buddypress' ),
array(
'status' => 404,
)
array( 'status' => 404 )
);
} elseif ( bp_current_user_can( 'bp_moderate' ) || ( bp_current_user_can( 'groups_join_group', array( 'group_id' => $group->id ) ) && $loggedin_user_id === $user->ID ) ) {
$retval = true;
} else {
$retval = new WP_Error(
'bp_rest_group_member_failed_to_join',
__( 'Could not join the group.', 'buddypress' ),
array(
'status' => 500,
)
array( 'status' => 500 )
);
}
}
Expand Down Expand Up @@ -396,28 +370,35 @@ public function update_item( $request ) {
$role = $request->get_param( 'role' );
$group_id = $group->id;

$bp_loggedin_user_id = bp_loggedin_user_id();

// Check if the user is a member of the group.
if ( 'unban' !== $action && ! groups_is_user_member( $user->ID, $group_id ) ) {
return new WP_Error(
'bp_rest_group_member_not_member',
__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),
array( 'status' => 500 )
);
}

if ( 'promote' === $action ) {
if ( ! groups_promote_member( $user->ID, $group_id, $role, bp_loggedin_user_id() ) ) {
if ( ! groups_promote_member( $user->ID, $group_id, $role, $bp_loggedin_user_id ) ) {
return new WP_Error(
'bp_rest_group_member_failed_to_promote',
__( 'Could not promote member.', 'buddypress' ),
array(
'status' => 500,
)
array( 'status' => 500 )
);
}
} elseif ( 'demote' === $action && 'member' !== $role ) {
if ( ! groups_promote_member( $user->ID, $group_id, $role, bp_loggedin_user_id() ) ) {
if ( ! groups_promote_member( $user->ID, $group_id, $role, $bp_loggedin_user_id ) ) {
return new WP_Error(
'bp_rest_group_member_failed_to_demote',
__( 'Could not demote member.', 'buddypress' ),
array(
'status' => 500,
)
array( 'status' => 500 )
);
}
} elseif ( in_array( $action, array( 'demote', 'ban', 'unban' ), true ) ) {
if ( ! call_user_func( 'groups_' . $action . '_member', $user->ID, $group_id, bp_loggedin_user_id() ) ) {
if ( ! call_user_func( 'groups_' . $action . '_member', $user->ID, $group_id, $bp_loggedin_user_id ) ) {
$messages = array(
'demote' => __( 'Could not demote member from the group.', 'buddypress' ),
'ban' => __( 'Could not ban member from the group.', 'buddypress' ),
Expand All @@ -427,19 +408,14 @@ public function update_item( $request ) {
return new WP_Error(
'bp_rest_group_member_failed_to_' . $action,
$messages[ $action ],
array(
'status' => 500,
)
array( 'status' => 500 )
);
}
}

// Get updated group member.
$group_member = new BP_Groups_Member( $user->ID, $group_id );

// Setting context.
$request->set_param( 'context', 'edit' );

$retval = array(
$this->prepare_response_for_collection(
$this->prepare_item_for_response( $group_member, $request )
Expand All @@ -449,7 +425,7 @@ public function update_item( $request ) {
$response = rest_ensure_response( $retval );

/**
* Fires after a group member is updated via the REST API.
* Fires after a group member status is updated via the REST API.
*
* @since 0.1.0
*
Expand All @@ -473,23 +449,23 @@ public function update_item( $request ) {
* @return true|WP_Error
*/
public function update_item_permissions_check( $request ) {
$error = new WP_Error(
$error = new WP_Error(
'bp_rest_authorization_required',
__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),
array(
'status' => rest_authorization_required_code(),
)
array( 'status' => rest_authorization_required_code() )
);

$admin_error = new WP_Error(
'bp_rest_authorization_required',
__( 'Group needs 1 admin at least. Please promote a user before trying to remove this group admin.', 'buddypress' ),
array( 'status' => rest_authorization_required_code() )
);

$retval = $error;
$action = $request->get_param( 'action' );

if ( ! is_user_logged_in() ) {
$retval = new WP_Error(
'bp_rest_authorization_required',
__( 'Sorry, you need to be logged in to make an update.', 'buddypress' ),
array(
'status' => rest_authorization_required_code(),
)
);
$retval = $error;
} else {
$user = bp_rest_get_user( $request->get_param( 'user_id' ) );
$loggedin_user_id = bp_loggedin_user_id();
Expand All @@ -498,9 +474,7 @@ public function update_item_permissions_check( $request ) {
$retval = new WP_Error(
'bp_rest_group_member_invalid_id',
__( 'Invalid group member ID.', 'buddypress' ),
array(
'status' => 404,
)
array( 'status' => 404 )
);
} else {
$group = $this->groups_endpoint->get_group_object( $request->get_param( 'group_id' ) );
Expand All @@ -509,41 +483,35 @@ public function update_item_permissions_check( $request ) {
$retval = new WP_Error(
'bp_rest_group_invalid_id',
__( 'Invalid group ID.', 'buddypress' ),
array(
'status' => 404,
)
array( 'status' => 404 )
);
} elseif ( bp_current_user_can( 'bp_moderate' ) ) {
$retval = true;
} elseif ( in_array( $request->get_param( 'action' ), array( 'ban', 'unban', 'promote', 'demote' ), true ) ) {
if ( groups_is_user_admin( $loggedin_user_id, $group->id ) ) {
if ( $loggedin_user_id !== $user->ID ) {
} elseif ( bp_current_user_can( 'bp_moderate' ) && $loggedin_user_id !== $user->ID ) {
if ( 'demote' === $action && groups_is_user_admin( $user->ID, $group->id ) ) {
$group_admins = groups_get_group_admins( $group->id );

if ( 1 !== count( $group_admins ) ) {
$retval = true;
} else {
$group_admins = groups_get_group_admins( $group->id );

if ( 1 !== count( $group_admins ) ) {
$retval = true;
} else {
$retval = $error;
}
$retval = $admin_error;
}
} else {
$messages = array(
'ban' => __( 'Sorry, you are not allowed to ban this group member.', 'buddypress' ),
'unban' => __( 'Sorry, you are not allowed to unban this group member.', 'buddypress' ),
'promote' => __( 'Sorry, you are not allowed to promote this group member.', 'buddypress' ),
'demote' => __( 'Sorry, you are not allowed to demote this group member.', 'buddypress' ),
);

$retval = new WP_Error(
'bp_rest_group_member_cannot_' . $request->get_param( 'action' ),
$messages[ $request->get_param( 'action' ) ],
array(
'status' => rest_authorization_required_code(),
)
);
$retval = true;
}
} elseif ( groups_is_user_admin( $loggedin_user_id, $group->id ) && $loggedin_user_id !== $user->ID ) {
$retval = true;
} else {
$messages = array(
'ban' => __( 'Sorry, you are not allowed to ban this group member.', 'buddypress' ),
'unban' => __( 'Sorry, you are not allowed to unban this group member.', 'buddypress' ),
'promote' => __( 'Sorry, you are not allowed to promote this group member.', 'buddypress' ),
'demote' => __( 'Sorry, you are not allowed to demote this group member.', 'buddypress' ),
);

$retval = new WP_Error(
'bp_rest_group_member_cannot_' . $action,
$messages[ $action ],
array( 'status' => rest_authorization_required_code() )
);
}
}
}
Expand All @@ -568,34 +536,33 @@ public function update_item_permissions_check( $request ) {
* @return WP_REST_Response|WP_Error
*/
public function delete_item( $request ) {
// Setting context.
$request->set_param( 'context', 'edit' );
$group_id = $request->get_param( 'group_id' );
$user_id = $request->get_param( 'user_id' );

// Get the Group member before it's removed.
$member = new BP_Groups_Member( $request->get_param( 'user_id' ), $request->get_param( 'group_id' ) );
$previous = $this->prepare_item_for_response( $member, $request );
$member = new BP_Groups_Member( $user_id, $group_id );

if ( ! $member->remove() ) {
return new WP_Error(
'bp_rest_group_member_failed_to_remove',
__( 'Could not remove member from this group.', 'buddypress' ),
array(
'status' => 500,
)
array( 'status' => 500 )
);
}

$previous_member = $this->prepare_item_for_response( $member, $request );

// Build the response.
$response = new WP_REST_Response();
$response->set_data(
array(
'removed' => true,
'previous' => $previous->get_data(),
'previous' => $previous_member->get_data(),
)
);

$user = bp_rest_get_user( $request->get_param( 'user_id' ) );
$group = $this->groups_endpoint->get_group_object( $request->get_param( 'group_id' ) );
$user = bp_rest_get_user( $user_id );
$group = $this->groups_endpoint->get_group_object( $group_id );

/**
* Fires after a group member is deleted via the REST API.
Expand All @@ -622,22 +589,27 @@ public function delete_item( $request ) {
* @return true|WP_Error
*/
public function delete_item_permissions_check( $request ) {
$error = new WP_Error(
$authorization_code = rest_authorization_required_code();

$error = new WP_Error(
'bp_rest_authorization_required',
__( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),
array(
'status' => rest_authorization_required_code(),
)
array( 'status' => $authorization_code )
);

$admin_error = new WP_Error(
'bp_rest_authorization_required',
__( 'Group needs 1 admin at least. Please promote a user before trying to remove this group admin.', 'buddypress' ),
array( 'status' => $authorization_code )
);

$retval = $error;

if ( ! is_user_logged_in() ) {
$retval = new WP_Error(
'bp_rest_authorization_required',
__( 'Sorry, you need to be logged in to view a group membership.', 'buddypress' ),
array(
'status' => rest_authorization_required_code(),
)
array( 'status' => $authorization_code )
);
} else {
$user = bp_rest_get_user( $request->get_param( 'user_id' ) );
Expand All @@ -647,9 +619,7 @@ public function delete_item_permissions_check( $request ) {
return new WP_Error(
'bp_rest_group_member_invalid_id',
__( 'Invalid group member ID.', 'buddypress' ),
array(
'status' => 404,
)
array( 'status' => 404 )
);
} else {
$group = $this->groups_endpoint->get_group_object( $request->get_param( 'group_id' ) );
Expand All @@ -658,21 +628,28 @@ public function delete_item_permissions_check( $request ) {
$retval = new WP_Error(
'bp_rest_group_invalid_id',
__( 'Invalid group ID.', 'buddypress' ),
array(
'status' => 404,
)
array( 'status' => 404 )
);
} elseif ( bp_current_user_can( 'bp_moderate' ) || ( $user->ID !== $loggedin_user_id && groups_is_user_admin( $loggedin_user_id, $group->id ) ) ) {
$retval = true;
} elseif ( bp_current_user_can( 'bp_moderate' ) || ( groups_is_user_admin( $loggedin_user_id, $group->id ) && $loggedin_user_id !== $user->ID ) ) {
if ( groups_is_user_admin( $user->ID, $group->id ) ) {
$group_admins = groups_get_group_admins( $group->id );

if ( 1 !== count( $group_admins ) ) {
$retval = true;
} else {
$retval = $admin_error;
}
} else {
$retval = true;
}
} elseif ( $user->ID === $loggedin_user_id && ! groups_is_user_banned( $user->ID, $group->id ) ) {
$group_admins = groups_get_group_admins( $group->id );
if ( groups_is_user_admin( $loggedin_user_id, $group->id ) ) {
$group_admins = groups_get_group_admins( $group->id );

// Special case for self-removal: don't allow if it'd leave a group with no admins.
if ( in_array( $loggedin_user_id, wp_list_pluck( $group_admins, 'user_id' ), true ) ) {
if ( 1 !== count( $group_admins ) ) {
$retval = true;
} else {
$retval = $error;
$retval = $admin_error;
}
} else {
$retval = true;
Expand Down
Loading

0 comments on commit 0c65053

Please sign in to comment.