discourse/app/controllers/embed_controller.rb

145 lines
4.4 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
require_dependency 'topic_query_params'
class EmbedController < ApplicationController
include TopicQueryParams
skip_before_action :check_xhr, :preload_json, :verify_authenticity_token
before_action :ensure_embeddable, except: [ :info, :topics ]
before_action :get_embeddable_css_class, except: [ :info, :topics ]
before_action :ensure_api_request, only: [ :info ]
layout 'embed'
rescue_from Discourse::InvalidAccess do
response.headers['X-Frame-Options'] = "ALLOWALL"
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
response.headers['X-Frame-Options'] = "ALLOWALL"
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
list_options = build_topic_list_options
list_options[:per_page] = params[:per_page].to_i if params.has_key?(:per_page)
topic_query = TopicQuery.new(current_user, list_options)
@list = topic_query.list_latest
end
2014-01-04 01:52:24 +08:00
def comments
embed_url = params[:embed_url]
embed_username = params[:discourse_username]
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,
exclude_first: true,
exclude_deleted_users: true,
exclude_hidden: true)
2014-01-03 01:15:48 +08:00
@second_post_url = "#{@topic_view.topic.url}/2" if @topic_view
@posts_left = 0
if @topic_view && @topic_view.posts.size == SiteSetting.embed_post_limit
2015-05-11 16:26:21 +08:00
@posts_left = @topic_view.topic.posts_count - SiteSetting.embed_post_limit - 1
end
2015-11-21 03:27:30 +08:00
if @topic_view
@reply_count = @topic_view.topic.posts_count - 1
@reply_count = 0 if @reply_count < 0
end
elsif embed_url.present?
2016-04-25 08:47:38 +08:00
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?
2017-07-28 09:20:09 +08:00
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
2017-07-28 09:20:09 +08:00
render json: { counts: by_url }, callback: params[:callback]
end
private
2018-06-07 13:28:18 +08:00
def get_embeddable_css_class
@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?
end
2018-06-07 13:28:18 +08:00
def ensure_api_request
raise Discourse::InvalidAccess.new('api key not set') if !is_api?
end
2018-06-07 13:28:18 +08:00
def ensure_embeddable
if !(Rails.env.development? && current_user&.admin?)
referer = request.referer
2018-06-07 13:28:18 +08:00
unless referer && EmbeddableHost.url_allowed?(referer)
raise Discourse::InvalidAccess.new('invalid referer host')
end
end
2018-06-07 13:28:18 +08:00
response.headers['X-Frame-Options'] = "ALLOWALL"
rescue URI::Error
2018-06-07 13:28:18 +08:00
raise Discourse::InvalidAccess.new('invalid referer host')
end
end