mirror of
https://ghfast.top/https://github.com/discourse/discourse-follow.git
synced 2026-07-15 11:36:38 +08:00
Some checks failed
Discourse Plugin / ci (push) Has been cancelled
## Summary Prevent the leakage of shared draft topic titles and post content in the follow feed by correctly filtering out topics with associated shared drafts for unauthorized users. The query now explicitly checks the viewer's shared draft visibility before returning posts from followed users. ## Source - Patch Triage: https://patch.discourse.org/patch-triage/1405 Co-authored-by: discourse-patch-triage <272280883+discourse-patch-triage[bot]@users.noreply.github.com>
100 lines
3.5 KiB
Ruby
100 lines
3.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class UserFollower < ActiveRecord::Base
|
|
def self.posts_for(user, current_user:, limit: nil, created_before: nil, created_after: nil)
|
|
visible_post_types = [Post.types[:regular], Post.types[:moderator_action]]
|
|
visible_post_types << Post.types[:whisper] if current_user.staff?
|
|
|
|
results =
|
|
Post
|
|
.joins(:topic, :user, topic: :category)
|
|
.joins("INNER JOIN user_followers ON user_followers.user_id = users.id")
|
|
.preload(:user, topic: :category)
|
|
.where(post_type: visible_post_types)
|
|
.where("topics.archetype != ?", Archetype.private_message)
|
|
.where("topics.visible")
|
|
.where("user_followers.follower_id = ?", user.id)
|
|
.where(action_code: nil)
|
|
.order(created_at: :desc)
|
|
|
|
guardian = Guardian.new(current_user)
|
|
|
|
results = filter_opted_out_users(results)
|
|
results = filter_shared_drafts(results, guardian)
|
|
results = guardian.filter_allowed_categories(results)
|
|
results = guardian.filter_hidden_posts(results)
|
|
results = results.limit(limit) if limit
|
|
results = results.where("posts.created_at < ?", created_before) if created_before
|
|
results = results.where("posts.created_at > ?", created_after) if created_after
|
|
|
|
results
|
|
end
|
|
|
|
def self.topics_for(user, current_user:, limit: nil, created_before: nil, created_after: nil)
|
|
results =
|
|
Topic
|
|
.joins(:user)
|
|
.joins("INNER JOIN user_followers ON user_followers.user_id = users.id")
|
|
.preload(:user, :category)
|
|
.where("user_followers.follower_id = ?", user.id)
|
|
.listable_topics
|
|
.visible
|
|
.order(created_at: :desc)
|
|
|
|
results = filter_opted_out_users(results)
|
|
results = Guardian.new(current_user).filter_allowed_categories(results)
|
|
results = results.limit(limit) if limit
|
|
results = results.where("topics.created_at < ?", created_before) if created_before
|
|
results = results.where("topics.created_at > ?", created_after) if created_after
|
|
|
|
results
|
|
end
|
|
|
|
def self.filter_shared_drafts(relation, guardian)
|
|
return relation if guardian.can_see_shared_draft?
|
|
|
|
relation.where.not(topic_id: SharedDraft.select(:topic_id))
|
|
end
|
|
|
|
def self.filter_opted_out_users(relation)
|
|
truthy_values = sanitize_sql(["?", HasCustomFields::Helpers::CUSTOM_FIELD_TRUE])
|
|
if SiteSetting.default_allow_people_to_follow_me
|
|
relation = relation.joins(<<~SQL)
|
|
LEFT OUTER JOIN user_custom_fields ucf
|
|
ON ucf.name = 'allow_people_to_follow_me'
|
|
AND ucf.user_id = users.id
|
|
AND ucf.value NOT IN (#{truthy_values})
|
|
SQL
|
|
relation = relation.where("ucf.user_id IS NULL")
|
|
else
|
|
relation = relation.joins(<<~SQL)
|
|
INNER JOIN user_custom_fields ucf
|
|
ON ucf.name = 'allow_people_to_follow_me'
|
|
AND ucf.user_id = users.id
|
|
AND ucf.value IN (#{truthy_values})
|
|
SQL
|
|
end
|
|
relation.joins("LEFT OUTER JOIN user_options uo ON uo.user_id = users.id").where(
|
|
"uo.user_id IS NULL OR NOT uo.hide_profile",
|
|
)
|
|
end
|
|
|
|
belongs_to :follower_user, class_name: "User", foreign_key: :follower_id
|
|
belongs_to :followed_user, class_name: "User", foreign_key: :user_id
|
|
end
|
|
|
|
# == Schema Information
|
|
#
|
|
# Table name: user_followers
|
|
#
|
|
# id :bigint not null, primary key
|
|
# user_id :bigint not null
|
|
# follower_id :bigint not null
|
|
# level :integer not null
|
|
# created_at :datetime not null
|
|
# updated_at :datetime not null
|
|
#
|
|
# Indexes
|
|
#
|
|
# index_user_followers_on_user_id_and_follower_id (user_id,follower_id) UNIQUE
|
|
#
|