Commit 1d02dfea authored by Mikołaj Wawrzyniak's avatar Mikołaj Wawrzyniak

Merge branch '284113-cleanup-invisible_captcha-feature-flag' into 'master'

Resolve "Cleanup invisible_captcha feature flag"

See merge request gitlab-org/gitlab!50650
parents ce39c4e6 da0ddb41
...@@ -57,7 +57,7 @@ gem 'gssapi', group: :kerberos ...@@ -57,7 +57,7 @@ gem 'gssapi', group: :kerberos
# Spam and anti-bot protection # Spam and anti-bot protection
gem 'recaptcha', '~> 4.11', require: 'recaptcha/rails' gem 'recaptcha', '~> 4.11', require: 'recaptcha/rails'
gem 'akismet', '~> 3.0' gem 'akismet', '~> 3.0'
gem 'invisible_captcha', '~> 0.12.1' gem 'invisible_captcha', '~> 1.1.0'
# Two-factor authentication # Two-factor authentication
gem 'devise-two-factor', '~> 3.1.0' gem 'devise-two-factor', '~> 3.1.0'
......
...@@ -598,8 +598,8 @@ GEM ...@@ -598,8 +598,8 @@ GEM
i18n_data (0.8.0) i18n_data (0.8.0)
icalendar (2.4.1) icalendar (2.4.1)
ice_nine (0.11.2) ice_nine (0.11.2)
invisible_captcha (0.12.1) invisible_captcha (1.1.0)
rails (>= 3.2.0) rails (>= 4.2)
ipaddress (0.8.3) ipaddress (0.8.3)
jaeger-client (1.1.0) jaeger-client (1.1.0)
opentracing (~> 0.3) opentracing (~> 0.3)
...@@ -1395,7 +1395,7 @@ DEPENDENCIES ...@@ -1395,7 +1395,7 @@ DEPENDENCIES
html2text html2text
httparty (~> 0.16.4) httparty (~> 0.16.4)
icalendar icalendar
invisible_captcha (~> 0.12.1) invisible_captcha (~> 1.1.0)
ipaddress (~> 0.8.3) ipaddress (~> 0.8.3)
jira-ruby (~> 2.1.4) jira-ruby (~> 2.1.4)
js_regex (~> 3.4) js_regex (~> 3.4)
......
...@@ -8,7 +8,7 @@ module InvisibleCaptchaOnSignup ...@@ -8,7 +8,7 @@ module InvisibleCaptchaOnSignup
end end
def on_honeypot_spam_callback def on_honeypot_spam_callback
return unless Feature.enabled?(:invisible_captcha) return unless Gitlab::CurrentSettings.invisible_captcha_enabled
invisible_captcha_honeypot_counter.increment invisible_captcha_honeypot_counter.increment
log_request('Invisible_Captcha_Honeypot_Request') log_request('Invisible_Captcha_Honeypot_Request')
...@@ -17,7 +17,7 @@ module InvisibleCaptchaOnSignup ...@@ -17,7 +17,7 @@ module InvisibleCaptchaOnSignup
end end
def on_timestamp_spam_callback def on_timestamp_spam_callback
return unless Feature.enabled?(:invisible_captcha) return unless Gitlab::CurrentSettings.invisible_captcha_enabled
invisible_captcha_timestamp_counter.increment invisible_captcha_timestamp_counter.increment
log_request('Invisible_Captcha_Timestamp_Request') log_request('Invisible_Captcha_Timestamp_Request')
......
...@@ -242,6 +242,7 @@ module ApplicationSettingsHelper ...@@ -242,6 +242,7 @@ module ApplicationSettingsHelper
:housekeeping_incremental_repack_period, :housekeeping_incremental_repack_period,
:html_emails_enabled, :html_emails_enabled,
:import_sources, :import_sources,
:invisible_captcha_enabled,
:max_artifacts_size, :max_artifacts_size,
:max_attachment_size, :max_attachment_size,
:max_import_size, :max_import_size,
......
...@@ -171,7 +171,7 @@ class ApplicationSetting < ApplicationRecord ...@@ -171,7 +171,7 @@ class ApplicationSetting < ApplicationRecord
validates :default_artifacts_expire_in, presence: true, duration: true validates :default_artifacts_expire_in, presence: true, duration: true
validates :container_expiration_policies_enable_historic_entries, validates :container_expiration_policies_enable_historic_entries,
inclusion: { in: [true, false], message: 'must be a boolean value' } inclusion: { in: [true, false], message: _('must be a boolean value') }
validates :container_registry_token_expire_delay, validates :container_registry_token_expire_delay,
presence: true, presence: true,
...@@ -309,6 +309,9 @@ class ApplicationSetting < ApplicationRecord ...@@ -309,6 +309,9 @@ class ApplicationSetting < ApplicationRecord
validates :container_registry_expiration_policies_worker_capacity, validates :container_registry_expiration_policies_worker_capacity,
numericality: { only_integer: true, greater_than_or_equal_to: 0 } numericality: { only_integer: true, greater_than_or_equal_to: 0 }
validates :invisible_captcha_enabled,
inclusion: { in: [true, false], message: _('must be a boolean value') }
SUPPORTED_KEY_TYPES.each do |type| SUPPORTED_KEY_TYPES.each do |type|
validates :"#{type}_key_restriction", presence: true, key_restriction: { type: type } validates :"#{type}_key_restriction", presence: true, key_restriction: { type: type }
end end
...@@ -469,7 +472,7 @@ class ApplicationSetting < ApplicationRecord ...@@ -469,7 +472,7 @@ class ApplicationSetting < ApplicationRecord
attr_encrypted :cloud_license_auth_token, encryption_options_base_truncated_aes_256_gcm attr_encrypted :cloud_license_auth_token, encryption_options_base_truncated_aes_256_gcm
validates :disable_feed_token, validates :disable_feed_token,
inclusion: { in: [true, false], message: 'must be a boolean value' } inclusion: { in: [true, false], message: _('must be a boolean value') }
before_validation :ensure_uuid! before_validation :ensure_uuid!
......
...@@ -91,6 +91,7 @@ module ApplicationSettingImplementation ...@@ -91,6 +91,7 @@ module ApplicationSettingImplementation
housekeeping_gc_period: 200, housekeeping_gc_period: 200,
housekeeping_incremental_repack_period: 10, housekeeping_incremental_repack_period: 10,
import_sources: Settings.gitlab['import_sources'], import_sources: Settings.gitlab['import_sources'],
invisible_captcha_enabled: false,
issues_create_limit: 300, issues_create_limit: 300,
local_markdown_version: 0, local_markdown_version: 0,
login_recaptcha_protection_enabled: false, login_recaptcha_protection_enabled: false,
......
...@@ -28,6 +28,14 @@ ...@@ -28,6 +28,14 @@
.form-group .form-group
= f.text_field :recaptcha_private_key, class: 'form-control' = f.text_field :recaptcha_private_key, class: 'form-control'
.form-group
.form-check
= f.check_box :invisible_captcha_enabled, class: 'form-check-input'
= f.label :invisible_captcha_enabled, class: 'form-check-label' do
= _('Enable Invisible Captcha during sign up')
%span.form-text.text-muted
= _('Helps prevent bots from creating accounts.')
.form-group .form-group
.form-check .form-check
= f.check_box :akismet_enabled, class: 'form-check-input' = f.check_box :akismet_enabled, class: 'form-check-input'
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
%p %p
- recaptcha_v2_link_url = 'https://developers.google.com/recaptcha/docs/versions' - recaptcha_v2_link_url = 'https://developers.google.com/recaptcha/docs/versions'
- recaptcha_v2_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: recaptcha_v2_link_url } - recaptcha_v2_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: recaptcha_v2_link_url }
= _('Enable reCAPTCHA or Akismet and set IP limits. For reCAPTCHA, we currently only support %{recaptcha_v2_link_start}v2%{recaptcha_v2_link_end}').html_safe % { recaptcha_v2_link_start: recaptcha_v2_link_start, recaptcha_v2_link_end: '</a>'.html_safe } = _('Enable reCAPTCHA, Invisible Captcha, Akismet and set IP limits. For reCAPTCHA, we currently only support %{recaptcha_v2_link_start}v2%{recaptcha_v2_link_end}').html_safe % { recaptcha_v2_link_start: recaptcha_v2_link_start, recaptcha_v2_link_end: '</a>'.html_safe }
.settings-content .settings-content
= render 'spam' = render 'spam'
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
= form_for(resource, as: "new_#{resource_name}", url: url, html: { class: 'new_user gl-show-field-errors', 'aria-live' => 'assertive' }) do |f| = form_for(resource, as: "new_#{resource_name}", url: url, html: { class: 'new_user gl-show-field-errors', 'aria-live' => 'assertive' }) do |f|
.devise-errors .devise-errors
= render 'devise/shared/error_messages', resource: resource = render 'devise/shared/error_messages', resource: resource
- if Feature.enabled?(:invisible_captcha) - if Gitlab::CurrentSettings.invisible_captcha_enabled
= invisible_captcha = invisible_captcha
.name.form-row .name.form-row
.col.form-group .col.form-group
......
---
title: Add setting to enable Invisible Captcha
merge_request: 50650
author:
type: added
---
name: invisible_captcha
introduced_by_url: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/31625
rollout_issue_url:
milestone: '12.2'
type: development
group: group::acquisition
default_enabled: false
# frozen_string_literal: true
class AddInvisibleCaptchaEnabledToSettings < ActiveRecord::Migration[6.0]
DOWNTIME = false
def change
add_column :application_settings, :invisible_captcha_enabled, :boolean, null: false, default: false
end
end
cf391e617ef16f70c0daa4584959d36eda4b29c7e211f3f90ad74b4ebbc7ebbd
\ No newline at end of file
...@@ -9388,6 +9388,7 @@ CREATE TABLE application_settings ( ...@@ -9388,6 +9388,7 @@ CREATE TABLE application_settings (
disable_feed_token boolean DEFAULT false NOT NULL, disable_feed_token boolean DEFAULT false NOT NULL,
personal_access_token_prefix text, personal_access_token_prefix text,
rate_limiting_response_text text, rate_limiting_response_text text,
invisible_captcha_enabled boolean DEFAULT false NOT NULL,
container_registry_cleanup_tags_service_max_list_size integer DEFAULT 200 NOT NULL, container_registry_cleanup_tags_service_max_list_size integer DEFAULT 200 NOT NULL,
CONSTRAINT app_settings_container_reg_cleanup_tags_max_list_size_positive CHECK ((container_registry_cleanup_tags_service_max_list_size >= 0)), CONSTRAINT app_settings_container_reg_cleanup_tags_max_list_size_positive CHECK ((container_registry_cleanup_tags_service_max_list_size >= 0)),
CONSTRAINT app_settings_registry_exp_policies_worker_capacity_positive CHECK ((container_registry_expiration_policies_worker_capacity >= 0)), CONSTRAINT app_settings_registry_exp_policies_worker_capacity_positive CHECK ((container_registry_expiration_policies_worker_capacity >= 0)),
......
...@@ -300,6 +300,7 @@ listed in the descriptions of the relevant settings. ...@@ -300,6 +300,7 @@ listed in the descriptions of the relevant settings.
| `housekeeping_incremental_repack_period` | integer | required by: `housekeeping_enabled` | Number of Git pushes after which an incremental `git repack` is run. | | `housekeeping_incremental_repack_period` | integer | required by: `housekeeping_enabled` | Number of Git pushes after which an incremental `git repack` is run. |
| `html_emails_enabled` | boolean | no | Enable HTML emails. | | `html_emails_enabled` | boolean | no | Enable HTML emails. |
| `import_sources` | array of strings | no | Sources to allow project import from, possible values: `github`, `bitbucket`, `bitbucket_server`, `gitlab`, `fogbugz`, `git`, `gitlab_project`, `gitea`, `manifest`, and `phabricator`. | | `import_sources` | array of strings | no | Sources to allow project import from, possible values: `github`, `bitbucket`, `bitbucket_server`, `gitlab`, `fogbugz`, `git`, `gitlab_project`, `gitea`, `manifest`, and `phabricator`. |
| `invisible_captcha_enabled` | boolean | no | Enable Invisible Captcha spam detection during signup. Disabled by default. |
| `issues_create_limit` | integer | no | Max number of issue creation requests per minute per user. Disabled by default.| | `issues_create_limit` | integer | no | Max number of issue creation requests per minute per user. Disabled by default.|
| `local_markdown_version` | integer | no | Increase this value when any cached Markdown should be invalidated. | | `local_markdown_version` | integer | no | Increase this value when any cached Markdown should be invalidated. |
| `maintenance_mode_message` | string | no | **(PREMIUM)** Message displayed when instance is in maintenance mode | | `maintenance_mode_message` | string | no | **(PREMIUM)** Message displayed when instance is in maintenance mode |
......
...@@ -6,7 +6,7 @@ class GroupMergeRequestApprovalSetting < ApplicationRecord ...@@ -6,7 +6,7 @@ class GroupMergeRequestApprovalSetting < ApplicationRecord
belongs_to :group, inverse_of: :group_merge_request_approval_setting belongs_to :group, inverse_of: :group_merge_request_approval_setting
validates :group, presence: true validates :group, presence: true
validates :allow_author_approval, inclusion: { in: [true, false], message: 'must be a boolean value' } validates :allow_author_approval, inclusion: { in: [true, false], message: _('must be a boolean value') }
scope :find_or_initialize_by_group, ->(group) { scope :find_or_initialize_by_group, ->(group) {
find_or_initialize_by(group: group) find_or_initialize_by(group: group)
......
...@@ -91,6 +91,7 @@ module API ...@@ -91,6 +91,7 @@ module API
optional :import_sources, type: Array[String], coerce_with: Validations::Types::CommaSeparatedToArray.coerce, optional :import_sources, type: Array[String], coerce_with: Validations::Types::CommaSeparatedToArray.coerce,
values: %w[github bitbucket bitbucket_server gitlab google_code fogbugz git gitlab_project gitea manifest phabricator], values: %w[github bitbucket bitbucket_server gitlab google_code fogbugz git gitlab_project gitea manifest phabricator],
desc: 'Enabled sources for code import during project creation. OmniAuth must be configured for GitHub, Bitbucket, and GitLab.com' desc: 'Enabled sources for code import during project creation. OmniAuth must be configured for GitHub, Bitbucket, and GitLab.com'
optional :invisible_captcha_enabled, type: Boolean, desc: 'Enable Invisible Captcha spam detection during signup.'
optional :max_artifacts_size, type: Integer, desc: "Set the maximum file size for each job's artifacts" optional :max_artifacts_size, type: Integer, desc: "Set the maximum file size for each job's artifacts"
optional :max_attachment_size, type: Integer, desc: 'Maximum attachment size in MB' optional :max_attachment_size, type: Integer, desc: 'Maximum attachment size in MB'
optional :max_import_size, type: Integer, desc: 'Maximum import size in MB' optional :max_import_size, type: Integer, desc: 'Maximum import size in MB'
......
...@@ -10605,6 +10605,9 @@ msgstr "" ...@@ -10605,6 +10605,9 @@ msgstr ""
msgid "Enable Incident Management inbound alert limit" msgid "Enable Incident Management inbound alert limit"
msgstr "" msgstr ""
msgid "Enable Invisible Captcha during sign up"
msgstr ""
msgid "Enable Kroki" msgid "Enable Kroki"
msgstr "" msgstr ""
...@@ -10692,7 +10695,7 @@ msgstr "" ...@@ -10692,7 +10695,7 @@ msgstr ""
msgid "Enable proxy" msgid "Enable proxy"
msgstr "" msgstr ""
msgid "Enable reCAPTCHA or Akismet and set IP limits. For reCAPTCHA, we currently only support %{recaptcha_v2_link_start}v2%{recaptcha_v2_link_end}" msgid "Enable reCAPTCHA, Invisible Captcha, Akismet and set IP limits. For reCAPTCHA, we currently only support %{recaptcha_v2_link_start}v2%{recaptcha_v2_link_end}"
msgstr "" msgstr ""
msgid "Enable shared runners" msgid "Enable shared runners"
...@@ -33849,6 +33852,9 @@ msgstr "" ...@@ -33849,6 +33852,9 @@ msgstr ""
msgid "mrWidget|to start a merge train when the pipeline succeeds" msgid "mrWidget|to start a merge train when the pipeline succeeds"
msgstr "" msgstr ""
msgid "must be a boolean value"
msgstr ""
msgid "must be a root namespace" msgid "must be a root namespace"
msgstr "" msgstr ""
......
...@@ -14,14 +14,6 @@ module QA ...@@ -14,14 +14,6 @@ module QA
sign_up.fill_new_user_username_field(user.username) sign_up.fill_new_user_username_field(user.username)
sign_up.fill_new_user_email_field(user.email) sign_up.fill_new_user_email_field(user.email)
sign_up.fill_new_user_password_field(user.password) sign_up.fill_new_user_password_field(user.password)
# Because invisible_captcha would prevent submitting this form
# within 4 seconds, sleep here. This can be removed once we
# implement invisible_captcha as an application setting instead
# of a feature flag, so we can turn it off while testing.
# Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/284113
sleep 5
sign_up.click_new_user_register_button sign_up.click_new_user_register_button
end end
......
...@@ -6,7 +6,6 @@ RSpec.describe RegistrationsController do ...@@ -6,7 +6,6 @@ RSpec.describe RegistrationsController do
include TermsHelper include TermsHelper
before do before do
stub_feature_flags(invisible_captcha: false)
stub_application_setting(require_admin_approval_after_user_signup: false) stub_application_setting(require_admin_approval_after_user_signup: false)
end end
...@@ -193,15 +192,10 @@ RSpec.describe RegistrationsController do ...@@ -193,15 +192,10 @@ RSpec.describe RegistrationsController do
context 'when invisible captcha is enabled' do context 'when invisible captcha is enabled' do
before do before do
stub_feature_flags(invisible_captcha: true) stub_application_setting(invisible_captcha_enabled: true)
InvisibleCaptcha.timestamp_enabled = true
InvisibleCaptcha.timestamp_threshold = treshold InvisibleCaptcha.timestamp_threshold = treshold
end end
after do
InvisibleCaptcha.timestamp_enabled = false
end
let(:treshold) { 4 } let(:treshold) { 4 }
let(:session_params) { { invisible_captcha_timestamp: form_rendered_time.iso8601 } } let(:session_params) { { invisible_captcha_timestamp: form_rendered_time.iso8601 } }
let(:form_rendered_time) { Time.current } let(:form_rendered_time) { Time.current }
......
...@@ -294,17 +294,13 @@ RSpec.describe 'Signup' do ...@@ -294,17 +294,13 @@ RSpec.describe 'Signup' do
context 'when reCAPTCHA and invisible captcha are enabled' do context 'when reCAPTCHA and invisible captcha are enabled' do
before do before do
InvisibleCaptcha.timestamp_enabled = true stub_application_setting(invisible_captcha_enabled: true)
stub_application_setting(recaptcha_enabled: true) stub_application_setting(recaptcha_enabled: true)
allow_next_instance_of(RegistrationsController) do |instance| allow_next_instance_of(RegistrationsController) do |instance|
allow(instance).to receive(:verify_recaptcha).and_return(true) allow(instance).to receive(:verify_recaptcha).and_return(true)
end end
end end
after do
InvisibleCaptcha.timestamp_enabled = false
end
context 'when reCAPTCHA detects malicious behaviour' do context 'when reCAPTCHA detects malicious behaviour' do
before do before do
allow_next_instance_of(RegistrationsController) do |instance| allow_next_instance_of(RegistrationsController) do |instance|
......
...@@ -369,8 +369,5 @@ end ...@@ -369,8 +369,5 @@ end
# Prevent Rugged from picking up local developer gitconfig. # Prevent Rugged from picking up local developer gitconfig.
Rugged::Settings['search_path_global'] = Rails.root.join('tmp/tests').to_s Rugged::Settings['search_path_global'] = Rails.root.join('tmp/tests').to_s
# Disable timestamp checks for invisible_captcha
InvisibleCaptcha.timestamp_enabled = false
# Initialize FactoryDefault to use create_default helper # Initialize FactoryDefault to use create_default helper
TestProf::FactoryDefault.init TestProf::FactoryDefault.init
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment