Commit 3255b5bf authored by Mayra Cabrera's avatar Mayra Cabrera

Merge branch '275962-update-users-rake' into 'master'

Resolve "Set users limit to 0 for project and group creation"

See merge request gitlab-org/gitlab!47655
parents a10b9c9a 0afa48b5
......@@ -402,6 +402,13 @@ class Group < Namespace
.where(source_id: self_and_hierarchy.reorder(nil).select(:id))
end
def direct_and_indirect_members_with_inactive
GroupMember
.non_request
.non_invite
.where(source_id: self_and_hierarchy.reorder(nil).select(:id))
end
def users_with_parents
User
.where(id: members_with_parents.select(:user_id))
......@@ -428,6 +435,20 @@ class Group < Namespace
])
end
# Returns all users (also inactive) that are members of the group because:
# 1. They belong to the group
# 2. They belong to a project that belongs to the group
# 3. They belong to a sub-group or project in such sub-group
# 4. They belong to an ancestor group
def direct_and_indirect_users_with_inactive
User.from_union([
User
.where(id: direct_and_indirect_members_with_inactive.select(:user_id))
.reorder(nil),
project_users_with_descendants
])
end
def users_count
members.count
end
......
---
title: Add rake task to disable personal project and group creation
merge_request: 47655
author:
type: added
......@@ -60,6 +60,20 @@ bundle exec rake gitlab:import:all_users_to_all_groups RAILS_ENV=production
Administrators are added as owners so they can add additional users to the group.
## Update all users in a given group to `project_limit:0` and `can_create_group: false`
To update all users in given group to `project_limit: 0` and `can_create_group: false`, run:
```shell
# omnibus-gitlab
sudo gitlab-rake gitlab:user_management:disable_project_and_group_creation\[:group_id\]
# installation from source
bundle exec rake gitlab:user_management:disable_project_and_group_creation\[:group_id\] RAILS_ENV=production
```
It updates all users in the given group, its subgroups and projects in this group namespace, with the noted limits.
## Control the number of billable users
Enable this setting to keep new users blocked until they have been cleared by the administrator.
......
namespace :gitlab do
namespace :user_management do
desc "GitLab | User management | Update all users of a group with personal project limit to 0 and can_create_group to false"
task :disable_project_and_group_creation, [:group_id] => :environment do |t, args|
group = Group.find(args.group_id)
result = User.where(id: group.direct_and_indirect_users_with_inactive.select(:id)).update_all(projects_limit: 0, can_create_group: false)
ids_count = group.direct_and_indirect_users_with_inactive.count
puts "Done".green if result == ids_count
puts "Something went wrong".red if result != ids_count
end
end
end
......@@ -798,20 +798,36 @@ RSpec.describe Group do
end
end
describe '#direct_and_indirect_members' do
context 'members-related methods' do
let!(:group) { create(:group, :nested) }
let!(:sub_group) { create(:group, parent: group) }
let!(:maintainer) { group.parent.add_user(create(:user), GroupMember::MAINTAINER) }
let!(:developer) { group.add_user(create(:user), GroupMember::DEVELOPER) }
let!(:other_developer) { group.add_user(create(:user), GroupMember::DEVELOPER) }
it 'returns parents members' do
expect(group.direct_and_indirect_members).to include(developer)
expect(group.direct_and_indirect_members).to include(maintainer)
describe '#direct_and_indirect_members' do
it 'returns parents members' do
expect(group.direct_and_indirect_members).to include(developer)
expect(group.direct_and_indirect_members).to include(maintainer)
end
it 'returns descendant members' do
expect(group.direct_and_indirect_members).to include(other_developer)
end
end
it 'returns descendant members' do
expect(group.direct_and_indirect_members).to include(other_developer)
describe '#direct_and_indirect_members_with_inactive' do
let!(:maintainer_blocked) { group.parent.add_user(create(:user, :blocked), GroupMember::MAINTAINER) }
it 'returns parents members' do
expect(group.direct_and_indirect_members_with_inactive).to include(developer)
expect(group.direct_and_indirect_members_with_inactive).to include(maintainer)
expect(group.direct_and_indirect_members_with_inactive).to include(maintainer_blocked)
end
it 'returns descendant members' do
expect(group.direct_and_indirect_members_with_inactive).to include(other_developer)
end
end
end
......@@ -834,7 +850,7 @@ RSpec.describe Group do
end
end
describe '#direct_and_indirect_users' do
context 'user-related methods' do
let(:user_a) { create(:user) }
let(:user_b) { create(:user) }
let(:user_c) { create(:user) }
......@@ -853,14 +869,40 @@ RSpec.describe Group do
project.add_developer(user_d)
end
it 'returns member users on every nest level without duplication' do
expect(group.direct_and_indirect_users).to contain_exactly(user_a, user_b, user_c, user_d)
expect(nested_group.direct_and_indirect_users).to contain_exactly(user_a, user_b, user_c)
expect(deep_nested_group.direct_and_indirect_users).to contain_exactly(user_a, user_b, user_c)
describe '#direct_and_indirect_users' do
it 'returns member users on every nest level without duplication' do
expect(group.direct_and_indirect_users).to contain_exactly(user_a, user_b, user_c, user_d)
expect(nested_group.direct_and_indirect_users).to contain_exactly(user_a, user_b, user_c)
expect(deep_nested_group.direct_and_indirect_users).to contain_exactly(user_a, user_b, user_c)
end
it 'does not return members of projects belonging to ancestor groups' do
expect(nested_group.direct_and_indirect_users).not_to include(user_d)
end
end
it 'does not return members of projects belonging to ancestor groups' do
expect(nested_group.direct_and_indirect_users).not_to include(user_d)
describe '#direct_and_indirect_users_with_inactive' do
let(:user_blocked_1) { create(:user, :blocked) }
let(:user_blocked_2) { create(:user, :blocked) }
let(:user_blocked_3) { create(:user, :blocked) }
let(:project_in_group) { create(:project, namespace: nested_group) }
before do
group.add_developer(user_blocked_1)
nested_group.add_developer(user_blocked_1)
deep_nested_group.add_developer(user_blocked_2)
project_in_group.add_developer(user_blocked_3)
end
it 'returns member users on every nest level without duplication' do
expect(group.direct_and_indirect_users_with_inactive).to contain_exactly(user_a, user_b, user_c, user_d, user_blocked_1, user_blocked_2, user_blocked_3)
expect(nested_group.direct_and_indirect_users_with_inactive).to contain_exactly(user_a, user_b, user_c, user_blocked_1, user_blocked_2, user_blocked_3)
expect(deep_nested_group.direct_and_indirect_users_with_inactive).to contain_exactly(user_a, user_b, user_c, user_blocked_1, user_blocked_2)
end
it 'returns members of projects belonging to group' do
expect(nested_group.direct_and_indirect_users_with_inactive).to include(user_blocked_3)
end
end
end
......
# frozen_string_literal: true
require 'rake_helper'
RSpec.describe 'gitlab:user_management tasks' do
before do
Rake.application.rake_require 'tasks/gitlab/user_management'
end
describe 'disable_project_and_group_creation' do
let(:group) { create(:group) }
subject(:run_rake) { run_rake_task('gitlab:user_management:disable_project_and_group_creation', group.id) }
it 'returns output info' do
expect { run_rake }.to output(/.*Done.*/).to_stdout
end
context 'with users' do
let(:user_1) { create(:user, projects_limit: 10, can_create_group: true) }
let(:user_2) { create(:user, projects_limit: 10, can_create_group: true) }
let(:user_other) { create(:user, projects_limit: 10, can_create_group: true) }
shared_examples 'updates proper users' do
it 'updates members' do
run_rake
expect(user_1.reload.projects_limit).to eq(0)
expect(user_1.can_create_group).to eq(false)
expect(user_2.reload.projects_limit).to eq(0)
expect(user_2.can_create_group).to eq(false)
end
it 'does not update other users' do
run_rake
expect(user_other.reload.projects_limit).to eq(10)
expect(user_other.reload.can_create_group).to eq(true)
end
end
context 'in the group' do
let(:other_group) { create(:group) }
before do
group.add_developer(user_1)
group.add_developer(user_2)
other_group.add_developer(user_other)
end
it_behaves_like 'updates proper users'
end
context 'in the descendant groups' do
let(:subgroup) { create(:group, parent: group) }
let(:sub_subgroup) { create(:group, parent: subgroup) }
let(:other_group) { create(:group) }
before do
subgroup.add_developer(user_1)
sub_subgroup.add_developer(user_2)
other_group.add_developer(user_other)
end
it_behaves_like 'updates proper users'
end
context 'in the children projects' do
let(:project_1) { create(:project, namespace: group) }
let(:project_2) { create(:project, namespace: group) }
let(:other_project) { create(:project) }
before do
project_1.add_developer(user_1)
project_2.add_developer(user_2)
other_project.add_developer(user_other)
end
it_behaves_like 'updates proper users'
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