SECURITY: Ensure the invite JSON API matches the UX
Anonymous users could query the invite json and see counts and summaries which is not allowed in the UX of Discourse. This commit has those endpoints return a 403 unless the user is allowed to invite.
This commit is contained in:
parent
d953c908d2
commit
79ce7085c2
|
@ -274,6 +274,8 @@ class UsersController < ApplicationController
|
|||
end
|
||||
|
||||
def invited
|
||||
guardian.ensure_can_invite_to_forum!
|
||||
|
||||
inviter = fetch_user_from_params(include_inactive: current_user.try(:staff?) || (current_user && SiteSetting.show_inactive_accounts))
|
||||
offset = params[:offset].to_i || 0
|
||||
filter_by = params[:filter]
|
||||
|
@ -290,6 +292,8 @@ class UsersController < ApplicationController
|
|||
end
|
||||
|
||||
def invited_count
|
||||
guardian.ensure_can_invite_to_forum!
|
||||
|
||||
inviter = fetch_user_from_params(include_inactive: current_user.try(:staff?) || (current_user && SiteSetting.show_inactive_accounts))
|
||||
|
||||
pending_count = Invite.find_pending_invites_count(inviter)
|
||||
|
|
|
@ -1429,16 +1429,47 @@ describe UsersController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#invited' do
|
||||
it 'returns success' do
|
||||
describe "#invited_count" do
|
||||
it "fails for anonymous users" do
|
||||
user = Fabricate(:user)
|
||||
get "/u/#{user.username}/invited_count.json"
|
||||
expect(response.status).to eq(403)
|
||||
end
|
||||
|
||||
it "works for users who can see invites" do
|
||||
inviter = Fabricate(:user, trust_level: 2)
|
||||
sign_in(inviter)
|
||||
invitee = Fabricate(:user)
|
||||
invite = Fabricate(:invite, invited_by: inviter, user: invitee)
|
||||
get "/u/#{user.username}/invited_count.json"
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
json = JSON.parse(response.body)
|
||||
expect(json).to be_present
|
||||
expect(json['counts']).to be_present
|
||||
end
|
||||
end
|
||||
|
||||
describe '#invited' do
|
||||
it 'fails for anonymous users' do
|
||||
user = Fabricate(:user)
|
||||
get "/u/#{user.username}/invited.json", params: { username: user.username }
|
||||
|
||||
expect(response.status).to eq(403)
|
||||
end
|
||||
|
||||
it 'returns success' do
|
||||
user = Fabricate(:user, trust_level: 2)
|
||||
sign_in(user)
|
||||
get "/u/#{user.username}/invited.json", params: { username: user.username }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
end
|
||||
|
||||
it 'filters by email' do
|
||||
inviter = Fabricate(:user)
|
||||
inviter = Fabricate(:user, trust_level: 2)
|
||||
sign_in(inviter)
|
||||
|
||||
invitee = Fabricate(:user)
|
||||
Fabricate(
|
||||
:invite,
|
||||
|
@ -1454,6 +1485,7 @@ describe UsersController do
|
|||
)
|
||||
|
||||
get "/u/#{inviter.username}/invited.json", params: { search: 'billybob' }
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
invites = JSON.parse(response.body)['invites']
|
||||
expect(invites.size).to eq(1)
|
||||
|
@ -1461,7 +1493,9 @@ describe UsersController do
|
|||
end
|
||||
|
||||
it 'filters by username' do
|
||||
inviter = Fabricate(:user)
|
||||
inviter = Fabricate(:user, trust_level: 2)
|
||||
sign_in(inviter)
|
||||
|
||||
invitee = Fabricate(:user, username: 'billybob')
|
||||
_invite = Fabricate(
|
||||
:invite,
|
||||
|
@ -1476,6 +1510,7 @@ describe UsersController do
|
|||
)
|
||||
|
||||
get "/u/#{inviter.username}/invited.json", params: { search: 'billybob' }
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
invites = JSON.parse(response.body)['invites']
|
||||
expect(invites.size).to eq(1)
|
||||
|
@ -1489,19 +1524,19 @@ describe UsersController do
|
|||
Fabricate(:invite, invited_by: inviter)
|
||||
|
||||
get "/u/#{user.username}/invited/pending.json"
|
||||
|
||||
invites = JSON.parse(response.body)['invites']
|
||||
expect(invites).to be_empty
|
||||
expect(response.status).to eq(403)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with redeemed invites' do
|
||||
it 'returns invites' do
|
||||
inviter = Fabricate(:user)
|
||||
inviter = Fabricate(:user, trust_level: 2)
|
||||
sign_in(inviter)
|
||||
invitee = Fabricate(:user)
|
||||
invite = Fabricate(:invite, invited_by: inviter, user: invitee)
|
||||
|
||||
get "/u/#{inviter.username}/invited.json"
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
invites = JSON.parse(response.body)['invites']
|
||||
expect(invites.size).to eq(1)
|
||||
|
@ -1514,11 +1549,12 @@ describe UsersController do
|
|||
context 'with pending invites' do
|
||||
context 'with permission to see pending invites' do
|
||||
it 'returns invites' do
|
||||
inviter = Fabricate(:user)
|
||||
inviter = Fabricate(:user, trust_level: 2)
|
||||
invite = Fabricate(:invite, invited_by: inviter)
|
||||
sign_in(inviter)
|
||||
|
||||
get "/u/#{inviter.username}/invited/pending.json"
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
invites = JSON.parse(response.body)['invites']
|
||||
expect(invites.size).to eq(1)
|
||||
|
@ -1538,21 +1574,20 @@ describe UsersController do
|
|||
end
|
||||
|
||||
get "/u/#{inviter.username}/invited/pending.json"
|
||||
|
||||
json = JSON.parse(response.body)['invites']
|
||||
expect(json).to be_empty
|
||||
expect(response.status).to eq(403)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with redeemed invites' do
|
||||
it 'returns invites' do
|
||||
_user = sign_in(Fabricate(:user))
|
||||
sign_in(Fabricate(:user, trust_level: 2))
|
||||
inviter = Fabricate(:user)
|
||||
invitee = Fabricate(:user)
|
||||
invite = Fabricate(:invite, invited_by: inviter, user: invitee)
|
||||
|
||||
get "/u/#{inviter.username}/invited.json"
|
||||
expect(response.status).to eq(200)
|
||||
|
||||
invites = JSON.parse(response.body)['invites']
|
||||
expect(invites.size).to eq(1)
|
||||
|
|
Loading…
Reference in New Issue