FIX: delete duplicate invites earlier in the process

There was a race condition when 2 invites existed for 1 user where in some
cases data from both invites would be used for the redeem. Depending on DB
ordering.

Fix is to delete duplicate invites earlier in the process prior to
`redeem_from_email` being called.
This commit is contained in:
Sam Saffron 2019-05-13 17:42:13 +10:00
parent 427cf295d9
commit d643294c9d
3 changed files with 11 additions and 4 deletions

View File

@ -56,7 +56,9 @@ class Invite < ActiveRecord::Base
end
def redeem(username: nil, name: nil, password: nil, user_custom_fields: nil, ip_address: nil)
InviteRedeemer.new(self, username, name, password, user_custom_fields, ip_address).redeem unless expired? || destroyed? || !link_valid?
if !expired? && !destroyed? && link_valid?
InviteRedeemer.new(self, username, name, password, user_custom_fields, ip_address).redeem
end
end
def self.invite_by_email(email, invited_by, topic = nil, group_ids = nil, custom_message = nil)

View File

@ -80,7 +80,6 @@ InviteRedeemer = Struct.new(:invite, :username, :name, :password, :user_custom_f
add_user_to_groups
send_welcome_message
notify_invitee
delete_duplicate_invites
end
def invite_was_redeemed?
@ -89,9 +88,15 @@ InviteRedeemer = Struct.new(:invite, :username, :name, :password, :user_custom_f
end
def mark_invite_redeemed
Invite.where('id = ? AND redeemed_at IS NULL AND created_at >= ?',
count = Invite.where('id = ? AND redeemed_at IS NULL AND created_at >= ?',
invite.id, SiteSetting.invite_expiry_days.days.ago)
.update_all('redeemed_at = CURRENT_TIMESTAMP')
if count == 1
delete_duplicate_invites
end
count
end
def get_invited_user

View File

@ -206,7 +206,7 @@ describe Invite do
end
it 'wont redeem an expired invite' do
SiteSetting.expects(:invite_expiry_days).returns(10)
SiteSetting.invite_expiry_days = 10
invite.update_column(:created_at, 20.days.ago)
expect(invite.redeem).to be_blank
end