Skip to content

Commit

Permalink
Merge branch 'add-recaptcha-support' into 'master'
Browse files Browse the repository at this point in the history
Add support for Google reCAPTCHA in user registration to prevent spammers

See merge request !2216
  • Loading branch information
dzaporozhets authored and rspeicher committed Dec 29, 2015
1 parent 795a29a commit 2ef0fec
Show file tree
Hide file tree
Showing 10 changed files with 120 additions and 10 deletions.
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ gem 'omniauth-twitter', '~> 1.2.0'
gem 'omniauth_crowd'
gem 'rack-oauth2', '~> 1.2.1'

# reCAPTCHA protection
gem 'recaptcha', require: 'recaptcha/rails'

# Two-factor authentication
gem 'devise-two-factor', '~> 2.0.0'
gem 'rqrcode-rails3', '~> 0.1.7'
Expand Down
3 changes: 3 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,8 @@ GEM
trollop
rdoc (3.12.2)
json (~> 1.4)
recaptcha (1.0.2)
json
redcarpet (3.3.3)
redis (3.2.2)
redis-actionpack (4.0.1)
Expand Down Expand Up @@ -917,6 +919,7 @@ DEPENDENCIES
raphael-rails (~> 2.1.2)
rblineprof
rdoc (~> 3.6)
recaptcha
redcarpet (~> 3.3.3)
redis-namespace
redis-rails (~> 4.0.0)
Expand Down
23 changes: 23 additions & 0 deletions app/controllers/registrations_controller.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
class RegistrationsController < Devise::RegistrationsController
before_action :signup_enabled?
include Recaptcha::Verify

def new
redirect_to(new_user_session_path)
end

def create
if !Gitlab.config.recaptcha.enabled || verify_recaptcha
super
else
flash[:alert] = "There was an error with the reCAPTCHA code below. Please re-enter the code."
flash.delete :recaptcha_error
render action: 'new'
end
end

def destroy
DeleteUserService.new(current_user).execute(current_user)

Expand Down Expand Up @@ -38,4 +49,16 @@ def signup_enabled?
def sign_up_params
params.require(:user).permit(:username, :email, :name, :password, :password_confirmation)
end

def resource_name
:user
end

def resource
@resource ||= User.new(sign_up_params)
end

def devise_mapping
@devise_mapping ||= Devise.mappings[:user]
end
end
13 changes: 7 additions & 6 deletions app/controllers/sessions_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class SessionsController < Devise::SessionsController
include AuthenticatesWithTwoFactor
include Recaptcha::ClientHelper

prepend_before_action :authenticate_with_two_factor, only: [:create]
prepend_before_action :store_redirect_path, only: [:new]
Expand Down Expand Up @@ -40,7 +41,7 @@ def find_user
User.find(session[:otp_user_id])
end
end

def store_redirect_path
redirect_path =
if request.referer.present? && (params['redirect_to_referer'] == 'yes')
Expand Down Expand Up @@ -87,14 +88,14 @@ def auto_sign_in_with_provider
provider = Gitlab.config.omniauth.auto_sign_in_with_provider
return unless provider.present?

# Auto sign in with an Omniauth provider only if the standard "you need to sign-in" alert is
# registered or no alert at all. In case of another alert (such as a blocked user), it is safer
# Auto sign in with an Omniauth provider only if the standard "you need to sign-in" alert is
# registered or no alert at all. In case of another alert (such as a blocked user), it is safer
# to do nothing to prevent redirection loops with certain Omniauth providers.
return unless flash[:alert].blank? || flash[:alert] == I18n.t('devise.failure.unauthenticated')

# Prevent alert from popping up on the first page shown after authentication.
flash[:alert] = nil
flash[:alert] = nil

redirect_to user_omniauth_authorize_path(provider.to_sym)
end

Expand Down
12 changes: 8 additions & 4 deletions app/views/devise/shared/_signup_box.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,21 @@
.login-heading
%h3 Create an account
.login-body
- user = params[:user].present? ? params[:user] : {}
= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
.devise-errors
= devise_error_messages!
%div
= f.text_field :name, class: "form-control top", placeholder: "Name", required: true
= f.text_field :name, class: "form-control top", value: user[:name], placeholder: "Name", required: true
%div
= f.text_field :username, class: "form-control middle", placeholder: "Username", required: true
= f.text_field :username, class: "form-control middle", value: user[:username], placeholder: "Username", required: true
%div
= f.email_field :email, class: "form-control middle", placeholder: "Email", required: true
= f.email_field :email, class: "form-control middle", value: user[:email], placeholder: "Email", required: true
.form-group.append-bottom-20#password-strength
= f.password_field :password, class: "form-control bottom", id: "user_password_sign_up", placeholder: "Password", required: true
= f.password_field :password, class: "form-control bottom", value: user[:password], id: "user_password_sign_up", placeholder: "Password", required: true
%div
- if Gitlab.config.recaptcha.enabled
= recaptcha_tags
%div
= f.submit "Sign up", class: "btn-create btn"

