Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Register
Sign in
Toggle navigation
Menu
Open sidebar
Tiger Ton
mastodon
Commits
bf0942a0
Commit
bf0942a0
authored
5 years ago
by
Eugen Rochko
Browse files
Options
Download
Email Patches
Plain Diff
Fix leak of arbitrary statuses through unfavourite action in REST API (#13161)
parent
c4118ba7
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb
+1
-2
...lers/api/v1/statuses/favourited_by_accounts_controller.rb
app/controllers/api/v1/statuses/favourites_controller.rb
+9
-17
app/controllers/api/v1/statuses/favourites_controller.rb
app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb
+1
-2
...llers/api/v1/statuses/reblogged_by_accounts_controller.rb
app/controllers/api/v1/statuses/reblogs_controller.rb
+14
-13
app/controllers/api/v1/statuses/reblogs_controller.rb
spec/controllers/api/v1/statuses/favourites_controller_spec.rb
+59
-27
...controllers/api/v1/statuses/favourites_controller_spec.rb
spec/controllers/api/v1/statuses/reblogs_controller_spec.rb
+59
-27
spec/controllers/api/v1/statuses/reblogs_controller_spec.rb
with
143 additions
and
88 deletions
+143
-88
app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb
+
1
-
2
View file @
bf0942a0
...
...
@@ -67,8 +67,7 @@ class Api::V1::Statuses::FavouritedByAccountsController < Api::BaseController
@status
=
Status
.
find
(
params
[
:status_id
])
authorize
@status
,
:show?
rescue
Mastodon
::
NotPermittedError
# Reraise in order to get a 404 instead of a 403 error code
raise
ActiveRecord
::
RecordNotFound
not_found
end
def
pagination_params
(
core_params
)
...
...
This diff is collapsed.
Click to expand it.
app/controllers/api/v1/statuses/favourites_controller.rb
+
9
-
17
View file @
bf0942a0
...
...
@@ -5,34 +5,26 @@ class Api::V1::Statuses::FavouritesController < Api::BaseController
before_action
->
{
doorkeeper_authorize!
:write
,
:'write:favourites'
}
before_action
:require_user!
before_action
:set_status
respond_to
:json
def
create
@status
=
favourited_
status
FavouriteService
.
new
.
call
(
current_account
,
@
status
)
render
json:
@status
,
serializer:
REST
::
StatusSerializer
end
def
destroy
@status
=
requested_status
@favourites_map
=
{
@status
.
id
=>
false
}
UnfavouriteWorker
.
perform_async
(
current_user
.
account_id
,
@status
.
id
)
render
json:
@status
,
serializer:
REST
::
StatusSerializer
,
relationships:
StatusRelationshipsPresenter
.
new
([
@status
],
current_user
&
.
account_id
,
favourites_map:
@favourites_map
)
UnfavouriteWorker
.
perform_async
(
current_account
.
id
,
@status
.
id
)
render
json:
@status
,
serializer:
REST
::
StatusSerializer
,
relationships:
StatusRelationshipsPresenter
.
new
([
@status
],
current_account
.
id
,
favourites_map:
{
@status
.
id
=>
false
})
end
private
def
favourited_status
service_result
.
status
.
reload
end
def
service_result
FavouriteService
.
new
.
call
(
current_user
.
account
,
requested_status
)
end
def
requested_status
Status
.
find
(
params
[
:status_id
])
def
set_status
@status
=
Status
.
find
(
params
[
:status_id
])
authorize
@status
,
:show?
rescue
Mastodon
::
NotPermittedError
not_found
end
end
This diff is collapsed.
Click to expand it.
app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb
+
1
-
2
View file @
bf0942a0
...
...
@@ -64,8 +64,7 @@ class Api::V1::Statuses::RebloggedByAccountsController < Api::BaseController
@status
=
Status
.
find
(
params
[
:status_id
])
authorize
@status
,
:show?
rescue
Mastodon
::
NotPermittedError
# Reraise in order to get a 404 instead of a 403 error code
raise
ActiveRecord
::
RecordNotFound
not_found
end
def
pagination_params
(
core_params
)
...
...
This diff is collapsed.
Click to expand it.
app/controllers/api/v1/statuses/reblogs_controller.rb
+
14
-
13
View file @
bf0942a0
...
...
@@ -5,33 +5,34 @@ class Api::V1::Statuses::ReblogsController < Api::BaseController
before_action
->
{
doorkeeper_authorize!
:write
,
:'write:statuses'
}
before_action
:require_user!
before_action
:set_reblog
respond_to
:json
def
create
@status
=
ReblogService
.
new
.
call
(
current_
user
.
account
,
status_for_
reblog
,
reblog_params
)
@status
=
ReblogService
.
new
.
call
(
current_account
,
@
reblog
,
reblog_params
)
render
json:
@status
,
serializer:
REST
::
StatusSerializer
end
def
destroy
@status
=
status_for_destroy
.
reblog
@reblogs_map
=
{
@status
.
id
=>
false
}
@status
=
current_account
.
statuses
.
find_by
(
reblog_of_id:
@reblog
.
id
)
authorize
status_for_destroy
,
:unreblog?
status_for_destroy
.
discard
RemovalWorker
.
perform_async
(
status_for_destroy
.
id
)
if
@status
authorize
@status
,
:unreblog?
@status
.
discard
RemovalWorker
.
perform_async
(
@status
.
id
)
end
render
json:
@
status
,
serializer:
REST
::
StatusSerializer
,
relationships:
StatusRelationshipsPresenter
.
new
([
@status
],
current_
user
&
.
account
_
id
,
reblogs_map:
@reblog
s_map
)
render
json:
@
reblog
,
serializer:
REST
::
StatusSerializer
,
relationships:
StatusRelationshipsPresenter
.
new
([
@status
],
current_account
.
id
,
reblogs_map:
{
@reblog
.
id
=>
false
}
)
end
private
def
status_for_reblog
Status
.
find
params
[
:status_id
]
end
def
status_for_destroy
@status_for_destroy
||=
current_user
.
account
.
statuses
.
where
(
reblog_of_id:
params
[
:status_id
]).
first!
def
set_reblog
@reblog
=
Status
.
find
(
params
[
:status_id
])
authorize
@reblog
,
:show?
rescue
Mastodon
::
NotPermittedError
not_found
end
def
reblog_params
...
...
This diff is collapsed.
Click to expand it.
spec/controllers/api/v1/statuses/favourites_controller_spec.rb
+
59
-
27
View file @
bf0942a0
...
...
@@ -21,45 +21,77 @@ describe Api::V1::Statuses::FavouritesController do
post
:create
,
params:
{
status_id:
status
.
id
}
end
it
'returns http success'
do
expect
(
response
).
to
have_http_status
(
200
)
context
'with public status'
do
it
'returns http success'
do
expect
(
response
).
to
have_http_status
(
200
)
end
it
'updates the favourites count'
do
expect
(
status
.
favourites
.
count
).
to
eq
1
end
it
'updates the favourited attribute'
do
expect
(
user
.
account
.
favourited?
(
status
)).
to
be
true
end
it
'returns json with updated attributes'
do
hash_body
=
body_as_json
expect
(
hash_body
[
:id
]).
to
eq
status
.
id
.
to_s
expect
(
hash_body
[
:favourites_count
]).
to
eq
1
expect
(
hash_body
[
:favourited
]).
to
be
true
end
end
it
'updates the favourites count'
do
expect
(
status
.
favourites
.
count
).
to
eq
1
end
it
'updates the favourited attribute'
do
expect
(
user
.
account
.
favourited?
(
status
)).
to
be
true
end
it
'return json with updated attributes'
do
hash_body
=
body_as_json
context
'with private status of not-followed account'
do
let
(
:status
)
{
Fabricate
(
:status
,
visibility: :private
)
}
expect
(
hash_body
[
:id
]).
to
eq
status
.
id
.
to_s
expect
(
hash_body
[
:favourites_count
]).
to
eq
1
e
xpect
(
hash_body
[
:favourited
]).
to
be
true
it
'returns http not found'
do
expect
(
response
).
to
have_http_status
(
404
)
e
nd
end
end
describe
'POST #destroy'
do
let
(
:status
)
{
Fabricate
(
:status
,
account:
user
.
account
)
}
context
'with public status'
do
let
(
:status
)
{
Fabricate
(
:status
,
account:
user
.
account
)
}
before
do
FavouriteService
.
new
.
call
(
user
.
account
,
status
)
post
:destroy
,
params:
{
status_id:
status
.
id
}
end
before
do
FavouriteService
.
new
.
call
(
user
.
account
,
status
)
post
:destroy
,
params:
{
status_id:
status
.
id
}
end
it
'returns http success'
do
expect
(
response
).
to
have_http_status
(
200
)
end
it
'returns http success'
do
expect
(
response
).
to
have_http_status
(
200
)
end
it
'updates the favourites count'
do
expect
(
status
.
favourites
.
count
).
to
eq
0
end
it
'updates the favourited attribute'
do
expect
(
user
.
account
.
favourited?
(
status
)).
to
be
false
end
it
'updates the favourites count'
do
expect
(
status
.
favourites
.
count
).
to
eq
0
it
'returns json with updated attributes'
do
hash_body
=
body_as_json
expect
(
hash_body
[
:id
]).
to
eq
status
.
id
.
to_s
expect
(
hash_body
[
:favourites_count
]).
to
eq
0
expect
(
hash_body
[
:favourited
]).
to
be
false
end
end
it
'updates the favourited attribute'
do
expect
(
user
.
account
.
favourited?
(
status
)).
to
be
false
context
'with private status that was not favourited'
do
let
(
:status
)
{
Fabricate
(
:status
,
visibility: :private
)
}
before
do
post
:destroy
,
params:
{
status_id:
status
.
id
}
end
it
'returns http not found'
do
expect
(
response
).
to
have_http_status
(
404
)
end
end
end
end
...
...
This diff is collapsed.
Click to expand it.
spec/controllers/api/v1/statuses/reblogs_controller_spec.rb
+
59
-
27
View file @
bf0942a0
...
...
@@ -21,45 +21,77 @@ describe Api::V1::Statuses::ReblogsController do
post
:create
,
params:
{
status_id:
status
.
id
}
end
it
'returns http success'
do
expect
(
response
).
to
have_http_status
(
200
)
context
'with public status'
do
it
'returns http success'
do
expect
(
response
).
to
have_http_status
(
200
)
end
it
'updates the reblogs count'
do
expect
(
status
.
reblogs
.
count
).
to
eq
1
end
it
'updates the reblogged attribute'
do
expect
(
user
.
account
.
reblogged?
(
status
)).
to
be
true
end
it
'returns json with updated attributes'
do
hash_body
=
body_as_json
expect
(
hash_body
[
:reblog
][
:id
]).
to
eq
status
.
id
.
to_s
expect
(
hash_body
[
:reblog
][
:reblogs_count
]).
to
eq
1
expect
(
hash_body
[
:reblog
][
:reblogged
]).
to
be
true
end
end
it
'updates the reblogs count'
do
expect
(
status
.
reblogs
.
count
).
to
eq
1
end
it
'updates the reblogged attribute'
do
expect
(
user
.
account
.
reblogged?
(
status
)).
to
be
true
end
it
'return json with updated attributes'
do
hash_body
=
body_as_json
context
'with private status of not-followed account'
do
let
(
:status
)
{
Fabricate
(
:status
,
visibility: :private
)
}
expect
(
hash_body
[
:reblog
][
:id
]).
to
eq
status
.
id
.
to_s
expect
(
hash_body
[
:reblog
][
:reblogs_count
]).
to
eq
1
e
xpect
(
hash_body
[
:reblog
][
:reblogged
]).
to
be
true
it
'returns http not found'
do
expect
(
response
).
to
have_http_status
(
404
)
e
nd
end
end
describe
'POST #destroy'
do
let
(
:status
)
{
Fabricate
(
:status
,
account:
user
.
account
)
}
context
'with public status'
do
let
(
:status
)
{
Fabricate
(
:status
,
account:
user
.
account
)
}
before
do
ReblogService
.
new
.
call
(
user
.
account
,
status
)
post
:destroy
,
params:
{
status_id:
status
.
id
}
end
before
do
ReblogService
.
new
.
call
(
user
.
account
,
status
)
post
:destroy
,
params:
{
status_id:
status
.
id
}
end
it
'returns http success'
do
expect
(
response
).
to
have_http_status
(
200
)
end
it
'returns http success'
do
expect
(
response
).
to
have_http_status
(
200
)
end
it
'updates the reblogs count'
do
expect
(
status
.
reblogs
.
count
).
to
eq
0
end
it
'updates the reblogged attribute'
do
expect
(
user
.
account
.
reblogged?
(
status
)).
to
be
false
end
it
'updates the reblogs count'
do
expect
(
status
.
reblogs
.
count
).
to
eq
0
it
'returns json with updated attributes'
do
hash_body
=
body_as_json
expect
(
hash_body
[
:id
]).
to
eq
status
.
id
.
to_s
expect
(
hash_body
[
:reblogs_count
]).
to
eq
0
expect
(
hash_body
[
:reblogged
]).
to
be
false
end
end
it
'updates the reblogged attribute'
do
expect
(
user
.
account
.
reblogged?
(
status
)).
to
be
false
context
'with private status that was not reblogged'
do
let
(
:status
)
{
Fabricate
(
:status
,
visibility: :private
)
}
before
do
post
:destroy
,
params:
{
status_id:
status
.
id
}
end
it
'returns http not found'
do
expect
(
response
).
to
have_http_status
(
404
)
end
end
end
end
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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