diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb index 0e3dff27da981b769604177c8c11c826a6206e1b..46414b49f37eb5c32689608647e77dd10aee6d75 100644 --- a/app/helpers/application_settings_helper.rb +++ b/app/helpers/application_settings_helper.rb @@ -368,7 +368,9 @@ def visible_attributes :container_registry_cleanup_tags_service_max_list_size, :keep_latest_artifact, :whats_new_variant - ] + ].tap do |settings| + settings << :deactivate_dormant_users unless Gitlab.com? + end end def external_authorization_service_attributes diff --git a/app/views/admin/application_settings/_account_and_limit.html.haml b/app/views/admin/application_settings/_account_and_limit.html.haml index 1e2c9f821d215dec9ac0ec7e5cdf92fc278c0d15..eb30efabb98c93e75b5f529f1c007eae3c3dc798 100644 --- a/app/views/admin/application_settings/_account_and_limit.html.haml +++ b/app/views/admin/application_settings/_account_and_limit.html.haml @@ -53,6 +53,14 @@ = _('Specify an e-mail address regex pattern to identify default internal users.') = link_to _('More information'), help_page_path('user/permissions', anchor: 'setting-new-users-to-external'), target: '_blank' + - unless Gitlab.com? + .form-group + = f.label :deactivate_dormant_users, _('Dormant users'), class: 'label-bold' + .form-check + = f.check_box :deactivate_dormant_users, class: 'form-check-input' + = f.label :deactivate_dormant_users, class: 'form-check-label' do + = _('Deactivate dormant users after 90 days of inactivity. Users can return to active status by signing in to their account. While inactive, a user is not counted as an active user in the instance.') + = link_to _('More information'), help_page_path('user/admin_area/moderate_users', anchor: 'automatically-deactivate-dormant-users'), target: '_blank' .form-group = f.label :personal_access_token_prefix, _('Personal Access Token prefix'), class: 'label-light' = f.text_field :personal_access_token_prefix, placeholder: _('Max 20 characters'), class: 'form-control gl-form-input' diff --git a/doc/api/settings.md b/doc/api/settings.md index ada1d0e7fc47148e937b4e3ca7ec5c8e3048575b..406688732feaa45383d97136559b14bdb740a21f 100644 --- a/doc/api/settings.md +++ b/doc/api/settings.md @@ -241,6 +241,7 @@ listed in the descriptions of the relevant settings. | `check_namespace_plan` | boolean | no | **(PREMIUM)** Enabling this makes only licensed EE features available to projects if the project namespace's plan includes the feature or if the project is public. | | `commit_email_hostname` | string | no | Custom hostname (for private commit emails). | | `container_registry_token_expire_delay` | integer | no | Container Registry token duration in minutes. | +| `deactivate_dormant_users` | boolean | no | Enable [atomatic deactivation of dormant users](../user/admin_area/moderate_users.md#automatically-deactivate-dormant-users). | | `default_artifacts_expire_in` | string | no | Set the default expiration time for each job's artifacts. | | `default_branch_protection` | integer | no | Determine if developers can push to the default branch. Can take: `0` _(not protected, both developers and maintainers can push new commits, force push, or delete the branch)_, `1` _(partially protected, developers and maintainers can push new commits, but cannot force push, or delete, the branch)_ or `2` _(fully protected, developers cannot push new commits, but maintainers can; no-one can force push or delete the branch)_ as a parameter. Default is `2`. | | `default_ci_config_path` | string | no | Default CI configuration path for new projects (`.gitlab-ci.yml` if not set). | diff --git a/doc/user/admin_area/moderate_users.md b/doc/user/admin_area/moderate_users.md index c04003dd75f4b5befc2bc66d65a99a5ce2aec224..5afecc6629448ee47fb3960a3cf65e73cb635828 100644 --- a/doc/user/admin_area/moderate_users.md +++ b/doc/user/admin_area/moderate_users.md @@ -95,6 +95,20 @@ Users can also be deactivated using the [GitLab API](../../api/users.md#deactiva NOTE: A deactivated user does not consume a [seat](../../subscriptions/self_managed/index.md#billable-users). +### Automatically deactivate dormant users + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/320875) in GitLab 14.0. + +Administrators can enable automatic deactivation of users who have not signed in, or have no activity in the last 90 days. To do this: + +1. Navigate to **Admin Area > Settings > General > Account and Limit**. +1. Under the **Dormant users** tab, check **Deactivate dormant users after 90 days of inactivity**. +1. Click **Save changes**. + +When this feature is enabled, GitLab runs a job once a day to deactivate the dormant users. + +A maximum of 100,000 users can be deactivated per day. + ### Activating a user > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22257) in GitLab 12.4. diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 08885af18ffcb710848fe9cbb263eee678d5d9b1..ec606fdf3981d4a20152468980bf11ee1c7d7654 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -10464,6 +10464,9 @@ msgstr "" msgid "Days to merge" msgstr "" +msgid "Deactivate dormant users after 90 days of inactivity. Users can return to active status by signing in to their account. While inactive, a user is not counted as an active user in the instance." +msgstr "" + msgid "Deactivate this user" msgstr "" @@ -11707,6 +11710,9 @@ msgstr "" msgid "Done" msgstr "" +msgid "Dormant users" +msgstr "" + msgid "Download" msgstr "" diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb index 7cccac11363fab57194434a3b4c2c661a5121ee6..c289c18126ddeb939d3ede266b58cc6182075d26 100644 --- a/spec/features/admin/admin_settings_spec.rb +++ b/spec/features/admin/admin_settings_spec.rb @@ -8,9 +8,11 @@ include UsageDataHelpers let(:admin) { create(:admin) } + let(:dot_com?) { false } context 'application setting :admin_mode is enabled', :request_store do before do + allow(Gitlab).to receive(:com?).and_return(dot_com?) stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') sign_in(admin) gitlab_enable_admin_mode_sign_in(admin) @@ -127,6 +129,37 @@ expect(user_internal_regex['placeholder']).to eq 'Regex pattern' end + context 'Dormant users' do + context 'when Gitlab.com' do + let(:dot_com?) { true } + + it 'does not expose the setting' do + expect(page).to have_no_selector('#application_setting_deactivate_dormant_users') + end + end + + context 'when not Gitlab.com' do + let(:dot_com?) { false } + + it 'change Dormant users' do + expect(page).to have_unchecked_field('Deactivate dormant users after 90 days of inactivity') + expect(current_settings.deactivate_dormant_users).to be_falsey + + page.within('.as-account-limit') do + check 'application_setting_deactivate_dormant_users' + click_button 'Save changes' + end + + expect(page).to have_content "Application settings saved successfully" + + page.refresh + + expect(current_settings.deactivate_dormant_users).to be_truthy + expect(page).to have_checked_field('Deactivate dormant users after 90 days of inactivity') + end + end + end + context 'Change Sign-up restrictions' do context 'Require Admin approval for new signup setting' do it 'changes the setting', :js do diff --git a/spec/helpers/application_settings_helper_spec.rb b/spec/helpers/application_settings_helper_spec.rb index c74ee3ce0ecee95a990667d8fc9142e370397be9..4c62b3e12c138af6552a9d461b78a0ad0ce5fa8a 100644 --- a/spec/helpers/application_settings_helper_spec.rb +++ b/spec/helpers/application_settings_helper_spec.rb @@ -37,8 +37,24 @@ it_behaves_like 'when HTTP protocol is in use', 'https' it_behaves_like 'when HTTP protocol is in use', 'http' - context 'with tracking parameters' do - it { expect(visible_attributes).to include(*%i(snowplow_collector_hostname snowplow_cookie_domain snowplow_enabled snowplow_app_id)) } + describe '.visible_attributes' do + it 'contains tracking parameters' do + expect(helper.visible_attributes).to include(*%i(snowplow_collector_hostname snowplow_cookie_domain snowplow_enabled snowplow_app_id)) + end + + it 'contains :deactivate_dormant_users' do + expect(helper.visible_attributes).to include(:deactivate_dormant_users) + end + + context 'when GitLab.com' do + before do + allow(Gitlab).to receive(:com?).and_return(true) + end + + it 'does not contain :deactivate_dormant_users' do + expect(helper.visible_attributes).not_to include(:deactivate_dormant_users) + end + end end describe '.integration_expanded?' do