Expand Down
6 changes: 6 additions & 0 deletions config/gitlab.yml.example
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,12 @@ production: &base
# application_name: 'YOUR_APP_NAME',
# application_password: 'YOUR_APP_PASSWORD' } }

# reCAPTCHA settings. See: http://www.google.com/recaptcha
recaptcha:
enabled: false
public_key: 'YOUR_PUBLIC_KEY'
private_key: 'YOUR_PRIVATE_KEY'

# Shared file storage settings
shared:
# path: /mnt/gitlab # Default: shared
Expand Down
7 changes: 7 additions & 0 deletions config/initializers/1_settings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,13 @@ def base_gitlab_url

Settings.omniauth['providers'] ||= []

# ReCAPTCHA settings
Settings['recaptcha'] ||= Settingslogic.new({})
Settings.recaptcha['enabled'] = false if Settings.recaptcha['enabled'].nil?
Settings.recaptcha['public_key'] ||= Settings.recaptcha['public_key']
Settings.recaptcha['private_key'] ||= Settings.recaptcha['private_key']


Settings['shared'] ||= Settingslogic.new({})
Settings.shared['path'] = File.expand_path(Settings.shared['path'] || "shared", Rails.root)

Expand Down
6 changes: 6 additions & 0 deletions config/initializers/recaptcha.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
if Gitlab.config.recaptcha.enabled
Recaptcha.configure do |config|
config.public_key = Gitlab.config.recaptcha['public_key']
config.private_key = Gitlab.config.recaptcha['private_key']
end
end
1 change: 1 addition & 0 deletions doc/integration/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ See the documentation below for details on how to configure these services.
- [Slack](slack.md) Integrate with the Slack chat service
- [OAuth2 provider](oauth_provider.md) OAuth2 application creation
- [Gmail actions buttons](gmail_action_buttons_for_gitlab.md) Adds GitLab actions to messages
- [reCAPTCHA](recaptcha.md) Configure GitLab to use Google reCAPTCHA for new users

GitLab Enterprise Edition contains [advanced JIRA support](http://doc.gitlab.com/ee/integration/jira.html) and [advanced Jenkins support](http://doc.gitlab.com/ee/integration/jenkins.html).

Expand Down
56 changes: 56 additions & 0 deletions doc/integration/recaptcha.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# reCAPTCHA

GitLab leverages [Google's reCAPTCHA](https://www.google.com/recaptcha/intro/index.html)
to protect against spam and abuse. GitLab displays the CAPTCHA form on the sign-up page
to confirm that a real user, not a bot, is attempting to create an account.

## Configuration

To use reCAPTCHA, first you must create a public and private key.

1. Go to the URL: https://www.google.com/recaptcha/admin

1. Fill out the form necessary to obtain reCAPTCHA keys.

1. On your GitLab server, open the configuration file.

For omnibus package:

```sh
sudo editor /etc/gitlab/gitlab.rb
```

For installations from source:

```sh
cd /home/git/gitlab
sudo -u git -H editor config/gitlab.yml
```

1. Enable reCAPTCHA and add the settings:

For omnibus package:

```ruby
gitlab_rails['recaptcha_enabled'] = true
gitlab_rails['recaptcha_public_key'] = 'YOUR_PUBLIC_KEY'
gitlab_rails['recaptcha_private_key'] = 'YOUR_PUBLIC_KEY'
```

For installation from source:

```
recaptcha:
enabled: true
public_key: 'YOUR_PUBLIC_KEY'
private_key: 'YOUR_PRIVATE_KEY'
```

1. Change 'YOUR_PUBLIC_KEY' to the public key from step 2.

1. Change 'YOUR_PRIVATE_KEY' to the private key from step 2.

1. Save the configuration file.

1. Restart GitLab.

0 comments on commit 2ef0fec

Please sign in to comment.