Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
63ab878f
Commit
63ab878f
authored
Nov 08, 2021
by
Vincent Fazio
Committed by
Sean McGivern
Nov 08, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Recalculate project authorizations on group transfer
Changelog: fixed
parent
6f06a967
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
84 additions
and
18 deletions
+84
-18
app/services/authorized_project_update/project_access_changed_service.rb
...thorized_project_update/project_access_changed_service.rb
+19
-0
app/services/groups/transfer_service.rb
app/services/groups/transfer_service.rb
+7
-10
app/workers/authorized_project_update/project_recalculate_worker.rb
...s/authorized_project_update/project_recalculate_worker.rb
+2
-0
spec/services/authorized_project_update/project_access_changed_service_spec.rb
...zed_project_update/project_access_changed_service_spec.rb
+21
-0
spec/services/groups/transfer_service_spec.rb
spec/services/groups/transfer_service_spec.rb
+35
-8
No files found.
app/services/authorized_project_update/project_access_changed_service.rb
0 → 100644
View file @
63ab878f
# frozen_string_literal: true
module
AuthorizedProjectUpdate
class
ProjectAccessChangedService
def
initialize
(
project_ids
)
@project_ids
=
Array
.
wrap
(
project_ids
)
end
def
execute
(
blocking:
true
)
bulk_args
=
@project_ids
.
map
{
|
id
|
[
id
]
}
if
blocking
AuthorizedProjectUpdate
::
ProjectRecalculateWorker
.
bulk_perform_and_wait
(
bulk_args
)
else
AuthorizedProjectUpdate
::
ProjectRecalculateWorker
.
bulk_perform_async
(
bulk_args
)
# rubocop:disable Scalability/BulkPerformWithContext
end
end
end
end
app/services/groups/transfer_service.rb
View file @
63ab878f
...
@@ -175,21 +175,18 @@ module Groups
...
@@ -175,21 +175,18 @@ module Groups
end
end
def
refresh_project_authorizations
def
refresh_project_authorizations
ProjectAuthorization
.
where
(
project_id:
@group
.
all_projects
.
select
(
:id
)).
delete_all
# rubocop: disable CodeReuse/ActiveRecord
projects_to_update
=
Set
.
new
# refresh authorized projects for current_user immediately
# All projects in this hierarchy need to have their project authorizations recalculated
current_user
.
refresh_authorized_projects
@group
.
all_projects
.
each_batch
{
|
prjs
|
projects_to_update
.
merge
(
prjs
.
ids
)
}
# rubocop: disable CodeReuse/ActiveRecord
# schedule refreshing projects for all the members of the group
@group
.
refresh_members_authorized_projects
# When a group is transferred, it also affects who gets access to the projects shared to
# When a group is transferred, it also affects who gets access to the projects shared to
# the subgroups within its hierarchy, so we also schedule jobs that refresh authorizations for all such shared projects.
# the subgroups within its hierarchy, so we also schedule jobs that refresh authorizations for all such shared projects.
project_group_shares_within_the_hierarchy
=
ProjectGroupLink
.
in_group
(
group
.
self_and_descendants
.
select
(
:id
))
ProjectGroupLink
.
in_group
(
@group
.
self_and_descendants
.
select
(
:id
)).
each_batch
do
|
project_group_links
|
projects_to_update
.
merge
(
project_group_links
.
pluck
(
:project_id
))
# rubocop: disable CodeReuse/ActiveRecord
project_group_shares_within_the_hierarchy
.
find_each
do
|
project_group_link
|
AuthorizedProjectUpdate
::
ProjectRecalculateWorker
.
perform_async
(
project_group_link
.
project_id
)
end
end
AuthorizedProjectUpdate
::
ProjectAccessChangedService
.
new
(
projects_to_update
.
to_a
).
execute
unless
projects_to_update
.
empty?
end
end
def
raise_transfer_error
(
message
)
def
raise_transfer_error
(
message
)
...
...
app/workers/authorized_project_update/project_recalculate_worker.rb
View file @
63ab878f
...
@@ -7,6 +7,8 @@ module AuthorizedProjectUpdate
...
@@ -7,6 +7,8 @@ module AuthorizedProjectUpdate
data_consistency
:always
data_consistency
:always
include
Gitlab
::
ExclusiveLeaseHelpers
include
Gitlab
::
ExclusiveLeaseHelpers
prepend
WaitableWorker
feature_category
:authentication_and_authorization
feature_category
:authentication_and_authorization
urgency
:high
urgency
:high
queue_namespace
:authorized_project_update
queue_namespace
:authorized_project_update
...
...
spec/services/authorized_project_update/project_access_changed_service_spec.rb
0 → 100644
View file @
63ab878f
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
AuthorizedProjectUpdate
::
ProjectAccessChangedService
do
describe
'#execute'
do
it
'schedules the project IDs'
do
expect
(
AuthorizedProjectUpdate
::
ProjectRecalculateWorker
).
to
receive
(
:bulk_perform_and_wait
)
.
with
([[
1
],
[
2
]])
described_class
.
new
([
1
,
2
]).
execute
end
it
'permits non-blocking operation'
do
expect
(
AuthorizedProjectUpdate
::
ProjectRecalculateWorker
).
to
receive
(
:bulk_perform_async
)
.
with
([[
1
],
[
2
]])
described_class
.
new
([
1
,
2
]).
execute
(
blocking:
false
)
end
end
end
spec/services/groups/transfer_service_spec.rb
View file @
63ab878f
...
@@ -593,11 +593,16 @@ RSpec.describe Groups::TransferService, :sidekiq_inline do
...
@@ -593,11 +593,16 @@ RSpec.describe Groups::TransferService, :sidekiq_inline do
let_it_be_with_reload
(
:group
)
{
create
(
:group
,
:private
,
parent:
old_parent_group
)
}
let_it_be_with_reload
(
:group
)
{
create
(
:group
,
:private
,
parent:
old_parent_group
)
}
let_it_be
(
:new_group_member
)
{
create
(
:user
)
}
let_it_be
(
:new_group_member
)
{
create
(
:user
)
}
let_it_be
(
:old_group_member
)
{
create
(
:user
)
}
let_it_be
(
:old_group_member
)
{
create
(
:user
)
}
let_it_be
(
:unique_subgroup_member
)
{
create
(
:user
)
}
let_it_be
(
:direct_project_member
)
{
create
(
:user
)
}
before
do
before
do
new_parent_group
.
add_maintainer
(
new_group_member
)
new_parent_group
.
add_maintainer
(
new_group_member
)
old_parent_group
.
add_maintainer
(
old_group_member
)
old_parent_group
.
add_maintainer
(
old_group_member
)
subgroup1
.
add_developer
(
unique_subgroup_member
)
nested_project
.
add_developer
(
direct_project_member
)
group
.
refresh_members_authorized_projects
group
.
refresh_members_authorized_projects
subgroup1
.
refresh_members_authorized_projects
end
end
it
'removes old project authorizations'
do
it
'removes old project authorizations'
do
...
@@ -613,7 +618,7 @@ RSpec.describe Groups::TransferService, :sidekiq_inline do
...
@@ -613,7 +618,7 @@ RSpec.describe Groups::TransferService, :sidekiq_inline do
end
end
it
'performs authorizations job immediately'
do
it
'performs authorizations job immediately'
do
expect
(
AuthorizedProject
s
Worker
).
to
receive
(
:bulk_perform_inline
)
expect
(
AuthorizedProject
Update
::
ProjectRecalculate
Worker
).
to
receive
(
:bulk_perform_inline
)
transfer_service
.
execute
(
new_parent_group
)
transfer_service
.
execute
(
new_parent_group
)
end
end
...
@@ -630,15 +635,25 @@ RSpec.describe Groups::TransferService, :sidekiq_inline do
...
@@ -630,15 +635,25 @@ RSpec.describe Groups::TransferService, :sidekiq_inline do
ProjectAuthorization
.
where
(
project_id:
nested_project
.
id
,
user_id:
new_group_member
.
id
).
size
ProjectAuthorization
.
where
(
project_id:
nested_project
.
id
,
user_id:
new_group_member
.
id
).
size
}.
from
(
0
).
to
(
1
)
}.
from
(
0
).
to
(
1
)
end
end
it
'preserves existing project authorizations for direct project members'
do
expect
{
transfer_service
.
execute
(
new_parent_group
)
}.
not_to
change
{
ProjectAuthorization
.
where
(
project_id:
nested_project
.
id
,
user_id:
direct_project_member
.
id
).
count
}
end
end
end
context
'for groups with many members'
do
context
'for nested groups with unique members'
do
before
do
it
'preserves existing project authorizations'
do
11
.
times
do
expect
{
transfer_service
.
execute
(
new_parent_group
)
}.
not_to
change
{
new_parent_group
.
add_maintainer
(
create
(
:user
))
ProjectAuthorization
.
where
(
project_id:
nested_project
.
id
,
user_id:
unique_subgroup_member
.
id
).
count
}
end
end
end
end
context
'for groups with many projects'
do
let_it_be
(
:project_list
)
{
create_list
(
:project
,
11
,
:repository
,
:private
,
namespace:
group
)
}
it
'adds new project authorizations for the user which makes a transfer'
do
it
'adds new project authorizations for the user which makes a transfer'
do
transfer_service
.
execute
(
new_parent_group
)
transfer_service
.
execute
(
new_parent_group
)
...
@@ -646,9 +661,21 @@ RSpec.describe Groups::TransferService, :sidekiq_inline do
...
@@ -646,9 +661,21 @@ RSpec.describe Groups::TransferService, :sidekiq_inline do
expect
(
ProjectAuthorization
.
where
(
project_id:
nested_project
.
id
,
user_id:
user
.
id
).
size
).
to
eq
(
1
)
expect
(
ProjectAuthorization
.
where
(
project_id:
nested_project
.
id
,
user_id:
user
.
id
).
size
).
to
eq
(
1
)
end
end
it
'adds project authorizations for users in the new hierarchy'
do
expect
{
transfer_service
.
execute
(
new_parent_group
)
}.
to
change
{
ProjectAuthorization
.
where
(
project_id:
project_list
.
map
{
|
project
|
project
.
id
},
user_id:
new_group_member
.
id
).
size
}.
from
(
0
).
to
(
project_list
.
count
)
end
it
'removes project authorizations for users in the old hierarchy'
do
expect
{
transfer_service
.
execute
(
new_parent_group
)
}.
to
change
{
ProjectAuthorization
.
where
(
project_id:
project_list
.
map
{
|
project
|
project
.
id
},
user_id:
old_group_member
.
id
).
size
}.
from
(
project_list
.
count
).
to
(
0
)
end
it
'schedules authorizations job'
do
it
'schedules authorizations job'
do
expect
(
AuthorizedProject
s
Worker
).
to
receive
(
:bulk_perform_async
)
expect
(
AuthorizedProject
Update
::
ProjectRecalculate
Worker
).
to
receive
(
:bulk_perform_async
)
.
with
(
array_including
(
new_parent_group
.
members_with_parents
.
pluck
(
:user_id
).
map
{
|
id
|
[
id
,
anything
]
}))
.
with
(
array_including
(
group
.
all_projects
.
ids
.
map
{
|
id
|
[
id
,
anything
]
}))
transfer_service
.
execute
(
new_parent_group
)
transfer_service
.
execute
(
new_parent_group
)
end
end
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment