More fix: two validation records would collide if generated at the
same millisecond. Use a persistent random, and include the userId and a bit of the timestamp to make a secret that cannot collide with another user's secret.
This commit is contained in:
@@ -21,7 +21,6 @@ import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
@@ -952,11 +951,7 @@ public class OOOUserRepository extends UserRepository
|
||||
update("delete from penders where userId = '" + userId + "'");
|
||||
|
||||
// create a new one and insert it into the database
|
||||
ValidateRecord rec = new ValidateRecord();
|
||||
rec.secret = Long.toString(Math.abs((new Random()).nextLong()), 16);
|
||||
rec.userId = userId;
|
||||
rec.persist = persist;
|
||||
rec.inserted = new Date(System.currentTimeMillis());
|
||||
ValidateRecord rec = ValidateRecord.create(userId, persist);
|
||||
insert(_vtable, rec);
|
||||
return rec;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
package com.threerings.user;
|
||||
|
||||
import java.sql.Date;
|
||||
import java.util.Random;
|
||||
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
/**
|
||||
* Maintains information on users that have not yet validated their
|
||||
@@ -18,4 +21,28 @@ public class ValidateRecord
|
||||
public boolean persist;
|
||||
|
||||
public Date inserted;
|
||||
|
||||
/**
|
||||
* Create a new ValidateRecord for the specified userId.
|
||||
*/
|
||||
public static ValidateRecord create (int userId, boolean persist)
|
||||
{
|
||||
ValidateRecord rec = new ValidateRecord();
|
||||
rec.userId = userId;
|
||||
rec.persist = persist;
|
||||
long now = System.currentTimeMillis();
|
||||
long secret;
|
||||
do {
|
||||
secret = rand.nextLong();
|
||||
} while (secret == Long.MIN_VALUE); // MIN_VALUE doesn't "abs" nicely
|
||||
// guarantee that secret cannot collide with another user by prepending the userId
|
||||
rec.secret = Integer.toString(userId, 16) +
|
||||
StringUtil.prepad(Integer.toString((int) (now & 0xFFFF), 16), 4, '0') +
|
||||
StringUtil.prepad(Long.toString(Math.abs(secret), 16), 16, '0');
|
||||
rec.inserted = new Date(now);
|
||||
return rec;
|
||||
}
|
||||
|
||||
/** Generates random numbers for validate records. */
|
||||
protected static final Random rand = new Random();
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
@@ -937,11 +936,7 @@ public class DepotUserRepository extends DepotRepository
|
||||
deleteAll(ValidateDepotRecord.class, new Where(ValidateDepotRecord.USER_ID.eq(userId)));
|
||||
|
||||
// create a new one and insert it into the database
|
||||
ValidateRecord rec = new ValidateRecord();
|
||||
rec.secret = Long.toString(Math.abs((new Random()).nextLong()), 16);
|
||||
rec.userId = userId;
|
||||
rec.persist = persist;
|
||||
rec.inserted = new Date(System.currentTimeMillis());
|
||||
ValidateRecord rec = ValidateRecord.create(userId, persist);
|
||||
insert(ValidateDepotRecord.fromValidateRecord(rec));
|
||||
return rec;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user