mirror of
https://github.com/discourse/discourse.git
synced 2025-04-10 16:41:41 +08:00
FEATURE: separate API endpoints for public and private posts
This commit is contained in:
parent
b575f97ece
commit
34469e725b
@ -37,14 +37,29 @@ class PostsController < ApplicationController
|
|||||||
last_post_id = params[:before].to_i
|
last_post_id = params[:before].to_i
|
||||||
last_post_id = Post.last.id if last_post_id <= 0
|
last_post_id = Post.last.id if last_post_id <= 0
|
||||||
|
|
||||||
# last 50 post IDs only, to avoid counting deleted posts in security check
|
if params[:id] == "private_posts"
|
||||||
posts = Post.order(created_at: :desc)
|
raise Discourse::NotFound if current_user.nil?
|
||||||
.where('posts.id <= ?', last_post_id)
|
posts = Post.private_posts
|
||||||
.where('posts.id > ?', last_post_id - 50)
|
.order(created_at: :desc)
|
||||||
.includes(topic: :category)
|
.where('posts.id <= ?', last_post_id)
|
||||||
.includes(user: :primary_group)
|
.where('posts.id > ?', last_post_id - 50)
|
||||||
.includes(:reply_to_user)
|
.includes(topic: :category)
|
||||||
.limit(50)
|
.includes(user: :primary_group)
|
||||||
|
.includes(:reply_to_user)
|
||||||
|
.limit(50)
|
||||||
|
rss_description = I18n.t("rss_description.private_posts")
|
||||||
|
else
|
||||||
|
posts = Post.public_posts
|
||||||
|
.order(created_at: :desc)
|
||||||
|
.where('posts.id <= ?', last_post_id)
|
||||||
|
.where('posts.id > ?', last_post_id - 50)
|
||||||
|
.includes(topic: :category)
|
||||||
|
.includes(user: :primary_group)
|
||||||
|
.includes(:reply_to_user)
|
||||||
|
.limit(50)
|
||||||
|
rss_description = I18n.t("rss_description.posts")
|
||||||
|
end
|
||||||
|
|
||||||
# Remove posts the user doesn't have permission to see
|
# Remove posts the user doesn't have permission to see
|
||||||
# This isn't leaking any information we weren't already through the post ID numbers
|
# This isn't leaking any information we weren't already through the post ID numbers
|
||||||
posts = posts.reject { |post| !guardian.can_see?(post) || post.topic.blank? }
|
posts = posts.reject { |post| !guardian.can_see?(post) || post.topic.blank? }
|
||||||
@ -53,7 +68,7 @@ class PostsController < ApplicationController
|
|||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.rss do
|
format.rss do
|
||||||
@posts = posts
|
@posts = posts
|
||||||
@title = "#{SiteSetting.title} - #{I18n.t("rss_description.posts")}"
|
@title = "#{SiteSetting.title} - #{rss_description}"
|
||||||
@link = Discourse.base_url
|
@link = Discourse.base_url
|
||||||
@description = I18n.t("rss_description.posts")
|
@description = I18n.t("rss_description.posts")
|
||||||
render 'posts/latest', formats: [:rss]
|
render 'posts/latest', formats: [:rss]
|
||||||
@ -62,7 +77,7 @@ class PostsController < ApplicationController
|
|||||||
render_json_dump(serialize_data(posts,
|
render_json_dump(serialize_data(posts,
|
||||||
PostSerializer,
|
PostSerializer,
|
||||||
scope: guardian,
|
scope: guardian,
|
||||||
root: 'latest_posts',
|
root: params[:id],
|
||||||
add_raw: true,
|
add_raw: true,
|
||||||
add_title: true,
|
add_title: true,
|
||||||
all_post_actions: counts)
|
all_post_actions: counts)
|
||||||
|
@ -204,6 +204,7 @@ en:
|
|||||||
hot: "Hot topics"
|
hot: "Hot topics"
|
||||||
top: "Top topics"
|
top: "Top topics"
|
||||||
posts: "Latest posts"
|
posts: "Latest posts"
|
||||||
|
private_posts: "Latest private messages"
|
||||||
group_posts: "Latest posts from %{group_name}"
|
group_posts: "Latest posts from %{group_name}"
|
||||||
group_mentions: "Latest mentions from %{group_name}"
|
group_mentions: "Latest mentions from %{group_name}"
|
||||||
too_late_to_edit: "That post was created too long ago. It can no longer be edited or deleted."
|
too_late_to_edit: "That post was created too long ago. It can no longer be edited or deleted."
|
||||||
|
@ -347,7 +347,8 @@ Discourse::Application.routes.draw do
|
|||||||
# used to download attachments (old route)
|
# used to download attachments (old route)
|
||||||
get "uploads/:site/:id/:sha" => "uploads#show", constraints: { site: /\w+/, id: /\d+/, sha: /[a-f0-9]{16}/ }
|
get "uploads/:site/:id/:sha" => "uploads#show", constraints: { site: /\w+/, id: /\d+/, sha: /[a-f0-9]{16}/ }
|
||||||
|
|
||||||
get "posts" => "posts#latest"
|
get "posts" => "posts#latest", id: "latest_posts"
|
||||||
|
get "private-posts" => "posts#latest", id: "private_posts"
|
||||||
get "posts/by_number/:topic_id/:post_number" => "posts#by_number"
|
get "posts/by_number/:topic_id/:post_number" => "posts#by_number"
|
||||||
get "posts/:id/reply-history" => "posts#reply_history"
|
get "posts/:id/reply-history" => "posts#reply_history"
|
||||||
get "posts/:username/deleted" => "posts#deleted_posts", constraints: {username: USERNAME_ROUTE_FORMAT}
|
get "posts/:username/deleted" => "posts#deleted_posts", constraints: {username: USERNAME_ROUTE_FORMAT}
|
||||||
|
@ -55,27 +55,56 @@ describe PostsController do
|
|||||||
|
|
||||||
describe 'latest' do
|
describe 'latest' do
|
||||||
let(:user) { log_in }
|
let(:user) { log_in }
|
||||||
let!(:post) { Fabricate(:post, user: user) }
|
let!(:public_topic) { Fabricate(:topic) }
|
||||||
|
let!(:post) { Fabricate(:post, user: user, topic: public_topic) }
|
||||||
|
let!(:private_topic) { Fabricate(:topic, archetype: Archetype.private_message, category: nil) }
|
||||||
|
let!(:private_post) { Fabricate(:post, user: user, topic: private_topic) }
|
||||||
let!(:topicless_post) { Fabricate(:post, user: user, raw: '<p>Car 54, where are you?</p>') }
|
let!(:topicless_post) { Fabricate(:post, user: user, raw: '<p>Car 54, where are you?</p>') }
|
||||||
|
|
||||||
before do
|
context "public posts" do
|
||||||
topicless_post.update topic_id: -100
|
before do
|
||||||
|
topicless_post.update topic_id: -100
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns public posts with topic for json' do
|
||||||
|
xhr :get, :latest, id: "latest_posts", format: :json
|
||||||
|
expect(response).to be_success
|
||||||
|
json = ::JSON.parse(response.body)
|
||||||
|
post_ids = json['latest_posts'].map { |p| p['id'] }
|
||||||
|
expect(post_ids).to include post.id
|
||||||
|
expect(post_ids).to_not include private_post.id
|
||||||
|
expect(post_ids).to_not include topicless_post.id
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns public posts with topic for rss' do
|
||||||
|
xhr :get, :latest, id: "latest_posts", format: :rss
|
||||||
|
expect(response).to be_success
|
||||||
|
expect(assigns(:posts)).to include post
|
||||||
|
expect(assigns(:posts)).to_not include private_post
|
||||||
|
expect(assigns(:posts)).to_not include topicless_post
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not return posts without a topic for json' do
|
context 'private posts' do
|
||||||
xhr :get, :latest, format: :json
|
before do
|
||||||
expect(response).to be_success
|
Guardian.any_instance.expects(:can_see?).with(private_post).returns(true)
|
||||||
json = ::JSON.parse(response.body)
|
end
|
||||||
post_ids = json['latest_posts'].map { |p| p['id'] }
|
|
||||||
expect(post_ids).to include post.id
|
|
||||||
expect(post_ids).to_not include topicless_post.id
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'does not return posts without a topic for rss' do
|
it 'returns private posts for json' do
|
||||||
xhr :get, :latest, format: :rss
|
xhr :get, :latest, id: "private_posts", format: :json
|
||||||
expect(response).to be_success
|
expect(response).to be_success
|
||||||
expect(assigns(:posts)).to include post
|
json = ::JSON.parse(response.body)
|
||||||
expect(assigns(:posts)).to_not include topicless_post
|
post_ids = json['private_posts'].map { |p| p['id'] }
|
||||||
|
expect(post_ids).to include private_post.id
|
||||||
|
expect(post_ids).to_not include post.id
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns private posts for rss' do
|
||||||
|
xhr :get, :latest, id: "private_posts", format: :rss
|
||||||
|
expect(response).to be_success
|
||||||
|
expect(assigns(:posts)).to include private_post
|
||||||
|
expect(assigns(:posts)).to_not include post
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user