/
embed_controller.rb
167 lines (134 loc) · 5.1 KB
/
embed_controller.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# frozen_string_literal: true
class EmbedController < ApplicationController
include TopicQueryParams
skip_before_action :check_xhr, :preload_json, :verify_authenticity_token
before_action :prepare_embeddable, except: [ :info ]
before_action :ensure_api_request, only: [ :info ]
layout 'embed'
rescue_from Discourse::InvalidAccess do
if current_user.try(:admin?)
@setup_url = "#{Discourse.base_url}/admin/customize/embedding"
@show_reason = true
@hosts = EmbeddableHost.all
end
render 'embed_error', status: 400
end
def topics
discourse_expires_in 1.minute
unless SiteSetting.embed_topics_list?
render 'embed_topics_error', status: 400
return
end
if @embed_id = params[:discourse_embed_id]
raise Discourse::InvalidParameters.new(:embed_id) unless @embed_id =~ /^de\-[a-zA-Z0-9]+$/
end
if @embed_class = params[:embed_class]
raise Discourse::InvalidParameters.new(:embed_class) unless @embed_class =~ /^[a-zA-Z0-9\-_]+$/
end
response.headers['X-Robots-Tag'] = 'noindex, indexifembedded'
if params.has_key?(:template) && params[:template] == "complete"
@template = "complete"
else
@template = "basic"
end
list_options = build_topic_list_options
if params.has_key?(:per_page)
list_options[:per_page] =
[params[:per_page].to_i, SiteSetting.embed_topic_limit_per_page].min
end
if params[:allow_create]
@allow_create = true
create_url_params = {}
create_url_params[:category_id] = params[:category] if params[:category].present?
create_url_params[:tags] = params[:tags] if params[:tags].present?
@create_url = "#{Discourse.base_url}/new-topic?#{create_url_params.to_query}"
end
topic_query = TopicQuery.new(current_user, list_options)
top_period = params[:top_period]
begin
TopTopic.validate_period(top_period)
valid_top_period = true
rescue Discourse::InvalidParameters
valid_top_period = false
end
@list = if valid_top_period
topic_query.list_top_for(top_period)
else
topic_query.list_latest
end
end
def comments
embed_url = params[:embed_url]
embed_username = params[:discourse_username]
embed_topic_id = params[:topic_id]&.to_i
unless embed_topic_id || EmbeddableHost.url_allowed?(embed_url)
raise Discourse::InvalidAccess.new('invalid embed host')
end
topic_id = nil
if embed_url.present?
topic_id = TopicEmbed.topic_id_for_embed(embed_url)
else
topic_id = params[:topic_id].to_i
end
if topic_id
@topic_view = TopicView.new(topic_id,
current_user,
limit: SiteSetting.embed_post_limit,
only_regular: true,
exclude_first: true,
exclude_deleted_users: true,
exclude_hidden: true)
raise Discourse::NotFound if @topic_view.blank?
@posts_left = 0
@second_post_url = "#{@topic_view.topic.url}/2"
@reply_count = @topic_view.filtered_posts.count - 1
@reply_count = 0 if @reply_count < 0
@posts_left = @reply_count - SiteSetting.embed_post_limit if @reply_count > SiteSetting.embed_post_limit
elsif embed_url.present?
Jobs.enqueue(:retrieve_topic,
user_id: current_user.try(:id),
embed_url: embed_url,
author_username: embed_username,
referer: request.env['HTTP_REFERER']
)
render 'loading'
end
discourse_expires_in 1.minute
end
def info
embed_url = params.require(:embed_url)
@topic_embed = TopicEmbed.where(embed_url: embed_url).first
raise Discourse::NotFound if @topic_embed.nil?
render_serialized(@topic_embed, TopicEmbedSerializer, root: false)
end
def count
embed_urls = params[:embed_url]
by_url = {}
if embed_urls.present?
urls = embed_urls.map { |u| u.sub(/#discourse-comments$/, '').sub(/\/$/, '') }
topic_embeds = TopicEmbed.where(embed_url: urls).includes(:topic).references(:topic)
topic_embeds.each do |te|
url = te.embed_url
url = "#{url}#discourse-comments" unless params[:embed_url].include?(url)
if te.topic.present?
by_url[url] = I18n.t('embed.replies', count: te.topic.posts_count - 1)
else
by_url[url] = I18n.t('embed.replies', count: 0)
end
end
end
render json: { counts: by_url }, callback: params[:callback]
end
private
def prepare_embeddable
response.headers.delete('X-Frame-Options')
@embeddable_css_class = ""
embeddable_host = EmbeddableHost.record_for_url(request.referer)
@embeddable_css_class = " class=\"#{embeddable_host.class_name}\"" if embeddable_host.present? && embeddable_host.class_name.present?
@data_referer = request.referer
@data_referer = '*' if SiteSetting.embed_any_origin? && @data_referer.blank?
end
def ensure_api_request
raise Discourse::InvalidAccess.new('api key not set') if !is_api?
end
end