FIX: Don't allow editing own posts user can no longer see (#30839)

In a PM, if a user has made a post, and is later removed from the PM, they can still edit their own post. This can be done either if they happen to have a composer open in an active tab, or by just manually sending an HTTP request.

The post guardian is missing a basic check, can_see_post_topic? when we determine whether a user can edit a post or not. This basic check is already in place when we determine whether a user can see the post in the first place.

This PR adds in the missing check, so that if the user tries to edit their post after being removed, they'll receive a 403.

It also adds a MessageBus message scoped to the affected user and topic when they are removed from the PM, which will redirect them to their inbox. This helps avoid a stale tab where they are still in the PM which they by right can now no longer see.
This commit is contained in:
Ted Johansson
2025-01-20 10:09:58 +08:00
committed by GitHub
parent dcb1e2a341
commit 96b725a11c
6 changed files with 45 additions and 0 deletions

View File

@ -1842,6 +1842,10 @@ export default class TopicController extends Controller.extend(
}
break;
}
case "remove_allowed_user": {
this.router.transitionTo("userPrivateMessages", this.currentUser);
break;
}
default: {
let callback = customPostMessageCallbacks[data.type];
if (callback) {

View File

@ -1174,6 +1174,7 @@ class Topic < ActiveRecord::Base
end
topic_user.destroy
MessageBus.publish("/topic/#{id}", { type: "remove_allowed_user" }, user_ids: [user.id])
return true
end
end

View File

@ -164,6 +164,7 @@ module PostGuardian
if (is_staff? || is_in_edit_post_groups? || is_category_group_moderator?(post.topic&.category))
return can_create_post?(post.topic)
end
return false if !can_see_post_topic?(post)
return false if post.topic&.archived? || post.user_deleted || post.deleted_at

View File

@ -97,5 +97,14 @@ RSpec.describe PostGuardian do
post.update!(user: anon)
expect(Guardian.new(anon).can_edit_post?(post)).to eq(true)
end
it "returns false if the user is the author, but can no longer see the post" do
post.update!(user: user)
guardian = Guardian.new(user)
guardian.stubs(:can_see_post_topic?).returns(false)
expect(guardian.can_edit_post?(post)).to eq(false)
end
end
end

View File

@ -566,6 +566,13 @@ RSpec.describe PostsController do
expect(response).to be_forbidden
end
it "raises an error when user is OP but can no longer see the post" do
post = Fabricate(:private_message_post, user: user)
post.topic.remove_allowed_user(admin, user)
put "/posts/#{post.id}.json", params: update_params
expect(response).to be_forbidden
end
it "updates post's raw attribute" do
put "/posts/#{post.id}.json", params: { post: { raw: "edited body " } }

View File

@ -0,0 +1,23 @@
# frozen_string_literal: true
describe "Private Message", type: :system do
let(:sender) { Fabricate(:user) }
let(:recipient) { Fabricate(:user) }
let(:post) { Fabricate(:private_message_post, user: sender, recipient: recipient) }
before { sign_in(recipient) }
context "when being removed from private conversation" do
it "redirects away from the private message" do
visit(post.full_url)
expect(page).to have_css("h1", text: post.topic.title)
post.topic.remove_allowed_user(sender, recipient)
expect(page).to have_no_css("h1", text: post.topic.title)
expect(page).to have_current_path("/u/#{recipient.username}/messages")
end
end
end