Commit 2c4e0ce5 authored by Serena Fang's avatar Serena Fang

Shadow ban UI

Add shadow ban user state and UI

Add config admin route

Add shadow ban admin user path

Run rake translate

Add shadow banned user state

Add specs and UI touches

Remove line about hiding comments and issues

Add shadow banned users tab

Run bin/rake translate

Add specs for shadow ban user

Model and controller specs, factory

Add specs for unsuccessful shadow ban

Add specs for unsuccessful shadow ban

Add application log when user shadow banned

Changelog: added

Add changelog entry

Add shadow_ban_user_feature_flag

Add feature flag, flag yml,
modify code and tests to check for flag

Check if shadow_ban_user_feature_flag enabled

Add un shadow ban option

Add route for un shadow ban user

Add docs page for shadow banning

Add docs for shadow banning users

Change un shadow ban to unban

Change to unban

Move shadow ban docs to block docs

Combine banning and blocking docs

Move shadow ban docs to block docs

Combine banning and blocking docs

Move activate deactivate into user moderation

Combine block, ban, and deactivate into one file

Rename blocking and unblocking to user moderation

Now that this page has blocking, banning,
and deactivating, rename to user moderation

Remove activating deactivating users page

All included in user moderation page

Apply MR review suggestion

Apply MR review suggestion

Fix broken anchors

Fix anchor, run translation

Fix anchor links

Fix anchor links to removed pages

Apply MR review suggestions

Check feature available helpers

Rename shadow ban to ban

Modify references to shadow ban,
WIP, clicking shadow ban just blocks the user
rename shadow ban files to ban

Remove references to shadow ban

Remove shadow ban from docs and changelog

Link to ban user docs

Add link to banned users docs

Move confirm text to helper

