144 行
4.2 KiB
Ruby
144 行
4.2 KiB
Ruby
class ApplicationController < ActionController::API
|
|
include RequestAccess
|
|
include ActionController::Cookies
|
|
include ActionController::RequestForgeryProtection
|
|
|
|
class UnsupportedLocale < StandardError
|
|
;
|
|
end
|
|
|
|
rescue_from ActiveRecord::RecordInvalid, with: :render_record_invalid
|
|
rescue_from ActiveRecord::RecordNotUnique, with: :render_record_not_unique
|
|
rescue_from(ActiveRecord::RecordNotFound) { head :not_found }
|
|
rescue_from(UnsupportedLocale) { head :not_found }
|
|
|
|
before_action :reject_banned_ip_address!
|
|
before_action :authenticate_user
|
|
before_action :reject_banned_user!
|
|
before_action :validate_explicit_locale!
|
|
before_action :enforce_query_contract!
|
|
around_action :with_history_authority
|
|
rescue_from(HistoryAccess::Forbidden) { head :not_found }
|
|
protect_from_forgery with: :exception
|
|
self.forgery_protection_origin_check = true
|
|
rescue_from ActionController::InvalidAuthenticityToken, with: :reject_invalid_csrf
|
|
after_action :prevent_authenticated_caching
|
|
|
|
private
|
|
|
|
def enforce_query_contract!
|
|
pairs = URI.decode_www_form(request.query_string)
|
|
return head :bad_request if pairs.length > 1000 || pairs.map(&:first).uniq.length != pairs.length
|
|
return head :bad_request if request.query_parameters.values.any? { !_1.is_a?(String) }
|
|
if (controller_name.start_with?('counts_') &&
|
|
(request.query_parameters.keys & ['headers', 'labels']).any?)
|
|
return head :bad_request
|
|
end
|
|
rescue ArgumentError
|
|
head :bad_request
|
|
end
|
|
|
|
def with_history_authority(&action)
|
|
response.headers['Cache-Control'] = 'private, no-store'
|
|
HistoryAccess.set(user: current_user, &action)
|
|
end
|
|
|
|
def reject_invalid_csrf
|
|
response.headers['X-CSRF-Invalid'] = '1'
|
|
response.headers['Cache-Control'] = 'private, no-store'
|
|
head :forbidden
|
|
end
|
|
|
|
def prevent_authenticated_caching
|
|
response.headers['Cache-Control'] = 'private, no-store' if current_user
|
|
end
|
|
|
|
def establish_user_session user
|
|
reset_session
|
|
session[:inheritance_code] = user.inheritance_code
|
|
@current_user = user
|
|
response.headers['Cache-Control'] = 'private, no-store'
|
|
end
|
|
|
|
def bool? key, default: false
|
|
return default if params[key].nil?
|
|
|
|
s = params[key].to_s.strip.downcase
|
|
if default
|
|
!(s.in?(['0', 'false', 'off', 'no']))
|
|
else
|
|
s.in?(['', '1', 'true', 'on', 'yes'])
|
|
end
|
|
end
|
|
|
|
def render_bad_request message = 'リクエストが不正です.'
|
|
render json: { type: 'bad_request',
|
|
message:,
|
|
errors: { },
|
|
base_errors: [message] },
|
|
status: :bad_request
|
|
end
|
|
|
|
def render_unprocessable_entity message = '入力を確認してください.', field: nil
|
|
render_validation_error(fields: field ? { field => [message] } : { },
|
|
base: field ? [] : [message])
|
|
end
|
|
|
|
def render_record_invalid error
|
|
render_validation_error error.record
|
|
end
|
|
|
|
def render_record_not_unique _error = nil
|
|
render_validation_error base: ['すでに存在してゐます.']
|
|
end
|
|
|
|
def render_validation_error record = nil, fields: { }, base: [], status: :unprocessable_entity
|
|
errors = { }
|
|
|
|
if record
|
|
record.errors.each do |error|
|
|
errors[error.attribute] ||= []
|
|
errors[error.attribute] << error.message
|
|
end
|
|
end
|
|
|
|
fields.each do |attr, messages|
|
|
errors[attr.to_sym] ||= []
|
|
errors[attr.to_sym].concat(Array(messages))
|
|
end
|
|
|
|
base_errors = Array(base) + Array(errors.delete(:base))
|
|
|
|
render json: { type: 'validation_error',
|
|
message: '入力内容を確認してください.',
|
|
errors:,
|
|
base_errors: },
|
|
status:
|
|
end
|
|
|
|
def normalise_json value
|
|
return nil if value.nil?
|
|
return JSON.parse(value) if value.is_a?(String)
|
|
|
|
value
|
|
end
|
|
|
|
def resolve_locale!
|
|
return @resolved_locale if defined?(@resolved_locale)
|
|
|
|
code = params.fetch(:locale, 'ja')
|
|
unless code.is_a?(String) && Locale.codes.value?(code)
|
|
raise UnsupportedLocale
|
|
end
|
|
|
|
locale = Locale.find_by(code:)
|
|
raise UnsupportedLocale unless locale && locale.deprecated_at.nil?
|
|
|
|
@resolved_locale = locale
|
|
end
|
|
|
|
def validate_explicit_locale!
|
|
resolve_locale! if params.key?(:locale)
|
|
end
|
|
end
|