Commit 08ed1167 authored by Jan Provaznik's avatar Jan Provaznik

Merge branch 'vs-admin-new-user-signups' into 'master'

Add new configuration option for setting the new user signups cap

See merge request gitlab-org/gitlab!45643
parents c15c4d08 d293c7fe
......@@ -21,6 +21,9 @@
= f.check_box :send_user_confirmation_email, class: 'form-check-input'
= f.label :send_user_confirmation_email, class: 'form-check-label' do
Send confirmation email on sign-up
= render_if_exists 'admin/application_settings/new_user_signups_cap', form: f
.form-group
= f.label :minimum_password_length, _('Minimum password length (number of characters)'), class: 'label-bold'
= f.number_field :minimum_password_length, class: 'form-control', rows: 4, min: ApplicationSetting::DEFAULT_MINIMUM_PASSWORD_LENGTH, max: Devise.password_length.max
......
---
title: Add migration to add a new configuration option for setting the new user signups count
merge_request: 45643
author:
type: other
# frozen_string_literal: true
class AddNewUserSignupsCapToApplicationSettings < ActiveRecord::Migration[6.0]
DOWNTIME = false
def change
add_column :application_settings, :new_user_signups_cap, :integer
end
end
fe57e8e74ebbe0e9567c1487e6e4f8b499afa6404c73424157c43ae79c005f08
\ No newline at end of file
......@@ -9305,6 +9305,7 @@ CREATE TABLE application_settings (
secret_detection_token_revocation_url text,
encrypted_secret_detection_token_revocation_token text,
encrypted_secret_detection_token_revocation_token_iv text,
new_user_signups_cap integer,
CONSTRAINT app_settings_registry_exp_policies_worker_capacity_positive CHECK ((container_registry_expiration_policies_worker_capacity >= 0)),
CONSTRAINT check_2dba05b802 CHECK ((char_length(gitpod_url) <= 255)),
CONSTRAINT check_51700b31b5 CHECK ((char_length(default_branch_name) <= 255)),
......
......@@ -63,6 +63,8 @@ module EE
attrs << :maintenance_mode_message
end
attrs << :new_user_signups_cap if ::Feature.enabled?(:admin_new_user_signups_cap)
attrs
end
......
......@@ -22,17 +22,21 @@ module EE
:allow_group_owners_to_manage_ldap,
:automatic_purchased_storage_allocation,
:check_namespace_plan,
:elasticsearch_aws,
:elasticsearch_aws_access_key,
:elasticsearch_aws_region,
:elasticsearch_aws_secret_access_key,
:elasticsearch_aws,
:elasticsearch_client_request_timeout,
:elasticsearch_indexed_field_length_limit,
:elasticsearch_indexed_file_size_limit_kb,
:elasticsearch_indexing,
:elasticsearch_pause_indexing,
:elasticsearch_limit_indexing,
:elasticsearch_max_bulk_concurrency,
:elasticsearch_max_bulk_size_mb,
:elasticsearch_namespace_ids,
:elasticsearch_pause_indexing,
:elasticsearch_project_ids,
:elasticsearch_replicas,
:elasticsearch_indexed_file_size_limit_kb,
:elasticsearch_indexed_field_length_limit,
:elasticsearch_search,
:elasticsearch_shards,
:elasticsearch_url,
......@@ -45,12 +49,12 @@ module EE
:elasticsearch_analyzers_kuromoji_enabled,
:elasticsearch_analyzers_kuromoji_search,
:enforce_namespace_storage_limit,
:geo_status_timeout,
:enforce_pat_expiration,
:geo_node_allowed_ips,
:geo_status_timeout,
:help_text,
:lock_memberships_to_ldap,
:max_personal_access_token_lifetime,
:enforce_pat_expiration,
:pseudonymizer_enabled,
:repository_size_limit,
:seat_link_enabled,
......@@ -60,8 +64,8 @@ module EE
:slack_app_secret,
:slack_app_verification_token,
:throttle_incident_management_notification_enabled,
:throttle_incident_management_notification_period_in_seconds,
:throttle_incident_management_notification_per_period
:throttle_incident_management_notification_per_period,
:throttle_incident_management_notification_period_in_seconds
]
end
......
......@@ -94,6 +94,14 @@ module EE
validate :allowed_frameworks, if: :compliance_frameworks_changed?
validates :new_user_signups_cap,
numericality: { only_integer: true,
allow_nil: true,
greater_than: 0 }
validates :new_user_signups_cap,
numericality: { less_than_or_equal_to: proc { License.current&.restricted_user_count } },
if: proc { License.current&.restricted_user_count? }
after_commit :update_personal_access_tokens_lifetime, if: :saved_change_to_max_personal_access_token_lifetime?
after_commit :resume_elasticsearch_indexing
end
......
......@@ -397,6 +397,10 @@ class License < ApplicationRecord
restricted_attr(:active_user_count)
end
def restricted_user_count?
restricted_user_count.to_i > 0
end
def previous_user_count
restricted_attr(:previous_user_count)
end
......
- return unless ::Feature.enabled?(:admin_new_user_signups_cap)
.form-group
= form.label :new_user_signups_cap, s_('AdminArea|User cap'), class: 'label-bold'
= form.number_field :new_user_signups_cap, class: 'form-control', max: License.current&.restricted_user_count
.form-text.text-muted
= s_('AdminArea|Once the instance reaches the user cap, any user who is added or requests access will have to be approved by an admin. Leave the field empty for unlimited.')
---
name: admin_new_user_signups_cap
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/45643
rollout_issue_url:
type: development
group: group::purchase
default_enabled: false
......@@ -272,6 +272,75 @@ RSpec.describe 'Admin updates EE-only settings' do
end
end
context 'sign up settings' do
context 'when feature flag is disabled' do
before do
stub_feature_flags(admin_new_user_signups_cap: false)
end
it 'does not render user cap form group' do
visit general_admin_application_settings_path
expect(page).not_to have_field('User cap')
end
end
context 'when feature flag is enabled' do
before do
stub_feature_flags(admin_new_user_signups_cap: true)
end
context 'when license has active user count' do
let(:license) { create(:license, restrictions: { active_user_count: 1 }) }
before do
allow(License).to receive(:current).and_return(license)
end
it 'disallows entering user cap greater then license allows', :js do
visit general_admin_application_settings_path
page.within('#js-signup-settings') do
fill_in 'User cap', with: 5
click_button 'Save changes'
message =
page.find('#application_setting_new_user_signups_cap').native.attribute('validationMessage')
expect(message).to eq('Value must be less than or equal to 1.')
end
end
end
it 'changes the user cap from unlimited to 5' do
visit general_admin_application_settings_path
expect(current_settings.new_user_signups_cap).to be_nil
page.within('#js-signup-settings') do
fill_in 'User cap', with: 5
click_button 'Save changes'
expect(current_settings.new_user_signups_cap).to eq(5)
end
end
it 'changes the user cap to unlimited' do
visit general_admin_application_settings_path
page.within('#js-signup-settings') do
fill_in 'User cap', with: nil
click_button 'Save changes'
expect(current_settings.new_user_signups_cap).to be_nil
end
end
end
end
def current_settings
ApplicationSetting.current_without_cache
end
......
......@@ -85,6 +85,12 @@ RSpec.describe ApplicationSetting do
it { is_expected.not_to allow_value(-5).for(:max_personal_access_token_lifetime) }
it { is_expected.not_to allow_value(366).for(:max_personal_access_token_lifetime) }
it { is_expected.to allow_value(nil).for(:new_user_signups_cap) }
it { is_expected.to allow_value(1).for(:new_user_signups_cap) }
it { is_expected.to allow_value(10).for(:new_user_signups_cap) }
it { is_expected.not_to allow_value(-1).for(:new_user_signups_cap) }
it { is_expected.not_to allow_value(2.5).for(:new_user_signups_cap) }
describe 'when additional email text is enabled' do
before do
stub_licensed_features(email_additional_text: true)
......@@ -159,6 +165,18 @@ RSpec.describe ApplicationSetting do
end
end
end
context 'when license presented' do
let_it_be(:max_active_user_count) { 20 }
before_all do
create_current_license({ restrictions: { active_user_count: max_active_user_count } })
end
it { is_expected.to allow_value(max_active_user_count - 1).for(:new_user_signups_cap) }
it { is_expected.to allow_value(max_active_user_count).for(:new_user_signups_cap) }
it { is_expected.not_to allow_value(max_active_user_count + 1).for(:new_user_signups_cap) }
end
end
describe '#should_check_namespace_plan?' do
......
......@@ -1090,4 +1090,23 @@ RSpec.describe License do
it { is_expected.to eq(result) }
end
end
describe '#restricted_user_count?' do
subject { license.restricted_user_count? }
where(:restricted_user_count, :result) do
nil | false
0 | false
1 | true
10 | true
end
with_them do
before do
allow(license).to receive(:restricted_user_count).and_return(restricted_user_count)
end
it { is_expected.to eq(result) }
end
end
end
......@@ -1914,6 +1914,9 @@ msgstr ""
msgid "AdminArea|New user"
msgstr ""
msgid "AdminArea|Once the instance reaches the user cap, any user who is added or requests access will have to be approved by an admin. Leave the field empty for unlimited."
msgstr ""
msgid "AdminArea|Owner"
msgstr ""
......@@ -1938,6 +1941,9 @@ msgstr ""
msgid "AdminArea|Total users"
msgstr ""
msgid "AdminArea|User cap"
msgstr ""
msgid "AdminArea|Users statistics"
msgstr ""
......
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