discourse/app/controllers/user_badges_controller.rb
Guo Xiang Tan 142571bba0 Remove use of rescue nil.
* `rescue nil` is a really bad pattern to use in our code base.
  We should rescue errors that we expect the code to throw and
  not rescue everything because we're unsure of what errors the
  code would throw. This would reduce the amount of pain we face
  when debugging why something isn't working as expexted. I've
  been bitten countless of times by errors being swallowed as a
  result during debugging sessions.
2018-04-02 13:52:51 +08:00

120 lines
3.5 KiB
Ruby

class UserBadgesController < ApplicationController
before_action :ensure_badges_enabled
def index
params.permit [:granted_before, :offset, :username]
badge = fetch_badge_from_params
user_badges = badge.user_badges.order('granted_at DESC, id DESC').limit(96)
user_badges = user_badges.includes(:user, :granted_by, badge: :badge_type, post: :topic)
grant_count = nil
if params[:username]
user_id = User.where(username_lower: params[:username].downcase).pluck(:id).first
user_badges = user_badges.where(user_id: user_id) if user_id
grant_count = badge.user_badges.where(user_id: user_id).count
end
if offset = params[:offset]
user_badges = user_badges.offset(offset.to_i)
end
user_badges = UserBadges.new(user_badges: user_badges,
username: params[:username],
grant_count: grant_count)
render_serialized(user_badges, UserBadgesSerializer, root: :user_badge_info, include_long_description: true)
end
def username
params.permit [:grouped]
user = fetch_user_from_params(include_inactive: current_user.try(:staff?) || (current_user && SiteSetting.show_inactive_accounts))
user_badges = user.user_badges
if params[:grouped]
user_badges = user_badges.group(:badge_id)
.select(UserBadge.attribute_names.map { |x| "MAX(#{x}) AS #{x}" }, 'COUNT(*) AS "count"')
end
user_badges = user_badges.includes(badge: [:badge_grouping, :badge_type])
.includes(post: :topic)
.includes(:granted_by)
render_serialized(user_badges, DetailedUserBadgeSerializer, root: :user_badges)
end
def create
params.require(:username)
user = fetch_user_from_params
unless can_assign_badge_to_user?(user)
render json: failed_json, status: 403
return
end
badge = fetch_badge_from_params
post_id = nil
if params[:reason].present?
path = begin
URI.parse(params[:reason]).path
rescue URI::InvalidURIError
end
route = Rails.application.routes.recognize_path(path) if path
if route
topic_id = route[:topic_id].to_i
post_number = route[:post_number] || 1
post_id = Post.find_by(topic_id: topic_id, post_number: post_number).try(:id) if topic_id > 0
end
end
user_badge = BadgeGranter.grant(badge, user, granted_by: current_user, post_id: post_id)
render_serialized(user_badge, DetailedUserBadgeSerializer, root: "user_badge")
end
def destroy
params.require(:id)
user_badge = UserBadge.find(params[:id])
unless can_assign_badge_to_user?(user_badge.user)
render json: failed_json, status: 403
return
end
BadgeGranter.revoke(user_badge, revoked_by: current_user)
render json: success_json
end
private
# 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
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