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
0
Merge Requests
0
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
Jérome Perrin
gitlab-ce
Commits
1b082a4c
Commit
1b082a4c
authored
Dec 14, 2016
by
Felipe Artur
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Check if user can read issue before being assigned
parent
77deeb12
Changes
14
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
189 additions
and
34 deletions
+189
-34
app/models/concerns/issuable.rb
app/models/concerns/issuable.rb
+3
-3
app/services/issuable_base_service.rb
app/services/issuable_base_service.rb
+29
-12
app/services/issues/base_service.rb
app/services/issues/base_service.rb
+0
-4
app/services/merge_requests/base_service.rb
app/services/merge_requests/base_service.rb
+0
-4
changelogs/unreleased/issue_22664.yml
changelogs/unreleased/issue_22664.yml
+1
-1
spec/models/concerns/issuable_spec.rb
spec/models/concerns/issuable_spec.rb
+24
-5
spec/services/issuable/bulk_update_service_spec.rb
spec/services/issuable/bulk_update_service_spec.rb
+8
-4
spec/services/issues/create_service_spec.rb
spec/services/issues/create_service_spec.rb
+2
-0
spec/services/issues/update_service_spec.rb
spec/services/issues/update_service_spec.rb
+11
-0
spec/services/merge_requests/create_service_spec.rb
spec/services/merge_requests/create_service_spec.rb
+2
-0
spec/services/notes/slash_commands_service_spec.rb
spec/services/notes/slash_commands_service_spec.rb
+2
-0
spec/support/services/issuable_create_service_shared_examples.rb
...pport/services/issuable_create_service_shared_examples.rb
+52
-0
spec/support/services/issuable_create_service_slash_commands_shared_examples.rb
...issuable_create_service_slash_commands_shared_examples.rb
+3
-1
spec/support/services/issuable_update_service_shared_examples.rb
...pport/services/issuable_update_service_shared_examples.rb
+52
-0
No files found.
app/models/concerns/issuable.rb
View file @
1b082a4c
...
...
@@ -93,9 +93,9 @@ module Issuable
def
update_assignee_cache_counts
# make sure we flush the cache for both the old *and* new assignees(if they exist)
previous_assignee
=
User
.
find_by_id
(
assignee_id_was
)
previous_assignee
.
try
(
:update_cache_counts
)
assignee
.
try
(
:update_cache_counts
)
previous_assignee
=
User
.
find_by_id
(
assignee_id_was
)
if
assignee_id_was
previous_assignee
.
update_cache_counts
if
previous_assignee
assignee
.
update_cache_counts
if
assignee
end
# We want to use optimistic lock for cases when only title or description are involved
...
...
app/services/issuable_base_service.rb
View file @
1b082a4c
...
...
@@ -36,14 +36,10 @@ class IssuableBaseService < BaseService
end
end
def
filter_params
(
issuable_ability_name
=
:issue
)
filter_assignee
filter_milestone
filter_labels
def
filter_params
(
issuable
)
ability_name
=
:"admin_
#{
issuable
.
to_ability_name
}
"
ability
=
:"admin_
#{
issuable_ability_name
}
"
unless
can?
(
current_user
,
ability
,
project
)
unless
can?
(
current_user
,
ability_name
,
project
)
params
.
delete
(
:milestone_id
)
params
.
delete
(
:labels
)
params
.
delete
(
:add_label_ids
)
...
...
@@ -52,14 +48,35 @@ class IssuableBaseService < BaseService
params
.
delete
(
:assignee_id
)
params
.
delete
(
:due_date
)
end
filter_assignee
(
issuable
)
filter_milestone
filter_labels
end
def
filter_assignee
if
params
[
:assignee_id
]
==
IssuableFinder
::
NONE
params
[
:assignee_id
]
=
''
def
filter_assignee
(
issuable
)
return
unless
params
[
:assignee_id
].
present?
assignee_id
=
params
[
:assignee_id
]
if
assignee_id
.
to_s
==
IssuableFinder
::
NONE
params
[
:assignee_id
]
=
""
else
params
.
delete
(
:assignee_id
)
unless
assignee_can_read?
(
issuable
,
assignee_id
)
end
end
def
assignee_can_read?
(
issuable
,
assignee_id
)
new_assignee
=
User
.
find_by_id
(
assignee_id
)
return
false
unless
new_assignee
.
present?
ability_name
=
:"read_
#{
issuable
.
to_ability_name
}
"
resource
=
issuable
.
persisted?
?
issuable
:
project
can?
(
new_assignee
,
ability_name
,
resource
)
end
def
filter_milestone
milestone_id
=
params
[
:milestone_id
]
return
unless
milestone_id
...
...
@@ -138,7 +155,7 @@ class IssuableBaseService < BaseService
def
create
(
issuable
)
merge_slash_commands_into_params!
(
issuable
)
filter_params
filter_params
(
issuable
)
params
.
delete
(
:state_event
)
params
[
:author
]
||=
current_user
...
...
@@ -180,7 +197,7 @@ class IssuableBaseService < BaseService
change_state
(
issuable
)
change_subscription
(
issuable
)
change_todo
(
issuable
)
filter_params
filter_params
(
issuable
)
old_labels
=
issuable
.
labels
.
to_a
old_mentioned_users
=
issuable
.
mentioned_users
.
to_a
...
...
app/services/issues/base_service.rb
View file @
1b082a4c
...
...
@@ -17,10 +17,6 @@ module Issues
private
def
filter_params
super
(
:issue
)
end
def
execute_hooks
(
issue
,
action
=
'open'
)
issue_data
=
hook_data
(
issue
,
action
)
hooks_scope
=
issue
.
confidential?
?
:confidential_issue_hooks
:
:issue_hooks
...
...
app/services/merge_requests/base_service.rb
View file @
1b082a4c
...
...
@@ -38,10 +38,6 @@ module MergeRequests
private
def
filter_params
super
(
:merge_request
)
end
def
merge_requests_for
(
branch
)
origin_merge_requests
=
@project
.
origin_merge_requests
.
opened
.
where
(
source_branch:
branch
).
to_a
...
...
changelogs/unreleased/issue_22664.yml
View file @
1b082a4c
---
title
:
Fix issuable assignee update bug when previous assignee is
null
title
:
Check if user can read project before being assigned to issue
merge_request
:
author
:
spec/models/concerns/issuable_spec.rb
View file @
1b082a4c
...
...
@@ -44,21 +44,40 @@ describe Issue, "Issuable" do
it
{
expect
(
described_class
).
to
respond_to
(
:assigned
)
}
end
describe
"
after
_save"
do
describe
"
before
_save"
do
describe
"#update_cache_counts"
do
context
"when previous assignee exists"
do
it
"user updates cache counts"
do
before
do
assignee
=
create
(
:user
)
issue
.
project
.
team
<<
[
assignee
,
:developer
]
issue
.
update
(
assignee:
assignee
)
end
it
"updates cache counts for new assignee"
do
user
=
create
(
:user
)
expect
(
user
).
to
receive
(
:update_cache_counts
)
issue
.
update
(
assignee:
user
)
end
it
"updates cache counts for previous assignee"
do
old_assignee
=
issue
.
assignee
allow
(
User
).
to
receive
(
:find_by_id
).
with
(
old_assignee
.
id
).
and_return
(
old_assignee
)
expect
(
old_assignee
).
to
receive
(
:update_cache_counts
)
issue
.
update
(
assignee:
nil
)
end
end
context
"when previous assignee does not exist"
do
it
"does not raise error"
do
issue
.
update
(
assignee_id:
""
)
before
{
issue
.
update
(
assignee:
nil
)
}
expect
{
issue
.
update
(
assignee_id:
user
)
}.
not_to
raise_error
it
"updates cache count for the new assignee"
do
expect_any_instance_of
(
User
).
to
receive
(
:update_cache_counts
)
issue
.
update
(
assignee:
user
)
end
end
end
...
...
spec/services/issuable/bulk_update_service_spec.rb
View file @
1b082a4c
...
...
@@ -52,7 +52,10 @@ describe Issuable::BulkUpdateService, services: true do
context
'when the new assignee ID is a valid user'
do
it
'succeeds'
do
result
=
bulk_update
(
issue
,
assignee_id:
create
(
:user
).
id
)
new_assignee
=
create
(
:user
)
project
.
team
<<
[
new_assignee
,
:developer
]
result
=
bulk_update
(
issue
,
assignee_id:
new_assignee
.
id
)
expect
(
result
[
:success
]).
to
be_truthy
expect
(
result
[
:count
]).
to
eq
(
1
)
...
...
@@ -60,15 +63,16 @@ describe Issuable::BulkUpdateService, services: true do
it
'updates the assignee to the use ID passed'
do
assignee
=
create
(
:user
)
project
.
team
<<
[
assignee
,
:developer
]
expect
{
bulk_update
(
issue
,
assignee_id:
assignee
.
id
)
}
.
to
change
{
issue
.
reload
.
assignee
}.
from
(
user
).
to
(
assignee
)
end
end
context
'when the new assignee ID is -1'
do
it
'unassigns the issues'
do
expect
{
bulk_update
(
issue
,
assignee_id:
-
1
)
}
context
"when the new assignee ID is
#{
IssuableFinder
::
NONE
}
"
do
it
"unassigns the issues"
do
expect
{
bulk_update
(
issue
,
assignee_id:
IssuableFinder
::
NONE
)
}
.
to
change
{
issue
.
reload
.
assignee
}.
to
(
nil
)
end
end
...
...
spec/services/issues/create_service_spec.rb
View file @
1b082a4c
...
...
@@ -135,6 +135,8 @@ describe Issues::CreateService, services: true do
end
end
it_behaves_like
'issuable create service'
it_behaves_like
'new issuable record that supports slash commands'
context
'for a merge request'
do
...
...
spec/services/issues/update_service_spec.rb
View file @
1b082a4c
...
...
@@ -142,6 +142,17 @@ describe Issues::UpdateService, services: true do
update_issue
(
confidential:
true
)
end
it
'does not update assignee_id with unauthorized users'
do
project
.
update
(
visibility_level:
Gitlab
::
VisibilityLevel
::
PUBLIC
)
update_issue
(
confidential:
true
)
non_member
=
create
(
:user
)
original_assignee
=
issue
.
assignee
update_issue
(
assignee_id:
non_member
.
id
)
expect
(
issue
.
reload
.
assignee_id
).
to
eq
(
original_assignee
.
id
)
end
end
context
'todos'
do
...
...
spec/services/merge_requests/create_service_spec.rb
View file @
1b082a4c
...
...
@@ -84,6 +84,8 @@ describe MergeRequests::CreateService, services: true do
end
end
it_behaves_like
'issuable create service'
context
'while saving references to issues that the created merge request closes'
do
let
(
:first_issue
)
{
create
(
:issue
,
project:
project
)
}
let
(
:second_issue
)
{
create
(
:issue
,
project:
project
)
}
...
...
spec/services/notes/slash_commands_service_spec.rb
View file @
1b082a4c
...
...
@@ -5,6 +5,8 @@ describe Notes::SlashCommandsService, services: true do
let
(
:project
)
{
create
(
:empty_project
)
}
let
(
:master
)
{
create
(
:user
).
tap
{
|
u
|
project
.
team
<<
[
u
,
:master
]
}
}
let
(
:assignee
)
{
create
(
:user
)
}
before
{
project
.
team
<<
[
assignee
,
:master
]
}
end
shared_examples
'note on noteable that does not support slash commands'
do
...
...
spec/support/services/issuable_create_service_shared_examples.rb
0 → 100644
View file @
1b082a4c
shared_examples
'issuable create service'
do
context
'asssignee_id'
do
let
(
:assignee
)
{
create
(
:user
)
}
before
{
project
.
team
<<
[
user
,
:master
]
}
it
'removes assignee_id when user id is invalid'
do
opts
=
{
title:
'Title'
,
description:
'Description'
,
assignee_id:
-
1
}
issuable
=
described_class
.
new
(
project
,
user
,
opts
).
execute
expect
(
issuable
.
assignee_id
).
to
be_nil
end
it
'removes assignee_id when user id is 0'
do
opts
=
{
title:
'Title'
,
description:
'Description'
,
assignee_id:
0
}
issuable
=
described_class
.
new
(
project
,
user
,
opts
).
execute
expect
(
issuable
.
assignee_id
).
to
be_nil
end
it
'saves assignee when user id is valid'
do
project
.
team
<<
[
assignee
,
:master
]
opts
=
{
title:
'Title'
,
description:
'Description'
,
assignee_id:
assignee
.
id
}
issuable
=
described_class
.
new
(
project
,
user
,
opts
).
execute
expect
(
issuable
.
assignee_id
).
to
eq
(
assignee
.
id
)
end
context
"when issuable feature is private"
do
before
do
project
.
project_feature
.
update
(
issues_access_level:
ProjectFeature
::
PRIVATE
)
project
.
project_feature
.
update
(
merge_requests_access_level:
ProjectFeature
::
PRIVATE
)
end
levels
=
[
Gitlab
::
VisibilityLevel
::
INTERNAL
,
Gitlab
::
VisibilityLevel
::
PUBLIC
]
levels
.
each
do
|
level
|
it
"removes not authorized assignee when project is
#{
Gitlab
::
VisibilityLevel
.
level_name
(
level
)
}
"
do
project
.
update
(
visibility_level:
level
)
opts
=
{
title:
'Title'
,
description:
'Description'
,
assignee_id:
assignee
.
id
}
issuable
=
described_class
.
new
(
project
,
user
,
opts
).
execute
expect
(
issuable
.
assignee_id
).
to
be_nil
end
end
end
end
end
spec/support/services/issuable_create_service_slash_commands_shared_examples.rb
View file @
1b082a4c
...
...
@@ -11,6 +11,8 @@ shared_examples 'new issuable record that supports slash commands' do
let
(
:params
)
{
base_params
.
merge
(
defined?
(
default_params
)
?
default_params
:
{}).
merge
(
example_params
)
}
let
(
:issuable
)
{
described_class
.
new
(
project
,
user
,
params
).
execute
}
before
{
project
.
team
<<
[
assignee
,
:master
]
}
context
'with labels in command only'
do
let
(
:example_params
)
do
{
...
...
@@ -55,7 +57,7 @@ shared_examples 'new issuable record that supports slash commands' do
context
'with assignee and milestone in params and command'
do
let
(
:example_params
)
do
{
assignee:
build_stubbed
(
:user
),
assignee:
create
(
:user
),
milestone_id:
double
(
:milestone
),
description:
%(/assign @#{assignee.username}\n/milestone %"#{milestone.name}")
}
...
...
spec/support/services/issuable_update_service_shared_examples.rb
View file @
1b082a4c
shared_examples
'issuable update service'
do
def
update_issuable
(
opts
)
described_class
.
new
(
project
,
user
,
opts
).
execute
(
open_issuable
)
end
context
'changing state'
do
before
{
expect
(
project
).
to
receive
(
:execute_hooks
).
once
}
...
...
@@ -14,4 +18,52 @@ shared_examples 'issuable update service' do
end
end
end
context
'asssignee_id'
do
it
'does not update assignee when assignee_id is invalid'
do
open_issuable
.
update
(
assignee_id:
user
.
id
)
update_issuable
(
assignee_id:
-
1
)
expect
(
open_issuable
.
reload
.
assignee
).
to
eq
(
user
)
end
it
'unassigns assignee when user id is 0'
do
open_issuable
.
update
(
assignee_id:
user
.
id
)
update_issuable
(
assignee_id:
0
)
expect
(
open_issuable
.
assignee_id
).
to
be_nil
end
it
'saves assignee when user id is valid'
do
update_issuable
(
assignee_id:
user
.
id
)
expect
(
open_issuable
.
assignee_id
).
to
eq
(
user
.
id
)
end
it
'does not update assignee_id when user cannot read issue'
do
non_member
=
create
(
:user
)
original_assignee
=
open_issuable
.
assignee
update_issuable
(
assignee_id:
non_member
.
id
)
expect
(
open_issuable
.
assignee_id
).
to
eq
(
original_assignee
.
id
)
end
context
"when issuable feature is private"
do
levels
=
[
Gitlab
::
VisibilityLevel
::
INTERNAL
,
Gitlab
::
VisibilityLevel
::
PUBLIC
]
levels
.
each
do
|
level
|
it
"does not update with unauthorized assignee when project is
#{
Gitlab
::
VisibilityLevel
.
level_name
(
level
)
}
"
do
assignee
=
create
(
:user
)
project
.
update
(
visibility_level:
level
)
feature_visibility_attr
=
:"
#{
open_issuable
.
model_name
.
plural
}
_access_level"
project
.
project_feature
.
update_attribute
(
feature_visibility_attr
,
ProjectFeature
::
PRIVATE
)
expect
{
update_issuable
(
assignee_id:
assignee
)
}.
not_to
change
{
open_issuable
.
assignee
}
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