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
03dba1fd
Commit
03dba1fd
authored
Oct 16, 2013
by
Dmitriy Zaporozhets
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #5344 from amacarthur/thread-variable-fix
Fixing unsafe use of Thread.current variable :current_user
parents
dad83166
aefe2e95
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
196 additions
and
120 deletions
+196
-120
app/controllers/application_controller.rb
app/controllers/application_controller.rb
+6
-1
db/fixtures/development/09_issues.rb
db/fixtures/development/09_issues.rb
+15
-10
db/fixtures/development/10_merge_requests.rb
db/fixtures/development/10_merge_requests.rb
+17
-13
features/support/env.rb
features/support/env.rb
+2
-0
lib/api/helpers.rb
lib/api/helpers.rb
+9
-0
lib/api/issues.rb
lib/api/issues.rb
+21
-18
lib/api/merge_requests.rb
lib/api/merge_requests.rb
+42
-37
lib/api/milestones.rb
lib/api/milestones.rb
+19
-15
lib/api/notes.rb
lib/api/notes.rb
+22
-18
spec/models/project_spec.rb
spec/models/project_spec.rb
+2
-8
spec/requests/api/issues_spec.rb
spec/requests/api/issues_spec.rb
+12
-0
spec/requests/api/milestones_spec.rb
spec/requests/api/milestones_spec.rb
+12
-0
spec/requests/api/notes_spec.rb
spec/requests/api/notes_spec.rb
+12
-0
spec/support/test_env.rb
spec/support/test_env.rb
+5
-0
No files found.
app/controllers/application_controller.rb
View file @
03dba1fd
...
@@ -2,7 +2,7 @@ class ApplicationController < ActionController::Base
...
@@ -2,7 +2,7 @@ class ApplicationController < ActionController::Base
before_filter
:authenticate_user!
before_filter
:authenticate_user!
before_filter
:reject_blocked!
before_filter
:reject_blocked!
before_filter
:check_password_expiration
before_filter
:check_password_expiration
before
_filter
:set_current_user_for_thread
around
_filter
:set_current_user_for_thread
before_filter
:add_abilities
before_filter
:add_abilities
before_filter
:dev_tools
if
Rails
.
env
==
'development'
before_filter
:dev_tools
if
Rails
.
env
==
'development'
before_filter
:default_headers
before_filter
:default_headers
...
@@ -50,6 +50,11 @@ class ApplicationController < ActionController::Base
...
@@ -50,6 +50,11 @@ class ApplicationController < ActionController::Base
def
set_current_user_for_thread
def
set_current_user_for_thread
Thread
.
current
[
:current_user
]
=
current_user
Thread
.
current
[
:current_user
]
=
current_user
begin
yield
ensure
Thread
.
current
[
:current_user
]
=
nil
end
end
end
def
abilities
def
abilities
...
...
db/fixtures/development/09_issues.rb
View file @
03dba1fd
...
@@ -11,17 +11,22 @@ Gitlab::Seeder.quiet do
...
@@ -11,17 +11,22 @@ Gitlab::Seeder.quiet do
next
unless
user
next
unless
user
user_id
=
user
.
id
user_id
=
user
.
id
Thread
.
current
[
:current_user
]
=
user
Issue
.
seed
(
:id
,
[{
begin
id:
i
,
Thread
.
current
[
:current_user
]
=
user
project_id:
project
.
id
,
author_id:
user_id
,
Issue
.
seed
(
:id
,
[{
assignee_id:
user_id
,
id:
i
,
state:
[
'opened'
,
'closed'
].
sample
,
project_id:
project
.
id
,
milestone:
project
.
milestones
.
sample
,
author_id:
user_id
,
title:
Faker
::
Lorem
.
sentence
(
6
)
assignee_id:
user_id
,
}])
state:
[
'opened'
,
'closed'
].
sample
,
milestone:
project
.
milestones
.
sample
,
title:
Faker
::
Lorem
.
sentence
(
6
)
}])
ensure
Thread
.
current
[
:current_user
]
=
nil
end
print
(
'.'
)
print
(
'.'
)
end
end
...
...
db/fixtures/development/10_merge_requests.rb
View file @
03dba1fd
...
@@ -17,19 +17,23 @@ Gitlab::Seeder.quiet do
...
@@ -17,19 +17,23 @@ Gitlab::Seeder.quiet do
next
if
branches
.
uniq
.
size
<
2
next
if
branches
.
uniq
.
size
<
2
user_id
=
user
.
id
user_id
=
user
.
id
Thread
.
current
[
:current_user
]
=
user
begin
Thread
.
current
[
:current_user
]
=
user
MergeRequest
.
seed
(
:id
,
[{
id:
i
,
MergeRequest
.
seed
(
:id
,
[{
source_branch:
branches
.
first
,
id:
i
,
target_branch:
branches
.
last
,
source_branch:
branches
.
first
,
source_project_id:
project
.
id
,
target_branch:
branches
.
last
,
target_project_id:
project
.
id
,
source_project_id:
project
.
id
,
author_id:
user_id
,
target_project_id:
project
.
id
,
assignee_id:
user_id
,
author_id:
user_id
,
milestone:
project
.
milestones
.
sample
,
assignee_id:
user_id
,
title:
Faker
::
Lorem
.
sentence
(
6
)
milestone:
project
.
milestones
.
sample
,
}])
title:
Faker
::
Lorem
.
sentence
(
6
)
}])
ensure
Thread
.
current
[
:current_user
]
=
nil
end
print
(
'.'
)
print
(
'.'
)
end
end
end
end
...
...
features/support/env.rb
View file @
03dba1fd
...
@@ -51,4 +51,6 @@ Spinach.hooks.before_run do
...
@@ -51,4 +51,6 @@ Spinach.hooks.before_run do
RSpec
::
Mocks
::
setup
self
RSpec
::
Mocks
::
setup
self
include
FactoryGirl
::
Syntax
::
Methods
include
FactoryGirl
::
Syntax
::
Methods
MergeRequestObserver
.
any_instance
.
stub
(
current_user:
create
(
:user
))
end
end
lib/api/helpers.rb
View file @
03dba1fd
...
@@ -27,6 +27,15 @@ module API
...
@@ -27,6 +27,15 @@ module API
end
end
end
end
def
set_current_user_for_thread
Thread
.
current
[
:current_user
]
=
current_user
begin
yield
ensure
Thread
.
current
[
:current_user
]
=
nil
end
end
def
user_project
def
user_project
@project
||=
find_project
(
params
[
:id
])
@project
||=
find_project
(
params
[
:id
])
@project
||
not_found!
@project
||
not_found!
...
...
lib/api/issues.rb
View file @
03dba1fd
...
@@ -2,7 +2,6 @@ module API
...
@@ -2,7 +2,6 @@ module API
# Issues API
# Issues API
class
Issues
<
Grape
::
API
class
Issues
<
Grape
::
API
before
{
authenticate!
}
before
{
authenticate!
}
before
{
Thread
.
current
[
:current_user
]
=
current_user
}
resource
:issues
do
resource
:issues
do
# Get currently authenticated user's issues
# Get currently authenticated user's issues
...
@@ -49,15 +48,17 @@ module API
...
@@ -49,15 +48,17 @@ module API
# Example Request:
# Example Request:
# POST /projects/:id/issues
# POST /projects/:id/issues
post
":id/issues"
do
post
":id/issues"
do
required_attributes!
[
:title
]
set_current_user_for_thread
do
attrs
=
attributes_for_keys
[
:title
,
:description
,
:assignee_id
,
:milestone_id
]
required_attributes!
[
:title
]
attrs
[
:label_list
]
=
params
[
:labels
]
if
params
[
:labels
].
present?
attrs
=
attributes_for_keys
[
:title
,
:description
,
:assignee_id
,
:milestone_id
]
@issue
=
user_project
.
issues
.
new
attrs
attrs
[
:label_list
]
=
params
[
:labels
]
if
params
[
:labels
].
present?
@issue
.
author
=
current_user
@issue
=
user_project
.
issues
.
new
attrs
if
@issue
.
save
@issue
.
author
=
current_user
present
@issue
,
with:
Entities
::
Issue
if
@issue
.
save
else
present
@issue
,
with:
Entities
::
Issue
not_found!
else
not_found!
end
end
end
end
end
...
@@ -75,16 +76,18 @@ module API
...
@@ -75,16 +76,18 @@ module API
# Example Request:
# Example Request:
# PUT /projects/:id/issues/:issue_id
# PUT /projects/:id/issues/:issue_id
put
":id/issues/:issue_id"
do
put
":id/issues/:issue_id"
do
@issue
=
user_project
.
issues
.
find
(
params
[
:issue_id
])
set_current_user_for_thread
do
authorize!
:modify_issue
,
@issue
@issue
=
user_project
.
issues
.
find
(
params
[
:issue_id
])
authorize!
:modify_issue
,
@issue
attrs
=
attributes_for_keys
[
:title
,
:description
,
:assignee_id
,
:milestone_id
,
:state_event
]
attrs
=
attributes_for_keys
[
:title
,
:description
,
:assignee_id
,
:milestone_id
,
:state_event
]
attrs
[
:label_list
]
=
params
[
:labels
]
if
params
[
:labels
].
present?
attrs
[
:label_list
]
=
params
[
:labels
]
if
params
[
:labels
].
present?
if
@issue
.
update_attributes
attrs
if
@issue
.
update_attributes
attrs
present
@issue
,
with:
Entities
::
Issue
present
@issue
,
with:
Entities
::
Issue
else
else
not_found!
not_found!
end
end
end
end
end
...
...
lib/api/merge_requests.rb
View file @
03dba1fd
...
@@ -2,7 +2,6 @@ module API
...
@@ -2,7 +2,6 @@ module API
# MergeRequest API
# MergeRequest API
class
MergeRequests
<
Grape
::
API
class
MergeRequests
<
Grape
::
API
before
{
authenticate!
}
before
{
authenticate!
}
before
{
Thread
.
current
[
:current_user
]
=
current_user
}
resource
:projects
do
resource
:projects
do
helpers
do
helpers
do
...
@@ -70,28 +69,30 @@ module API
...
@@ -70,28 +69,30 @@ module API
# POST /projects/:id/merge_requests
# POST /projects/:id/merge_requests
#
#
post
":id/merge_requests"
do
post
":id/merge_requests"
do
authorize!
:write_merge_request
,
user_project
set_current_user_for_thread
do
required_attributes!
[
:source_branch
,
:target_branch
,
:title
]
authorize!
:write_merge_request
,
user_project
attrs
=
attributes_for_keys
[
:source_branch
,
:target_branch
,
:assignee_id
,
:title
,
:target_project_id
]
required_attributes!
[
:source_branch
,
:target_branch
,
:title
]
merge_request
=
user_project
.
merge_requests
.
new
(
attrs
)
attrs
=
attributes_for_keys
[
:source_branch
,
:target_branch
,
:assignee_id
,
:title
,
:target_project_id
]
merge_request
.
author
=
current_user
merge_request
=
user_project
.
merge_requests
.
new
(
attrs
)
merge_request
.
source_project
=
user_project
merge_request
.
author
=
current_user
target_project_id
=
attrs
[
:target_project_id
]
merge_request
.
source_project
=
user_project
if
not_fork?
(
target_project_id
,
user_project
)
target_project_id
=
attrs
[
:target_project_id
]
merge_request
.
target_project
=
user_project
if
not_fork?
(
target_project_id
,
user_project
)
else
merge_request
.
target_project
=
user_project
if
target_matches_fork
(
target_project_id
,
user_project
)
merge_request
.
target_project
=
Project
.
find_by_id
(
attrs
[
:target_project_id
])
else
else
render_api_error!
(
'(Bad Request) Specified target project that is not the source project, or the source fork of the project.'
,
400
)
if
target_matches_fork
(
target_project_id
,
user_project
)
merge_request
.
target_project
=
Project
.
find_by_id
(
attrs
[
:target_project_id
])
else
render_api_error!
(
'(Bad Request) Specified target project that is not the source project, or the source fork of the project.'
,
400
)
end
end
end
end
if
merge_request
.
save
if
merge_request
.
save
merge_request
.
reload_code
merge_request
.
reload_code
present
merge_request
,
with:
Entities
::
MergeRequest
present
merge_request
,
with:
Entities
::
MergeRequest
else
else
handle_merge_request_errors!
merge_request
.
errors
handle_merge_request_errors!
merge_request
.
errors
end
end
end
end
end
...
@@ -109,17 +110,19 @@ module API
...
@@ -109,17 +110,19 @@ module API
# PUT /projects/:id/merge_request/:merge_request_id
# PUT /projects/:id/merge_request/:merge_request_id
#
#
put
":id/merge_request/:merge_request_id"
do
put
":id/merge_request/:merge_request_id"
do
attrs
=
attributes_for_keys
[
:source_branch
,
:target_branch
,
:assignee_id
,
:title
,
:state_event
]
set_current_user_for_thread
do
merge_request
=
user_project
.
merge_requests
.
find
(
params
[
:merge_request_id
])
attrs
=
attributes_for_keys
[
:source_branch
,
:target_branch
,
:assignee_id
,
:title
,
:state_event
]
merge_request
=
user_project
.
merge_requests
.
find
(
params
[
:merge_request_id
])
authorize!
:modify_merge_request
,
merge_request
authorize!
:modify_merge_request
,
merge_request
if
merge_request
.
update_attributes
attrs
if
merge_request
.
update_attributes
attrs
merge_request
.
reload_code
merge_request
.
reload_code
merge_request
.
mark_as_unchecked
merge_request
.
mark_as_unchecked
present
merge_request
,
with:
Entities
::
MergeRequest
present
merge_request
,
with:
Entities
::
MergeRequest
else
else
handle_merge_request_errors!
merge_request
.
errors
handle_merge_request_errors!
merge_request
.
errors
end
end
end
end
end
...
@@ -133,16 +136,18 @@ module API
...
@@ -133,16 +136,18 @@ module API
# POST /projects/:id/merge_request/:merge_request_id/comments
# POST /projects/:id/merge_request/:merge_request_id/comments
#
#
post
":id/merge_request/:merge_request_id/comments"
do
post
":id/merge_request/:merge_request_id/comments"
do
required_attributes!
[
:note
]
set_current_user_for_thread
do
required_attributes!
[
:note
]
merge_request
=
user_project
.
merge_requests
.
find
(
params
[
:merge_request_id
])
merge_request
=
user_project
.
merge_requests
.
find
(
params
[
:merge_request_id
])
note
=
merge_request
.
notes
.
new
(
note:
params
[
:note
],
project_id:
user_project
.
id
)
note
=
merge_request
.
notes
.
new
(
note:
params
[
:note
],
project_id:
user_project
.
id
)
note
.
author
=
current_user
note
.
author
=
current_user
if
note
.
save
if
note
.
save
present
note
,
with:
Entities
::
MRNote
present
note
,
with:
Entities
::
MRNote
else
else
not_found!
not_found!
end
end
end
end
end
...
...
lib/api/milestones.rb
View file @
03dba1fd
...
@@ -40,15 +40,17 @@ module API
...
@@ -40,15 +40,17 @@ module API
# Example Request:
# Example Request:
# POST /projects/:id/milestones
# POST /projects/:id/milestones
post
":id/milestones"
do
post
":id/milestones"
do
authorize!
:admin_milestone
,
user_project
set_current_user_for_thread
do
required_attributes!
[
:title
]
authorize!
:admin_milestone
,
user_project
required_attributes!
[
:title
]
attrs
=
attributes_for_keys
[
:title
,
:description
,
:due_date
]
attrs
=
attributes_for_keys
[
:title
,
:description
,
:due_date
]
@milestone
=
user_project
.
milestones
.
new
attrs
@milestone
=
user_project
.
milestones
.
new
attrs
if
@milestone
.
save
if
@milestone
.
save
present
@milestone
,
with:
Entities
::
Milestone
present
@milestone
,
with:
Entities
::
Milestone
else
else
not_found!
not_found!
end
end
end
end
end
...
@@ -64,14 +66,16 @@ module API
...
@@ -64,14 +66,16 @@ module API
# Example Request:
# Example Request:
# PUT /projects/:id/milestones/:milestone_id
# PUT /projects/:id/milestones/:milestone_id
put
":id/milestones/:milestone_id"
do
put
":id/milestones/:milestone_id"
do
authorize!
:admin_milestone
,
user_project
set_current_user_for_thread
do
authorize!
:admin_milestone
,
user_project
@milestone
=
user_project
.
milestones
.
find
(
params
[
:milestone_id
])
@milestone
=
user_project
.
milestones
.
find
(
params
[
:milestone_id
])
attrs
=
attributes_for_keys
[
:title
,
:description
,
:due_date
,
:state_event
]
attrs
=
attributes_for_keys
[
:title
,
:description
,
:due_date
,
:state_event
]
if
@milestone
.
update_attributes
attrs
if
@milestone
.
update_attributes
attrs
present
@milestone
,
with:
Entities
::
Milestone
present
@milestone
,
with:
Entities
::
Milestone
else
else
not_found!
not_found!
end
end
end
end
end
end
end
...
...
lib/api/notes.rb
View file @
03dba1fd
...
@@ -41,17 +41,19 @@ module API
...
@@ -41,17 +41,19 @@ module API
# Example Request:
# Example Request:
# POST /projects/:id/notes
# POST /projects/:id/notes
post
":id/notes"
do
post
":id/notes"
do
required_attributes!
[
:body
]
set_current_user_for_thread
do
required_attributes!
[
:body
]
@note
=
user_project
.
notes
.
new
(
note:
params
[
:body
])
@note
=
user_project
.
notes
.
new
(
note:
params
[
:body
])
@note
.
author
=
current_user
@note
.
author
=
current_user
if
@note
.
save
if
@note
.
save
present
@note
,
with:
Entities
::
Note
present
@note
,
with:
Entities
::
Note
else
else
# :note is exposed as :body, but :note is set on error
# :note is exposed as :body, but :note is set on error
bad_request!
(
:note
)
if
@note
.
errors
[
:note
].
any?
bad_request!
(
:note
)
if
@note
.
errors
[
:note
].
any?
not_found!
not_found!
end
end
end
end
end
...
@@ -97,17 +99,19 @@ module API
...
@@ -97,17 +99,19 @@ module API
# POST /projects/:id/issues/:noteable_id/notes
# POST /projects/:id/issues/:noteable_id/notes
# POST /projects/:id/snippets/:noteable_id/notes
# POST /projects/:id/snippets/:noteable_id/notes
post
":id/
#{
noteables_str
}
/:
#{
noteable_id_str
}
/notes"
do
post
":id/
#{
noteables_str
}
/:
#{
noteable_id_str
}
/notes"
do
required_attributes!
[
:body
]
set_current_user_for_thread
do
required_attributes!
[
:body
]
@noteable
=
user_project
.
send
(
:"
#{
noteables_str
}
"
).
find
(
params
[
:"
#{
noteable_id_str
}
"
])
@noteable
=
user_project
.
send
(
:"
#{
noteables_str
}
"
).
find
(
params
[
:"
#{
noteable_id_str
}
"
])
@note
=
@noteable
.
notes
.
new
(
note:
params
[
:body
])
@note
=
@noteable
.
notes
.
new
(
note:
params
[
:body
])
@note
.
author
=
current_user
@note
.
author
=
current_user
@note
.
project
=
user_project
@note
.
project
=
user_project
if
@note
.
save
if
@note
.
save
present
@note
,
with:
Entities
::
Note
present
@note
,
with:
Entities
::
Note
else
else
not_found!
not_found!
end
end
end
end
end
end
end
...
...
spec/models/project_spec.rb
View file @
03dba1fd
...
@@ -27,14 +27,8 @@
...
@@ -27,14 +27,8 @@
require
'spec_helper'
require
'spec_helper'
describe
Project
do
describe
Project
do
let
(
:user
)
{
create
(
:user
)
}
before
{
enable_observers
}
after
{
disable_observers
}
before
do
enable_observers
Thread
.
current
[
:current_user
]
=
user
end
after
{
disable_observers
}
describe
"Associations"
do
describe
"Associations"
do
it
{
should
belong_to
(
:group
)
}
it
{
should
belong_to
(
:group
)
}
...
...
spec/requests/api/issues_spec.rb
View file @
03dba1fd
...
@@ -100,4 +100,16 @@ describe API::API do
...
@@ -100,4 +100,16 @@ describe API::API do
response
.
status
.
should
==
405
response
.
status
.
should
==
405
end
end
end
end
describe
"PUT /projects/:id/issues/:issue_id to test observer on close"
do
before
{
enable_observers
}
after
{
disable_observers
}
it
"should create an activity event when an issue is closed"
do
Event
.
should_receive
(
:create
)
put
api
(
"/projects/
#{
project
.
id
}
/issues/
#{
issue
.
id
}
"
,
user
),
state_event:
"close"
end
end
end
end
spec/requests/api/milestones_spec.rb
View file @
03dba1fd
...
@@ -90,4 +90,16 @@ describe API::API do
...
@@ -90,4 +90,16 @@ describe API::API do
json_response
[
'state'
].
should
==
'closed'
json_response
[
'state'
].
should
==
'closed'
end
end
end
end
describe
"PUT /projects/:id/milestones/:milestone_id to test observer on close"
do
before
{
enable_observers
}
after
{
disable_observers
}
it
"should create an activity event when an milestone is closed"
do
Event
.
should_receive
(
:create
)
put
api
(
"/projects/
#{
project
.
id
}
/milestones/
#{
milestone
.
id
}
"
,
user
),
state_event:
'close'
end
end
end
end
spec/requests/api/notes_spec.rb
View file @
03dba1fd
...
@@ -176,4 +176,16 @@ describe API::API do
...
@@ -176,4 +176,16 @@ describe API::API do
end
end
end
end
end
end
describe
"POST /projects/:id/noteable/:noteable_id/notes to test observer on create"
do
before
{
enable_observers
}
after
{
disable_observers
}
it
"should create an activity event when an issue note is created"
do
Event
.
should_receive
(
:create
)
post
api
(
"/projects/
#{
project
.
id
}
/issues/
#{
issue
.
id
}
/notes"
,
user
),
body:
'hi!'
end
end
end
end
spec/support/test_env.rb
View file @
03dba1fd
...
@@ -84,6 +84,11 @@ module TestEnv
...
@@ -84,6 +84,11 @@ module TestEnv
Repository
.
any_instance
.
stub
(
Repository
.
any_instance
.
stub
(
size:
12.45
size:
12.45
)
)
ActivityObserver
.
any_instance
.
stub
(
current_user:
double
(
"current_user"
,
id:
1
)
)
end
end
def
clear_repo_dir
(
namespace
,
name
)
def
clear_repo_dir
(
namespace
,
name
)
...
...
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