mirror of
https://github.com/discourse/discourse.git
synced 2024-11-26 02:40:53 -06:00
SECURITY: Handle concurrent invite accepts
Raise an error on concurrent invite accept attempts.
This commit is contained in:
parent
bfc3132bb2
commit
62a609ea2d
@ -278,7 +278,10 @@ class InvitesController < ApplicationController
|
||||
end
|
||||
|
||||
user = invite.redeem(**attrs)
|
||||
rescue ActiveRecord::RecordInvalid, ActiveRecord::RecordNotSaved, Invite::UserExists => e
|
||||
rescue ActiveRecord::RecordInvalid,
|
||||
ActiveRecord::RecordNotSaved,
|
||||
ActiveRecord::LockWaitTimeout,
|
||||
Invite::UserExists => e
|
||||
return render json: failed_json.merge(message: e.message), status: 412
|
||||
end
|
||||
|
||||
|
@ -243,7 +243,10 @@ class InviteRedeemer
|
||||
@invited_user_record = InvitedUser.create!(invite_id: invite.id, redeemed_at: Time.zone.now)
|
||||
|
||||
if @invited_user_record.present?
|
||||
Invite.increment_counter(:redemption_count, invite.id)
|
||||
invite.with_lock("FOR UPDATE NOWAIT") do
|
||||
Invite.increment_counter(:redemption_count, invite.id)
|
||||
invite.save!
|
||||
end
|
||||
delete_duplicate_invites
|
||||
end
|
||||
|
||||
|
@ -984,6 +984,27 @@ RSpec.describe InvitesController do
|
||||
Fabricate(:invite, email: nil, emailed_status: Invite.emailed_status_types[:not_required])
|
||||
end
|
||||
|
||||
it "does not create multiple users for a single use invite" do
|
||||
user_count = User.count
|
||||
|
||||
2
|
||||
.times
|
||||
.map do
|
||||
Thread.new do
|
||||
put "/invites/show/#{invite.invite_key}.json",
|
||||
params: {
|
||||
email: "test@example.com",
|
||||
password: "verystrongpassword",
|
||||
}
|
||||
end
|
||||
end
|
||||
.each(&:join)
|
||||
|
||||
expect(invite.reload.max_redemptions_allowed).to eq(1)
|
||||
expect(invite.reload.redemption_count).to eq(1)
|
||||
expect(User.count).to eq(user_count + 1)
|
||||
end
|
||||
|
||||
it "sends an activation email and does not activate the user" do
|
||||
expect {
|
||||
put "/invites/show/#{invite.invite_key}.json",
|
||||
|
Loading…
Reference in New Issue
Block a user