Skip to content

Commit

Permalink
Add support for using an cloudflare turnstile widget during signup
Browse files Browse the repository at this point in the history
  • Loading branch information
tomhughes committed Oct 24, 2023
1 parent dd905b5 commit 179b877
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 5 deletions.
2 changes: 1 addition & 1 deletion .rubocop_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Metrics/BlockNesting:
# Offense count: 26
# Configuration parameters: CountComments, CountAsOne.
Metrics/ClassLength:
Max: 285
Max: 295

# Offense count: 59
# Configuration parameters: AllowedMethods, AllowedPatterns.
Expand Down
40 changes: 36 additions & 4 deletions app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class UsersController < ApplicationController
before_action :require_cookies, :only => [:new]
before_action :lookup_user_by_name, :only => [:set_status, :destroy]
before_action :allow_thirdparty_images, :only => [:show]
before_action :set_content_security_policy, :only => [:new, :create]

##
# display a list of users matching specified criteria
Expand Down Expand Up @@ -61,10 +62,6 @@ def new
session[:referer]
end

append_content_security_policy_directives(
:form_action => %w[accounts.google.com *.facebook.com login.live.com github.com meta.wikimedia.org]
)

if current_user
# The user is logged in already, so don't show them the signup
# page, instead send them to the home page
Expand Down Expand Up @@ -102,6 +99,10 @@ def create
if current_user.invalid?
# Something is wrong with a new user, so rerender the form
render :action => "new"
elsif Settings.turnstile_site_key && !valid_turnstile_response?(params["cf-turnstile-response"])
# Invalid turnstile response, so rerender the form
flash.now[:error] = t ".not_human"
render :action => "new"
elsif current_user.auth_provider.present?
# Verify external authenticator before moving on
session[:new_user] = current_user
Expand Down Expand Up @@ -362,4 +363,35 @@ def check_signup_allowed(email = nil)

!blocked
end

##
# add additional CSP rules for signup page
def set_content_security_policy
append_content_security_policy_directives(
:form_action => %w[accounts.google.com *.facebook.com login.live.com github.com meta.wikimedia.org]
)

if Settings.turnstile_site_key
append_content_security_policy_directives(
:frame_src => %w[challenges.cloudflare.com],
:script_src => %w[challenges.cloudflare.com]
)
end
end

##
# check if a turnstile response is valid
def valid_turnstile_response?(turnstile_response)
response = OSM.http_client.post("https://challenges.cloudflare.com/turnstile/v0/siteverify", {
:secret => Settings.turnstile_secret_key,
:response => turnstile_response,
:remoteip => request.remote_ip
})

return false unless response.success?

parsed_response = JSON.parse(response.body)

parsed_response["success"]
end
end
10 changes: 10 additions & 0 deletions app/views/users/new.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<% content_for :head do %>
<%= javascript_include_tag "user" %>
<% if Settings.turnstile_site_key -%>
<%= javascript_include_tag "https://challenges.cloudflare.com/turnstile/v0/api.js", :async => true, :defer => true %>
<% end -%>
<% end %>

<% content_for :heading_class, "pb-0" %>
Expand Down Expand Up @@ -42,6 +45,13 @@
<%= f.password_field :pass_crypt, :tabindex => 6 %>
<%= f.password_field :pass_crypt_confirmation, :tabindex => 7 %>

<% if Settings.turnstile_site_key -%>
<div class="mb-3">
<label class="form_label"><%= t ".verify_human" %></label>
<div class="pt-2 cf-turnstile" data-sitekey="<%= Settings.turnstile_site_key %>"></div>
</div>
<% end %>

<div id="auth_prompt">
<p><%= link_to t(".use external auth"), "#", :id => "auth_enable" %></p>
</div>
Expand Down
3 changes: 3 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2666,6 +2666,9 @@ en:
privacy_policy: privacy policy
privacy_policy_url: https://wiki.osmfoundation.org/wiki/Privacy_Policy
privacy_policy_title: OSMF privacy policy including section on email addresses
verify_human: Verify you're a human
create:
not_human: Human verification failed
terms:
title: "Terms"
heading: "Terms"
Expand Down
3 changes: 3 additions & 0 deletions config/settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -159,3 +159,6 @@ smtp_password: null
# -----BEGIN PRIVATE KEY-----
# ...
# -----END PRIVATE KEY-----
# Credentials for optional cloudflare turnstile widget
#turnstile_site_key:
#turnstile_secret_key:

0 comments on commit 179b877

Please sign in to comment.