Move confirm text to helper
parent cbd76096
......@@ -7,6 +7,7 @@ class Admin::UsersController < Admin::ApplicationController
before_action :user, except: [:index, :cohorts, :new, :create]
before_action :check_impersonation_availability, only: :impersonate
before_action :ensure_destroy_prerequisites_met, only: [:destroy]
before_action :check_ban_user_feature_flag, only: [:ban]
feature_category :users
......@@ -130,6 +131,24 @@ class Admin::UsersController < Admin::ApplicationController
end
end
def ban
result = Users::BanService.new(current_user).execute(user)
if result[:status] == :success
redirect_back_or_admin_user(notice: _("Successfully banned"))
else
redirect_back_or_admin_user(alert: _("Error occurred. User was not banned"))
end
end
def unban
if update_user { |user| user.activate }
redirect_back_or_admin_user(notice: _("Successfully unbanned"))
else
redirect_back_or_admin_user(alert: _("Error occurred. User was not unbanned"))
end
end
def unlock
if update_user { |user| user.unlock_access! }
redirect_back_or_admin_user(alert: _("Successfully unlocked"))
......@@ -325,6 +344,10 @@ class Admin::UsersController < Admin::ApplicationController
access_denied! unless Gitlab.config.gitlab.impersonation_enabled
end
def check_ban_user_feature_flag
access_denied! unless Feature.enabled?(:ban_user_feature_flag)
end
def log_impersonation_event
Gitlab::AppLogger.info(_("User %{current_user_username} has started impersonating %{username}") % { current_user_username: current_user.username, username: user.username })
end
......
......@@ -162,6 +162,49 @@ module UsersHelper
header + list
end
def user_ban_data(user)
{
path: ban_admin_user_path(user),
method: 'put',
modal_attributes: {
title: s_('AdminUsers|Ban user %{username}?') % { username: sanitize_name(user.name) },
message: s_('AdminUsers|You can always unban their account. Their data remains intact.'),
okVariant: 'warning',
okTitle: s_('AdminUsers|Ban')
}.to_json
}
end
def user_unban_data(user)
{
path: unban_admin_user_path(user),
method: 'put',
modal_attributes: {
title: s_('AdminUsers|Unban %{username}?') % { username: sanitize_name(user.name) },
message: s_('AdminUsers|You can always ban their account again if needed.'),
okVariant: 'info',
okTitle: s_('AdminUsers|Unban')
}.to_json
}
end
def user_ban_effects
header = tag.p s_('AdminUsers|Banning the user has the following effects:')
list = tag.ul do
concat tag.li s_('AdminUsers|User will be blocked')
end
link_start = '<a href="%{url}" target="_blank">'.html_safe % { url: help_page_path("user/admin_area/user_moderation", anchor: "banning-a-user") }
info = tag.p s_('AdminUsers|Learn more about %{link_start}banned users.%{link_end}').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
header + list + info
end
def ban_feature_available?
Feature.enabled?(:ban_user_feature_flag)
end
def user_deactivation_data(user, message)
{
path: deactivate_admin_user_path(user),
......@@ -235,6 +278,9 @@ module UsersHelper
pending_approval_badge = { text: s_('AdminUsers|Pending approval'), variant: 'info' }
return pending_approval_badge if user.blocked_pending_approval?
banned_badge = { text: s_('AdminUsers|Banned'), variant: 'danger' }
return banned_badge if user.banned?
{ text: s_('AdminUsers|Blocked'), variant: 'danger' }
end
......
......@@ -326,6 +326,7 @@ class User < ApplicationRecord
transition deactivated: :blocked
transition ldap_blocked: :blocked
transition blocked_pending_approval: :blocked
transition banned: :blocked
end
event :ldap_block do
......@@ -338,19 +339,24 @@ class User < ApplicationRecord
transition blocked: :active
transition ldap_blocked: :active
transition blocked_pending_approval: :active
transition banned: :active
end
event :block_pending_approval do
transition active: :blocked_pending_approval
end
event :ban do
transition active: :banned
end
event :deactivate do
# Any additional changes to this event should be also
# reflected in app/workers/users/deactivate_dormant_users_worker.rb
transition active: :deactivated
end
state :blocked, :ldap_blocked, :blocked_pending_approval do
state :blocked, :ldap_blocked, :blocked_pending_approval, :banned do
def blocked?
true
end
......@@ -375,8 +381,9 @@ class User < ApplicationRecord
# Scopes
scope :admins, -> { where(admin: true) }
scope :instance_access_request_approvers_to_be_notified, -> { admins.active.order_recent_sign_in.limit(INSTANCE_ACCESS_REQUEST_APPROVERS_TO_BE_NOTIFIED_LIMIT) }
scope :blocked, -> { with_states(:blocked, :ldap_blocked) }
scope :blocked, -> { with_states(:blocked, :ldap_blocked, :banned) }
scope :blocked_pending_approval, -> { with_states(:blocked_pending_approval) }
scope :banned, -> { with_states(:banned) }
scope :external, -> { where(external: true) }
scope :non_external, -> { where(external: false) }
scope :confirmed, -> { where.not(confirmed_at: nil) }
......@@ -598,6 +605,8 @@ class User < ApplicationRecord
blocked
when 'blocked_pending_approval'
blocked_pending_approval
when 'banned'
banned
when 'two_factor_disabled'
without_two_factor
when 'two_factor_enabled'
......
# frozen_string_literal: true
module Users
class BanService < BaseService
def initialize(current_user)
@current_user = current_user
end
def execute(user)
if user.ban
log_event(user)
success
else
messages = user.errors.full_messages
error(messages.uniq.join('. '))
end
end
def log_event(user)
Gitlab::AppLogger.info(message: "User banned", user: "#{user.username}", email: "#{user.email}", banned_by: "#{current_user.username}", ip_address: "#{current_user.current_sign_in_ip}")
end
end
end
- if ban_feature_available?
.card.border-warning
.card-header.bg-warning.text-white
= s_('AdminUsers|Ban user')
.card-body
= user_ban_effects
%br
%button.btn.gl-button.btn-warning.js-confirm-modal-button{ data: user_ban_data(user) }
= s_('AdminUsers|Ban user')
......@@ -3,6 +3,9 @@
- if @user.blocked_pending_approval?
%span.cred
= s_('AdminUsers|(Pending approval)')
- elsif @user.banned?
%span.cred
= s_('AdminUsers|(Banned)')
- elsif @user.blocked?
%span.cred
= s_('AdminUsers|(Blocked)')
......
......@@ -28,6 +28,11 @@
= link_to admin_users_path(filter: "blocked") do
= s_('AdminUsers|Blocked')
%small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.blocked)
- if ban_feature_available?
= nav_link(html_options: { class: active_when(params[:filter] == 'banned') }) do
= link_to admin_users_path(filter: "banned") do
= s_('AdminUsers|Banned')
%small.badge.gl-tab-counter-badge.badge-muted.badge-pill.gl-badge.sm= limited_counter_with_delimiter(User.banned)
= nav_link(html_options: { class: "#{active_when(params[:filter] == 'blocked_pending_approval')} filter-blocked-pending-approval" }) do
= link_to admin_users_path(filter: "blocked_pending_approval"), data: { qa_selector: 'pending_approval_tab' } do
= s_('AdminUsers|Pending approval')
......
......@@ -176,6 +176,20 @@
- if @user.blocked_pending_approval?
= render 'admin/users/approve_user', user: @user
= render 'admin/users/reject_pending_user', user: @user
- elsif @user.banned?
.gl-card.border-info.gl-mb-5
.gl-card-header.gl-bg-blue-500.gl-text-white
= _('This user is banned')
.gl-card-body
%p= _('A banned user cannot:')
%ul
%li= _('Log in')
%li= _('Access Git repositories')
- link_start = '<a href="%{url}" target="_blank">'.html_safe % { url: help_page_path("user/admin_area/user_moderation", anchor: "banning-a-user") }
= s_('AdminUsers|Learn more about %{link_start}banned users.%{link_end}').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
%p
%button.btn.gl-button.btn-info.js-confirm-modal-button{ data: user_unban_data(@user) }
= s_('AdminUsers|Unban user')
- else
.gl-card.border-info.gl-mb-5
.gl-card-header.gl-bg-blue-500.gl-text-white
......@@ -190,6 +204,7 @@
= s_('AdminUsers|Unblock user')
- elsif !@user.internal?
= render 'admin/users/block_user', user: @user
= render 'admin/users/ban_user', user: @user
- if @user.access_locked?
.card.border-info.gl-mb-5
......
---
title: Ban user state and UI
merge_request: 61292
author:
type: added
---
name: ban_user_feature_flag
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61292
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/330667
milestone: '13.12'
type: development
group: group::access
default_enabled: false
......@@ -21,6 +21,8 @@ namespace :admin do
get :keys
put :block
put :unblock
put :ban
put :unban
put :deactivate
put :activate
put :unlock
......
......@@ -48,8 +48,8 @@ using [Seat Link](#seat-link).
A _billable user_ counts against the number of subscription seats. Every user is considered a
billable user, with the following exceptions:
- [Deactivated users](../../user/admin_area/activating_deactivating_users.md#deactivating-a-user) and
[blocked users](../../user/admin_area/blocking_unblocking_users.md) don't count as billable users in the current subscription. When they are either deactivated or blocked they release a _billable user_ seat. However, they may
- [Deactivated users](../../user/admin_area/user_moderation.md#deactivating-a-user) and
[blocked users](../../user/admin_area/user_moderation.md#blocking-a-user) don't count as billable users in the current subscription. When they are either deactivated or blocked they release a _billable user_ seat. However, they may
count toward overages in the subscribed seat count.
- Users who are [pending approval](../../user/admin_area/approving_users.md).
- Members with Guest permissions on an Ultimate subscription.
......@@ -183,7 +183,7 @@ Starting 30 days before a subscription expires, GitLab notifies administrators o
We recommend following these steps during renewal:
1. Prune any inactive or unwanted users by [blocking them](../../user/admin_area/blocking_unblocking_users.md#blocking-a-user).
1. Prune any inactive or unwanted users by [blocking them](../../user/admin_area/user_moderation.md#blocking-a-user).
1. Determine if you have a need for user growth in the upcoming subscription.
1. Log in to the [Customers Portal](https://customers.gitlab.com/customers/sign_in) and select the **Renew** button beneath your existing subscription.
......
......@@ -21,7 +21,7 @@ When a user registers for an account while this setting is enabled:
A user pending approval:
- Is functionally identical to a [blocked](blocking_unblocking_users.md) user.
- Is functionally identical to a [blocked](user_moderation.md#blocking-a-user) user.
- Cannot sign in.
- Cannot access Git repositories or the GitLab API.
- Does not receive any notifications from GitLab.
......
---
stage: Manage
group: Access
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
type: howto
---
# Blocking and unblocking users
GitLab administrators block and unblock users.
## Blocking a user
In order to completely prevent access of a user to the GitLab instance, administrators can choose to
block the user.
Users can be blocked [via an abuse report](review_abuse_reports.md#blocking-users),
or directly from the Admin Area. To do this:
1. Navigate to **Admin Area > Overview > Users**.
1. Select a user.
1. Under the **Account** tab, click **Block user**.
A blocked user:
- Cannot log in.
- Cannot access Git repositories or the API.
- Does not receive any notifications from GitLab.
- Cannot use [slash commands](../../integration/slash_commands.md).
Personal projects, and group and user history of the blocked user are left intact.
Users can also be blocked using the [GitLab API](../../api/users.md#block-user).
NOTE:
A blocked user does not consume a [seat](../../subscriptions/self_managed/index.md#billable-users).
## Unblocking a user
A blocked user can be unblocked from the Admin Area. To do this:
1. Navigate to **Admin Area > Overview > Users**.
1. Click on the **Blocked** tab.
1. Select a user.
1. Under the **Account** tab, click **Unblock user**.
Users can also be unblocked using the [GitLab API](../../api/users.md#unblock-user).
NOTE:
Unblocking a user changes the user's state to active and consumes a
[seat](../../subscriptions/self_managed/index.md#billable-users).
......@@ -117,8 +117,8 @@ To list users matching a specific criteria, click on one of the following tabs o
- **2FA Enabled**
- **2FA Disabled**
- **External**
- **[Blocked](blocking_unblocking_users.md)**
- **[Deactivated](activating_deactivating_users.md)**
- **[Blocked](user_moderation.md#blocking-a-user)**
- **[Deactivated](user_moderation.md#deactivating-a-user)**
- **Without projects**
For each user, the following are listed:
......
......@@ -5,18 +5,67 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: howto
---
# Activating and deactivating users
# User moderation
GitLab administrators can moderate user access by blocking, banning, or deactivating users.
## Blocking and unblocking users
GitLab administrators can block and unblock users.
### Blocking a user
In order to completely prevent access of a user to the GitLab instance,
administrators can choose to block the user.
Users can be blocked [via an abuse report](review_abuse_reports.md#blocking-users),
or directly from the Admin Area. To do this:
1. Navigate to **Admin Area > Overview > Users**.
1. Select a user.
1. Under the **Account** tab, click **Block user**.
A blocked user:
- Cannot log in.
- Cannot access Git repositories or the API.
- Does not receive any notifications from GitLab.
- Cannot use [slash commands](../../integration/slash_commands.md).
Personal projects, and group and user history of the blocked user are left intact.
Users can also be blocked using the [GitLab API](../../api/users.md#block-user).
NOTE:
A blocked user does not consume a [seat](../../subscriptions/self_managed/index.md#billable-users).
### Unblocking a user
A blocked user can be unblocked from the Admin Area. To do this:
1. Navigate to **Admin Area > Overview > Users**.
1. Click on the **Blocked** tab.
1. Select a user.
1. Under the **Account** tab, click **Unblock user**.
Users can also be unblocked using the [GitLab API](../../api/users.md#unblock-user).
NOTE:
Unblocking a user changes the user's state to active and consumes a
[seat](../../subscriptions/self_managed/index.md#billable-users).
## Activating and deactivating users
GitLab administrators can deactivate and activate users.
## Deactivating a user
### Deactivating a user
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22257) in GitLab 12.4.
In order to temporarily prevent access by a GitLab user that has no recent activity, administrators
can choose to deactivate the user.
In order to temporarily prevent access by a GitLab user that has no recent activity,
administrators can choose to deactivate the user.
Deactivating a user is functionally identical to [blocking a user](blocking_unblocking_users.md),
Deactivating a user is functionally identical to [blocking a user](#blocking-and-unblocking-users),
with the following differences:
- It does not prohibit the user from logging back in via the UI.
......@@ -28,7 +77,7 @@ A deactivated user:
- Will not receive any notifications from GitLab.
- Will not be able to use [slash commands](../../integration/slash_commands.md).
Personal projects, and group and user history of the deactivated user will be left intact.
Personal projects, and group and user history of the deactivated user are left intact.
A user can be deactivated from the Admin Area. To do this:
......@@ -46,7 +95,7 @@ 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).
## Activating a user
### Activating a user
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22257) in GitLab 12.4.
......@@ -67,3 +116,49 @@ Activating a user changes the user's state to active and consumes a
NOTE:
A deactivated user can also activate their account themselves by logging back in via the UI.
## Banning and unbanning users
GitLab administrators can ban users.
NOTE:
This feature is behind a feature flag that is disabled by default. GitLab administrators
with access to the GitLab Rails console can [enable](../../administration/feature_flags.md)
this feature for your GitLab instance.
### Banning a user
In order to completely block a user and hide the user's comments and issues from other users,
administrators can choose to ban the user.
Users can be banned from the Admin Area. To do this:
1. Navigate to **Admin Area > Overview > Users**.
1. Select a user.
1. Under the **Account** tab, click **Ban user**.
Banning a user is functionally identical to [blocking a user](#blocking-and-unblocking-users),
with the following differences:
- Comments made by the banned user will be hidden from other users.
- Issues created by the banned user will be hidden from other users.
Personal projects, and group and user history of the blocked user are left intact.
NOTE:
This feature is a work in progress. Currently, banning a user
only blocks them and does not hide their comments or issues.
This functionality will be implemented in follow up issues.
### Unbanning a user
A banned user can be unbanned from the Admin Area. To do this:
1. Navigate to **Admin Area > Overview > Users**.
1. Click on the **Banned** tab.
1. Select a user.
1. Under the **Account** tab, click **Unban user**.
NOTE:
Unbanning a user changes the user's state to active and consumes a
[seat](../../subscriptions/self_managed/index.md#billable-users).
......@@ -69,7 +69,7 @@ username of the original user.
When using the **Delete user and contributions** option, **all** associated records
are removed. This includes all of the items mentioned above including issues,
merge requests, notes/comments, and more. Consider
[blocking a user](../../admin_area/blocking_unblocking_users.md)
[blocking a user](../../admin_area/user_moderation.md#blocking-a-user)
or using the **Delete user** option instead.
When a user is deleted from an [abuse report](../../admin_area/review_abuse_reports.md)
......
......@@ -73,7 +73,7 @@ Your account has been blocked. Fatal: Could not read from remote repository
Your primary email address is not confirmed.
```
You can assure your users that they have not been [Blocked](admin_area/blocking_unblocking_users.md) by an administrator.
You can assure your users that they have not been [Blocked](admin_area/user_moderation.md#blocking-and-unblocking-users) by an administrator.
When affected users see this message, they must confirm their email address before they can commit code.
## What do I need to know as an administrator of a GitLab self-managed Instance?
......
......@@ -1373,6 +1373,9 @@ msgstr ""
msgid "A Let's Encrypt account will be configured for this GitLab installation using your email address. You will receive emails to warn of expiring certificates."
msgstr ""
msgid "A banned user cannot:"
msgstr ""
msgid "A basic page and serverless function that uses AWS Lambda, AWS API Gateway, and GitLab Pages"
msgstr ""
......@@ -2435,6 +2438,9 @@ msgstr ""
msgid "AdminUsers|(Admin)"
msgstr ""
msgid "AdminUsers|(Banned)"
msgstr ""
msgid "AdminUsers|(Blocked)"
msgstr ""
......@@ -2501,6 +2507,21 @@ msgstr ""
msgid "AdminUsers|Automatically marked as default internal user"
msgstr ""
msgid "AdminUsers|Ban"
msgstr ""
msgid "AdminUsers|Ban user"
msgstr ""
msgid "AdminUsers|Ban user %{username}?"
msgstr ""
msgid "AdminUsers|Banned"
msgstr ""
msgid "AdminUsers|Banning the user has the following effects:"
msgstr ""
msgid "AdminUsers|Be added to groups and projects"
msgstr ""
......@@ -2588,6 +2609,9 @@ msgstr ""
msgid "AdminUsers|It's you!"
msgstr ""
msgid "AdminUsers|Learn more about %{link_start}banned users.%{link_end}"
msgstr ""
msgid "AdminUsers|Log in"
msgstr ""
......@@ -2669,6 +2693,15 @@ msgstr ""
msgid "AdminUsers|To confirm, type %{username}"
msgstr ""
msgid "AdminUsers|Unban"
msgstr ""
msgid "AdminUsers|Unban %{username}?"
msgstr ""
msgid "AdminUsers|Unban user"
msgstr ""
msgid "AdminUsers|Unblock"
msgstr ""
......@@ -2684,6 +2717,9 @@ msgstr ""
msgid "AdminUsers|Unlock user %{username}?"
msgstr ""
msgid "AdminUsers|User will be blocked"
msgstr ""
msgid "AdminUsers|User will not be able to access git repositories"
msgstr ""
......@@ -2720,6 +2756,9 @@ msgstr ""
msgid "AdminUsers|You are about to permanently delete the user %{username}. This will delete all of the issues, merge requests, and groups linked to them. To avoid data loss, consider using the %{strongStart}block user%{strongEnd} feature instead. Once you %{strongStart}Delete user%{strongEnd}, it cannot be undone or recovered."
msgstr ""
msgid "AdminUsers|You can always ban their account again if needed."
msgstr ""
msgid "AdminUsers|You can always block their account again if needed."
msgstr ""
......@@ -2729,6 +2768,9 @@ msgstr ""
msgid "AdminUsers|You can always re-activate their account, their data will remain intact."
msgstr ""
msgid "AdminUsers|You can always unban their account. Their data remains intact."
msgstr ""
msgid "AdminUsers|You can always unblock their account, their data will remain intact."
msgstr ""
......@@ -12905,12 +12947,18 @@ msgstr ""
msgid "Error occurred. A blocked user must be unblocked to be activated"
msgstr ""
msgid "Error occurred. User was not banned"
msgstr ""
msgid "Error occurred. User was not blocked"
msgstr ""
msgid "Error occurred. User was not confirmed"
msgstr ""
msgid "Error occurred. User was not unbanned"
msgstr ""
msgid "Error occurred. User was not unblocked"
msgstr ""
......@@ -31247,6 +31295,9 @@ msgstr ""
msgid "Successfully approved"
msgstr ""
msgid "Successfully banned"
msgstr ""
msgid "Successfully blocked"
msgstr ""
......@@ -31271,6 +31322,9 @@ msgstr ""
msgid "Successfully synced %{synced_timeago}."
msgstr ""
msgid "Successfully unbanned"
msgstr ""
msgid "Successfully unblocked"
msgstr ""
......@@ -33377,6 +33431,9 @@ msgstr ""
msgid "This user has the %{access} role in the %{name} project."
msgstr ""
msgid "This user is banned"
msgstr ""
msgid "This user is blocked"
msgstr ""
......
......@@ -365,6 +365,28 @@ RSpec.describe Admin::UsersController do
end
end
describe 'PUT ban/:id' do
it 'bans user' do
put :ban, params: { id: user.username }
user.reload
expect(user.banned?).to be_truthy
expect(flash[:notice]).to eq _('Successfully banned')
end
context 'when unsuccessful' do
let(:user) { create(:user, :blocked) }
it 'does not ban user' do
put :ban, params: { id: user.username }
user.reload
expect(user.banned?).to be_falsey
expect(flash[:alert]).to eq _('Error occurred. User was not banned')
end
end
end
describe 'PUT unlock/:id' do
before do
request.env["HTTP_REFERER"] = "/"
......
......@@ -27,6 +27,10 @@ FactoryBot.define do
after(:build) { |user, _| user.block_pending_approval! }
end
trait :banned do
after(:build) { |user, _| user.ban! }
end
trait :ldap_blocked do
after(:build) { |user, _| user.ldap_block! }
end
......
......@@ -85,6 +85,7 @@ RSpec.describe 'Admin::Users' do
expect(page).to have_link('2FA Disabled', href: admin_users_path(filter: 'two_factor_disabled'))
expect(page).to have_link('External', href: admin_users_path(filter: 'external'))
expect(page).to have_link('Blocked', href: admin_users_path(filter: 'blocked'))
expect(page).to have_link('Banned', href: admin_users_path(filter: 'banned'))
expect(page).to have_link('Deactivated', href: admin_users_path(filter: 'deactivated'))
expect(page).to have_link('Without projects', href: admin_users_path(filter: 'wop'))
end
......
......@@ -136,6 +136,16 @@ RSpec.describe UsersHelper do
end
end
context 'with a banned user' do
it 'returns the banned badge' do
banned_user = create(:user, :banned)
badges = helper.user_badges_in_admin_section(banned_user)
expect(filter_ee_badges(badges)).to eq([text: 'Banned', variant: 'danger'])
end
end
context 'with an admin user' do
it "returns the admin badge" do
admin_user = create(:admin)
......
......@@ -728,6 +728,7 @@ RSpec.describe User do
let_it_be(:blocked_user) { create(:user, :blocked) }
let_it_be(:ldap_blocked_user) { create(:omniauth_user, :ldap_blocked) }
let_it_be(:blocked_pending_approval_user) { create(:user, :blocked_pending_approval) }
let_it_be(:banned_user) { create(:user, :banned) }
describe '.blocked' do
subject { described_class.blocked }
......@@ -735,6 +736,7 @@ RSpec.describe User do
it 'returns only blocked users' do
expect(subject).to include(
blocked_user,
banned_user,
ldap_blocked_user
)
......@@ -749,6 +751,14 @@ RSpec.describe User do
expect(subject).to contain_exactly(blocked_pending_approval_user)
end
end
describe '.banned' do
subject { described_class.banned }
it 'returns only banned users' do
expect(subject).to contain_exactly(banned_user)
end
end
end
describe ".with_two_factor" do
......@@ -1934,6 +1944,12 @@ RSpec.describe User do
expect(described_class.filter_items('blocked')).to include user
end
it 'filters by banned' do
expect(described_class).to receive(:banned).and_return([user])
expect(described_class.filter_items('banned')).to include user
end
it 'filters by blocked pending approval' do
expect(described_class).to receive(:blocked_pending_approval).and_return([user])
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Users::BanService do
let(:current_user) { create(:admin) }
subject(:service) { described_class.new(current_user) }
describe '#execute' do
subject(:operation) { service.execute(user) }
context 'when successful' do
let(:user) { create(:user) }
it { is_expected.to eq(status: :success) }
it "bans the user" do
expect { operation }.to change { user.state }.to('banned')
end
it "blocks the user" do
expect { operation }.to change { user.blocked? }.from(false).to(true)
end
it 'logs ban in application logs' do
allow(Gitlab::AppLogger).to receive(:info)
operation
expect(Gitlab::AppLogger).to have_received(:info).with(message: "User banned", user: "#{user.username}", email: "#{user.email}", banned_by: "#{current_user.username}", ip_address: "#{current_user.current_sign_in_ip}")
end
end
context 'when failed' do
let(:user) { create(:user, :blocked) }
it 'returns error result' do
aggregate_failures 'error result' do
expect(operation[:status]).to eq(:error)
expect(operation[:message]).to match(/State cannot transition/)
end
end
it "does not change the user's state" do
expect { operation }.not_to change { user.state }
end
end
end
end
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