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
2f8d8dca
Commit
2f8d8dca
authored
Sep 30, 2020
by
GitLab Bot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add latest changes from gitlab-org/security/gitlab@13-4-stable-ee
parent
4d243f5c
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
273 additions
and
167 deletions
+273
-167
app/graphql/mutations/metrics/dashboard/annotations/base.rb
app/graphql/mutations/metrics/dashboard/annotations/base.rb
+1
-1
app/services/members/base_service.rb
app/services/members/base_service.rb
+5
-0
app/services/todos/destroy/entity_leave_service.rb
app/services/todos/destroy/entity_leave_service.rb
+37
-8
changelogs/unreleased/security-insufficient-type-check.yml
changelogs/unreleased/security-insufficient-type-check.yml
+5
-0
changelogs/unreleased/security-todos-redact-guests.yml
changelogs/unreleased/security-todos-redact-guests.yml
+5
-0
spec/requests/api/graphql/mutations/metrics/dashboard/annotations/delete_spec.rb
...ql/mutations/metrics/dashboard/annotations/delete_spec.rb
+5
-13
spec/services/members/update_service_spec.rb
spec/services/members/update_service_spec.rb
+25
-7
spec/services/todos/destroy/entity_leave_service_spec.rb
spec/services/todos/destroy/entity_leave_service_spec.rb
+190
-138
No files found.
app/graphql/mutations/metrics/dashboard/annotations/base.rb
View file @
2f8d8dca
...
@@ -9,7 +9,7 @@ module Mutations
...
@@ -9,7 +9,7 @@ module Mutations
# This method is defined here in order to be used by `authorized_find!` in the subclasses.
# This method is defined here in order to be used by `authorized_find!` in the subclasses.
def
find_object
(
id
:)
def
find_object
(
id
:)
GitlabSchema
.
object_from_id
(
id
)
GitlabSchema
.
object_from_id
(
id
,
expected_type:
::
Metrics
::
Dashboard
::
Annotation
)
end
end
end
end
end
end
...
...
app/services/members/base_service.rb
View file @
2f8d8dca
...
@@ -7,6 +7,11 @@ module Members
...
@@ -7,6 +7,11 @@ module Members
def
initialize
(
current_user
=
nil
,
params
=
{})
def
initialize
(
current_user
=
nil
,
params
=
{})
@current_user
=
current_user
@current_user
=
current_user
@params
=
params
@params
=
params
# could be a string, force to an integer, part of fix
# https://gitlab.com/gitlab-org/gitlab/-/issues/219496
# Allow the ArgumentError to be raised if it can't be converted to an integer.
@params
[
:access_level
]
=
Integer
(
@params
[
:access_level
])
if
@params
[
:access_level
]
end
end
def
after_execute
(
args
)
def
after_execute
(
args
)
...
...
app/services/todos/destroy/entity_leave_service.rb
View file @
2f8d8dca
...
@@ -52,7 +52,14 @@ module Todos
...
@@ -52,7 +52,14 @@ module Todos
# rubocop: disable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def
remove_project_todos
def
remove_project_todos
Todo
.
where
(
project_id:
non_authorized_projects
,
user_id:
user
.
id
).
delete_all
# Issues are viewable by guests (even in private projects), so remove those todos
# from projects without guest access
Todo
.
where
(
project_id:
non_authorized_guest_projects
,
user_id:
user
.
id
)
.
delete_all
# MRs require reporter access, so remove those todos that are not authorized
Todo
.
where
(
project_id:
non_authorized_reporter_projects
,
target_type:
MergeRequest
.
name
,
user_id:
user
.
id
)
.
delete_all
end
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: enable CodeReuse/ActiveRecord
...
@@ -68,7 +75,7 @@ module Todos
...
@@ -68,7 +75,7 @@ module Todos
when
Project
when
Project
{
id:
entity
.
id
}
{
id:
entity
.
id
}
when
Namespace
when
Namespace
{
namespace_id:
non_
memb
er_groups
}
{
namespace_id:
non_
authorized_report
er_groups
}
end
end
Project
.
where
(
condition
)
Project
.
where
(
condition
)
...
@@ -76,8 +83,32 @@ module Todos
...
@@ -76,8 +83,32 @@ module Todos
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def
non_authorized_projects
def
authorized_reporter_projects
projects
.
where
(
'id NOT IN (?)'
,
user
.
authorized_projects
.
select
(
:id
))
user
.
authorized_projects
(
Gitlab
::
Access
::
REPORTER
).
select
(
:id
)
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def
authorized_guest_projects
user
.
authorized_projects
(
Gitlab
::
Access
::
GUEST
).
select
(
:id
)
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def
non_authorized_reporter_projects
projects
.
where
(
'id NOT IN (?)'
,
authorized_reporter_projects
)
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def
non_authorized_guest_projects
projects
.
where
(
'id NOT IN (?)'
,
authorized_guest_projects
)
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def
authorized_reporter_groups
GroupsFinder
.
new
(
user
,
min_access_level:
Gitlab
::
Access
::
REPORTER
).
execute
.
select
(
:id
)
end
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: enable CodeReuse/ActiveRecord
...
@@ -91,9 +122,9 @@ module Todos
...
@@ -91,9 +122,9 @@ module Todos
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def
non_
memb
er_groups
def
non_
authorized_report
er_groups
entity
.
self_and_descendants
.
select
(
:id
)
entity
.
self_and_descendants
.
select
(
:id
)
.
where
(
'id NOT IN (?)'
,
user
.
membership_groups
.
select
(
:id
)
)
.
where
(
'id NOT IN (?)'
,
authorized_reporter_groups
)
end
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: enable CodeReuse/ActiveRecord
...
@@ -106,8 +137,6 @@ module Todos
...
@@ -106,8 +137,6 @@ module Todos
# rubocop: disable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def
confidential_issues
def
confidential_issues
assigned_ids
=
IssueAssignee
.
select
(
:issue_id
).
where
(
user_id:
user
.
id
)
assigned_ids
=
IssueAssignee
.
select
(
:issue_id
).
where
(
user_id:
user
.
id
)
authorized_reporter_projects
=
user
.
authorized_projects
(
Gitlab
::
Access
::
REPORTER
).
select
(
:id
)
Issue
.
where
(
project_id:
projects
,
confidential:
true
)
Issue
.
where
(
project_id:
projects
,
confidential:
true
)
.
where
(
'project_id NOT IN(?)'
,
authorized_reporter_projects
)
.
where
(
'project_id NOT IN(?)'
,
authorized_reporter_projects
)
...
...
changelogs/unreleased/security-insufficient-type-check.yml
0 → 100644
View file @
2f8d8dca
---
title
:
Ensure global ID is of Annotation type in GraphQL destroy mutation
merge_request
:
author
:
type
:
security
changelogs/unreleased/security-todos-redact-guests.yml
0 → 100644
View file @
2f8d8dca
---
title
:
Fix redaction of confidential Todos
merge_request
:
author
:
type
:
security
spec/requests/api/graphql/mutations/metrics/dashboard/annotations/delete_spec.rb
View file @
2f8d8dca
...
@@ -9,13 +9,9 @@ RSpec.describe Mutations::Metrics::Dashboard::Annotations::Delete do
...
@@ -9,13 +9,9 @@ RSpec.describe Mutations::Metrics::Dashboard::Annotations::Delete do
let_it_be
(
:project
)
{
create
(
:project
,
:private
,
:repository
)
}
let_it_be
(
:project
)
{
create
(
:project
,
:private
,
:repository
)
}
let_it_be
(
:environment
)
{
create
(
:environment
,
project:
project
)
}
let_it_be
(
:environment
)
{
create
(
:environment
,
project:
project
)
}
let_it_be
(
:annotation
)
{
create
(
:metrics_dashboard_annotation
,
environment:
environment
)
}
let_it_be
(
:annotation
)
{
create
(
:metrics_dashboard_annotation
,
environment:
environment
)
}
let
(
:mutation
)
do
variables
=
{
id:
GitlabSchema
.
id_from_object
(
annotation
).
to_s
}
graphql_mutation
(
:delete_annotation
,
variables
)
let
(
:variables
)
{
{
id:
GitlabSchema
.
id_from_object
(
annotation
).
to_s
}
}
end
let
(
:mutation
)
{
graphql_mutation
(
:delete_annotation
,
variables
)
}
def
mutation_response
def
mutation_response
graphql_mutation_response
(
:delete_annotation
)
graphql_mutation_response
(
:delete_annotation
)
...
@@ -37,15 +33,11 @@ RSpec.describe Mutations::Metrics::Dashboard::Annotations::Delete do
...
@@ -37,15 +33,11 @@ RSpec.describe Mutations::Metrics::Dashboard::Annotations::Delete do
end
end
context
'with invalid params'
do
context
'with invalid params'
do
let
(
:mutation
)
do
let
(
:variables
)
{
{
id:
GitlabSchema
.
id_from_object
(
project
).
to_s
}
}
variables
=
{
id:
'invalid_id'
}
graphql_mutation
(
:delete_annotation
,
variables
)
it_behaves_like
'a mutation that returns top-level errors'
do
let
(
:match_errors
)
{
eq
([
"
#{
variables
[
:id
]
}
is not a valid ID for
#{
annotation
.
class
}
."
])
}
end
end
it_behaves_like
'a mutation that returns top-level errors'
,
errors:
[
'invalid_id is not a valid GitLab ID.'
]
end
end
context
'when the delete fails'
do
context
'when the delete fails'
do
...
...
spec/services/members/update_service_spec.rb
View file @
2f8d8dca
...
@@ -31,11 +31,8 @@ RSpec.describe Members::UpdateService do
...
@@ -31,11 +31,8 @@ RSpec.describe Members::UpdateService do
end
end
context
'when member is downgraded to guest'
do
context
'when member is downgraded to guest'
do
let
(
:params
)
do
shared_examples
'schedules to delete confidential todos'
do
{
access_level:
Gitlab
::
Access
::
GUEST
}
it
do
end
it
'schedules to delete confidential todos'
do
expect
(
TodosDestroyer
::
EntityLeaveWorker
).
to
receive
(
:perform_in
).
with
(
Todo
::
WAIT_FOR_DELETE
,
member
.
user_id
,
member
.
source_id
,
source
.
class
.
name
).
once
expect
(
TodosDestroyer
::
EntityLeaveWorker
).
to
receive
(
:perform_in
).
with
(
Todo
::
WAIT_FOR_DELETE
,
member
.
user_id
,
member
.
source_id
,
source
.
class
.
name
).
once
updated_member
=
described_class
.
new
(
current_user
,
params
).
execute
(
member
,
permission:
permission
)
updated_member
=
described_class
.
new
(
current_user
,
params
).
execute
(
member
,
permission:
permission
)
...
@@ -44,6 +41,27 @@ RSpec.describe Members::UpdateService do
...
@@ -44,6 +41,27 @@ RSpec.describe Members::UpdateService do
expect
(
updated_member
.
access_level
).
to
eq
(
Gitlab
::
Access
::
GUEST
)
expect
(
updated_member
.
access_level
).
to
eq
(
Gitlab
::
Access
::
GUEST
)
end
end
end
end
context
'with Gitlab::Access::GUEST level as a string'
do
let
(
:params
)
{
{
access_level:
Gitlab
::
Access
::
GUEST
.
to_s
}
}
it_behaves_like
'schedules to delete confidential todos'
end
context
'with Gitlab::Access::GUEST level as an integer'
do
let
(
:params
)
{
{
access_level:
Gitlab
::
Access
::
GUEST
}
}
it_behaves_like
'schedules to delete confidential todos'
end
end
context
'when access_level is invalid'
do
let
(
:params
)
{
{
access_level:
'invalid'
}
}
it
'raises an error'
do
expect
{
described_class
.
new
(
current_user
,
params
)
}.
to
raise_error
(
ArgumentError
,
'invalid value for Integer(): "invalid"'
)
end
end
end
end
before
do
before
do
...
...
spec/services/todos/destroy/entity_leave_service_spec.rb
View file @
2f8d8dca
...
@@ -3,77 +3,145 @@
...
@@ -3,77 +3,145 @@
require
'spec_helper'
require
'spec_helper'
RSpec
.
describe
Todos
::
Destroy
::
EntityLeaveService
do
RSpec
.
describe
Todos
::
Destroy
::
EntityLeaveService
do
let_it_be
(
:user
,
reload:
true
)
{
create
(
:user
)
}
let_it_be
(
:user2
,
reload:
true
)
{
create
(
:user
)
}
let
(
:group
)
{
create
(
:group
,
:private
)
}
let
(
:group
)
{
create
(
:group
,
:private
)
}
let
(
:project
)
{
create
(
:project
,
group:
group
)
}
let
(
:project
)
{
create
(
:project
,
:private
,
group:
group
)
}
let
(
:
user
)
{
create
(
:user
)
}
let
(
:
issue
)
{
create
(
:issue
,
project:
project
)
}
let
(
:
user2
)
{
create
(
:user
)
}
let
(
:
issue_c
)
{
create
(
:issue
,
project:
project
,
confidential:
true
)
}
let
(
:issue
)
{
create
(
:issue
,
project:
project
,
confidential:
true
)
}
let
!
(
:todo_group_user
)
{
create
(
:todo
,
user:
user
,
group:
group
)
}
let
(
:mr
)
{
create
(
:merge_request
,
source_project:
project
)
}
let
!
(
:todo_group_user2
)
{
create
(
:todo
,
user:
user2
,
group:
group
)
}
let
(
:mr
)
{
create
(
:merge_request
,
source_project:
project
)
}
let!
(
:todo_mr_user
)
{
create
(
:todo
,
user:
user
,
target:
mr
,
project:
project
)
}
let!
(
:todo_mr_user
)
{
create
(
:todo
,
user:
user
,
target:
mr
,
project:
project
)
}
let!
(
:todo_issue_user
)
{
create
(
:todo
,
user:
user
,
target:
issue
,
project:
project
)
}
let!
(
:todo_issue_user
)
{
create
(
:todo
,
user:
user
,
target:
issue
,
project:
project
)
}
let!
(
:todo_group_user
)
{
create
(
:todo
,
user:
user
,
group:
group
)
}
let!
(
:todo_issue_c_user
)
{
create
(
:todo
,
user:
user
,
target:
issue_c
,
project:
project
)
}
let!
(
:todo_issue_user2
)
{
create
(
:todo
,
user:
user2
,
target:
issue
,
project:
project
)
}
let!
(
:todo_issue_c_user2
)
{
create
(
:todo
,
user:
user2
,
target:
issue_c
,
project:
project
)
}
let!
(
:todo_group_user2
)
{
create
(
:todo
,
user:
user2
,
group:
group
)
}
describe
'#execute'
do
shared_examples
'using different access permissions'
do
|
access_table
|
context
'when a user leaves a project'
do
using
RSpec
::
Parameterized
::
TableSyntax
subject
{
described_class
.
new
(
user
.
id
,
project
.
id
,
'Project'
).
execute
}
context
'when project is private'
do
where
(
:group_access
,
:project_access
,
:c_todos
,
:mr_todos
,
:method
,
&
access_table
)
it
'removes project todos for the provided user'
do
expect
{
subject
}.
to
change
{
Todo
.
count
}.
from
(
5
).
to
(
3
)
expect
(
user
.
todos
).
to
match_array
([
todo_group_user
])
with_them
do
expect
(
user2
.
todos
).
to
match_array
([
todo_issue_user2
,
todo_group_user2
])
before
do
set_access
(
project
,
user
,
project_access
)
if
project_access
set_access
(
group
,
user
,
group_access
)
if
group_access
end
end
context
'when the user is member of the project'
do
it
"
#{
params
[
:method
].
to_s
.
humanize
(
capitalize:
false
)
}
"
do
before
do
send
(
method
)
project
.
add_developer
(
user
)
end
end
end
end
it
'does not remove any todos'
do
shared_examples
'does not remove any todos'
do
it
{
does_not_remove_any_todos
}
end
shared_examples
'removes only confidential issues todos'
do
it
{
removes_only_confidential_issues_todos
}
end
def
does_not_remove_any_todos
expect
{
subject
}.
not_to
change
{
Todo
.
count
}
expect
{
subject
}.
not_to
change
{
Todo
.
count
}
end
end
def
removes_only_confidential_issues_todos
expect
{
subject
}.
to
change
{
Todo
.
count
}.
from
(
6
).
to
(
5
)
end
end
context
'when the user is a project guest'
do
def
removes_confidential_issues_and_merge_request_todos
before
do
expect
{
subject
}.
to
change
{
Todo
.
count
}.
from
(
6
).
to
(
4
)
project
.
add_guest
(
user
)
expect
(
user
.
todos
).
to
match_array
([
todo_issue_user
,
todo_group_user
]
)
end
end
it
'removes only confidential issues todos'
do
def
set_access
(
object
,
user
,
access_name
)
expect
{
subject
}.
to
change
{
Todo
.
count
}.
from
(
5
).
to
(
4
)
case
access_name
when
:developer
object
.
add_developer
(
user
)
when
:reporter
object
.
add_reporter
(
user
)
when
:guest
object
.
add_guest
(
user
)
end
end
end
end
context
'when the user is member of a parent group'
do
describe
'#execute'
do
before
do
describe
'updating a Project'
do
group
.
add_developer
(
user
)
subject
{
described_class
.
new
(
user
.
id
,
project
.
id
,
'Project'
).
execute
}
# a private project in a private group is valid
context
'when project is private'
do
context
'when user is not a member of the project'
do
it
'removes project todos for the provided user'
do
expect
{
subject
}.
to
change
{
Todo
.
count
}.
from
(
6
).
to
(
3
)
expect
(
user
.
todos
).
to
match_array
([
todo_group_user
])
expect
(
user2
.
todos
).
to
match_array
([
todo_issue_c_user2
,
todo_group_user2
])
end
end
end
it
'does not remove any todos'
do
context
'access permissions'
do
expect
{
subject
}.
not_to
change
{
Todo
.
count
}
# rubocop:disable RSpec/LeakyConstantDeclaration
PRIVATE_PROJECT_PRIVATE_GROUP_ACCESS_TABLE
=
lambda
do
|
_
|
[
# :group_access, :project_access, :c_todos, :mr_todos, :method
[
nil
,
:reporter
,
:keep
,
:keep
,
:does_not_remove_any_todos
],
[
nil
,
:guest
,
:delete
,
:delete
,
:removes_confidential_issues_and_merge_request_todos
],
[
:reporter
,
nil
,
:keep
,
:keep
,
:does_not_remove_any_todos
],
[
:guest
,
nil
,
:delete
,
:delete
,
:removes_confidential_issues_and_merge_request_todos
],
[
:guest
,
:reporter
,
:keep
,
:keep
,
:does_not_remove_any_todos
],
[
:guest
,
:guest
,
:delete
,
:delete
,
:removes_confidential_issues_and_merge_request_todos
]
]
end
# rubocop:enable RSpec/LeakyConstantDeclaration
it_behaves_like
'using different access permissions'
,
PRIVATE_PROJECT_PRIVATE_GROUP_ACCESS_TABLE
end
end
end
end
context
'when the user is guest of a parent group'
do
# a private project in an internal/public group is valid
before
do
context
'when project is private in an internal/public group'
do
project
.
add_guest
(
user
)
let
(
:group
)
{
create
(
:group
,
:internal
)
}
context
'when user is not a member of the project'
do
it
'removes project todos for the provided user'
do
expect
{
subject
}.
to
change
{
Todo
.
count
}.
from
(
6
).
to
(
3
)
expect
(
user
.
todos
).
to
match_array
([
todo_group_user
])
expect
(
user2
.
todos
).
to
match_array
([
todo_issue_c_user2
,
todo_group_user2
])
end
end
end
it
'removes only confidential issues todos'
do
context
'access permissions'
do
expect
{
subject
}.
to
change
{
Todo
.
count
}.
from
(
5
).
to
(
4
)
# rubocop:disable RSpec/LeakyConstantDeclaration
PRIVATE_PROJECT_INTERNAL_GROUP_ACCESS_TABLE
=
lambda
do
|
_
|
[
# :group_access, :project_access, :c_todos, :mr_todos, :method
[
nil
,
:reporter
,
:keep
,
:keep
,
:does_not_remove_any_todos
],
[
nil
,
:guest
,
:delete
,
:delete
,
:removes_confidential_issues_and_merge_request_todos
],
[
:reporter
,
nil
,
:keep
,
:keep
,
:does_not_remove_any_todos
],
[
:guest
,
nil
,
:delete
,
:delete
,
:removes_confidential_issues_and_merge_request_todos
],
[
:guest
,
:reporter
,
:keep
,
:keep
,
:does_not_remove_any_todos
],
[
:guest
,
:guest
,
:delete
,
:delete
,
:removes_confidential_issues_and_merge_request_todos
]
]
end
end
# rubocop:enable RSpec/LeakyConstantDeclaration
it_behaves_like
'using different access permissions'
,
PRIVATE_PROJECT_INTERNAL_GROUP_ACCESS_TABLE
end
end
end
end
# an internal project in an internal/public group is valid
context
'when project is not private'
do
context
'when project is not private'
do
before
do
let
(
:group
)
{
create
(
:group
,
:internal
)
}
group
.
update!
(
visibility_level:
Gitlab
::
VisibilityLevel
::
INTERNAL
)
let
(
:project
)
{
create
(
:project
,
:internal
,
group:
group
)
}
project
.
update!
(
visibility_level:
Gitlab
::
VisibilityLevel
::
INTERNAL
)
let
(
:issue
)
{
create
(
:issue
,
project:
project
)
}
end
let
(
:issue_c
)
{
create
(
:issue
,
project:
project
,
confidential:
true
)
}
it
'enqueues the PrivateFeaturesWorker'
do
it
'enqueues the PrivateFeaturesWorker'
do
expect
(
TodosDestroyer
::
PrivateFeaturesWorker
)
expect
(
TodosDestroyer
::
PrivateFeaturesWorker
)
...
@@ -84,50 +152,42 @@ RSpec.describe Todos::Destroy::EntityLeaveService do
...
@@ -84,50 +152,42 @@ RSpec.describe Todos::Destroy::EntityLeaveService do
context
'confidential issues'
do
context
'confidential issues'
do
context
'when a user is not an author of confidential issue'
do
context
'when a user is not an author of confidential issue'
do
it
'removes only confidential issues todos'
do
it_behaves_like
'removes only confidential issues todos'
expect
{
subject
}.
to
change
{
Todo
.
count
}.
from
(
5
).
to
(
4
)
end
end
end
context
'when a user is an author of confidential issue'
do
context
'when a user is an author of confidential issue'
do
before
do
before
do
issue
.
update!
(
author:
user
)
issue
_c
.
update!
(
author:
user
)
end
end
it
'does not remove any todos'
do
it_behaves_like
'does not remove any todos'
expect
{
subject
}.
not_to
change
{
Todo
.
count
}
end
end
end
context
'when a user is an assignee of confidential issue'
do
context
'when a user is an assignee of confidential issue'
do
before
do
before
do
issue
.
assignees
<<
user
issue_c
.
assignees
<<
user
end
it
'does not remove any todos'
do
expect
{
subject
}.
not_to
change
{
Todo
.
count
}
end
end
context
'when a user is a project guest'
do
before
do
project
.
add_guest
(
user
)
end
end
it
'removes only confidential issues todos'
do
it_behaves_like
'does not remove any todos'
expect
{
subject
}.
to
change
{
Todo
.
count
}.
from
(
5
).
to
(
4
)
end
end
end
context
'when a user is a project guest but group developer'
do
context
'access permissions'
do
before
do
# rubocop:disable RSpec/LeakyConstantDeclaration
project
.
add_guest
(
user
)
INTERNAL_PROJECT_INTERNAL_GROUP_ACCESS_TABLE
=
group
.
add_developer
(
user
)
lambda
do
|
_
|
[
# :group_access, :project_access, :c_todos, :mr_todos, :method
[
nil
,
:reporter
,
:keep
,
:keep
,
:does_not_remove_any_todos
],
[
nil
,
:guest
,
:delete
,
:keep
,
:removes_only_confidential_issues_todos
],
[
:reporter
,
nil
,
:keep
,
:keep
,
:does_not_remove_any_todos
],
[
:guest
,
nil
,
:delete
,
:keep
,
:removes_only_confidential_issues_todos
],
[
:guest
,
:reporter
,
:keep
,
:keep
,
:does_not_remove_any_todos
],
[
:guest
,
:guest
,
:delete
,
:keep
,
:removes_only_confidential_issues_todos
]
]
end
end
# rubocop:enable RSpec/LeakyConstantDeclaration
it
'does not remove any todos'
do
it_behaves_like
'using different access permissions'
,
INTERNAL_PROJECT_INTERNAL_GROUP_ACCESS_TABLE
expect
{
subject
}.
not_to
change
{
Todo
.
count
}
end
end
end
end
end
...
@@ -138,42 +198,43 @@ RSpec.describe Todos::Destroy::EntityLeaveService do
...
@@ -138,42 +198,43 @@ RSpec.describe Todos::Destroy::EntityLeaveService do
end
end
it
'removes only users issue todos'
do
it
'removes only users issue todos'
do
expect
{
subject
}.
to
change
{
Todo
.
count
}.
from
(
5
).
to
(
4
)
expect
{
subject
}.
to
change
{
Todo
.
count
}.
from
(
6
).
to
(
5
)
end
end
end
end
end
end
end
end
end
end
context
'when a user leaves a g
roup'
do
describe
'updating a G
roup'
do
subject
{
described_class
.
new
(
user
.
id
,
group
.
id
,
'Group'
).
execute
}
subject
{
described_class
.
new
(
user
.
id
,
group
.
id
,
'Group'
).
execute
}
context
'when group is private'
do
context
'when group is private'
do
context
'when a user leaves a group'
do
it
'removes group and subproject todos for the user'
do
it
'removes group and subproject todos for the user'
do
expect
{
subject
}.
to
change
{
Todo
.
count
}.
from
(
5
).
to
(
2
)
expect
{
subject
}.
to
change
{
Todo
.
count
}.
from
(
6
).
to
(
2
)
expect
(
user
.
todos
).
to
be_empty
expect
(
user
.
todos
).
to
be_empty
expect
(
user2
.
todos
).
to
match_array
([
todo_issue_user2
,
todo_group_user2
])
expect
(
user2
.
todos
).
to
match_array
([
todo_issue_c_user2
,
todo_group_user2
])
end
context
'when the user is member of the group'
do
before
do
group
.
add_developer
(
user
)
end
it
'does not remove any todos'
do
expect
{
subject
}.
not_to
change
{
Todo
.
count
}
end
end
end
end
context
'when the user is member of the group project but not the group'
do
context
'access permissions'
do
before
do
# rubocop:disable RSpec/LeakyConstantDeclaration
project
.
add_developer
(
user
)
PRIVATE_GROUP_PRIVATE_PROJECT_ACCESS_TABLE
=
lambda
do
|
_
|
[
# :group_access, :project_access, :c_todos, :mr_todos, :method
[
nil
,
:reporter
,
:keep
,
:keep
,
:does_not_remove_any_todos
],
[
nil
,
:guest
,
:delete
,
:delete
,
:removes_confidential_issues_and_merge_request_todos
],
[
:reporter
,
nil
,
:keep
,
:keep
,
:does_not_remove_any_todos
],
[
:guest
,
nil
,
:delete
,
:delete
,
:removes_confidential_issues_and_merge_request_todos
],
[
:guest
,
:reporter
,
:keep
,
:keep
,
:does_not_remove_any_todos
],
[
:guest
,
:guest
,
:delete
,
:delete
,
:removes_confidential_issues_and_merge_request_todos
]
]
end
end
# rubocop:enable RSpec/LeakyConstantDeclaration
it
'does not remove any todos'
do
it_behaves_like
'using different access permissions'
,
PRIVATE_GROUP_PRIVATE_PROJECT_ACCESS_TABLE
expect
{
subject
}.
not_to
change
{
Todo
.
count
}
end
end
end
context
'with nested groups'
do
context
'with nested groups'
do
...
@@ -191,12 +252,12 @@ RSpec.describe Todos::Destroy::EntityLeaveService do
...
@@ -191,12 +252,12 @@ RSpec.describe Todos::Destroy::EntityLeaveService do
context
'when the user is not a member of any groups/projects'
do
context
'when the user is not a member of any groups/projects'
do
it
'removes todos for the user including subprojects todos'
do
it
'removes todos for the user including subprojects todos'
do
expect
{
subject
}.
to
change
{
Todo
.
count
}.
from
(
1
1
).
to
(
4
)
expect
{
subject
}.
to
change
{
Todo
.
count
}.
from
(
1
2
).
to
(
4
)
expect
(
user
.
todos
).
to
be_empty
expect
(
user
.
todos
).
to
be_empty
expect
(
user2
.
todos
)
expect
(
user2
.
todos
)
.
to
match_array
(
.
to
match_array
(
[
todo_issue_user2
,
todo_group_user2
,
todo_subproject_user2
,
todo_subpgroup_user2
]
[
todo_issue_
c_
user2
,
todo_group_user2
,
todo_subproject_user2
,
todo_subpgroup_user2
]
)
)
end
end
end
end
...
@@ -208,9 +269,7 @@ RSpec.describe Todos::Destroy::EntityLeaveService do
...
@@ -208,9 +269,7 @@ RSpec.describe Todos::Destroy::EntityLeaveService do
parent_group
.
add_developer
(
user
)
parent_group
.
add_developer
(
user
)
end
end
it
'does not remove any todos'
do
it_behaves_like
'does not remove any todos'
expect
{
subject
}.
not_to
change
{
Todo
.
count
}
end
end
end
context
'when the user is member of a subgroup'
do
context
'when the user is member of a subgroup'
do
...
@@ -219,12 +278,12 @@ RSpec.describe Todos::Destroy::EntityLeaveService do
...
@@ -219,12 +278,12 @@ RSpec.describe Todos::Destroy::EntityLeaveService do
end
end
it
'does not remove group and subproject todos'
do
it
'does not remove group and subproject todos'
do
expect
{
subject
}.
to
change
{
Todo
.
count
}.
from
(
1
1
).
to
(
7
)
expect
{
subject
}.
to
change
{
Todo
.
count
}.
from
(
1
2
).
to
(
7
)
expect
(
user
.
todos
).
to
match_array
([
todo_group_user
,
todo_subgroup_user
,
todo_subproject_user
])
expect
(
user
.
todos
).
to
match_array
([
todo_group_user
,
todo_subgroup_user
,
todo_subproject_user
])
expect
(
user2
.
todos
)
expect
(
user2
.
todos
)
.
to
match_array
(
.
to
match_array
(
[
todo_issue_user2
,
todo_group_user2
,
todo_subproject_user2
,
todo_subpgroup_user2
]
[
todo_issue_
c_
user2
,
todo_group_user2
,
todo_subproject_user2
,
todo_subpgroup_user2
]
)
)
end
end
end
end
...
@@ -235,12 +294,12 @@ RSpec.describe Todos::Destroy::EntityLeaveService do
...
@@ -235,12 +294,12 @@ RSpec.describe Todos::Destroy::EntityLeaveService do
end
end
it
'does not remove subproject and group todos'
do
it
'does not remove subproject and group todos'
do
expect
{
subject
}.
to
change
{
Todo
.
count
}.
from
(
1
1
).
to
(
7
)
expect
{
subject
}.
to
change
{
Todo
.
count
}.
from
(
1
2
).
to
(
7
)
expect
(
user
.
todos
).
to
match_array
([
todo_subgroup_user
,
todo_group_user
,
todo_subproject_user
])
expect
(
user
.
todos
).
to
match_array
([
todo_subgroup_user
,
todo_group_user
,
todo_subproject_user
])
expect
(
user2
.
todos
)
expect
(
user2
.
todos
)
.
to
match_array
(
.
to
match_array
(
[
todo_issue_user2
,
todo_group_user2
,
todo_subproject_user2
,
todo_subpgroup_user2
]
[
todo_issue_
c_
user2
,
todo_group_user2
,
todo_subproject_user2
,
todo_subpgroup_user2
]
)
)
end
end
end
end
...
@@ -248,10 +307,10 @@ RSpec.describe Todos::Destroy::EntityLeaveService do
...
@@ -248,10 +307,10 @@ RSpec.describe Todos::Destroy::EntityLeaveService do
end
end
context
'when group is not private'
do
context
'when group is not private'
do
before
do
let
(
:group
)
{
create
(
:group
,
:internal
)
}
group
.
update!
(
visibility_level:
Gitlab
::
VisibilityLevel
::
INTERNAL
)
let
(
:project
)
{
create
(
:project
,
:internal
,
group:
group
)
}
project
.
update!
(
visibility_level:
Gitlab
::
VisibilityLevel
::
INTERNAL
)
let
(
:issue
)
{
create
(
:issue
,
project:
project
)
}
end
let
(
:issue_c
)
{
create
(
:issue
,
project:
project
,
confidential:
true
)
}
it
'enqueues the PrivateFeaturesWorker'
do
it
'enqueues the PrivateFeaturesWorker'
do
expect
(
TodosDestroyer
::
PrivateFeaturesWorker
)
expect
(
TodosDestroyer
::
PrivateFeaturesWorker
)
...
@@ -260,31 +319,24 @@ RSpec.describe Todos::Destroy::EntityLeaveService do
...
@@ -260,31 +319,24 @@ RSpec.describe Todos::Destroy::EntityLeaveService do
subject
subject
end
end
context
'when user is not member'
do
context
'access permissions'
do
it
'removes only confidential issues todos'
do
# rubocop:disable RSpec/LeakyConstantDeclaration
expect
{
subject
}.
to
change
{
Todo
.
count
}.
from
(
5
).
to
(
4
)
INTERNAL_GROUP_INTERNAL_PROJECT_ACCESS_TABLE
=
end
lambda
do
|
_
|
end
[
# :group_access, :project_access, :c_todos, :mr_todos, :method
context
'when user is a project guest'
do
[
nil
,
nil
,
:delete
,
:keep
,
:removes_only_confidential_issues_todos
],
before
do
[
nil
,
:reporter
,
:keep
,
:keep
,
:does_not_remove_any_todos
],
project
.
add_guest
(
user
)
[
nil
,
:guest
,
:delete
,
:keep
,
:removes_only_confidential_issues_todos
],
end
[
:reporter
,
nil
,
:keep
,
:keep
,
:does_not_remove_any_todos
],
[
:guest
,
nil
,
:delete
,
:keep
,
:removes_only_confidential_issues_todos
],
it
'removes only confidential issues todos'
do
[
:guest
,
:reporter
,
:keep
,
:keep
,
:does_not_remove_any_todos
],
expect
{
subject
}.
to
change
{
Todo
.
count
}.
from
(
5
).
to
(
4
)
[
:guest
,
:guest
,
:delete
,
:keep
,
:removes_only_confidential_issues_todos
]
end
]
end
end
# rubocop:enable RSpec/LeakyConstantDeclaration
context
'when user is a project guest & group developer'
do
before
do
it_behaves_like
'using different access permissions'
,
INTERNAL_GROUP_INTERNAL_PROJECT_ACCESS_TABLE
project
.
add_guest
(
user
)
group
.
add_developer
(
user
)
end
it
'does not remove any todos'
do
expect
{
subject
}.
not_to
change
{
Todo
.
count
}
end
end
end
end
end
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