#442 Fix email presence check being case-insensitive

- Add integration tests
- Change DataSource interface to return the number of accounts only, since that's all we require
This commit is contained in:
ljacqu 2016-02-21 21:38:29 +01:00
parent 203e954eea
commit e8f518711c
7 changed files with 61 additions and 38 deletions

View File

@ -160,8 +160,8 @@ public class CacheDataSource implements DataSource {
}
@Override
public synchronized List<String> getAllAuthsByEmail(final String email) {
return source.getAllAuthsByEmail(email);
public synchronized int countAuthsByEmail(final String email) {
return source.countAuthsByEmail(email);
}
@Override

View File

@ -101,12 +101,12 @@ public interface DataSource {
List<String> getAllAuthsByIp(String ip);
/**
* Return all usernames associated with the given email address.
* Return the number of accounts associated with the given email address.
*
* @param email The email address to look up
* @return Users using the given email address
* @return Number of accounts using the given email address
*/
List<String> getAllAuthsByEmail(String email);
int countAuthsByEmail(String email);
/**
* Update the email of the PlayerAuth in the data source.

View File

@ -487,25 +487,21 @@ public class FlatFile implements DataSource {
}
@Override
public List<String> getAllAuthsByEmail(String email) {
public int countAuthsByEmail(String email) {
BufferedReader br = null;
List<String> countEmail = new ArrayList<>();
int countEmail = 0;
try {
br = new BufferedReader(new FileReader(source));
String line;
while ((line = br.readLine()) != null) {
String[] args = line.split(":");
if (args.length > 8 && args[8].equals(email)) {
countEmail.add(args[0]);
++countEmail;
}
}
return countEmail;
} catch (FileNotFoundException ex) {
ConsoleLogger.showError(ex.getMessage());
return new ArrayList<>();
} catch (IOException ex) {
ConsoleLogger.showError(ex.getMessage());
return new ArrayList<>();
} finally {
if (br != null) {
try {
@ -514,6 +510,7 @@ public class FlatFile implements DataSource {
}
}
}
return 0;
}
@Override

View File

@ -706,20 +706,19 @@ public class MySQL implements DataSource {
}
@Override
public synchronized List<String> getAllAuthsByEmail(String email) {
List<String> emails = new ArrayList<>();
String sql = "SELECT " + col.NAME + " FROM " + tableName + " WHERE " + col.EMAIL + "=?;";
public synchronized int countAuthsByEmail(String email) {
String sql = "SELECT COUNT(1) FROM " + tableName + " WHERE UPPER(" + col.EMAIL + ") = UPPER(?)";
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
pst.setString(1, email);
try (ResultSet rs = pst.executeQuery()) {
while (rs.next()) {
emails.add(rs.getString(col.NAME));
if (rs.next()) {
return rs.getInt(1);
}
}
} catch (SQLException ex) {
logSqlException(ex);
}
return emails;
return 0;
}
@Override
@ -907,12 +906,12 @@ public class MySQL implements DataSource {
@Override
public synchronized boolean isEmailStored(String email) {
String sql = "SELECT 1 FROM " + tableName + " WHERE " + col.EMAIL + " = ?";
try (Connection con = ds.getConnection()) {
PreparedStatement pst = con.prepareStatement(sql);
String sql = "SELECT 1 FROM " + tableName + " WHERE UPPER(" + col.EMAIL + ") = UPPER(?)";
try (Connection con = ds.getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
pst.setString(1, email);
ResultSet rs = pst.executeQuery();
return rs.next();
try (ResultSet rs = pst.executeQuery()) {
return rs.next();
}
} catch (SQLException e) {
logSqlException(e);
}

View File

@ -410,25 +410,19 @@ public class SQLite implements DataSource {
}
@Override
public List<String> getAllAuthsByEmail(String email) {
PreparedStatement pst = null;
ResultSet rs = null;
List<String> countEmail = new ArrayList<>();
try {
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE " + col.EMAIL + "=?;");
public int countAuthsByEmail(String email) {
String sql = "SELECT COUNT(1) FROM " + tableName + " WHERE " + col.EMAIL + " = ? COLLATE NOCASE;";
try (PreparedStatement pst = con.prepareStatement(sql)) {
pst.setString(1, email);
rs = pst.executeQuery();
while (rs.next()) {
countEmail.add(rs.getString(col.NAME));
try (ResultSet rs = pst.executeQuery()) {
if (rs.next()) {
return rs.getInt(1);
}
}
return countEmail;
} catch (SQLException ex) {
logSqlException(ex);
} finally {
close(rs);
close(pst);
}
return new ArrayList<>();
return 0;
}
@Override

View File

@ -98,7 +98,7 @@ public class AsyncRegister {
private void emailRegister() {
if (Settings.getmaxRegPerEmail > 0
&& !plugin.getPermissionsManager().hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)
&& database.getAllAuthsByEmail(email).size() >= Settings.getmaxRegPerEmail) {
&& database.countAuthsByEmail(email) >= Settings.getmaxRegPerEmail) {
m.send(player, MessageKey.MAX_REGISTER_EXCEEDED);
return;
}

View File

@ -138,6 +138,39 @@ public class SQLiteIntegrationTest {
assertThat(userAuth.getPassword(), equalToHash("b28c32f624a4eb161d6adc9acb5bfc5b", "f750ba32"));
}
@Test
public void shouldFindIfEmailExists() {
// given
DataSource dataSource = new SQLite(settings, con, false);
// when
boolean isUserMailPresent = dataSource.isEmailStored("user@example.org");
boolean isUserMailPresentCaseInsensitive = dataSource.isEmailStored("user@example.ORG");
boolean isInvalidMailPresent = dataSource.isEmailStored("not-in-database@example.com");
// then
assertThat(isUserMailPresent, equalTo(true));
assertThat(isUserMailPresentCaseInsensitive, equalTo(true));
assertThat(isInvalidMailPresent, equalTo(false));
}
@Test
public void shouldCountAuthsByEmail() {
// given
DataSource dataSource = new SQLite(settings, con, false);
// when
int userMailCount = dataSource.countAuthsByEmail("user@example.ORG");
int invalidMailCount = dataSource.countAuthsByEmail("not.in.db@example.com");
dataSource.saveAuth(PlayerAuth.builder().name("Test").email("user@EXAMPLE.org").build());
int newUserCount = dataSource.countAuthsByEmail("user@Example.org");
// then
assertThat(userMailCount, equalTo(1));
assertThat(invalidMailCount, equalTo(0));
assertThat(newUserCount, equalTo(2));
}
private static <T> void set(Property<T> property, T value) {
when(settings.getProperty(property)).thenReturn(value);
}