FEATURE: Allow expanding hidden posts for groups in SiteSetting.can_see_hidden_post (#21853)

Allow expanding hidden posts for groups in SiteSetting.can_see_hidden_post
This commit is contained in:
锦心 2023-06-01 11:32:05 +08:00 committed by GitHub
parent 6fec9628a4
commit 96a2893284
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 97 additions and 18 deletions

View File

@ -57,6 +57,7 @@ export function transformBasicPost(post) {
canPermanentlyDelete: false,
showFlagDelete: false,
canRecover: post.can_recover,
canSeeHiddenPost: post.can_see_hidden_post,
canEdit: post.can_edit,
canFlag: !post.get("topic.deleted") && !isEmpty(post.get("flagsAvailable")),
canReviewTopic: false,

View File

@ -497,10 +497,7 @@ createWidget("post-contents", {
result = result.concat(applyDecorators(this, "after-cooked", attrs, state));
if (
attrs.cooked_hidden &&
(this.currentUser?.isLeader || attrs.user_id === this.currentUser?.id)
) {
if (attrs.cooked_hidden && attrs.canSeeHiddenPost) {
result.push(this.attach("expand-hidden", attrs));
}

View File

@ -495,7 +495,7 @@ module("Integration | Component | Widget | post", function (hooks) {
});
test("cooked content hidden", async function (assert) {
this.set("args", { cooked_hidden: true });
this.set("args", { cooked_hidden: true, canSeeHiddenPost: true });
this.set("expandHidden", () => (this.unhidden = true));
await render(hbs`
@ -506,6 +506,17 @@ module("Integration | Component | Widget | post", function (hooks) {
assert.ok(this.unhidden, "triggers the action");
});
test(`cooked content hidden - can't view hidden post`, async function (assert) {
this.set("args", { cooked_hidden: true, canSeeHiddenPost: false });
this.set("expandHidden", () => (this.unhidden = true));
await render(hbs`
<MountWidget @widget="post" @args={{this.args}} @expandHidden={{this.expandHidden}} />
`);
assert.ok(!exists(".topic-body .expand-hidden"), "button is not displayed");
});
test("expand first post", async function (assert) {
const store = getOwner(this).lookup("service:store");
this.set("args", { expandablePost: true });

View File

@ -43,6 +43,7 @@ class PostSerializer < BasicPostSerializer
:can_delete,
:can_permanently_delete,
:can_recover,
:can_see_hidden_post,
:can_wiki,
:link_counts,
:read,
@ -180,6 +181,10 @@ class PostSerializer < BasicPostSerializer
scope.can_recover_post?(object)
end
def can_see_hidden_post
scope.can_see_hidden_post?(object)
end
def can_wiki
scope.can_wiki?(object)
end

View File

@ -20,6 +20,7 @@ class WebHookPostSerializer < PostSerializer
can_edit
can_delete
can_recover
can_see_hidden_post
can_wiki
actions_summary
can_view_edit_history

View File

@ -1700,6 +1700,7 @@ en:
enable_badges: "Enable the badge system"
max_favorite_badges: "Maximum number of badges that user can select"
whispers_allowed_groups: "Allow private communication within topics for members of specified groups."
hidden_post_visible_groups: "Allow members of these groups to view hidden posts. Staff users can always view hidden posts."
allow_index_in_robots_txt: "Specify in robots.txt that this site is allowed to be indexed by web search engines. In exceptional cases you can permanently <a href='%{base_path}/admin/customize/robots'>override robots.txt</a>."
blocked_email_domains: "A pipe-delimited list of email domains that users are not allowed to register accounts with. Subdomains are automatically handled for the specified domains. Wildcard symbols * and ? are not supported. Example: mailinator.com|trashmail.net"

View File

@ -336,6 +336,12 @@ basic:
default: ""
allow_any: false
refresh: true
hidden_post_visible_groups:
type: group_list
list_type: compact
default: "14"
allow_any: false
refresh: true
enable_bookmarks_with_reminders:
client: true
default: true

View File

@ -284,8 +284,12 @@ module PostGuardian
end
def can_see_hidden_post?(post)
if SiteSetting.hidden_post_visible_groups_map.include?(Group::AUTO_GROUPS[:everyone])
return true
end
return false if anonymous?
post.user_id == @user.id || @user.has_trust_level_or_staff?(TrustLevel[4])
return true if is_staff?
post.user_id == @user.id || @user.in_any_groups?(SiteSetting.hidden_post_visible_groups_map)
end
def can_view_edit_history?(post)

View File

@ -1,32 +1,59 @@
# frozen_string_literal: true
RSpec.describe PostGuardian do
fab!(:groupless_user) { Fabricate(:user) }
fab!(:user) { Fabricate(:user) }
fab!(:anon) { Fabricate(:anonymous) }
fab!(:admin) { Fabricate(:admin) }
fab!(:tl3_user) { Fabricate(:trust_level_3) }
fab!(:tl4_user) { Fabricate(:trust_level_4) }
fab!(:moderator) { Fabricate(:moderator) }
fab!(:group) { Fabricate(:group) }
fab!(:group_user) { Fabricate(:group_user, group: group, user: user) }
fab!(:category) { Fabricate(:category) }
fab!(:topic) { Fabricate(:topic, category: category) }
fab!(:hidden_post) { Fabricate(:post, topic: topic, hidden: true) }
describe "#can_see_hidden_post?" do
it "returns false for anonymous users" do
expect(Guardian.new(anon).can_see_hidden_post?(hidden_post)).to eq(false)
context "when the hidden_post_visible_groups contains everyone" do
before { SiteSetting.hidden_post_visible_groups = "#{Group::AUTO_GROUPS[:everyone]}" }
it "returns true for everyone" do
expect(Guardian.new(anon).can_see_hidden_post?(hidden_post)).to eq(true)
expect(Guardian.new(user).can_see_hidden_post?(hidden_post)).to eq(true)
expect(Guardian.new(admin).can_see_hidden_post?(hidden_post)).to eq(true)
expect(Guardian.new(moderator).can_see_hidden_post?(hidden_post)).to eq(true)
end
end
it "returns false for TL3 users" do
expect(Guardian.new(tl3_user).can_see_hidden_post?(hidden_post)).to eq(false)
context "when the post is a created by the user" do
fab!(:hidden_post) { Fabricate(:post, topic: topic, hidden: true, user: user) }
before { SiteSetting.hidden_post_visible_groups = "" }
it "returns true for the author" do
SiteSetting.hidden_post_visible_groups = ""
expect(Guardian.new(user).can_see_hidden_post?(hidden_post)).to eq(true)
end
end
it "returns true for TL4 users" do
expect(Guardian.new(tl4_user).can_see_hidden_post?(hidden_post)).to eq(true)
end
context "when the post is a created by another user" do
before { SiteSetting.hidden_post_visible_groups = "14|#{group.id}" }
it "returns true for staff users" do
expect(Guardian.new(moderator).can_see_hidden_post?(hidden_post)).to eq(true)
expect(Guardian.new(admin).can_see_hidden_post?(hidden_post)).to eq(true)
it "returns true for staff users" do
expect(Guardian.new(admin).can_see_hidden_post?(hidden_post)).to eq(true)
expect(Guardian.new(moderator).can_see_hidden_post?(hidden_post)).to eq(true)
end
it "returns false for anonymous users" do
expect(Guardian.new(anon).can_see_hidden_post?(hidden_post)).to eq(false)
end
it "returns true if the user is in hidden_post_visible_groups" do
expect(Guardian.new(user).can_see_hidden_post?(hidden_post)).to eq(true)
end
it "returns false if the user is not in hidden_post_visible_groups" do
expect(Guardian.new(groupless_user).can_see_hidden_post?(hidden_post)).to eq(false)
end
end
end
end

View File

@ -131,6 +131,9 @@ RSpec.describe "posts" do
can_recover: {
type: :boolean,
},
can_see_hidden_post: {
type: :boolean,
},
can_wiki: {
type: :boolean,
},

View File

@ -119,6 +119,9 @@
"can_recover": {
"type": "boolean"
},
"can_see_hidden_post": {
"type": "boolean"
},
"can_wiki": {
"type": "boolean"
},
@ -252,6 +255,7 @@
"can_edit",
"can_delete",
"can_recover",
"can_see_hidden_post",
"can_wiki",
"user_title",
"reply_to_user",

View File

@ -106,6 +106,9 @@
"can_recover": {
"type": "boolean"
},
"can_see_hidden_post": {
"type": "boolean"
},
"can_wiki": {
"type": "boolean"
},

View File

@ -110,6 +110,9 @@
"can_recover": {
"type": "boolean"
},
"can_see_hidden_post": {
"type": "boolean"
},
"can_wiki": {
"type": "boolean"
},

View File

@ -121,6 +121,9 @@
"can_recover": {
"type": "boolean"
},
"can_see_hidden_post": {
"type": "boolean"
},
"can_wiki": {
"type": "boolean"
},

View File

@ -117,6 +117,9 @@
"can_recover": {
"type": "boolean"
},
"can_see_hidden_post": {
"type": "boolean"
},
"can_wiki": {
"type": "boolean"
},

View File

@ -141,6 +141,13 @@ RSpec.describe PostSerializer do
)
end
it "includes if the user can see it" do
expect(serialized_post_for_user(Fabricate(:moderator))[:can_see_hidden_post]).to eq(true)
expect(serialized_post_for_user(Fabricate(:admin))[:can_see_hidden_post]).to eq(true)
expect(serialized_post_for_user(user)[:can_see_hidden_post]).to eq(true)
expect(serialized_post_for_user(Fabricate(:user))[:can_see_hidden_post]).to eq(false)
end
it "shows the raw post only if authorized to see it" do
expect(serialized_post_for_user(nil)[:raw]).to eq(nil)
expect(serialized_post_for_user(Fabricate(:user))[:raw]).to eq(nil)