mastodon/app/controllers/concerns/auth/captcha_concern.rb

88 lines
1.7 KiB
Ruby

# frozen_string_literal: true
module Auth::CaptchaConcern
extend ActiveSupport::Concern
include Hcaptcha::Adapters::ViewMethods
CAPTCHA_DIRECTIVES = %w(
connect_src
frame_src
script_src
style_src
).freeze
CAPTCHA_SOURCES = %w(
https://*.hcaptcha.com
https://hcaptcha.com
).freeze
included do
helper_method :render_captcha
end
def captcha_available?
Rails.configuration.x.captcha.secret_key.present? && Rails.configuration.x.captcha.site_key.present?
end
def captcha_enabled?
captcha_available? && Setting.captcha_enabled
end
def captcha_user_bypass?
false
end
def captcha_required?
captcha_enabled? && !captcha_user_bypass?
end
def check_captcha!
return true unless captcha_required?
if verify_hcaptcha
true
else
if block_given?
message = flash[:hcaptcha_error]
flash.delete(:hcaptcha_error)
yield message
end
false
end
end
def extend_csp_for_captcha!
return unless captcha_required? && request.content_security_policy.present?
request.content_security_policy = captcha_adjusted_policy
end
def render_captcha
return unless captcha_required?
hcaptcha_tags
end
private
def captcha_adjusted_policy
request.content_security_policy.clone.tap do |policy|
populate_captcha_policy(policy)
end
end
def populate_captcha_policy(policy)
CAPTCHA_DIRECTIVES.each do |directive|
values = policy.send(directive)
CAPTCHA_SOURCES.each do |source|
values << source unless values.include?(source) || values.include?('https:')
end
policy.send(directive, *values)
end
end
end