Skip to content

Commit

Permalink
Use Cloudflare Turnstile.
Browse files Browse the repository at this point in the history
  • Loading branch information
yukimochi committed Nov 15, 2022
1 parent 84e0fe3 commit 4f7e7c3
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .env.production.sample
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,9 @@ S3_ALIAS_HOST=files.example.com
# -----------------------
IP_RETENTION_PERIOD=31556952
SESSION_RETENTION_PERIOD=31556952

# Turnstile secrets (optional)
# -----------------------
TURNSTILE_ENABLED=false
TURNSTILE_SITE_KEY=
TURNSTILE_SECRET_KEY=
3 changes: 3 additions & 0 deletions app/controllers/auth/registrations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

class Auth::RegistrationsController < Devise::RegistrationsController
include RegistrationSpamConcern
include TurnstileConcern

layout :determine_layout

Expand All @@ -17,6 +18,8 @@ class Auth::RegistrationsController < Devise::RegistrationsController
before_action :set_rules, only: :new
before_action :require_rules_acceptance!, only: :new
before_action :set_registration_form_time, only: :new
before_action :add_csp_for_turnstile, only: [:new, :create]
before_action :check_turnstile, if: :turnstile_enabled?, only: [:create]

skip_before_action :require_functional!, only: [:edit, :update]

Expand Down
47 changes: 47 additions & 0 deletions app/controllers/concerns/turnstile_concern.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# frozen_string_literal: true

module TurnstileConcern
extend ActiveSupport::Concern

def turnstile_enabled?
ENV['TURNSTILE_ENABLED'] == 'true'
end

def add_csp_for_turnstile
return unless turnstile_enabled?

policy = request.content_security_policy
%w(script_src frame_src style_src connect_src).each do |directive|
values = policy.send(directive)
values << 'https://challenges.cloudflare.com' unless values.include?('https://hcaptcha.com') || values.include?('https:')
policy.send(directive, *values)
end
end

def check_turnstile
unless is_success?
self.resource = resource_class.new sign_up_params
set_instance_presenter
flash.now[:alert] = 'Cloudflare Turnstile reports malformed request'
respond_with_navigational(resource) { render :new }
end
end

private

def is_success?
cf_turnstile_response = params["cf-turnstile-response"]
return false unless cf_turnstile_response.present?
verify_by_turnstile cf_turnstile_response
end

def verify_by_turnstile(cf_turnstile_response)
conn = Faraday.new(url: 'https://challenges.cloudflare.com')
res = conn.post '/turnstile/v0/siteverify', {
secret: ENV['TURNSTILE_SECRET_KEY'],
response: cf_turnstile_response
}
j = JSON.parse(res.body)
j['success']
end
end
2 changes: 2 additions & 0 deletions app/views/auth/registrations/new.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
.fields-group
= f.input :agreement, as: :boolean, wrapper: :with_label, label: t('auth.privacy_policy_agreement_html', rules_path: about_more_path, privacy_policy_path: privacy_policy_path), required: true

= render partial: 'auth/shared/turnstile'

.actions
= f.button :button, @invite.present? ? t('auth.register') : sign_up_message, type: :submit

Expand Down
4 changes: 4 additions & 0 deletions app/views/auth/shared/_turnstile.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
- if ENV['TURNSTILE_ENABLED'] == 'true'
.turnstile
%script(src='https://challenges.cloudflare.com/turnstile/v0/api.js')
%div.cf-turnstile{ "data-sitekey": ENV['TURNSTILE_SITE_KEY'] }

0 comments on commit 4f7e7c3

Please sign in to comment.