Make rubocop happy again.

This commit is contained in:
Guo Xiang Tan
2018-06-07 13:28:18 +08:00
parent c6c1ef71c1
commit ad5082d969
79 changed files with 3155 additions and 3155 deletions
+34 -34
View File
@@ -88,44 +88,44 @@ class Admin::BadgesController < Admin::AdminController
end
private
def find_badge
params.require(:id)
Badge.find(params[:id])
end
def find_badge
params.require(:id)
Badge.find(params[:id])
end
# Options:
# :new - reset the badge id to nil before saving
def update_badge_from_params(badge, opts = {})
errors = []
Badge.transaction do
allowed = Badge.column_names.map(&:to_sym)
allowed -= [:id, :created_at, :updated_at, :grant_count]
allowed -= Badge.protected_system_fields if badge.system?
allowed -= [:query] unless SiteSetting.enable_badge_sql
# Options:
# :new - reset the badge id to nil before saving
def update_badge_from_params(badge, opts = {})
errors = []
Badge.transaction do
allowed = Badge.column_names.map(&:to_sym)
allowed -= [:id, :created_at, :updated_at, :grant_count]
allowed -= Badge.protected_system_fields if badge.system?
allowed -= [:query] unless SiteSetting.enable_badge_sql
params.permit(*allowed)
params.permit(*allowed)
allowed.each do |key|
badge.send("#{key}=" , params[key]) if params[key]
end
# Badge query contract checks
begin
if SiteSetting.enable_badge_sql
BadgeGranter.contract_checks!(badge.query, target_posts: badge.target_posts, trigger: badge.trigger)
end
rescue => e
errors << e.message
raise ActiveRecord::Rollback
end
badge.id = nil if opts[:new]
badge.save!
allowed.each do |key|
badge.send("#{key}=" , params[key]) if params[key]
end
errors
rescue ActiveRecord::RecordInvalid
errors.push(*badge.errors.full_messages)
errors
# Badge query contract checks
begin
if SiteSetting.enable_badge_sql
BadgeGranter.contract_checks!(badge.query, target_posts: badge.target_posts, trigger: badge.trigger)
end
rescue => e
errors << e.message
raise ActiveRecord::Rollback
end
badge.id = nil if opts[:new]
badge.save!
end
errors
rescue ActiveRecord::RecordInvalid
errors.push(*badge.errors.full_messages)
errors
end
end
@@ -17,18 +17,18 @@ class Admin::EmbeddableHostsController < Admin::AdminController
protected
def save_host(host)
host.host = params[:embeddable_host][:host]
host.path_whitelist = params[:embeddable_host][:path_whitelist]
host.class_name = params[:embeddable_host][:class_name]
host.category_id = params[:embeddable_host][:category_id]
host.category_id = SiteSetting.uncategorized_category_id if host.category_id.blank?
def save_host(host)
host.host = params[:embeddable_host][:host]
host.path_whitelist = params[:embeddable_host][:path_whitelist]
host.class_name = params[:embeddable_host][:class_name]
host.category_id = params[:embeddable_host][:category_id]
host.category_id = SiteSetting.uncategorized_category_id if host.category_id.blank?
if host.save
render_serialized(host, EmbeddableHostSerializer, root: 'embeddable_host', rest_serializer: true)
else
render_json_error(host)
end
if host.save
render_serialized(host, EmbeddableHostSerializer, root: 'embeddable_host', rest_serializer: true)
else
render_json_error(host)
end
end
end
@@ -27,7 +27,7 @@ class Admin::EmbeddingController < Admin::AdminController
protected
def fetch_embedding
@embedding = Embedding.find
end
def fetch_embedding
@embedding = Embedding.find
end
end
@@ -51,13 +51,13 @@ class Admin::ScreenedIpAddressesController < Admin::AdminController
private
def allowed_params
params.require(:ip_address)
params.permit(:ip_address, :action_name)
end
def allowed_params
params.require(:ip_address)
params.permit(:ip_address, :action_name)
end
def fetch_screened_ip_address
@screened_ip_address = ScreenedIpAddress.find(params[:id])
end
def fetch_screened_ip_address
@screened_ip_address = ScreenedIpAddress.find(params[:id])
end
end
+12 -12
View File
@@ -75,19 +75,19 @@ class Admin::SiteTextsController < Admin::AdminController
protected
def record_for(k, value = nil)
if k.ends_with?("_MF")
ovr = TranslationOverride.where(translation_key: k, locale: I18n.locale).pluck(:value)
value = ovr[0] if ovr.present?
end
value ||= I18n.t(k)
{ id: k, value: value }
def record_for(k, value = nil)
if k.ends_with?("_MF")
ovr = TranslationOverride.where(translation_key: k, locale: I18n.locale).pluck(:value)
value = ovr[0] if ovr.present?
end
def find_site_text
raise Discourse::NotFound unless I18n.exists?(params[:id]) && !self.class.restricted_keys.include?(params[:id])
record_for(params[:id])
end
value ||= I18n.t(k)
{ id: k, value: value }
end
def find_site_text
raise Discourse::NotFound unless I18n.exists?(params[:id]) && !self.class.restricted_keys.include?(params[:id])
record_for(params[:id])
end
end
+43 -43
View File
@@ -223,59 +223,59 @@ class Admin::ThemesController < Admin::AdminController
private
def update_default_theme
if theme_params.key?(:default)
is_default = theme_params[:default].to_s == "true"
if @theme.key == SiteSetting.default_theme_key && !is_default
Theme.clear_default!
elsif is_default
@theme.set_default!
end
def update_default_theme
if theme_params.key?(:default)
is_default = theme_params[:default].to_s == "true"
if @theme.key == SiteSetting.default_theme_key && !is_default
Theme.clear_default!
elsif is_default
@theme.set_default!
end
end
end
def theme_params
@theme_params ||=
begin
# deep munge is a train wreck, work around it for now
params[:theme][:child_theme_ids] ||= [] if params[:theme].key?(:child_theme_ids)
def theme_params
@theme_params ||=
begin
# deep munge is a train wreck, work around it for now
params[:theme][:child_theme_ids] ||= [] if params[:theme].key?(:child_theme_ids)
params.require(:theme).permit(
:name,
:color_scheme_id,
:default,
:user_selectable,
settings: {},
theme_fields: [:name, :target, :value, :upload_id, :type_id],
child_theme_ids: []
)
end
end
def set_fields
return unless fields = theme_params[:theme_fields]
fields.each do |field|
@theme.set_field(
target: field[:target],
name: field[:name],
value: field[:value],
type_id: field[:type_id],
upload_id: field[:upload_id]
params.require(:theme).permit(
:name,
:color_scheme_id,
:default,
:user_selectable,
settings: {},
theme_fields: [:name, :target, :value, :upload_id, :type_id],
child_theme_ids: []
)
end
end
end
def update_settings
return unless target_settings = theme_params[:settings]
def set_fields
return unless fields = theme_params[:theme_fields]
target_settings.each_pair do |setting_name, new_value|
@theme.update_setting(setting_name.to_sym, new_value)
end
fields.each do |field|
@theme.set_field(
target: field[:target],
name: field[:name],
value: field[:value],
type_id: field[:type_id],
upload_id: field[:upload_id]
)
end
end
def log_theme_change(old_record, new_record)
StaffActionLogger.new(current_user).log_theme_change(old_record, new_record)
def update_settings
return unless target_settings = theme_params[:settings]
target_settings.each_pair do |setting_name, new_value|
@theme.update_setting(setting_name.to_sym, new_value)
end
end
def log_theme_change(old_record, new_record)
StaffActionLogger.new(current_user).log_theme_change(old_record, new_record)
end
end
@@ -47,11 +47,11 @@ class Admin::UserFieldsController < Admin::AdminController
protected
def update_options(field)
options = params[:user_field][:options]
if options.present?
UserFieldOption.where(user_field_id: field.id).delete_all
field.user_field_options_attributes = options.map { |o| { value: o } }.uniq
end
def update_options(field)
options = params[:user_field][:options]
if options.present?
UserFieldOption.where(user_field_id: field.id).delete_all
field.user_field_options_attributes = options.map { |o| { value: o } }.uniq
end
end
end
+23 -23
View File
@@ -544,34 +544,34 @@ class Admin::UsersController < Admin::AdminController
private
def perform_post_action
return unless params[:post_id].present? &&
params[:post_action].present?
def perform_post_action
return unless params[:post_id].present? &&
params[:post_action].present?
if post = Post.where(id: params[:post_id]).first
case params[:post_action]
when 'delete'
PostDestroyer.new(current_user, post).destroy
when 'edit'
revisor = PostRevisor.new(post)
if post = Post.where(id: params[:post_id]).first
case params[:post_action]
when 'delete'
PostDestroyer.new(current_user, post).destroy
when 'edit'
revisor = PostRevisor.new(post)
# Take what the moderator edited in as gospel
revisor.revise!(
current_user,
{ raw: params[:post_edit] },
skip_validations: true,
skip_revision: true
)
end
# Take what the moderator edited in as gospel
revisor.revise!(
current_user,
{ raw: params[:post_edit] },
skip_validations: true,
skip_revision: true
)
end
end
end
def fetch_user
@user = User.find_by(id: params[:user_id])
end
def fetch_user
@user = User.find_by(id: params[:user_id])
end
def refresh_browser(user)
MessageBus.publish "/file-change", ["refresh"], user_ids: [user.id]
end
def refresh_browser(user)
MessageBus.publish "/file-change", ["refresh"], user_ids: [user.id]
end
end
+220 -220
View File
@@ -462,255 +462,255 @@ class ApplicationController < ActionController::Base
private
def check_readonly_mode
@readonly_mode = Discourse.readonly_mode?
def check_readonly_mode
@readonly_mode = Discourse.readonly_mode?
end
def locale_from_header
begin
# Rails I18n uses underscores between the locale and the region; the request
# headers use hyphens.
require 'http_accept_language' unless defined? HttpAcceptLanguage
available_locales = I18n.available_locales.map { |locale| locale.to_s.tr('_', '-') }
parser = HttpAcceptLanguage::Parser.new(request.env["HTTP_ACCEPT_LANGUAGE"])
parser.language_region_compatible_from(available_locales).tr('-', '_')
rescue
# If Accept-Language headers are not set.
I18n.default_locale
end
end
def locale_from_header
begin
# Rails I18n uses underscores between the locale and the region; the request
# headers use hyphens.
require 'http_accept_language' unless defined? HttpAcceptLanguage
available_locales = I18n.available_locales.map { |locale| locale.to_s.tr('_', '-') }
parser = HttpAcceptLanguage::Parser.new(request.env["HTTP_ACCEPT_LANGUAGE"])
parser.language_region_compatible_from(available_locales).tr('-', '_')
rescue
# If Accept-Language headers are not set.
I18n.default_locale
end
end
def preload_anonymous_data
store_preloaded("site", Site.json_for(guardian))
store_preloaded("siteSettings", SiteSetting.client_settings_json)
store_preloaded("themeSettings", Theme.settings_for_client(@theme_key))
store_preloaded("customHTML", custom_html_json)
store_preloaded("banner", banner_json)
store_preloaded("customEmoji", custom_emoji)
store_preloaded("translationOverrides", I18n.client_overrides_json(I18n.locale))
end
def preload_anonymous_data
store_preloaded("site", Site.json_for(guardian))
store_preloaded("siteSettings", SiteSetting.client_settings_json)
store_preloaded("themeSettings", Theme.settings_for_client(@theme_key))
store_preloaded("customHTML", custom_html_json)
store_preloaded("banner", banner_json)
store_preloaded("customEmoji", custom_emoji)
store_preloaded("translationOverrides", I18n.client_overrides_json(I18n.locale))
end
def preload_current_user_data
store_preloaded("currentUser", MultiJson.dump(CurrentUserSerializer.new(current_user, scope: guardian, root: false)))
report = TopicTrackingState.report(current_user)
serializer = ActiveModel::ArraySerializer.new(report, each_serializer: TopicTrackingStateSerializer)
store_preloaded("topicTrackingStates", MultiJson.dump(serializer))
end
def preload_current_user_data
store_preloaded("currentUser", MultiJson.dump(CurrentUserSerializer.new(current_user, scope: guardian, root: false)))
report = TopicTrackingState.report(current_user)
serializer = ActiveModel::ArraySerializer.new(report, each_serializer: TopicTrackingStateSerializer)
store_preloaded("topicTrackingStates", MultiJson.dump(serializer))
end
def custom_html_json
target = view_context.mobile_view? ? :mobile : :desktop
def custom_html_json
target = view_context.mobile_view? ? :mobile : :desktop
data =
if @theme_key
{
top: Theme.lookup_field(@theme_key, target, "after_header"),
footer: Theme.lookup_field(@theme_key, target, "footer")
}
else
{}
end
if DiscoursePluginRegistry.custom_html
data.merge! DiscoursePluginRegistry.custom_html
end
DiscoursePluginRegistry.html_builders.each do |name, _|
if name.start_with?("client:")
data[name.sub(/^client:/, '')] = DiscoursePluginRegistry.build_html(name, self)
end
end
MultiJson.dump(data)
end
def self.banner_json_cache
@banner_json_cache ||= DistributedCache.new("banner_json")
end
def banner_json
json = ApplicationController.banner_json_cache["json"]
unless json
topic = Topic.where(archetype: Archetype.banner).first
banner = topic.present? ? topic.banner : {}
ApplicationController.banner_json_cache["json"] = json = MultiJson.dump(banner)
end
json
end
def custom_emoji
serializer = ActiveModel::ArraySerializer.new(Emoji.custom, each_serializer: EmojiSerializer)
MultiJson.dump(serializer)
end
# Render action for a JSON error.
#
# obj - a translated string, an ActiveRecord model, or an array of translated strings
# opts:
# type - a machine-readable description of the error
# status - HTTP status code to return
# headers - extra headers for the response
def render_json_error(obj, opts = {})
opts = { status: opts } if opts.is_a?(Integer)
opts.fetch(:headers, {}).each { |name, value| headers[name.to_s] = value }
render json: MultiJson.dump(create_errors_json(obj, opts)), status: opts[:status] || 422
end
def success_json
{ success: 'OK' }
end
def failed_json
{ failed: 'FAILED' }
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?
json[obj.class.name.underscore] = opts[:serializer].new(obj, scope: guardian).serializable_hash
end
render json: MultiJson.dump(json)
data =
if @theme_key
{
top: Theme.lookup_field(@theme_key, target, "after_header"),
footer: Theme.lookup_field(@theme_key, target, "footer")
}
else
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
if DiscoursePluginRegistry.custom_html
data.merge! DiscoursePluginRegistry.custom_html
end
DiscoursePluginRegistry.html_builders.each do |name, _|
if name.start_with?("client:")
data[name.sub(/^client:/, '')] = DiscoursePluginRegistry.build_html(name, self)
end
end
MultiJson.dump(data)
end
def self.banner_json_cache
@banner_json_cache ||= DistributedCache.new("banner_json")
end
def banner_json
json = ApplicationController.banner_json_cache["json"]
unless json
topic = Topic.where(archetype: Archetype.banner).first
banner = topic.present? ? topic.banner : {}
ApplicationController.banner_json_cache["json"] = json = MultiJson.dump(banner)
end
json
end
def custom_emoji
serializer = ActiveModel::ArraySerializer.new(Emoji.custom, each_serializer: EmojiSerializer)
MultiJson.dump(serializer)
end
# Render action for a JSON error.
#
# obj - a translated string, an ActiveRecord model, or an array of translated strings
# opts:
# type - a machine-readable description of the error
# status - HTTP status code to return
# headers - extra headers for the response
def render_json_error(obj, opts = {})
opts = { status: opts } if opts.is_a?(Integer)
opts.fetch(:headers, {}).each { |name, value| headers[name.to_s] = value }
render json: MultiJson.dump(create_errors_json(obj, opts)), status: opts[:status] || 422
end
def success_json
{ success: 'OK' }
end
def failed_json
{ failed: 'FAILED' }
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?
json[obj.class.name.underscore] = opts[:serializer].new(obj, scope: guardian).serializable_hash
end
render json: MultiJson.dump(json)
else
error_obj = nil
if opts[:additional_errors]
error_target = opts[:additional_errors].find do |o|
target = obj.send(o)
target && target.errors.present?
end
render_json_error(error_obj || obj)
error_obj = obj.send(error_target) if error_target
end
render_json_error(error_obj || obj)
end
end
def mini_profiler_enabled?
defined?(Rack::MiniProfiler) && (guardian.is_developer? || Rails.env.development?)
end
def mini_profiler_enabled?
defined?(Rack::MiniProfiler) && (guardian.is_developer? || Rails.env.development?)
end
def authorize_mini_profiler
return unless mini_profiler_enabled?
Rack::MiniProfiler.authorize_request
end
def authorize_mini_profiler
return unless mini_profiler_enabled?
Rack::MiniProfiler.authorize_request
end
def check_xhr
# bypass xhr check on PUT / POST / DELETE provided api key is there, otherwise calling api is annoying
return if !request.get? && (is_api? || is_user_api?)
raise RenderEmpty.new unless ((request.format && request.format.json?) || request.xhr?)
end
def check_xhr
# bypass xhr check on PUT / POST / DELETE provided api key is there, otherwise calling api is annoying
return if !request.get? && (is_api? || is_user_api?)
raise RenderEmpty.new unless ((request.format && request.format.json?) || request.xhr?)
end
def self.requires_login(arg = {})
@requires_login_arg = arg
end
def self.requires_login(arg = {})
@requires_login_arg = arg
end
def self.requires_login_arg
@requires_login_arg
end
def self.requires_login_arg
@requires_login_arg
end
def block_if_requires_login
if arg = self.class.requires_login_arg
check =
if except = arg[:except]
!except.include?(action_name.to_sym)
elsif only = arg[:only]
only.include?(action_name.to_sym)
else
true
end
ensure_logged_in if check
end
end
def ensure_logged_in
raise Discourse::NotLoggedIn.new unless current_user.present?
end
def ensure_staff
raise Discourse::InvalidAccess.new unless current_user && current_user.staff?
end
def ensure_admin
raise Discourse::InvalidAccess.new unless current_user && current_user.admin?
end
def ensure_wizard_enabled
raise Discourse::InvalidAccess.new unless SiteSetting.wizard_enabled?
end
def destination_url
request.original_url unless request.original_url =~ /uploads/
end
def redirect_to_login_if_required
return if current_user || (request.format.json? && is_api?)
if SiteSetting.login_required?
flash.keep
if SiteSetting.enable_sso?
# save original URL in a session so we can redirect after login
session[:destination_url] = destination_url
redirect_to path('/session/sso')
elsif params[:authComplete].present?
redirect_to path("/login?authComplete=true")
def block_if_requires_login
if arg = self.class.requires_login_arg
check =
if except = arg[:except]
!except.include?(action_name.to_sym)
elsif only = arg[:only]
only.include?(action_name.to_sym)
else
# save original URL in a cookie (javascript redirects after login in this case)
cookies[:destination_url] = destination_url
redirect_to path("/login")
true
end
ensure_logged_in if check
end
end
def ensure_logged_in
raise Discourse::NotLoggedIn.new unless current_user.present?
end
def ensure_staff
raise Discourse::InvalidAccess.new unless current_user && current_user.staff?
end
def ensure_admin
raise Discourse::InvalidAccess.new unless current_user && current_user.admin?
end
def ensure_wizard_enabled
raise Discourse::InvalidAccess.new unless SiteSetting.wizard_enabled?
end
def destination_url
request.original_url unless request.original_url =~ /uploads/
end
def redirect_to_login_if_required
return if current_user || (request.format.json? && is_api?)
if SiteSetting.login_required?
flash.keep
if SiteSetting.enable_sso?
# save original URL in a session so we can redirect after login
session[:destination_url] = destination_url
redirect_to path('/session/sso')
elsif params[:authComplete].present?
redirect_to path("/login?authComplete=true")
else
# save original URL in a cookie (javascript redirects after login in this case)
cookies[:destination_url] = destination_url
redirect_to path("/login")
end
end
end
def block_if_readonly_mode
return if request.fullpath.start_with?(path "/admin/backups")
raise Discourse::ReadOnly.new if !(request.get? || request.head?) && @readonly_mode
def block_if_readonly_mode
return if request.fullpath.start_with?(path "/admin/backups")
raise Discourse::ReadOnly.new if !(request.get? || request.head?) && @readonly_mode
end
def build_not_found_page(status = 404, layout = false)
if SiteSetting.bootstrap_error_pages?
preload_json
layout = 'application' if layout == 'no_ember'
end
def build_not_found_page(status = 404, layout = false)
if SiteSetting.bootstrap_error_pages?
preload_json
layout = 'application' if layout == 'no_ember'
end
category_topic_ids = Category.pluck(:topic_id).compact
@container_class = "wrap not-found-container"
@top_viewed = TopicQuery.new(nil, except_topic_ids: category_topic_ids).list_top_for("monthly").topics.first(10)
@recent = Topic.includes(:category).where.not(id: category_topic_ids).recent(10)
@slug = params[:slug].class == String ? params[:slug] : ''
@slug = (params[:id].class == String ? params[:id] : '') if @slug.blank?
@slug.tr!('-', ' ')
@hide_google = true if SiteSetting.login_required
render_to_string status: status, layout: layout, formats: [:html], template: '/exceptions/not_found'
end
category_topic_ids = Category.pluck(:topic_id).compact
@container_class = "wrap not-found-container"
@top_viewed = TopicQuery.new(nil, except_topic_ids: category_topic_ids).list_top_for("monthly").topics.first(10)
@recent = Topic.includes(:category).where.not(id: category_topic_ids).recent(10)
@slug = params[:slug].class == String ? params[:slug] : ''
@slug = (params[:id].class == String ? params[:id] : '') if @slug.blank?
@slug.tr!('-', ' ')
@hide_google = true if SiteSetting.login_required
render_to_string status: status, layout: layout, formats: [:html], template: '/exceptions/not_found'
end
def is_asset_path
request.env['DISCOURSE_IS_ASSET_PATH'] = 1
end
def is_asset_path
request.env['DISCOURSE_IS_ASSET_PATH'] = 1
end
protected
def render_post_json(post, add_raw = true)
post_serializer = PostSerializer.new(post, scope: guardian, root: false)
post_serializer.add_raw = add_raw
def render_post_json(post, add_raw = true)
post_serializer = PostSerializer.new(post, scope: guardian, root: false)
post_serializer.add_raw = add_raw
counts = PostAction.counts_for([post], current_user)
if counts && counts = counts[post.id]
post_serializer.post_actions = counts
end
render_json_dump(post_serializer)
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
# 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
# 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
end
+92 -92
View File
@@ -201,109 +201,109 @@ class CategoriesController < ApplicationController
end
private
def categories_and_topics(topics_filter)
discourse_expires_in 1.minute
def categories_and_topics(topics_filter)
discourse_expires_in 1.minute
category_options = {
is_homepage: current_homepage == "categories".freeze,
parent_category_id: params[:parent_category_id],
include_topics: false
}
category_options = {
is_homepage: current_homepage == "categories".freeze,
parent_category_id: params[:parent_category_id],
include_topics: false
}
topic_options = {
per_page: SiteSetting.categories_topics,
no_definitions: true,
exclude_category_ids: Category.where(suppress_from_latest: true).pluck(:id)
}
topic_options = {
per_page: SiteSetting.categories_topics,
no_definitions: true,
exclude_category_ids: Category.where(suppress_from_latest: true).pluck(:id)
}
result = CategoryAndTopicLists.new
result.category_list = CategoryList.new(guardian, category_options)
result = CategoryAndTopicLists.new
result.category_list = CategoryList.new(guardian, category_options)
if topics_filter == :latest
result.topic_list = TopicQuery.new(current_user, topic_options).list_latest
elsif topics_filter == :top
result.topic_list = TopicQuery.new(nil, topic_options).list_top_for(SiteSetting.top_page_default_timeframe.to_sym)
if topics_filter == :latest
result.topic_list = TopicQuery.new(current_user, topic_options).list_latest
elsif topics_filter == :top
result.topic_list = TopicQuery.new(nil, topic_options).list_top_for(SiteSetting.top_page_default_timeframe.to_sym)
end
draft_key = Draft::NEW_TOPIC
draft_sequence = DraftSequence.current(current_user, draft_key)
draft = Draft.get(current_user, draft_key, draft_sequence) if current_user
%w{category topic}.each do |type|
result.send(:"#{type}_list").draft = draft
result.send(:"#{type}_list").draft_key = draft_key
result.send(:"#{type}_list").draft_sequence = draft_sequence
end
render_serialized(result, CategoryAndTopicListsSerializer, root: false)
end
def required_param_keys
[:name, :color, :text_color]
end
def category_params
@category_params ||= begin
required_param_keys.each do |key|
params.require(key)
end
draft_key = Draft::NEW_TOPIC
draft_sequence = DraftSequence.current(current_user, draft_key)
draft = Draft.get(current_user, draft_key, draft_sequence) if current_user
%w{category topic}.each do |type|
result.send(:"#{type}_list").draft = draft
result.send(:"#{type}_list").draft_key = draft_key
result.send(:"#{type}_list").draft_sequence = draft_sequence
if p = params[:permissions]
p.each do |k, v|
p[k] = v.to_i
end
end
render_serialized(result, CategoryAndTopicListsSerializer, root: false)
end
def required_param_keys
[:name, :color, :text_color]
end
def category_params
@category_params ||= begin
required_param_keys.each do |key|
params.require(key)
end
if p = params[:permissions]
p.each do |k, v|
p[k] = v.to_i
end
end
if SiteSetting.tagging_enabled
params[:allowed_tags] ||= []
params[:allowed_tag_groups] ||= []
end
params.permit(*required_param_keys,
:position,
:email_in,
:email_in_allow_strangers,
:mailinglist_mirror,
:suppress_from_latest,
:all_topics_wiki,
:parent_category_id,
:auto_close_hours,
:auto_close_based_on_last_post,
:uploaded_logo_id,
:uploaded_background_id,
:slug,
:allow_badges,
:topic_template,
:sort_order,
:sort_ascending,
:topic_featured_link_allowed,
:show_subcategory_list,
:num_featured_topics,
:default_view,
:subcategory_list_style,
:default_top_period,
:minimum_required_tags,
custom_fields: [params[:custom_fields].try(:keys)],
permissions: [*p.try(:keys)],
allowed_tags: [],
allowed_tag_groups: [])
if SiteSetting.tagging_enabled
params[:allowed_tags] ||= []
params[:allowed_tag_groups] ||= []
end
end
def fetch_category
@category = Category.find_by(slug: params[:id]) || Category.find_by(id: params[:id].to_i)
params.permit(*required_param_keys,
:position,
:email_in,
:email_in_allow_strangers,
:mailinglist_mirror,
:suppress_from_latest,
:all_topics_wiki,
:parent_category_id,
:auto_close_hours,
:auto_close_based_on_last_post,
:uploaded_logo_id,
:uploaded_background_id,
:slug,
:allow_badges,
:topic_template,
:sort_order,
:sort_ascending,
:topic_featured_link_allowed,
:show_subcategory_list,
:num_featured_topics,
:default_view,
:subcategory_list_style,
:default_top_period,
:minimum_required_tags,
custom_fields: [params[:custom_fields].try(:keys)],
permissions: [*p.try(:keys)],
allowed_tags: [],
allowed_tag_groups: [])
end
end
def initialize_staff_action_logger
@staff_action_logger = StaffActionLogger.new(current_user)
end
def fetch_category
@category = Category.find_by(slug: params[:id]) || Category.find_by(id: params[:id].to_i)
end
def include_topics(parent_category = nil)
style = SiteSetting.desktop_category_page_style
view_context.mobile_view? ||
params[:include_topics] ||
(parent_category && parent_category.subcategory_list_includes_topics?) ||
style == "categories_with_featured_topics".freeze ||
style == "categories_with_top_topics".freeze
end
def initialize_staff_action_logger
@staff_action_logger = StaffActionLogger.new(current_user)
end
def include_topics(parent_category = nil)
style = SiteSetting.desktop_category_page_style
view_context.mobile_view? ||
params[:include_topics] ||
(parent_category && parent_category.subcategory_list_includes_topics?) ||
style == "categories_with_featured_topics".freeze ||
style == "categories_with_top_topics".freeze
end
end
+4 -4
View File
@@ -31,9 +31,9 @@ class ClicksController < ApplicationController
private
def track_params
params.require(:url)
params.permit(:url, :post_id, :topic_id, :redirect)
end
def track_params
params.require(:url)
params.permit(:url, :post_id, :topic_id, :redirect)
end
end
+18 -18
View File
@@ -92,28 +92,28 @@ class EmbedController < ApplicationController
private
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
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
def ensure_api_request
raise Discourse::InvalidAccess.new('api key not set') if !is_api?
end
def ensure_api_request
raise Discourse::InvalidAccess.new('api key not set') if !is_api?
end
def ensure_embeddable
if !(Rails.env.development? && current_user&.admin?)
referer = request.referer
def ensure_embeddable
if !(Rails.env.development? && current_user&.admin?)
referer = request.referer
unless referer && EmbeddableHost.url_allowed?(referer)
raise Discourse::InvalidAccess.new('invalid referer host')
end
unless referer && EmbeddableHost.url_allowed?(referer)
raise Discourse::InvalidAccess.new('invalid referer host')
end
response.headers['X-Frame-Options'] = "ALLOWALL"
rescue URI::InvalidURIError
raise Discourse::InvalidAccess.new('invalid referer host')
end
response.headers['X-Frame-Options'] = "ALLOWALL"
rescue URI::InvalidURIError
raise Discourse::InvalidAccess.new('invalid referer host')
end
end
+3 -3
View File
@@ -14,8 +14,8 @@ class ExceptionsController < ApplicationController
private
def hide_google
@hide_google = true if SiteSetting.login_required
end
def hide_google
@hide_google = true if SiteSetting.login_required
end
end
+5 -5
View File
@@ -9,10 +9,10 @@ class ExportCsvController < ApplicationController
end
private
def export_params
@_export_params ||= begin
params.require(:entity)
params.permit(:entity, args: [:name, :start_date, :end_date, :category_id, :group_id, :trust_level]).to_h
end
def export_params
@_export_params ||= begin
params.require(:entity)
params.permit(:entity, args: [:name, :start_date, :end_date, :category_id, :group_id, :trust_level]).to_h
end
end
end
@@ -48,18 +48,18 @@ class FinishInstallationController < ApplicationController
protected
def redirect_confirm(email)
session[:registered_email] = email
redirect_to(finish_installation_confirm_email_path)
end
def redirect_confirm(email)
session[:registered_email] = email
redirect_to(finish_installation_confirm_email_path)
end
def find_allowed_emails
return [] unless GlobalSetting.respond_to?(:developer_emails) && GlobalSetting.developer_emails.present?
GlobalSetting.developer_emails.split(",").map(&:strip)
end
def find_allowed_emails
return [] unless GlobalSetting.respond_to?(:developer_emails) && GlobalSetting.developer_emails.present?
GlobalSetting.developer_emails.split(",").map(&:strip)
end
def ensure_no_admins
preload_anonymous_data
raise Discourse::InvalidAccess.new unless SiteSetting.has_login_hint?
end
def ensure_no_admins
preload_anonymous_data
raise Discourse::InvalidAccess.new unless SiteSetting.has_login_hint?
end
end
+8 -8
View File
@@ -211,14 +211,14 @@ class InvitesController < ApplicationController
private
def post_process_invite(user)
user.enqueue_welcome_message('welcome_invite') if user.send_welcome_message
if user.has_password?
email_token = user.email_tokens.create(email: user.email)
Jobs.enqueue(:critical_user_email, type: :signup, user_id: user.id, email_token: email_token.token)
elsif !SiteSetting.enable_sso && SiteSetting.enable_local_logins
Jobs.enqueue(:invite_password_instructions_email, username: user.username)
end
def post_process_invite(user)
user.enqueue_welcome_message('welcome_invite') if user.send_welcome_message
if user.has_password?
email_token = user.email_tokens.create(email: user.email)
Jobs.enqueue(:critical_user_email, type: :signup, user_id: user.id, email_token: email_token.token)
elsif !SiteSetting.enable_sso && SiteSetting.enable_local_logins
Jobs.enqueue(:invite_password_instructions_email, username: user.username)
end
end
end
+9 -9
View File
@@ -84,16 +84,16 @@ class NotificationsController < ApplicationController
private
def set_notification
@notification = Notification.find(params[:id])
end
def set_notification
@notification = Notification.find(params[:id])
end
def notification_params
params.permit(:notification_type, :user_id, :data, :read, :topic_id, :post_number, :post_action_id)
end
def notification_params
params.permit(:notification_type, :user_id, :data, :read, :topic_id, :post_number, :post_action_id)
end
def render_notification
render_json_dump(NotificationSerializer.new(@notification, scope: guardian, root: false))
end
def render_notification
render_json_dump(NotificationSerializer.new(@notification, scope: guardian, root: false))
end
end
+23 -23
View File
@@ -65,32 +65,32 @@ class PostActionsController < ApplicationController
private
def fetch_post_from_params
params.require(:id)
def fetch_post_from_params
params.require(:id)
flag_topic = params[:flag_topic]
flag_topic = flag_topic && (flag_topic == true || flag_topic == "true")
flag_topic = params[:flag_topic]
flag_topic = flag_topic && (flag_topic == true || flag_topic == "true")
post_id = if flag_topic
begin
Topic.find(params[:id]).posts.first.id
rescue
raise Discourse::NotFound
end
else
params[:id]
post_id = if flag_topic
begin
Topic.find(params[:id]).posts.first.id
rescue
raise Discourse::NotFound
end
finder = Post.where(id: post_id)
# Include deleted posts if the user is a staff
finder = finder.with_deleted if guardian.is_staff?
@post = finder.first
else
params[:id]
end
def fetch_post_action_type_id_from_params
params.require(:post_action_type_id)
@post_action_type_id = params[:post_action_type_id].to_i
end
finder = Post.where(id: post_id)
# Include deleted posts if the user is a staff
finder = finder.with_deleted if guardian.is_staff?
@post = finder.first
end
def fetch_post_action_type_id_from_params
params.require(:post_action_type_id)
@post_action_type_id = params[:post_action_type_id].to_i
end
end
+11 -11
View File
@@ -52,18 +52,18 @@ class QueuedPostsController < ApplicationController
private
def user_deletion_opts
base = {
context: I18n.t('queue.delete_reason', performed_by: current_user.username),
delete_posts: true,
delete_as_spammer: true
}
def user_deletion_opts
base = {
context: I18n.t('queue.delete_reason', performed_by: current_user.username),
delete_posts: true,
delete_as_spammer: true
}
if Rails.env.production? && ENV["Staging"].nil?
base.merge!(block_email: true, block_ip: true)
end
base
if Rails.env.production? && ENV["Staging"].nil?
base.merge!(block_email: true, block_ip: true)
end
base
end
end
+5 -5
View File
@@ -98,11 +98,11 @@ class StylesheetsController < ApplicationController
private
def read_file(location)
begin
File.read(location)
rescue Errno::ENOENT
end
def read_file(location)
begin
File.read(location)
rescue Errno::ENOENT
end
end
end
+21 -21
View File
@@ -64,28 +64,28 @@ class TagGroupsController < ApplicationController
private
def fetch_tag_group
@tag_group = TagGroup.find(params[:id])
end
def fetch_tag_group
@tag_group = TagGroup.find(params[:id])
end
def tag_groups_params
if permissions = params[:permissions]
permissions.each do |k, v|
permissions[k] = v.to_i
end
def tag_groups_params
if permissions = params[:permissions]
permissions.each do |k, v|
permissions[k] = v.to_i
end
result = params.permit(
:id,
:name,
:one_per_topic,
tag_names: [],
parent_tag_name: [],
permissions: permissions&.keys,
)
result[:tag_names] ||= []
result[:parent_tag_name] ||= []
result[:one_per_topic] = (params[:one_per_topic] == "true")
result
end
result = params.permit(
:id,
:name,
:one_per_topic,
tag_names: [],
parent_tag_name: [],
permissions: permissions&.keys,
)
result[:tag_names] ||= []
result[:parent_tag_name] ||= []
result[:one_per_topic] = (params[:one_per_topic] == "true")
result
end
end
+111 -111
View File
@@ -207,130 +207,130 @@ class TagsController < ::ApplicationController
private
def ensure_tags_enabled
raise Discourse::NotFound unless SiteSetting.tagging_enabled?
end
def ensure_tags_enabled
raise Discourse::NotFound unless SiteSetting.tagging_enabled?
end
def self.tag_counts_json(tags)
tags.map { |t| { id: t.name, text: t.name, count: t.topic_count, pm_count: t.pm_topic_count } }
end
def self.tag_counts_json(tags)
tags.map { |t| { id: t.name, text: t.name, count: t.topic_count, pm_count: t.pm_topic_count } }
end
def set_category_from_params
slug_or_id = params[:category]
return true if slug_or_id.nil?
def set_category_from_params
slug_or_id = params[:category]
return true if slug_or_id.nil?
if slug_or_id == 'none' && params[:parent_category]
@filter_on_category = Category.query_category(params[:parent_category], nil)
params[:no_subcategories] = 'true'
else
parent_slug_or_id = params[:parent_category]
if slug_or_id == 'none' && params[:parent_category]
@filter_on_category = Category.query_category(params[:parent_category], nil)
params[:no_subcategories] = 'true'
else
parent_slug_or_id = params[:parent_category]
parent_category_id = nil
if parent_slug_or_id.present?
parent_category_id = Category.query_parent_category(parent_slug_or_id)
category_redirect_or_not_found && (return) if parent_category_id.blank?
end
@filter_on_category = Category.query_category(slug_or_id, parent_category_id)
parent_category_id = nil
if parent_slug_or_id.present?
parent_category_id = Category.query_parent_category(parent_slug_or_id)
category_redirect_or_not_found && (return) if parent_category_id.blank?
end
category_redirect_or_not_found && (return) if !@filter_on_category
guardian.ensure_can_see!(@filter_on_category)
@filter_on_category = Category.query_category(slug_or_id, parent_category_id)
end
# TODO: this is duplication of ListController
def page_params(opts = nil)
opts ||= {}
route_params = { format: 'json' }
route_params[:category] = @filter_on_category.slug_for_url if @filter_on_category
route_params[:parent_category] = @filter_on_category.parent_category.slug_for_url if @filter_on_category && @filter_on_category.parent_category
route_params[:order] = opts[:order] if opts[:order].present?
route_params[:ascending] = opts[:ascending] if opts[:ascending].present?
route_params
end
category_redirect_or_not_found && (return) if !@filter_on_category
def next_page_params(opts = nil)
page_params(opts).merge(page: params[:page].to_i + 1)
end
guardian.ensure_can_see!(@filter_on_category)
end
def prev_page_params(opts = nil)
pg = params[:page].to_i
if pg > 1
page_params(opts).merge(page: pg - 1)
else
page_params(opts).merge(page: nil)
# TODO: this is duplication of ListController
def page_params(opts = nil)
opts ||= {}
route_params = { format: 'json' }
route_params[:category] = @filter_on_category.slug_for_url if @filter_on_category
route_params[:parent_category] = @filter_on_category.parent_category.slug_for_url if @filter_on_category && @filter_on_category.parent_category
route_params[:order] = opts[:order] if opts[:order].present?
route_params[:ascending] = opts[:ascending] if opts[:ascending].present?
route_params
end
def next_page_params(opts = nil)
page_params(opts).merge(page: params[:page].to_i + 1)
end
def prev_page_params(opts = nil)
pg = params[:page].to_i
if pg > 1
page_params(opts).merge(page: pg - 1)
else
page_params(opts).merge(page: nil)
end
end
def url_method(opts = {})
if opts[:parent_category] && opts[:category]
"tag_parent_category_category_#{action_name}_path"
elsif opts[:category]
"tag_category_#{action_name}_path"
else
"tag_#{action_name}_path"
end
end
def construct_url_with(action, opts)
method = url_method(opts)
begin
url = if action == :prev
public_send(method, opts.merge(prev_page_params(opts)))
else # :next
public_send(method, opts.merge(next_page_params(opts)))
end
rescue ActionController::UrlGenerationError
raise Discourse::NotFound
end
url.sub('.json?', '?')
end
def build_topic_list_options
options = {
page: params[:page],
topic_ids: param_to_integer_list(:topic_ids),
exclude_category_ids: params[:exclude_category_ids],
category: @filter_on_category ? @filter_on_category.id : params[:category],
order: params[:order],
ascending: params[:ascending],
min_posts: params[:min_posts],
max_posts: params[:max_posts],
status: params[:status],
filter: params[:filter],
state: params[:state],
search: params[:search],
q: params[:q]
}
options[:no_subcategories] = true if params[:no_subcategories] == 'true'
options[:slow_platform] = true if slow_platform?
if params[:tag_id] == 'none'
options[:no_tags] = true
else
options[:tags] = tag_params
options[:match_all_tags] = true
end
def url_method(opts = {})
if opts[:parent_category] && opts[:category]
"tag_parent_category_category_#{action_name}_path"
elsif opts[:category]
"tag_category_#{action_name}_path"
else
"tag_#{action_name}_path"
end
options
end
def category_redirect_or_not_found
# automatic redirects for renamed categories
url = params[:parent_category] ? "c/#{params[:parent_category]}/#{params[:category]}" : "c/#{params[:category]}"
permalink = Permalink.find_by_url(url)
if permalink.present? && permalink.category_id
redirect_to "#{Discourse::base_uri}/tags#{permalink.target_url}/#{params[:tag_id]}", status: :moved_permanently
else
# redirect to 404
raise Discourse::NotFound
end
end
def construct_url_with(action, opts)
method = url_method(opts)
begin
url = if action == :prev
public_send(method, opts.merge(prev_page_params(opts)))
else # :next
public_send(method, opts.merge(next_page_params(opts)))
end
rescue ActionController::UrlGenerationError
raise Discourse::NotFound
end
url.sub('.json?', '?')
end
def build_topic_list_options
options = {
page: params[:page],
topic_ids: param_to_integer_list(:topic_ids),
exclude_category_ids: params[:exclude_category_ids],
category: @filter_on_category ? @filter_on_category.id : params[:category],
order: params[:order],
ascending: params[:ascending],
min_posts: params[:min_posts],
max_posts: params[:max_posts],
status: params[:status],
filter: params[:filter],
state: params[:state],
search: params[:search],
q: params[:q]
}
options[:no_subcategories] = true if params[:no_subcategories] == 'true'
options[:slow_platform] = true if slow_platform?
if params[:tag_id] == 'none'
options[:no_tags] = true
else
options[:tags] = tag_params
options[:match_all_tags] = true
end
options
end
def category_redirect_or_not_found
# automatic redirects for renamed categories
url = params[:parent_category] ? "c/#{params[:parent_category]}/#{params[:category]}" : "c/#{params[:category]}"
permalink = Permalink.find_by_url(url)
if permalink.present? && permalink.category_id
redirect_to "#{Discourse::base_uri}/tags#{permalink.target_url}/#{params[:tag_id]}", status: :moved_permanently
else
# redirect to 404
raise Discourse::NotFound
end
end
def tag_params
[@tag_id].concat(Array(@additional_tags))
end
def tag_params
[@tag_id].concat(Array(@additional_tags))
end
end
+20 -20
View File
@@ -92,28 +92,28 @@ class UserBadgesController < ApplicationController
private
# Get the badge from either the badge name or id specified in the params.
def fetch_badge_from_params
badge = nil
# Get the badge from either the badge name or id specified in the params.
def fetch_badge_from_params
badge = nil
params.permit(:badge_name)
if params[:badge_name].nil?
params.require(:badge_id)
badge = Badge.find_by(id: params[:badge_id], enabled: true)
else
badge = Badge.find_by(name: params[:badge_name], enabled: true)
end
raise Discourse::NotFound if badge.blank?
badge
params.permit(:badge_name)
if params[:badge_name].nil?
params.require(:badge_id)
badge = Badge.find_by(id: params[:badge_id], enabled: true)
else
badge = Badge.find_by(name: params[:badge_name], enabled: true)
end
raise Discourse::NotFound if badge.blank?
def can_assign_badge_to_user?(user)
master_api_call = current_user.nil? && is_api?
master_api_call || guardian.can_grant_badges?(user)
end
badge
end
def ensure_badges_enabled
raise Discourse::NotFound unless SiteSetting.enable_badges?
end
def can_assign_badge_to_user?(user)
master_api_call = current_user.nil? && is_api?
master_api_call || guardian.can_grant_badges?(user)
end
def ensure_badges_enabled
raise Discourse::NotFound unless SiteSetting.enable_badges?
end
end
+93 -93
View File
@@ -994,104 +994,104 @@ class UsersController < ApplicationController
private
def honeypot_value
Digest::SHA1::hexdigest("#{Discourse.current_hostname}:#{GlobalSetting.safe_secret_key_base}")[0, 15]
def honeypot_value
Digest::SHA1::hexdigest("#{Discourse.current_hostname}:#{GlobalSetting.safe_secret_key_base}")[0, 15]
end
def challenge_value
challenge = $redis.get('SECRET_CHALLENGE')
unless challenge && challenge.length == 16 * 2
challenge = SecureRandom.hex(16)
$redis.set('SECRET_CHALLENGE', challenge)
end
def challenge_value
challenge = $redis.get('SECRET_CHALLENGE')
unless challenge && challenge.length == 16 * 2
challenge = SecureRandom.hex(16)
$redis.set('SECRET_CHALLENGE', challenge)
end
challenge
end
challenge
def respond_to_suspicious_request
if suspicious?(params)
render json: {
success: true,
active: false,
message: I18n.t("login.activate_email", email: params[:email])
}
end
end
def suspicious?(params)
return false if current_user && is_api? && current_user.admin?
honeypot_or_challenge_fails?(params) || SiteSetting.invite_only?
end
def honeypot_or_challenge_fails?(params)
return false if is_api?
params[:password_confirmation] != honeypot_value ||
params[:challenge] != challenge_value.try(:reverse)
end
def user_params
permitted = [
:name,
:email,
:password,
:username,
:title,
:date_of_birth,
:muted_usernames,
:theme_key,
:locale,
:bio_raw,
:location,
:website,
:dismissed_banner_key,
:profile_background,
:card_background
]
permitted.concat UserUpdater::OPTION_ATTR
permitted.concat UserUpdater::CATEGORY_IDS.keys.map { |k| { k => [] } }
permitted.concat UserUpdater::TAG_NAMES.keys
result = params
.permit(permitted)
.reverse_merge(
ip_address: request.remote_ip,
registration_ip_address: request.remote_ip,
locale: user_locale
)
if !UsernameCheckerService.is_developer?(result['email']) &&
is_api? &&
current_user.present? &&
current_user.admin?
result.merge!(params.permit(:active, :staged, :approved))
end
def respond_to_suspicious_request
if suspicious?(params)
render json: {
success: true,
active: false,
message: I18n.t("login.activate_email", email: params[:email])
}
end
end
def suspicious?(params)
return false if current_user && is_api? && current_user.admin?
honeypot_or_challenge_fails?(params) || SiteSetting.invite_only?
end
def honeypot_or_challenge_fails?(params)
return false if is_api?
params[:password_confirmation] != honeypot_value ||
params[:challenge] != challenge_value.try(:reverse)
end
def user_params
permitted = [
:name,
:email,
:password,
:username,
:title,
:date_of_birth,
:muted_usernames,
:theme_key,
:locale,
:bio_raw,
:location,
:website,
:dismissed_banner_key,
:profile_background,
:card_background
]
permitted.concat UserUpdater::OPTION_ATTR
permitted.concat UserUpdater::CATEGORY_IDS.keys.map { |k| { k => [] } }
permitted.concat UserUpdater::TAG_NAMES.keys
result = params
.permit(permitted)
.reverse_merge(
ip_address: request.remote_ip,
registration_ip_address: request.remote_ip,
locale: user_locale
)
if !UsernameCheckerService.is_developer?(result['email']) &&
is_api? &&
current_user.present? &&
current_user.admin?
result.merge!(params.permit(:active, :staged, :approved))
end
modify_user_params(result)
end
# Plugins can use this to modify user parameters
def modify_user_params(attrs)
attrs
end
def user_locale
I18n.locale
end
def fail_with(key)
render json: { success: false, message: I18n.t(key) }
end
def track_visit_to_user_profile
user_profile_id = @user.user_profile.id
ip = request.remote_ip
user_id = (current_user.id if current_user)
Scheduler::Defer.later 'Track profile view visit' do
UserProfileView.add(user_profile_id, ip, user_id)
end
modify_user_params(result)
end
# Plugins can use this to modify user parameters
def modify_user_params(attrs)
attrs
end
def user_locale
I18n.locale
end
def fail_with(key)
render json: { success: false, message: I18n.t(key) }
end
def track_visit_to_user_profile
user_profile_id = @user.user_profile.id
ip = request.remote_ip
user_id = (current_user.id if current_user)
Scheduler::Defer.later 'Track profile view visit' do
UserProfileView.add(user_profile_id, ip, user_id)
end
end
end
+19 -19
View File
@@ -119,30 +119,30 @@ class WebhooksController < ActionController::Base
private
def mailgun_failure
render body: nil, status: 406
end
def mailgun_failure
render body: nil, status: 406
end
def mailgun_success
render body: nil, status: 200
end
def mailgun_success
render body: nil, status: 200
end
def mailgun_verify(timestamp, token, signature)
digest = OpenSSL::Digest::SHA256.new
data = "#{timestamp}#{token}"
signature == OpenSSL::HMAC.hexdigest(digest, SiteSetting.mailgun_api_key, data)
end
def mailgun_verify(timestamp, token, signature)
digest = OpenSSL::Digest::SHA256.new
data = "#{timestamp}#{token}"
signature == OpenSSL::HMAC.hexdigest(digest, SiteSetting.mailgun_api_key, data)
end
def process_bounce(message_id, to_address, bounce_score)
return if message_id.blank? || to_address.blank?
def process_bounce(message_id, to_address, bounce_score)
return if message_id.blank? || to_address.blank?
email_log = EmailLog.find_by(message_id: message_id, to_address: to_address)
return if email_log.nil?
email_log = EmailLog.find_by(message_id: message_id, to_address: to_address)
return if email_log.nil?
email_log.update_columns(bounced: true)
return if email_log.user.nil? || email_log.user.email.blank?
email_log.update_columns(bounced: true)
return if email_log.user.nil? || email_log.user.email.blank?
Email::Receiver.update_bounce_score(email_log.user.email, bounce_score)
end
Email::Receiver.update_bounce_score(email_log.user.email, bounce_score)
end
end
+149 -149
View File
@@ -211,169 +211,169 @@ module Jobs
private
def escape_comma(string)
if string && string =~ /,/
return "#{string}"
else
return string
def escape_comma(string)
if string && string =~ /,/
return "#{string}"
else
return string
end
end
def get_base_user_array(user)
user_array = []
user_array.push(user.id, escape_comma(user.name), user.username, user.email, escape_comma(user.title), user.created_at, user.last_seen_at, user.last_posted_at, user.last_emailed_at, user.trust_level, user.approved, user.suspended_at, user.suspended_till, user.silenced_till, user.active, user.admin, user.moderator, user.ip_address, user.staged, user.user_stat.topics_entered, user.user_stat.posts_read_count, user.user_stat.time_read, user.user_stat.topic_count, user.user_stat.post_count, user.user_stat.likes_given, user.user_stat.likes_received, escape_comma(user.user_profile.location), user.user_profile.website, user.user_profile.views)
end
def add_single_sign_on(user, user_info_array)
if user.single_sign_on_record
user_info_array.push(user.single_sign_on_record.external_id, user.single_sign_on_record.external_email, user.single_sign_on_record.external_username, escape_comma(user.single_sign_on_record.external_name), user.single_sign_on_record.external_avatar_url)
else
user_info_array.push(nil, nil, nil, nil, nil)
end
user_info_array
end
def add_custom_fields(user, user_info_array, user_field_ids)
if user_field_ids.present?
user.user_fields.each do |custom_field|
user_info_array << escape_comma(custom_field[1])
end
end
user_info_array
end
def get_base_user_array(user)
user_array = []
user_array.push(user.id, escape_comma(user.name), user.username, user.email, escape_comma(user.title), user.created_at, user.last_seen_at, user.last_posted_at, user.last_emailed_at, user.trust_level, user.approved, user.suspended_at, user.suspended_till, user.silenced_till, user.active, user.admin, user.moderator, user.ip_address, user.staged, user.user_stat.topics_entered, user.user_stat.posts_read_count, user.user_stat.time_read, user.user_stat.topic_count, user.user_stat.post_count, user.user_stat.likes_given, user.user_stat.likes_received, escape_comma(user.user_profile.location), user.user_profile.website, user.user_profile.views)
def add_group_names(user, user_info_array)
group_names = user.groups.each_with_object("") do |group, names|
names << "#{group.name};"
end
user_info_array << group_names[0..-2] unless group_names.blank?
group_names = nil
user_info_array
end
def add_single_sign_on(user, user_info_array)
if user.single_sign_on_record
user_info_array.push(user.single_sign_on_record.external_id, user.single_sign_on_record.external_email, user.single_sign_on_record.external_username, escape_comma(user.single_sign_on_record.external_name), user.single_sign_on_record.external_avatar_url)
else
user_info_array.push(nil, nil, nil, nil, nil)
end
user_info_array
end
def add_custom_fields(user, user_info_array, user_field_ids)
if user_field_ids.present?
user.user_fields.each do |custom_field|
user_info_array << escape_comma(custom_field[1])
def get_user_archive_fields(user_archive)
user_archive_array = []
topic_data = user_archive.topic
user_archive = user_archive.as_json
topic_data = Topic.with_deleted.find_by(id: user_archive['topic_id']) if topic_data.nil?
return user_archive_array if topic_data.nil?
category = topic_data.category
sub_category_name = "-"
if category
category_name = category.name
if category.parent_category_id.present?
# sub category
if parent_category = Category.find_by(id: category.parent_category_id)
category_name = parent_category.name
sub_category_name = category.name
end
end
user_info_array
else
# PM
category_name = "-"
end
is_pm = topic_data.archetype == "private_message" ? I18n.t("csv_export.boolean_yes") : I18n.t("csv_export.boolean_no")
url = "#{Discourse.base_url}/t/#{topic_data.slug}/#{topic_data.id}/#{user_archive['post_number']}"
topic_hash = { "post" => user_archive['raw'], "topic_title" => topic_data.title, "category" => category_name, "sub_category" => sub_category_name, "is_pm" => is_pm, "url" => url }
user_archive.merge!(topic_hash)
HEADER_ATTRS_FOR['user_archive'].each do |attr|
user_archive_array.push(user_archive[attr])
end
def add_group_names(user, user_info_array)
group_names = user.groups.each_with_object("") do |group, names|
names << "#{group.name};"
end
user_info_array << group_names[0..-2] unless group_names.blank?
group_names = nil
user_info_array
end
user_archive_array
end
def get_user_archive_fields(user_archive)
user_archive_array = []
topic_data = user_archive.topic
user_archive = user_archive.as_json
topic_data = Topic.with_deleted.find_by(id: user_archive['topic_id']) if topic_data.nil?
return user_archive_array if topic_data.nil?
category = topic_data.category
sub_category_name = "-"
if category
category_name = category.name
if category.parent_category_id.present?
# sub category
if parent_category = Category.find_by(id: category.parent_category_id)
category_name = parent_category.name
sub_category_name = category.name
end
end
else
# PM
category_name = "-"
end
is_pm = topic_data.archetype == "private_message" ? I18n.t("csv_export.boolean_yes") : I18n.t("csv_export.boolean_no")
url = "#{Discourse.base_url}/t/#{topic_data.slug}/#{topic_data.id}/#{user_archive['post_number']}"
def get_staff_action_fields(staff_action)
staff_action_array = []
topic_hash = { "post" => user_archive['raw'], "topic_title" => topic_data.title, "category" => category_name, "sub_category" => sub_category_name, "is_pm" => is_pm, "url" => url }
user_archive.merge!(topic_hash)
HEADER_ATTRS_FOR['user_archive'].each do |attr|
user_archive_array.push(user_archive[attr])
end
user_archive_array
end
def get_staff_action_fields(staff_action)
staff_action_array = []
HEADER_ATTRS_FOR['staff_action'].each do |attr|
data =
if attr == 'action'
UserHistory.actions.key(staff_action.attributes[attr]).to_s
elsif attr == 'staff_user'
user = User.find_by(id: staff_action.attributes['acting_user_id'])
user.username if !user.nil?
elsif attr == 'subject'
user = User.find_by(id: staff_action.attributes['target_user_id'])
user.nil? ? staff_action.attributes[attr] : "#{user.username} #{staff_action.attributes[attr]}"
else
staff_action.attributes[attr]
end
staff_action_array.push(data)
end
staff_action_array
end
def get_screened_email_fields(screened_email)
screened_email_array = []
HEADER_ATTRS_FOR['screened_email'].each do |attr|
data =
if attr == 'action'
ScreenedEmail.actions.key(screened_email.attributes['action_type']).to_s
else
screened_email.attributes[attr]
end
screened_email_array.push(data)
end
screened_email_array
end
def get_screened_ip_fields(screened_ip)
screened_ip_array = []
HEADER_ATTRS_FOR['screened_ip'].each do |attr|
data =
if attr == 'action'
ScreenedIpAddress.actions.key(screened_ip.attributes['action_type']).to_s
else
screened_ip.attributes[attr]
end
screened_ip_array.push(data)
end
screened_ip_array
end
def get_screened_url_fields(screened_url)
screened_url_array = []
HEADER_ATTRS_FOR['screened_url'].each do |attr|
data =
if attr == 'action'
action = ScreenedUrl.actions.key(screened_url.attributes['action_type']).to_s
action = "do nothing" if action.blank?
else
screened_url.attributes[attr]
end
screened_url_array.push(data)
end
screened_url_array
end
def notify_user(download_link, file_name, file_size, export_title)
if @current_user
if download_link.present?
SystemMessage.create_from_system_user(
@current_user,
:csv_export_succeeded,
download_link: download_link,
file_name: "#{file_name}.gz",
file_size: file_size,
export_title: export_title
)
HEADER_ATTRS_FOR['staff_action'].each do |attr|
data =
if attr == 'action'
UserHistory.actions.key(staff_action.attributes[attr]).to_s
elsif attr == 'staff_user'
user = User.find_by(id: staff_action.attributes['acting_user_id'])
user.username if !user.nil?
elsif attr == 'subject'
user = User.find_by(id: staff_action.attributes['target_user_id'])
user.nil? ? staff_action.attributes[attr] : "#{user.username} #{staff_action.attributes[attr]}"
else
SystemMessage.create_from_system_user(@current_user, :csv_export_failed)
staff_action.attributes[attr]
end
staff_action_array.push(data)
end
staff_action_array
end
def get_screened_email_fields(screened_email)
screened_email_array = []
HEADER_ATTRS_FOR['screened_email'].each do |attr|
data =
if attr == 'action'
ScreenedEmail.actions.key(screened_email.attributes['action_type']).to_s
else
screened_email.attributes[attr]
end
screened_email_array.push(data)
end
screened_email_array
end
def get_screened_ip_fields(screened_ip)
screened_ip_array = []
HEADER_ATTRS_FOR['screened_ip'].each do |attr|
data =
if attr == 'action'
ScreenedIpAddress.actions.key(screened_ip.attributes['action_type']).to_s
else
screened_ip.attributes[attr]
end
screened_ip_array.push(data)
end
screened_ip_array
end
def get_screened_url_fields(screened_url)
screened_url_array = []
HEADER_ATTRS_FOR['screened_url'].each do |attr|
data =
if attr == 'action'
action = ScreenedUrl.actions.key(screened_url.attributes['action_type']).to_s
action = "do nothing" if action.blank?
else
screened_url.attributes[attr]
end
screened_url_array.push(data)
end
screened_url_array
end
def notify_user(download_link, file_name, file_size, export_title)
if @current_user
if download_link.present?
SystemMessage.create_from_system_user(
@current_user,
:csv_export_succeeded,
download_link: download_link,
file_name: "#{file_name}.gz",
file_size: file_size,
export_title: export_title
)
else
SystemMessage.create_from_system_user(@current_user, :csv_export_failed)
end
end
end
end
end
+3 -3
View File
@@ -174,9 +174,9 @@ module Jobs
private
def remove_scheme(src)
src.sub(/^https?:/i, "")
end
def remove_scheme(src)
src.sub(/^https?:/i, "")
end
end
end
+6 -6
View File
@@ -225,13 +225,13 @@ class Badge < ActiveRecord::Base
protected
def ensure_not_system
self.id = [Badge.maximum(:id) + 1, 100].max unless id
end
def ensure_not_system
self.id = [Badge.maximum(:id) + 1, 100].max unless id
end
def i18n_name
self.name.downcase.tr(' ', '_')
end
def i18n_name
self.name.downcase.tr(' ', '_')
end
end
+96 -96
View File
@@ -44,127 +44,127 @@ class CategoryList
private
def find_relevant_topics
@topics_by_id = {}
@topics_by_category_id = {}
def find_relevant_topics
@topics_by_id = {}
@topics_by_category_id = {}
category_featured_topics = CategoryFeaturedTopic.select([:category_id, :topic_id]).order(:rank)
category_featured_topics = CategoryFeaturedTopic.select([:category_id, :topic_id]).order(:rank)
@all_topics = Topic.where(id: category_featured_topics.map(&:topic_id))
@all_topics = @all_topics.includes(:last_poster) if @options[:include_topics]
@all_topics.each do |t|
# hint for the serializer
t.include_last_poster = true if @options[:include_topics]
@topics_by_id[t.id] = t
end
category_featured_topics.each do |cft|
@topics_by_category_id[cft.category_id] ||= []
@topics_by_category_id[cft.category_id] << cft.topic_id
end
@all_topics = Topic.where(id: category_featured_topics.map(&:topic_id))
@all_topics = @all_topics.includes(:last_poster) if @options[:include_topics]
@all_topics.each do |t|
# hint for the serializer
t.include_last_poster = true if @options[:include_topics]
@topics_by_id[t.id] = t
end
def find_categories
@categories = Category.includes(
:uploaded_background,
:uploaded_logo,
:topic_only_relative_url,
subcategories: [:topic_only_relative_url]
).secured(@guardian)
category_featured_topics.each do |cft|
@topics_by_category_id[cft.category_id] ||= []
@topics_by_category_id[cft.category_id] << cft.topic_id
end
end
@categories = @categories.where("categories.parent_category_id = ?", @options[:parent_category_id].to_i) if @options[:parent_category_id].present?
def find_categories
@categories = Category.includes(
:uploaded_background,
:uploaded_logo,
:topic_only_relative_url,
subcategories: [:topic_only_relative_url]
).secured(@guardian)
if SiteSetting.fixed_category_positions
@categories = @categories.order(:position, :id)
else
@categories = @categories.order('COALESCE(categories.posts_week, 0) DESC')
.order('COALESCE(categories.posts_month, 0) DESC')
.order('COALESCE(categories.posts_year, 0) DESC')
.order('id ASC')
end
@categories = @categories.where("categories.parent_category_id = ?", @options[:parent_category_id].to_i) if @options[:parent_category_id].present?
@categories = @categories.to_a
if SiteSetting.fixed_category_positions
@categories = @categories.order(:position, :id)
else
@categories = @categories.order('COALESCE(categories.posts_week, 0) DESC')
.order('COALESCE(categories.posts_month, 0) DESC')
.order('COALESCE(categories.posts_year, 0) DESC')
.order('id ASC')
end
category_user = {}
default_notification_level = nil
unless @guardian.anonymous?
category_user = Hash[*CategoryUser.where(user: @guardian.user).pluck(:category_id, :notification_level).flatten]
default_notification_level = CategoryUser.notification_levels[:regular]
end
@categories = @categories.to_a
allowed_topic_create = Set.new(Category.topic_create_allowed(@guardian).pluck(:id))
@categories.each do |category|
category.notification_level = category_user[category.id] || default_notification_level
category.permission = CategoryGroup.permission_types[:full] if allowed_topic_create.include?(category.id)
category.has_children = category.subcategories.present?
end
category_user = {}
default_notification_level = nil
unless @guardian.anonymous?
category_user = Hash[*CategoryUser.where(user: @guardian.user).pluck(:category_id, :notification_level).flatten]
default_notification_level = CategoryUser.notification_levels[:regular]
end
if @options[:parent_category_id].blank?
subcategories = {}
to_delete = Set.new
@categories.each do |c|
if c.parent_category_id.present?
subcategories[c.parent_category_id] ||= []
subcategories[c.parent_category_id] << c.id
to_delete << c
end
allowed_topic_create = Set.new(Category.topic_create_allowed(@guardian).pluck(:id))
@categories.each do |category|
category.notification_level = category_user[category.id] || default_notification_level
category.permission = CategoryGroup.permission_types[:full] if allowed_topic_create.include?(category.id)
category.has_children = category.subcategories.present?
end
if @options[:parent_category_id].blank?
subcategories = {}
to_delete = Set.new
@categories.each do |c|
if c.parent_category_id.present?
subcategories[c.parent_category_id] ||= []
subcategories[c.parent_category_id] << c.id
to_delete << c
end
@categories.each { |c| c.subcategory_ids = subcategories[c.id] }
@categories.delete_if { |c| to_delete.include?(c) }
end
@categories.each { |c| c.subcategory_ids = subcategories[c.id] }
@categories.delete_if { |c| to_delete.include?(c) }
end
if @topics_by_category_id
@categories.each do |c|
topics_in_cat = @topics_by_category_id[c.id]
if topics_in_cat.present?
c.displayable_topics = []
topics_in_cat.each do |topic_id|
topic = @topics_by_id[topic_id]
if topic.present? && @guardian.can_see?(topic)
# topic.category is very slow under rails 4.2
topic.association(:category).target = c
c.displayable_topics << topic
end
if @topics_by_category_id
@categories.each do |c|
topics_in_cat = @topics_by_category_id[c.id]
if topics_in_cat.present?
c.displayable_topics = []
topics_in_cat.each do |topic_id|
topic = @topics_by_id[topic_id]
if topic.present? && @guardian.can_see?(topic)
# topic.category is very slow under rails 4.2
topic.association(:category).target = c
c.displayable_topics << topic
end
end
end
end
end
end
def prune_empty
return if SiteSetting.allow_uncategorized_topics
@categories.delete_if { |c| c.uncategorized? && c.displayable_topics.blank? }
def prune_empty
return if SiteSetting.allow_uncategorized_topics
@categories.delete_if { |c| c.uncategorized? && c.displayable_topics.blank? }
end
# Attach some data for serialization to each topic
def find_user_data
if @guardian.current_user && @all_topics.present?
topic_lookup = TopicUser.lookup_for(@guardian.current_user, @all_topics)
@all_topics.each { |ft| ft.user_data = topic_lookup[ft.id] }
end
end
# Attach some data for serialization to each topic
def find_user_data
if @guardian.current_user && @all_topics.present?
topic_lookup = TopicUser.lookup_for(@guardian.current_user, @all_topics)
@all_topics.each { |ft| ft.user_data = topic_lookup[ft.id] }
end
end
# Put unpinned topics at the end of the list
def sort_unpinned
if @guardian.current_user && @all_topics.present?
@categories.each do |c|
next if c.displayable_topics.blank? || c.displayable_topics.size <= c.num_featured_topics
unpinned = []
c.displayable_topics.each do |t|
unpinned << t if t.pinned_at && PinnedCheck.unpinned?(t, t.user_data)
end
unless unpinned.empty?
c.displayable_topics = (c.displayable_topics - unpinned) + unpinned
end
# Put unpinned topics at the end of the list
def sort_unpinned
if @guardian.current_user && @all_topics.present?
@categories.each do |c|
next if c.displayable_topics.blank? || c.displayable_topics.size <= c.num_featured_topics
unpinned = []
c.displayable_topics.each do |t|
unpinned << t if t.pinned_at && PinnedCheck.unpinned?(t, t.user_data)
end
unless unpinned.empty?
c.displayable_topics = (c.displayable_topics - unpinned) + unpinned
end
end
end
end
def trim_results
@categories.each do |c|
next if c.displayable_topics.blank?
c.displayable_topics = c.displayable_topics[0, c.num_featured_topics]
end
def trim_results
@categories.each do |c|
next if c.displayable_topics.blank?
c.displayable_topics = c.displayable_topics[0, c.num_featured_topics]
end
end
end
+3 -3
View File
@@ -45,8 +45,8 @@ module Trashable
private
def trash_update(deleted_at, deleted_by_id)
self.update_columns(deleted_at: deleted_at, deleted_by_id: deleted_by_id)
end
def trash_update(deleted_at, deleted_by_id)
self.update_columns(deleted_at: deleted_at, deleted_by_id: deleted_by_id)
end
end
+6 -6
View File
@@ -53,13 +53,13 @@ class EmbeddableHost < ActiveRecord::Base
private
def host_must_be_valid
if host !~ /\A[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,10}(:[0-9]{1,5})?(\/.*)?\Z/i &&
host !~ /\A(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})(:[0-9]{1,5})?(\/.*)?\Z/ &&
host !~ /\A([a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.)?localhost(\:[0-9]{1,5})?(\/.*)?\Z/i
errors.add(:host, I18n.t('errors.messages.invalid'))
end
def host_must_be_valid
if host !~ /\A[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,10}(:[0-9]{1,5})?(\/.*)?\Z/i &&
host !~ /\A(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})(:[0-9]{1,5})?(\/.*)?\Z/ &&
host !~ /\A([a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.)?localhost(\:[0-9]{1,5})?(\/.*)?\Z/i
errors.add(:host, I18n.t('errors.messages.invalid'))
end
end
end
# == Schema Information
+86 -86
View File
@@ -598,58 +598,58 @@ class Group < ActiveRecord::Base
protected
def name_format_validator
self.name.strip!
def name_format_validator
self.name.strip!
UsernameValidator.perform_validation(self, 'name') || begin
name_lower = self.name.downcase
UsernameValidator.perform_validation(self, 'name') || begin
name_lower = self.name.downcase
if self.will_save_change_to_name? && self.name_was&.downcase != name_lower
existing = Group.exec_sql(
User::USERNAME_EXISTS_SQL, username: name_lower
).values.present?
if self.will_save_change_to_name? && self.name_was&.downcase != name_lower
existing = Group.exec_sql(
User::USERNAME_EXISTS_SQL, username: name_lower
).values.present?
if existing
errors.add(:name, I18n.t("activerecord.errors.messages.taken"))
end
if existing
errors.add(:name, I18n.t("activerecord.errors.messages.taken"))
end
end
end
end
def automatic_membership_email_domains_format_validator
return if self.automatic_membership_email_domains.blank?
def automatic_membership_email_domains_format_validator
return if self.automatic_membership_email_domains.blank?
domains = self.automatic_membership_email_domains.split("|")
domains.each do |domain|
domain.sub!(/^https?:\/\//, '')
domain.sub!(/\/.*$/, '')
self.errors.add :base, (I18n.t('groups.errors.invalid_domain', domain: domain)) unless domain =~ /\A[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,24}(:[0-9]{1,5})?(\/.*)?\Z/i
end
self.automatic_membership_email_domains = domains.join("|")
domains = self.automatic_membership_email_domains.split("|")
domains.each do |domain|
domain.sub!(/^https?:\/\//, '')
domain.sub!(/\/.*$/, '')
self.errors.add :base, (I18n.t('groups.errors.invalid_domain', domain: domain)) unless domain =~ /\A[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,24}(:[0-9]{1,5})?(\/.*)?\Z/i
end
self.automatic_membership_email_domains = domains.join("|")
end
# hack around AR
def destroy_deletions
if @deletions
@deletions.each do |gu|
gu.destroy
User.where('id = ? AND primary_group_id = ?', gu.user_id, gu.group_id).update_all 'primary_group_id = NULL'
end
end
@deletions = nil
end
def automatic_group_membership
if self.automatic_membership_retroactive
Jobs.enqueue(:automatic_group_membership, group_id: self.id)
# hack around AR
def destroy_deletions
if @deletions
@deletions.each do |gu|
gu.destroy
User.where('id = ? AND primary_group_id = ?', gu.user_id, gu.group_id).update_all 'primary_group_id = NULL'
end
end
@deletions = nil
end
def update_title
return if new_record? && !self.title.present?
def automatic_group_membership
if self.automatic_membership_retroactive
Jobs.enqueue(:automatic_group_membership, group_id: self.id)
end
end
if self.saved_change_to_title?
sql = <<-SQL.squish
def update_title
return if new_record? && !self.title.present?
if self.saved_change_to_title?
sql = <<-SQL.squish
UPDATE users
SET title = :title
WHERE (title = :title_was OR title = '' OR title IS NULL)
@@ -657,71 +657,71 @@ class Group < ActiveRecord::Base
AND id IN (SELECT user_id FROM group_users WHERE group_id = :id)
SQL
self.class.exec_sql(sql, title: title, title_was: title_before_last_save, id: id)
end
self.class.exec_sql(sql, title: title, title_was: title_before_last_save, id: id)
end
end
def update_primary_group
return if new_record? && !self.primary_group?
def update_primary_group
return if new_record? && !self.primary_group?
if self.saved_change_to_primary_group?
sql = <<~SQL
if self.saved_change_to_primary_group?
sql = <<~SQL
UPDATE users
/*set*/
/*where*/
SQL
builder = SqlBuilder.new(sql)
builder.where("
id IN (
SELECT user_id
FROM group_users
WHERE group_id = :id
)", id: id)
builder = SqlBuilder.new(sql)
builder.where("
id IN (
SELECT user_id
FROM group_users
WHERE group_id = :id
)", id: id)
if primary_group
builder.set("primary_group_id = :id")
else
builder.set("primary_group_id = NULL")
builder.where("primary_group_id = :id")
end
builder.exec
if primary_group
builder.set("primary_group_id = :id")
else
builder.set("primary_group_id = NULL")
builder.where("primary_group_id = :id")
end
builder.exec
end
end
private
def validate_grant_trust_level
unless TrustLevel.valid?(self.grant_trust_level)
self.errors.add(:base, I18n.t(
'groups.errors.grant_trust_level_not_valid',
trust_level: self.grant_trust_level
))
def validate_grant_trust_level
unless TrustLevel.valid?(self.grant_trust_level)
self.errors.add(:base, I18n.t(
'groups.errors.grant_trust_level_not_valid',
trust_level: self.grant_trust_level
))
end
end
def can_allow_membership_requests
valid = true
valid =
if self.persisted?
self.group_users.where(owner: true).exists?
else
self.group_users.any?(&:owner)
end
if !valid
self.errors.add(:base, I18n.t('groups.errors.cant_allow_membership_requests'))
end
end
def can_allow_membership_requests
valid = true
valid =
if self.persisted?
self.group_users.where(owner: true).exists?
else
self.group_users.any?(&:owner)
end
if !valid
self.errors.add(:base, I18n.t('groups.errors.cant_allow_membership_requests'))
end
end
def enqueue_update_mentions_job
Jobs.enqueue(:update_group_mentions,
previous_name: self.name_before_last_save,
group_id: self.id
)
end
def enqueue_update_mentions_job
Jobs.enqueue(:update_group_mentions,
previous_name: self.name_before_last_save,
group_id: self.id
)
end
end
# == Schema Information
+5 -5
View File
@@ -29,11 +29,11 @@ class GroupArchivedMessage < ActiveRecord::Base
private
def self.publish_topic_tracking_state(topic)
TopicTrackingState.publish_private_message(
topic, group_archive: true
)
end
def self.publish_topic_tracking_state(topic)
TopicTrackingState.publish_private_message(
topic, group_archive: true
)
end
end
# == Schema Information
+12 -12
View File
@@ -127,19 +127,19 @@ class PostAnalyzer
private
def cooked_stripped
@cooked_stripped ||= begin
doc = Nokogiri::HTML.fragment(cook(@raw, topic_id: @topic_id))
doc.css("pre .mention, aside.quote > .title, aside.quote .mention, .onebox, .elided").remove
doc
end
def cooked_stripped
@cooked_stripped ||= begin
doc = Nokogiri::HTML.fragment(cook(@raw, topic_id: @topic_id))
doc.css("pre .mention, aside.quote > .title, aside.quote .mention, .onebox, .elided").remove
doc
end
end
def link_is_a_mention?(l)
html_class = l['class']
return false if html_class.blank?
href = l['href'].to_s
html_class.to_s['mention'] && href[/^\/u\//] || href[/^\/users\//]
end
def link_is_a_mention?(l)
html_class = l['class']
return false if html_class.blank?
href = l['href'].to_s
html_class.to_s['mention'] && href[/^\/u\//] || href[/^\/users\//]
end
end
+19 -19
View File
@@ -94,30 +94,30 @@ class QueuedPost < ActiveRecord::Base
private
def change_to!(state, changed_by)
state_val = QueuedPost.states[state]
def change_to!(state, changed_by)
state_val = QueuedPost.states[state]
updates = { state: state_val,
"#{state}_by_id" => changed_by.id,
"#{state}_at" => Time.now }
updates = { state: state_val,
"#{state}_by_id" => changed_by.id,
"#{state}_at" => Time.now }
# We use an update with `row_count` trick here to avoid stampeding requests to
# update the same row simultaneously. Only one state change should go through and
# we can use the DB to enforce this
row_count = QueuedPost.where('id = ? AND state <> ?', id, state_val).update_all(updates)
raise InvalidStateTransition.new if row_count == 0
# We use an update with `row_count` trick here to avoid stampeding requests to
# update the same row simultaneously. Only one state change should go through and
# we can use the DB to enforce this
row_count = QueuedPost.where('id = ? AND state <> ?', id, state_val).update_all(updates)
raise InvalidStateTransition.new if row_count == 0
if [:rejected, :approved].include?(state)
UserAction.where(queued_post_id: id).destroy_all
end
# Update the record in memory too, and clear the dirty flag
updates.each { |k, v| send("#{k}=", v) }
changes_applied
QueuedPost.broadcast_new! if visible?
if [:rejected, :approved].include?(state)
UserAction.where(queued_post_id: id).destroy_all
end
# Update the record in memory too, and clear the dirty flag
updates.each { |k, v| send("#{k}=", v) }
changes_applied
QueuedPost.broadcast_new! if visible?
end
end
# == Schema Information
+4 -4
View File
@@ -84,8 +84,8 @@ SQL
private
def update_participant_count
count = topic.posts.where('NOT hidden AND post_type in (?)', Topic.visible_post_types).count('distinct user_id')
topic.update_columns(participant_count: count)
end
def update_participant_count
count = topic.posts.where('NOT hidden AND post_type in (?)', Topic.visible_post_types).count('distinct user_id')
topic.update_columns(participant_count: count)
end
end
+47 -47
View File
@@ -83,66 +83,66 @@ class TopicTimer < ActiveRecord::Base
private
def ensure_update_will_happen
if created_at && (execute_at < created_at)
errors.add(:execute_at, I18n.t(
'activerecord.errors.models.topic_timer.attributes.execute_at.in_the_past'
))
end
def ensure_update_will_happen
if created_at && (execute_at < created_at)
errors.add(:execute_at, I18n.t(
'activerecord.errors.models.topic_timer.attributes.execute_at.in_the_past'
))
end
end
def cancel_auto_close_job
Jobs.cancel_scheduled_job(:toggle_topic_closed, topic_timer_id: id)
end
alias_method :cancel_auto_open_job, :cancel_auto_close_job
def cancel_auto_close_job
Jobs.cancel_scheduled_job(:toggle_topic_closed, topic_timer_id: id)
end
alias_method :cancel_auto_open_job, :cancel_auto_close_job
def cancel_auto_publish_to_category_job
Jobs.cancel_scheduled_job(:publish_topic_to_category, topic_timer_id: id)
end
def cancel_auto_publish_to_category_job
Jobs.cancel_scheduled_job(:publish_topic_to_category, topic_timer_id: id)
end
def cancel_auto_delete_job
Jobs.cancel_scheduled_job(:delete_topic, topic_timer_id: id)
end
def cancel_auto_delete_job
Jobs.cancel_scheduled_job(:delete_topic, topic_timer_id: id)
end
def cancel_auto_reminder_job
Jobs.cancel_scheduled_job(:topic_reminder, topic_timer_id: id)
end
def cancel_auto_reminder_job
Jobs.cancel_scheduled_job(:topic_reminder, topic_timer_id: id)
end
def schedule_auto_open_job(time)
return unless topic
topic.update_status('closed', true, user) if !topic.closed
def schedule_auto_open_job(time)
return unless topic
topic.update_status('closed', true, user) if !topic.closed
Jobs.enqueue_at(time, :toggle_topic_closed,
topic_timer_id: id,
state: false
)
end
Jobs.enqueue_at(time, :toggle_topic_closed,
topic_timer_id: id,
state: false
)
end
def schedule_auto_close_job(time)
return unless topic
topic.update_status('closed', false, user) if topic.closed
def schedule_auto_close_job(time)
return unless topic
topic.update_status('closed', false, user) if topic.closed
Jobs.enqueue_at(time, :toggle_topic_closed,
topic_timer_id: id,
state: true
)
end
Jobs.enqueue_at(time, :toggle_topic_closed,
topic_timer_id: id,
state: true
)
end
def schedule_auto_publish_to_category_job(time)
Jobs.enqueue_at(time, :publish_topic_to_category, topic_timer_id: id)
end
def schedule_auto_publish_to_category_job(time)
Jobs.enqueue_at(time, :publish_topic_to_category, topic_timer_id: id)
end
def publishing_to_category?
self.status_type.to_i == TopicTimer.types[:publish_to_category]
end
def publishing_to_category?
self.status_type.to_i == TopicTimer.types[:publish_to_category]
end
def schedule_auto_delete_job(time)
Jobs.enqueue_at(time, :delete_topic, topic_timer_id: id)
end
def schedule_auto_delete_job(time)
Jobs.enqueue_at(time, :delete_topic, topic_timer_id: id)
end
def schedule_auto_reminder_job(time)
Jobs.enqueue_at(time, :topic_reminder, topic_timer_id: id)
end
def schedule_auto_reminder_job(time)
Jobs.enqueue_at(time, :topic_reminder, topic_timer_id: id)
end
end
# == Schema Information
+3 -3
View File
@@ -19,9 +19,9 @@ class UnsubscribeKey < ActiveRecord::Base
private
def generate_random_key
self.key = SecureRandom.hex(32)
end
def generate_random_key
self.key = SecureRandom.hex(32)
end
end
# == Schema Information
+5 -5
View File
@@ -36,11 +36,11 @@ class UserArchivedMessage < ActiveRecord::Base
private
def self.publish_topic_tracking_state(topic, user_id)
TopicTrackingState.publish_private_message(
topic, archive_user_id: user_id
)
end
def self.publish_topic_tracking_state(topic, user_id)
TopicTrackingState.publish_private_message(
topic, archive_user_id: user_id
)
end
end
# == Schema Information
+3 -3
View File
@@ -26,9 +26,9 @@ class UserBadge < ActiveRecord::Base
private
def single_grant_badge?
self.badge.single_grant?
end
def single_grant_badge?
self.badge.single_grant?
end
end
# == Schema Information
+4 -4
View File
@@ -141,10 +141,10 @@ class UserOption < ActiveRecord::Base
private
def update_tracked_topics
return unless saved_change_to_auto_track_topics_after_msecs?
TrackedTopicsUpdater.new(id, auto_track_topics_after_msecs).call
end
def update_tracked_topics
return unless saved_change_to_auto_track_topics_after_msecs?
TrackedTopicsUpdater.new(id, auto_track_topics_after_msecs).call
end
end
+3 -3
View File
@@ -93,9 +93,9 @@ class WebHook < ActiveRecord::Base
private
def self.guardian
@guardian ||= Guardian.new(Discourse.system_user)
end
def self.guardian
@guardian ||= Guardian.new(Discourse.system_user)
end
end
# == Schema Information
@@ -81,12 +81,12 @@ class AdminUserActionSerializer < ApplicationSerializer
private
# we need this to handle deleted topics which aren't loaded via the .includes(:topic)
# because Rails 4 "unscoped" support is bugged (cf. https://github.com/rails/rails/issues/13775)
def topic
return @topic if @topic
@topic = object.topic || Topic.with_deleted.find(object.topic_id)
@topic
end
# we need this to handle deleted topics which aren't loaded via the .includes(:topic)
# because Rails 4 "unscoped" support is bugged (cf. https://github.com/rails/rails/issues/13775)
def topic
return @topic if @topic
@topic = object.topic || Topic.with_deleted.find(object.topic_id)
@topic
end
end
+9 -9
View File
@@ -68,15 +68,15 @@ class BasicGroupSerializer < ApplicationSerializer
private
def staff?
@staff ||= scope.is_staff?
end
def staff?
@staff ||= scope.is_staff?
end
def user_group_ids
@options[:user_group_ids]
end
def user_group_ids
@options[:user_group_ids]
end
def owner_group_ids
@options[:owner_group_ids]
end
def owner_group_ids
@options[:owner_group_ids]
end
end
+3 -3
View File
@@ -121,8 +121,8 @@ class ListableTopicSerializer < BasicTopicSerializer
protected
def unread_helper
@unread_helper ||= Unread.new(object, object.user_data, scope)
end
def unread_helper
@unread_helper ||= Unread.new(object, object.user_data, scope)
end
end
@@ -45,9 +45,9 @@ class PostActionTypeSerializer < ApplicationSerializer
protected
def i18n(field, vars = nil)
key = "post_action_types.#{name_key}.#{field}"
vars ? I18n.t(key, vars) : I18n.t(key)
end
def i18n(field, vars = nil)
key = "post_action_types.#{name_key}.#{field}"
vars ? I18n.t(key, vars) : I18n.t(key)
end
end
+76 -76
View File
@@ -173,94 +173,94 @@ class PostRevisionSerializer < ApplicationSerializer
protected
def post
@post ||= object.post
def post
@post ||= object.post
end
def topic
@topic ||= object.post.topic
end
def revisions
@revisions ||= all_revisions.select { |r| scope.can_view_hidden_post_revisions? || !r["hidden"] }
end
def all_revisions
return @all_revisions if @all_revisions
post_revisions = PostRevision.where(post_id: object.post_id).order(:number).to_a
latest_modifications = {
"raw" => [post.raw],
"cooked" => [post.cooked],
"edit_reason" => [post.edit_reason],
"wiki" => [post.wiki],
"post_type" => [post.post_type],
"user_id" => [post.user_id]
}
# Retrieve any `tracked_topic_fields`
PostRevisor.tracked_topic_fields.each_key do |field|
latest_modifications[field.to_s] = [topic.send(field)] if topic.respond_to?(field)
end
def topic
@topic ||= object.post.topic
end
latest_modifications["featured_link"] = [post.topic.featured_link] if SiteSetting.topic_featured_link_enabled
latest_modifications["tags"] = [topic.tags.pluck(:name)] if scope.can_see_tags?(topic)
def revisions
@revisions ||= all_revisions.select { |r| scope.can_view_hidden_post_revisions? || !r["hidden"] }
end
post_revisions << PostRevision.new(
number: post_revisions.last.number + 1,
hidden: post.hidden,
modifications: latest_modifications
)
def all_revisions
return @all_revisions if @all_revisions
@all_revisions = []
post_revisions = PostRevision.where(post_id: object.post_id).order(:number).to_a
# backtrack
post_revisions.each do |pr|
revision = HashWithIndifferentAccess.new
revision[:revision] = pr.number
revision[:hidden] = pr.hidden
latest_modifications = {
"raw" => [post.raw],
"cooked" => [post.cooked],
"edit_reason" => [post.edit_reason],
"wiki" => [post.wiki],
"post_type" => [post.post_type],
"user_id" => [post.user_id]
}
# Retrieve any `tracked_topic_fields`
PostRevisor.tracked_topic_fields.each_key do |field|
latest_modifications[field.to_s] = [topic.send(field)] if topic.respond_to?(field)
pr.modifications.each_key do |field|
revision[field] = pr.modifications[field][0]
end
latest_modifications["featured_link"] = [post.topic.featured_link] if SiteSetting.topic_featured_link_enabled
latest_modifications["tags"] = [topic.tags.pluck(:name)] if scope.can_see_tags?(topic)
post_revisions << PostRevision.new(
number: post_revisions.last.number + 1,
hidden: post.hidden,
modifications: latest_modifications
)
@all_revisions = []
# backtrack
post_revisions.each do |pr|
revision = HashWithIndifferentAccess.new
revision[:revision] = pr.number
revision[:hidden] = pr.hidden
pr.modifications.each_key do |field|
revision[field] = pr.modifications[field][0]
end
@all_revisions << revision
end
# waterfall
(@all_revisions.count - 1).downto(1).each do |r|
cur = @all_revisions[r]
prev = @all_revisions[r - 1]
cur.each_key do |field|
prev[field] = prev.has_key?(field) ? prev[field] : cur[field]
end
end
@all_revisions
@all_revisions << revision
end
def previous
@previous ||= revisions.select { |r| r["revision"] <= current_revision }.last
end
# waterfall
(@all_revisions.count - 1).downto(1).each do |r|
cur = @all_revisions[r]
prev = @all_revisions[r - 1]
def current
@current ||= revisions.select { |r| r["revision"] > current_revision }.first
end
def user
# if stuff goes pear shape attribute to system
object.user || Discourse.system_user
end
def filter_visible_tags(tags)
if tags.is_a?(Array) && tags.size > 0
@hidden_tag_names ||= DiscourseTagging.hidden_tag_names(scope)
tags - @hidden_tag_names
else
tags
cur.each_key do |field|
prev[field] = prev.has_key?(field) ? prev[field] : cur[field]
end
end
@all_revisions
end
def previous
@previous ||= revisions.select { |r| r["revision"] <= current_revision }.last
end
def current
@current ||= revisions.select { |r| r["revision"] > current_revision }.first
end
def user
# if stuff goes pear shape attribute to system
object.user || Discourse.system_user
end
def filter_visible_tags(tags)
if tags.is_a?(Array) && tags.size > 0
@hidden_tag_names ||= DiscourseTagging.hidden_tag_names(scope)
tags - @hidden_tag_names
else
tags
end
end
end
+17 -17
View File
@@ -380,26 +380,26 @@ class PostSerializer < BasicPostSerializer
private
def topic
@topic = object.topic
@topic ||= Topic.with_deleted.find(object.topic_id) if scope.is_staff?
@topic
end
def topic
@topic = object.topic
@topic ||= Topic.with_deleted.find(object.topic_id) if scope.is_staff?
@topic
end
def post_actions
@post_actions ||= (@topic_view&.all_post_actions || {})[object.id]
end
def post_actions
@post_actions ||= (@topic_view&.all_post_actions || {})[object.id]
end
def active_flags
@active_flags ||= (@topic_view&.all_active_flags || {})[object.id]
end
def active_flags
@active_flags ||= (@topic_view&.all_active_flags || {})[object.id]
end
def post_custom_fields
@post_custom_fields ||= if @topic_view
(@topic_view.post_custom_fields || {})[object.id] || {}
else
object.custom_fields
end
def post_custom_fields
@post_custom_fields ||= if @topic_view
(@topic_view.post_custom_fields || {})[object.id] || {}
else
object.custom_fields
end
end
end
@@ -2,9 +2,9 @@ class TopicFlagTypeSerializer < PostActionTypeSerializer
protected
def i18n(field, vars = nil)
key = "topic_flag_types.#{name_key}.#{field}"
vars ? I18n.t(key, vars) : I18n.t(key)
end
def i18n(field, vars = nil)
key = "topic_flag_types.#{name_key}.#{field}"
vars ? I18n.t(key, vars) : I18n.t(key)
end
end
+3 -3
View File
@@ -301,8 +301,8 @@ class TopicViewSerializer < ApplicationSerializer
private
def private_message?(topic)
@private_message ||= topic.private_message?
end
def private_message?(topic)
@private_message ||= topic.private_message?
end
end
+14 -14
View File
@@ -58,21 +58,21 @@ class GroupActionLogger
private
def excluded_attributes
[
:bio_cooked,
:updated_at,
:created_at,
:user_count
]
end
def excluded_attributes
[
:bio_cooked,
:updated_at,
:created_at,
:user_count
]
end
def default_params
{ group: @group, acting_user: @acting_user }
end
def default_params
{ group: @group, acting_user: @acting_user }
end
def can_edit?
raise Discourse::InvalidParameters.new unless Guardian.new(@acting_user).can_log_group_changes?(@group)
end
def can_edit?
raise Discourse::InvalidParameters.new unless Guardian.new(@acting_user).can_log_group_changes?(@group)
end
end
+7 -7
View File
@@ -550,13 +550,13 @@ class StaffActionLogger
private
def params(opts = nil)
opts ||= {}
{ acting_user_id: @admin.id, context: opts[:context] }
end
def params(opts = nil)
opts ||= {}
{ acting_user_id: @admin.id, context: opts[:context] }
end
def validate_category(category)
raise Discourse::InvalidParameters.new(:category) unless category && category.is_a?(Category)
end
def validate_category(category)
raise Discourse::InvalidParameters.new(:category) unless category && category.is_a?(Category)
end
end
+6 -6
View File
@@ -77,13 +77,13 @@ class UserAnonymizer
private
def make_anon_username
100.times do
new_username = "anon#{(SecureRandom.random_number * 100000000).to_i}"
return new_username unless User.where(username_lower: new_username).exists?
end
raise "Failed to generate an anon username"
def make_anon_username
100.times do
new_username = "anon#{(SecureRandom.random_number * 100000000).to_i}"
return new_username unless User.where(username_lower: new_username).exists?
end
raise "Failed to generate an anon username"
end
def ip_where(column = 'user_id')
["#{column} = :user_id AND ip_address IS NOT NULL", user_id: @user.id]