2013-10-09 02:22:41 -04:00
|
|
|
require 'current_user'
|
2013-10-09 00:10:37 -04:00
|
|
|
require_dependency 'canonical_url'
|
2013-02-05 14:16:51 -05:00
|
|
|
require_dependency 'discourse'
|
|
|
|
require_dependency 'custom_renderer'
|
2013-10-09 00:10:37 -04:00
|
|
|
require_dependency 'archetype'
|
2013-02-05 14:16:51 -05:00
|
|
|
require_dependency 'rate_limiter'
|
2014-02-20 16:07:02 -05:00
|
|
|
require_dependency 'crawler_detection'
|
2014-04-02 13:22:10 -04:00
|
|
|
require_dependency 'json_error'
|
2014-05-30 00:17:35 -04:00
|
|
|
require_dependency 'letter_avatar'
|
2014-11-13 23:39:17 -05:00
|
|
|
require_dependency 'distributed_cache'
|
2013-02-05 14:16:51 -05:00
|
|
|
|
|
|
|
class ApplicationController < ActionController::Base
|
|
|
|
include CurrentUser
|
2013-02-13 06:04:43 -05:00
|
|
|
include CanonicalURL::ControllerExtensions
|
2014-04-02 13:22:10 -04:00
|
|
|
include JsonError
|
2013-02-05 14:16:51 -05:00
|
|
|
|
|
|
|
serialization_scope :guardian
|
|
|
|
|
|
|
|
protect_from_forgery
|
|
|
|
|
2013-07-29 01:13:13 -04:00
|
|
|
# Default Rails 3.2 lets the request through with a blank session
|
|
|
|
# we are being more pedantic here and nulling session / current_user
|
|
|
|
# and then raising a CSRF exception
|
|
|
|
def handle_unverified_request
|
|
|
|
# NOTE: API key is secret, having it invalidates the need for a CSRF token
|
|
|
|
unless is_api?
|
|
|
|
super
|
|
|
|
clear_current_user
|
2013-08-27 01:56:12 -04:00
|
|
|
render text: "['BAD CSRF']", status: 403
|
2013-07-29 01:13:13 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-05-12 01:27:58 -04:00
|
|
|
before_filter :set_current_user_for_logs
|
2013-12-04 06:49:54 -05:00
|
|
|
before_filter :set_locale
|
2013-12-18 14:47:22 -05:00
|
|
|
before_filter :set_mobile_view
|
2013-02-05 14:16:51 -05:00
|
|
|
before_filter :inject_preview_style
|
2013-11-12 12:13:17 -05:00
|
|
|
before_filter :disable_customization
|
2014-02-12 23:37:28 -05:00
|
|
|
before_filter :block_if_readonly_mode
|
2013-02-05 14:16:51 -05:00
|
|
|
before_filter :authorize_mini_profiler
|
|
|
|
before_filter :preload_json
|
|
|
|
before_filter :check_xhr
|
2013-06-04 18:32:36 -04:00
|
|
|
before_filter :redirect_to_login_if_required
|
2013-02-07 10:45:24 -05:00
|
|
|
|
2014-02-14 17:10:08 -05:00
|
|
|
layout :set_layout
|
|
|
|
|
2014-02-20 17:02:26 -05:00
|
|
|
def has_escaped_fragment?
|
|
|
|
SiteSetting.enable_escaped_fragments? && params.key?("_escaped_fragment_")
|
|
|
|
end
|
|
|
|
|
2014-10-30 14:26:35 -04:00
|
|
|
def use_crawler_layout?
|
|
|
|
@use_crawler_layout ||= (has_escaped_fragment? || CrawlerDetection.crawler?(request.user_agent))
|
|
|
|
end
|
|
|
|
|
2014-12-15 11:54:26 -05:00
|
|
|
def slow_platform?
|
|
|
|
request.user_agent =~ /Android/
|
|
|
|
end
|
|
|
|
|
2014-02-14 17:10:08 -05:00
|
|
|
def set_layout
|
2014-10-30 14:26:35 -04:00
|
|
|
use_crawler_layout? ? 'crawler' : 'application'
|
2014-02-14 17:10:08 -05:00
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
rescue_from Exception do |exception|
|
2013-11-12 12:13:17 -05:00
|
|
|
unless [ActiveRecord::RecordNotFound,
|
|
|
|
ActionController::RoutingError,
|
|
|
|
ActionController::UnknownController,
|
|
|
|
AbstractController::ActionNotFound].include? exception.class
|
2013-02-07 10:45:24 -05:00
|
|
|
begin
|
2013-02-05 14:16:51 -05:00
|
|
|
ErrorLog.report_async!(exception, self, request, current_user)
|
2013-02-07 10:45:24 -05:00
|
|
|
rescue
|
2013-02-05 14:16:51 -05:00
|
|
|
# dont care give up
|
|
|
|
end
|
|
|
|
end
|
|
|
|
raise
|
|
|
|
end
|
2013-02-07 10:45:24 -05:00
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
# Some exceptions
|
|
|
|
class RenderEmpty < Exception; end
|
|
|
|
|
2015-02-08 15:25:03 -05:00
|
|
|
# Render nothing
|
2013-02-05 14:16:51 -05:00
|
|
|
rescue_from RenderEmpty do
|
|
|
|
render 'default/empty'
|
|
|
|
end
|
|
|
|
|
|
|
|
# If they hit the rate limiter
|
|
|
|
rescue_from RateLimiter::LimitExceeded do |e|
|
|
|
|
|
|
|
|
time_left = ""
|
|
|
|
if e.available_in < 1.minute.to_i
|
|
|
|
time_left = I18n.t("rate_limiter.seconds", count: e.available_in)
|
|
|
|
elsif e.available_in < 1.hour.to_i
|
2013-02-07 10:45:24 -05:00
|
|
|
time_left = I18n.t("rate_limiter.minutes", count: (e.available_in / 1.minute.to_i))
|
2013-02-05 14:16:51 -05:00
|
|
|
else
|
2013-02-07 10:45:24 -05:00
|
|
|
time_left = I18n.t("rate_limiter.hours", count: (e.available_in / 1.hour.to_i))
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
2015-02-09 13:19:47 -05:00
|
|
|
render_json_error I18n.t("rate_limiter.too_many_requests", time_left: time_left), :rate_limit, 429
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
rescue_from Discourse::NotLoggedIn do |e|
|
|
|
|
raise e if Rails.env.test?
|
2014-03-05 11:48:06 -05:00
|
|
|
|
2015-02-08 16:35:09 -05:00
|
|
|
if (request.format && request.format.json?) || request.xhr? || !request.get?
|
2015-02-09 13:19:47 -05:00
|
|
|
rescue_discourse_actions(:not_logged_in, 403, true)
|
2014-03-05 11:48:06 -05:00
|
|
|
else
|
2015-02-08 15:25:03 -05:00
|
|
|
redirect_to "/"
|
2014-03-05 11:48:06 -05:00
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
rescue_from Discourse::NotFound do
|
2015-02-09 13:19:47 -05:00
|
|
|
rescue_discourse_actions(:not_found, 404)
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
rescue_from Discourse::InvalidAccess do
|
2015-02-09 13:19:47 -05:00
|
|
|
rescue_discourse_actions(:invalid_access, 403, true)
|
2013-06-20 11:47:33 -04:00
|
|
|
end
|
|
|
|
|
2014-02-12 23:37:28 -05:00
|
|
|
rescue_from Discourse::ReadOnly do
|
2015-02-09 13:19:47 -05:00
|
|
|
render_json_error I18n.t('read_only_mode_enabled'), :read_only, 405
|
2014-02-12 23:37:28 -05:00
|
|
|
end
|
|
|
|
|
2015-02-08 15:25:03 -05:00
|
|
|
def rescue_discourse_actions(type, status_code, include_ember=false)
|
2015-02-08 16:35:09 -05:00
|
|
|
|
2015-02-08 15:25:03 -05:00
|
|
|
if (request.format && request.format.json?) || (request.xhr?)
|
2015-02-08 16:35:09 -05:00
|
|
|
# HACK: do not use render_json_error for topics#show
|
|
|
|
if request.params[:controller] == 'topics' && request.params[:action] == 'show'
|
|
|
|
return render status: status_code, layout: false, text: (status_code == 404) ? build_not_found_page(status_code) : I18n.t(type)
|
|
|
|
end
|
|
|
|
|
2015-02-08 15:25:03 -05:00
|
|
|
render_json_error I18n.t(type), type, status_code
|
2013-05-30 14:46:02 -04:00
|
|
|
else
|
2015-02-08 15:25:03 -05:00
|
|
|
render text: build_not_found_page(status_code, include_ember ? 'application' : 'no_ember')
|
2013-05-30 14:46:02 -04:00
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
2015-02-04 16:23:39 -05:00
|
|
|
class PluginDisabled < Exception; end
|
|
|
|
|
|
|
|
# If a controller requires a plugin, it will raise an exception if that plugin is
|
|
|
|
# disabled. This allows plugins to be disabled programatically.
|
|
|
|
def self.requires_plugin(plugin_name)
|
|
|
|
before_filter do
|
|
|
|
raise PluginDisabled.new if Discourse.disabled_plugin_names.include?(plugin_name)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-05-12 01:27:58 -04:00
|
|
|
def set_current_user_for_logs
|
|
|
|
if current_user
|
|
|
|
Logster.add_to_env(request.env,"username",current_user.username)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-02-28 14:31:39 -05:00
|
|
|
def set_locale
|
2015-02-05 22:38:51 -05:00
|
|
|
I18n.locale = if current_user
|
|
|
|
current_user.effective_locale
|
2014-02-07 22:24:10 -05:00
|
|
|
else
|
|
|
|
SiteSetting.default_locale
|
|
|
|
end
|
2013-02-28 14:31:39 -05:00
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
def store_preloaded(key, json)
|
|
|
|
@preloaded ||= {}
|
2013-02-25 11:42:20 -05:00
|
|
|
# I dislike that there is a gsub as opposed to a gsub!
|
|
|
|
# but we can not be mucking with user input, I wonder if there is a way
|
2013-02-11 01:28:21 -05:00
|
|
|
# to inject this safty deeper in the library or even in AM serializer
|
|
|
|
@preloaded[key] = json.gsub("</", "<\\/")
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
# If we are rendering HTML, preload the session data
|
|
|
|
def preload_json
|
2013-06-04 12:56:12 -04:00
|
|
|
# We don't preload JSON on xhr or JSON request
|
2015-01-24 00:03:44 -05:00
|
|
|
return if request.xhr? || request.format.json?
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2013-08-05 16:25:44 -04:00
|
|
|
preload_anonymous_data
|
2013-06-04 12:56:12 -04:00
|
|
|
|
2013-08-05 16:25:44 -04:00
|
|
|
if current_user
|
|
|
|
preload_current_user_data
|
|
|
|
current_user.sync_notification_channel_position
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-12-18 14:47:22 -05:00
|
|
|
def set_mobile_view
|
|
|
|
session[:mobile_view] = params[:mobile_view] if params.has_key?(:mobile_view)
|
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
def inject_preview_style
|
|
|
|
style = request['preview-style']
|
2015-01-06 01:39:08 -05:00
|
|
|
|
|
|
|
if style.nil?
|
|
|
|
session[:preview_style] = cookies[:preview_style]
|
2014-06-20 12:06:36 -04:00
|
|
|
else
|
2015-01-06 01:39:08 -05:00
|
|
|
cookies.delete(:preview_style)
|
|
|
|
|
|
|
|
if style.blank? || style == 'default'
|
|
|
|
session[:preview_style] = nil
|
|
|
|
else
|
|
|
|
session[:preview_style] = style
|
|
|
|
if request['sticky']
|
|
|
|
cookies[:preview_style] = style
|
|
|
|
end
|
|
|
|
end
|
2014-06-20 12:06:36 -04:00
|
|
|
end
|
2015-01-06 01:39:08 -05:00
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
2013-11-12 12:13:17 -05:00
|
|
|
def disable_customization
|
|
|
|
session[:disable_customization] = params[:customization] == "0" if params.has_key?(:customization)
|
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
def guardian
|
|
|
|
@guardian ||= Guardian.new(current_user)
|
|
|
|
end
|
|
|
|
|
2013-05-29 16:49:34 -04:00
|
|
|
def serialize_data(obj, serializer, opts={})
|
2013-02-05 14:16:51 -05:00
|
|
|
# If it's an array, apply the serializer as an each_serializer to the elements
|
|
|
|
serializer_opts = {scope: guardian}.merge!(opts)
|
2014-04-16 11:18:09 -04:00
|
|
|
if obj.respond_to?(:to_ary)
|
2013-02-05 14:16:51 -05:00
|
|
|
serializer_opts[:each_serializer] = serializer
|
2014-04-16 11:18:09 -04:00
|
|
|
ActiveModel::ArraySerializer.new(obj.to_ary, serializer_opts).as_json
|
2013-02-07 10:45:24 -05:00
|
|
|
else
|
2013-05-29 16:49:34 -04:00
|
|
|
serializer.new(obj, serializer_opts).as_json
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
2013-05-29 16:49:34 -04:00
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2013-05-29 16:49:34 -04:00
|
|
|
# This is odd, but it seems that in Rails `render json: obj` is about
|
|
|
|
# 20% slower than calling MultiJSON.dump ourselves. I'm not sure why
|
|
|
|
# Rails doesn't call MultiJson.dump when you pass it json: obj but
|
|
|
|
# it seems we don't need whatever Rails is doing.
|
|
|
|
def render_serialized(obj, serializer, opts={})
|
|
|
|
render_json_dump(serialize_data(obj, serializer, opts))
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def render_json_dump(obj)
|
|
|
|
render json: MultiJson.dump(obj)
|
|
|
|
end
|
|
|
|
|
2013-02-06 11:55:54 -05:00
|
|
|
def can_cache_content?
|
2013-10-16 01:39:18 -04:00
|
|
|
!current_user.present?
|
2013-02-06 11:55:54 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
# Our custom cache method
|
|
|
|
def discourse_expires_in(time_length)
|
|
|
|
return unless can_cache_content?
|
2014-01-04 02:53:27 -05:00
|
|
|
Middleware::AnonymousCache.anon_cache(request.env, time_length)
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
2014-08-28 12:07:13 -04:00
|
|
|
def fetch_user_from_params(opts=nil)
|
|
|
|
opts ||= {}
|
2014-06-18 14:40:15 -04:00
|
|
|
user = if params[:username]
|
|
|
|
username_lower = params[:username].downcase
|
|
|
|
username_lower.gsub!(/\.json$/, '')
|
2014-08-28 12:07:13 -04:00
|
|
|
find_opts = {username_lower: username_lower}
|
|
|
|
find_opts[:active] = true unless opts[:include_inactive]
|
|
|
|
User.find_by(find_opts)
|
2014-06-18 14:40:15 -04:00
|
|
|
elsif params[:external_id]
|
|
|
|
SingleSignOnRecord.find_by(external_id: params[:external_id]).try(:user)
|
|
|
|
end
|
2013-05-22 11:20:16 -04:00
|
|
|
raise Discourse::NotFound.new if user.blank?
|
|
|
|
|
|
|
|
guardian.ensure_can_see!(user)
|
|
|
|
user
|
|
|
|
end
|
|
|
|
|
2013-09-04 11:53:00 -04:00
|
|
|
def post_ids_including_replies
|
|
|
|
post_ids = params[:post_ids].map {|p| p.to_i}
|
|
|
|
if params[:reply_post_ids]
|
|
|
|
post_ids << PostReply.where(post_id: params[:reply_post_ids].map {|p| p.to_i}).pluck(:reply_id)
|
|
|
|
post_ids.flatten!
|
|
|
|
post_ids.uniq!
|
|
|
|
end
|
|
|
|
post_ids
|
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
private
|
|
|
|
|
2013-08-05 16:25:44 -04:00
|
|
|
def preload_anonymous_data
|
2014-02-24 14:24:18 -05:00
|
|
|
store_preloaded("site", Site.json_for(guardian))
|
2013-08-05 16:25:44 -04:00
|
|
|
store_preloaded("siteSettings", SiteSetting.client_settings_json)
|
2013-12-17 12:49:22 -05:00
|
|
|
store_preloaded("customHTML", custom_html_json)
|
2014-06-18 14:04:10 -04:00
|
|
|
store_preloaded("banner", banner_json)
|
2014-12-22 19:12:26 -05:00
|
|
|
store_preloaded("customEmoji", custom_emoji)
|
2013-08-05 16:25:44 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def preload_current_user_data
|
2013-11-06 12:56:26 -05:00
|
|
|
store_preloaded("currentUser", MultiJson.dump(CurrentUserSerializer.new(current_user, scope: guardian, root: false)))
|
2013-08-05 16:25:44 -04:00
|
|
|
serializer = ActiveModel::ArraySerializer.new(TopicTrackingState.report([current_user.id]), each_serializer: TopicTrackingStateSerializer)
|
|
|
|
store_preloaded("topicTrackingStates", MultiJson.dump(serializer))
|
|
|
|
end
|
|
|
|
|
2013-12-17 12:49:22 -05:00
|
|
|
def custom_html_json
|
2015-01-12 20:18:52 -05:00
|
|
|
data = {
|
2015-01-14 05:52:42 -05:00
|
|
|
top: SiteCustomization.custom_top(session[:preview_style]),
|
2015-01-12 20:18:52 -05:00
|
|
|
footer: SiteCustomization.custom_footer(session[:preview_style])
|
|
|
|
}
|
2014-06-04 21:39:33 -04:00
|
|
|
|
|
|
|
if DiscoursePluginRegistry.custom_html
|
|
|
|
data.merge! DiscoursePluginRegistry.custom_html
|
|
|
|
end
|
|
|
|
|
|
|
|
MultiJson.dump(data)
|
2013-12-17 12:25:27 -05:00
|
|
|
end
|
|
|
|
|
2014-11-13 23:39:17 -05:00
|
|
|
def self.banner_json_cache
|
|
|
|
@banner_json_cache ||= DistributedCache.new("banner_json")
|
|
|
|
end
|
|
|
|
|
2014-06-18 14:04:10 -04:00
|
|
|
def banner_json
|
2014-11-13 23:39:17 -05:00
|
|
|
json = ApplicationController.banner_json_cache["json"]
|
|
|
|
|
|
|
|
unless json
|
|
|
|
topic = Topic.where(archetype: Archetype.banner).limit(1).first
|
|
|
|
banner = topic.present? ? topic.banner : {}
|
|
|
|
ApplicationController.banner_json_cache["json"] = json = MultiJson.dump(banner)
|
|
|
|
end
|
|
|
|
|
|
|
|
json
|
2014-06-18 14:04:10 -04:00
|
|
|
end
|
|
|
|
|
2014-12-22 19:12:26 -05:00
|
|
|
def custom_emoji
|
|
|
|
serializer = ActiveModel::ArraySerializer.new(Emoji.custom, each_serializer: EmojiSerializer)
|
|
|
|
MultiJson.dump(serializer)
|
|
|
|
end
|
|
|
|
|
2015-02-08 15:25:03 -05:00
|
|
|
# Render action for a JSON error.
|
|
|
|
#
|
|
|
|
# obj - a translated string, an ActiveRecord model, or an array of translated strings
|
|
|
|
# type - a machine-readable description of the error
|
|
|
|
# status - HTTP status code to return
|
|
|
|
def render_json_error(obj, type=nil, status=422)
|
|
|
|
render json: MultiJson.dump(create_errors_json(obj, type)), status: status
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def success_json
|
2014-06-18 14:04:10 -04:00
|
|
|
{ success: 'OK' }
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def failed_json
|
2014-06-18 14:04:10 -04:00
|
|
|
{ failed: 'FAILED' }
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def json_result(obj, opts={})
|
|
|
|
if yield(obj)
|
|
|
|
json = success_json
|
|
|
|
|
|
|
|
# If we were given a serializer, add the class to the json that comes back
|
|
|
|
if opts[:serializer].present?
|
2013-04-11 20:07:46 -04:00
|
|
|
json[obj.class.name.underscore] = opts[:serializer].new(obj, scope: guardian).serializable_hash
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
render json: MultiJson.dump(json)
|
|
|
|
else
|
2014-09-08 15:17:31 -04:00
|
|
|
error_obj = nil
|
|
|
|
if opts[:additional_errors]
|
|
|
|
error_target = opts[:additional_errors].find do |o|
|
|
|
|
target = obj.send(o)
|
|
|
|
target && target.errors.present?
|
|
|
|
end
|
|
|
|
error_obj = obj.send(error_target) if error_target
|
|
|
|
end
|
|
|
|
render_json_error(error_obj || obj)
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
2013-02-07 10:45:24 -05:00
|
|
|
end
|
2013-02-05 14:16:51 -05:00
|
|
|
|
|
|
|
def mini_profiler_enabled?
|
2014-07-16 18:34:30 -04:00
|
|
|
defined?(Rack::MiniProfiler) && guardian.is_developer?
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def authorize_mini_profiler
|
|
|
|
return unless mini_profiler_enabled?
|
|
|
|
Rack::MiniProfiler.authorize_request
|
|
|
|
end
|
|
|
|
|
2013-02-07 10:45:24 -05:00
|
|
|
def check_xhr
|
2013-08-05 16:25:44 -04:00
|
|
|
# bypass xhr check on PUT / POST / DELETE provided api key is there, otherwise calling api is annoying
|
|
|
|
return if !request.get? && api_key_valid?
|
|
|
|
raise RenderEmpty.new unless ((request.format && request.format.json?) || request.xhr?)
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def ensure_logged_in
|
|
|
|
raise Discourse::NotLoggedIn.new unless current_user.present?
|
|
|
|
end
|
2013-02-07 10:45:24 -05:00
|
|
|
|
2013-06-04 18:32:36 -04:00
|
|
|
def redirect_to_login_if_required
|
2014-01-24 07:47:35 -05:00
|
|
|
return if current_user || (request.format.json? && api_key_valid?)
|
|
|
|
|
2014-12-16 02:45:42 -05:00
|
|
|
# save original URL in a cookie
|
|
|
|
cookies[:destination_url] = request.original_url unless request.original_url =~ /uploads/
|
2014-01-24 07:47:35 -05:00
|
|
|
redirect_to :login if SiteSetting.login_required?
|
2013-06-04 18:32:36 -04:00
|
|
|
end
|
|
|
|
|
2014-02-12 23:37:28 -05:00
|
|
|
def block_if_readonly_mode
|
2014-02-13 11:34:24 -05:00
|
|
|
return if request.fullpath.start_with?("/admin/backups")
|
|
|
|
raise Discourse::ReadOnly.new if !request.get? && Discourse.readonly_mode?
|
2014-02-12 23:37:28 -05:00
|
|
|
end
|
|
|
|
|
2013-07-11 16:38:46 -04:00
|
|
|
def build_not_found_page(status=404, layout=false)
|
2014-07-04 16:18:09 -04:00
|
|
|
category_topic_ids = Category.pluck(:topic_id).compact
|
2015-02-03 14:10:21 -05:00
|
|
|
@container_class = "container not-found-container"
|
2014-07-04 16:18:09 -04:00
|
|
|
@top_viewed = Topic.where.not(id: category_topic_ids).top_viewed(10)
|
|
|
|
@recent = Topic.where.not(id: category_topic_ids).recent(10)
|
2013-05-30 14:46:02 -04:00
|
|
|
@slug = params[:slug].class == String ? params[:slug] : ''
|
2013-06-06 14:41:27 -04:00
|
|
|
@slug = (params[:id].class == String ? params[:id] : '') if @slug.blank?
|
2013-05-30 14:46:02 -04:00
|
|
|
@slug.gsub!('-',' ')
|
2013-07-11 16:38:46 -04:00
|
|
|
render_to_string status: status, layout: layout, formats: [:html], template: '/exceptions/not_found'
|
2013-05-30 14:46:02 -04:00
|
|
|
end
|
|
|
|
|
2013-06-19 22:11:14 -04:00
|
|
|
protected
|
2013-06-17 02:09:59 -04:00
|
|
|
|
2014-09-24 22:02:41 -04:00
|
|
|
def render_post_json(post, add_raw=true)
|
2014-09-02 17:37:19 -04:00
|
|
|
post_serializer = PostSerializer.new(post, scope: guardian, root: false)
|
2014-09-24 22:02:41 -04:00
|
|
|
post_serializer.add_raw = add_raw
|
2014-09-02 17:37:19 -04:00
|
|
|
|
|
|
|
counts = PostAction.counts_for([post], current_user)
|
|
|
|
if counts && counts = counts[post.id]
|
|
|
|
post_serializer.post_actions = counts
|
|
|
|
end
|
|
|
|
render_json_dump(post_serializer)
|
|
|
|
end
|
|
|
|
|
2013-06-17 02:09:59 -04:00
|
|
|
def api_key_valid?
|
2013-10-22 15:53:08 -04:00
|
|
|
request["api_key"] && ApiKey.where(key: request["api_key"]).exists?
|
2013-06-17 02:09:59 -04:00
|
|
|
end
|
|
|
|
|
2013-06-19 22:11:14 -04:00
|
|
|
# returns an array of integers given a param key
|
|
|
|
# returns nil if key is not found
|
|
|
|
def param_to_integer_list(key, delimiter = ',')
|
|
|
|
if params[key]
|
|
|
|
params[key].split(delimiter).map(&:to_i)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
end
|