mirror of
https://github.com/AuthMe/AuthMeReloaded.git
synced 2024-12-20 07:37:47 +01:00
#437 Add/change email should check if email is already used
- Untested/incomplete implementation
This commit is contained in:
parent
ace95f750a
commit
b0ba893827
@ -289,4 +289,9 @@ public class CacheDataSource implements DataSource {
|
||||
public List<PlayerAuth> getLoggedPlayers() {
|
||||
return new ArrayList<>(PlayerCache.getInstance().getCache().values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmailStored(String email) {
|
||||
return source.isEmailStored(email);
|
||||
}
|
||||
}
|
||||
|
@ -218,6 +218,8 @@ public interface DataSource {
|
||||
*/
|
||||
List<PlayerAuth> getLoggedPlayers();
|
||||
|
||||
boolean isEmailStored(String email);
|
||||
|
||||
enum DataSourceType {
|
||||
MYSQL,
|
||||
FILE,
|
||||
|
@ -52,13 +52,6 @@ public class FlatFile implements DataSource {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method isAuthAvailable.
|
||||
*
|
||||
* @param user String
|
||||
*
|
||||
* @return boolean * @see fr.xephi.authme.datasource.DataSource#isAuthAvailable(String)
|
||||
*/
|
||||
@Override
|
||||
public synchronized boolean isAuthAvailable(String user) {
|
||||
BufferedReader br = null;
|
||||
@ -97,13 +90,6 @@ public class FlatFile implements DataSource {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method saveAuth.
|
||||
*
|
||||
* @param auth PlayerAuth
|
||||
*
|
||||
* @return boolean * @see fr.xephi.authme.datasource.DataSource#saveAuth(PlayerAuth)
|
||||
*/
|
||||
@Override
|
||||
public synchronized boolean saveAuth(PlayerAuth auth) {
|
||||
if (isAuthAvailable(auth.getNickname())) {
|
||||
@ -127,13 +113,6 @@ public class FlatFile implements DataSource {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method updatePassword.
|
||||
*
|
||||
* @param auth PlayerAuth
|
||||
*
|
||||
* @return boolean * @see fr.xephi.authme.datasource.DataSource#updatePassword(PlayerAuth)
|
||||
*/
|
||||
@Override
|
||||
public synchronized boolean updatePassword(PlayerAuth auth) {
|
||||
return updatePassword(auth.getNickname(), auth.getPassword());
|
||||
@ -200,13 +179,6 @@ public class FlatFile implements DataSource {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method updateSession.
|
||||
*
|
||||
* @param auth PlayerAuth
|
||||
*
|
||||
* @return boolean * @see fr.xephi.authme.datasource.DataSource#updateSession(PlayerAuth)
|
||||
*/
|
||||
@Override
|
||||
public boolean updateSession(PlayerAuth auth) {
|
||||
if (!isAuthAvailable(auth.getNickname())) {
|
||||
@ -266,13 +238,6 @@ public class FlatFile implements DataSource {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method updateQuitLoc.
|
||||
*
|
||||
* @param auth PlayerAuth
|
||||
*
|
||||
* @return boolean * @see fr.xephi.authme.datasource.DataSource#updateQuitLoc(PlayerAuth)
|
||||
*/
|
||||
@Override
|
||||
public boolean updateQuitLoc(PlayerAuth auth) {
|
||||
if (!isAuthAvailable(auth.getNickname())) {
|
||||
@ -311,13 +276,6 @@ public class FlatFile implements DataSource {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getIps.
|
||||
*
|
||||
* @param ip String
|
||||
*
|
||||
* @return int * @see fr.xephi.authme.datasource.DataSource#getIps(String)
|
||||
*/
|
||||
@Override
|
||||
public int getIps(String ip) {
|
||||
BufferedReader br = null;
|
||||
@ -348,13 +306,6 @@ public class FlatFile implements DataSource {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method purgeDatabase.
|
||||
*
|
||||
* @param until long
|
||||
*
|
||||
* @return int * @see fr.xephi.authme.datasource.DataSource#purgeDatabase(long)
|
||||
*/
|
||||
@Override
|
||||
public int purgeDatabase(long until) {
|
||||
BufferedReader br = null;
|
||||
@ -401,13 +352,6 @@ public class FlatFile implements DataSource {
|
||||
return cleared;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method autoPurgeDatabase.
|
||||
*
|
||||
* @param until long
|
||||
*
|
||||
* @return List of String * @see fr.xephi.authme.datasource.DataSource#autoPurgeDatabase(long)
|
||||
*/
|
||||
@Override
|
||||
public List<String> autoPurgeDatabase(long until) {
|
||||
BufferedReader br = null;
|
||||
@ -454,13 +398,6 @@ public class FlatFile implements DataSource {
|
||||
return cleared;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method removeAuth.
|
||||
*
|
||||
* @param user String
|
||||
*
|
||||
* @return boolean * @see fr.xephi.authme.datasource.DataSource#removeAuth(String)
|
||||
*/
|
||||
@Override
|
||||
public synchronized boolean removeAuth(String user) {
|
||||
if (!isAuthAvailable(user)) {
|
||||
@ -505,13 +442,6 @@ public class FlatFile implements DataSource {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getAuth.
|
||||
*
|
||||
* @param user String
|
||||
*
|
||||
* @return PlayerAuth * @see fr.xephi.authme.datasource.DataSource#getAuth(String)
|
||||
*/
|
||||
@Override
|
||||
public synchronized PlayerAuth getAuth(String user) {
|
||||
BufferedReader br = null;
|
||||
@ -554,31 +484,14 @@ public class FlatFile implements DataSource {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method close.
|
||||
*
|
||||
* @see fr.xephi.authme.datasource.DataSource#close()
|
||||
*/
|
||||
@Override
|
||||
public synchronized void close() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method reload.
|
||||
*
|
||||
* @see fr.xephi.authme.datasource.DataSource#reload()
|
||||
*/
|
||||
@Override
|
||||
public void reload() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method updateEmail.
|
||||
*
|
||||
* @param auth PlayerAuth
|
||||
*
|
||||
* @return boolean * @see fr.xephi.authme.datasource.DataSource#updateEmail(PlayerAuth)
|
||||
*/
|
||||
@Override
|
||||
public boolean updateEmail(PlayerAuth auth) {
|
||||
if (!isAuthAvailable(auth.getNickname())) {
|
||||
@ -617,13 +530,6 @@ public class FlatFile implements DataSource {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getAllAuthsByName.
|
||||
*
|
||||
* @param auth PlayerAuth
|
||||
*
|
||||
* @return List of String * @see fr.xephi.authme.datasource.DataSource#getAllAuthsByName(PlayerAuth)
|
||||
*/
|
||||
@Override
|
||||
public List<String> getAllAuthsByName(PlayerAuth auth) {
|
||||
BufferedReader br = null;
|
||||
@ -654,13 +560,6 @@ public class FlatFile implements DataSource {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getAllAuthsByIp.
|
||||
*
|
||||
* @param ip String
|
||||
*
|
||||
* @return List of String * @see fr.xephi.authme.datasource.DataSource#getAllAuthsByIp(String)
|
||||
*/
|
||||
@Override
|
||||
public List<String> getAllAuthsByIp(String ip) {
|
||||
BufferedReader br = null;
|
||||
@ -691,13 +590,6 @@ public class FlatFile implements DataSource {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getAllAuthsByEmail.
|
||||
*
|
||||
* @param email String
|
||||
*
|
||||
* @return List of String * @see fr.xephi.authme.datasource.DataSource#getAllAuthsByEmail(String)
|
||||
*/
|
||||
@Override
|
||||
public List<String> getAllAuthsByEmail(String email) {
|
||||
BufferedReader br = null;
|
||||
@ -728,13 +620,6 @@ public class FlatFile implements DataSource {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method purgeBanned.
|
||||
*
|
||||
* @param banned List of String
|
||||
*
|
||||
* @see fr.xephi.authme.datasource.DataSource#purgeBanned(List)
|
||||
*/
|
||||
@Override
|
||||
public void purgeBanned(List<String> banned) {
|
||||
BufferedReader br = null;
|
||||
@ -776,64 +661,28 @@ public class FlatFile implements DataSource {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getType.
|
||||
*
|
||||
* @return DataSourceType * @see fr.xephi.authme.datasource.DataSource#getType()
|
||||
*/
|
||||
@Override
|
||||
public DataSourceType getType() {
|
||||
return DataSourceType.FILE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method isLogged.
|
||||
*
|
||||
* @param user String
|
||||
*
|
||||
* @return boolean * @see fr.xephi.authme.datasource.DataSource#isLogged(String)
|
||||
*/
|
||||
@Override
|
||||
public boolean isLogged(String user) {
|
||||
return PlayerCache.getInstance().isAuthenticated(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method setLogged.
|
||||
*
|
||||
* @param user String
|
||||
*
|
||||
* @see fr.xephi.authme.datasource.DataSource#setLogged(String)
|
||||
*/
|
||||
@Override
|
||||
public void setLogged(String user) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method setUnlogged.
|
||||
*
|
||||
* @param user String
|
||||
*
|
||||
* @see fr.xephi.authme.datasource.DataSource#setUnlogged(String)
|
||||
*/
|
||||
@Override
|
||||
public void setUnlogged(String user) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method purgeLogged.
|
||||
*
|
||||
* @see fr.xephi.authme.datasource.DataSource#purgeLogged()
|
||||
*/
|
||||
@Override
|
||||
public void purgeLogged() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getAccountsRegistered.
|
||||
*
|
||||
* @return int * @see fr.xephi.authme.datasource.DataSource#getAccountsRegistered()
|
||||
*/
|
||||
@Override
|
||||
public int getAccountsRegistered() {
|
||||
BufferedReader br = null;
|
||||
@ -857,14 +706,6 @@ public class FlatFile implements DataSource {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method updateName.
|
||||
*
|
||||
* @param oldOne String
|
||||
* @param newOne String
|
||||
*
|
||||
* @see fr.xephi.authme.datasource.DataSource#updateName(String, String)
|
||||
*/
|
||||
@Override
|
||||
public void updateName(String oldOne, String newOne) {
|
||||
PlayerAuth auth = this.getAuth(oldOne);
|
||||
@ -873,11 +714,6 @@ public class FlatFile implements DataSource {
|
||||
this.removeAuth(oldOne);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getAllAuths.
|
||||
*
|
||||
* @return List of PlayerAuth * @see fr.xephi.authme.datasource.DataSource#getAllAuths()
|
||||
*/
|
||||
@Override
|
||||
public List<PlayerAuth> getAllAuths() {
|
||||
BufferedReader br = null;
|
||||
@ -925,13 +761,13 @@ public class FlatFile implements DataSource {
|
||||
return auths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getLoggedPlayers.
|
||||
*
|
||||
* @return List of PlayerAuth * @see fr.xephi.authme.datasource.DataSource#getLoggedPlayers()
|
||||
*/
|
||||
@Override
|
||||
public List<PlayerAuth> getLoggedPlayers() {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmailStored(String email) {
|
||||
throw new UnsupportedOperationException("Flat file no longer supported");
|
||||
}
|
||||
}
|
||||
|
@ -971,9 +971,8 @@ public class MySQL implements DataSource {
|
||||
pst.close();
|
||||
rs.close();
|
||||
st.close();
|
||||
} catch (Exception ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
ConsoleLogger.writeStackTrace(ex);
|
||||
} catch (SQLException ex) {
|
||||
logSqlException(ex);
|
||||
}
|
||||
return auths;
|
||||
}
|
||||
@ -1015,11 +1014,29 @@ public class MySQL implements DataSource {
|
||||
}
|
||||
auths.add(pAuth);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
ConsoleLogger.writeStackTrace(ex);
|
||||
} catch (SQLException ex) {
|
||||
logSqlException(ex);
|
||||
}
|
||||
return auths;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isEmailStored(String email) {
|
||||
String sql = "SELECT 1 FROM " + tableName + " WHERE " + columnEmail + " = ?";
|
||||
try (Connection con = ds.getConnection()) {
|
||||
PreparedStatement pst = con.prepareStatement(sql);
|
||||
pst.setString(1, email);
|
||||
ResultSet rs = pst.executeQuery();
|
||||
return rs.next();
|
||||
} catch (SQLException e) {
|
||||
logSqlException(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void logSqlException(SQLException e) {
|
||||
ConsoleLogger.showError("Error executing SQL query: " + StringUtils.formatException(e));
|
||||
ConsoleLogger.writeStackTrace(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -684,6 +684,25 @@ public class SQLite implements DataSource {
|
||||
return auths;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isEmailStored(String email) {
|
||||
try {
|
||||
PreparedStatement ps = con.prepareStatement(
|
||||
"SELECT 1 FROM " + tableName + " WHERE LOWER(" + columnEmail + ") = LOWER(?)");
|
||||
ps.setString(1, email);
|
||||
ResultSet rs = ps.executeQuery();
|
||||
return rs.next();
|
||||
} catch (SQLException e) {
|
||||
logSqlException(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void logSqlException(SQLException e) {
|
||||
ConsoleLogger.showError("Error while executing SQL statement: " + StringUtils.formatException(e));
|
||||
ConsoleLogger.writeStackTrace(e);
|
||||
}
|
||||
|
||||
private PlayerAuth buildAuthFromResultSet(ResultSet row) throws SQLException {
|
||||
String salt = !columnSalt.isEmpty() ? row.getString(columnSalt) : null;
|
||||
|
||||
|
@ -121,7 +121,9 @@ public enum MessageKey {
|
||||
|
||||
ANTIBOT_AUTO_ENABLED_MESSAGE("antibot_auto_enabled"),
|
||||
|
||||
ANTIBOT_AUTO_DISABLED_MESSAGE("antibot_auto_disabled", "%m");
|
||||
ANTIBOT_AUTO_DISABLED_MESSAGE("antibot_auto_disabled", "%m"),
|
||||
|
||||
EMAIL_ALREADY_USED_ERROR("email_already_used");
|
||||
|
||||
|
||||
private String key;
|
||||
|
@ -36,10 +36,13 @@ public class AsyncAddEmail {
|
||||
PlayerAuth auth = playerCache.getAuth(playerName);
|
||||
String currentEmail = auth.getEmail();
|
||||
|
||||
if (currentEmail != null) {
|
||||
if (currentEmail != null && !"your@mail.com".equals(currentEmail)) {
|
||||
System.out.println("Email is currentEmail " + currentEmail); // FIXME remove
|
||||
messages.send(player, MessageKey.USAGE_CHANGE_EMAIL);
|
||||
} else if (isEmailInvalid(email)) {
|
||||
messages.send(player, MessageKey.INVALID_EMAIL);
|
||||
} else if (dataSource.isEmailStored(email)) {
|
||||
messages.send(player, MessageKey.EMAIL_ALREADY_USED_ERROR);
|
||||
} else {
|
||||
auth.setEmail(email);
|
||||
playerCache.updatePlayer(auth);
|
||||
|
@ -44,6 +44,8 @@ public class AsyncChangeEmail {
|
||||
m.send(player, MessageKey.INVALID_NEW_EMAIL);
|
||||
} else if (!oldEmail.equals(currentEmail)) {
|
||||
m.send(player, MessageKey.INVALID_OLD_EMAIL);
|
||||
} else if (dataSource.isEmailStored(newEmail)) {
|
||||
m.send(player, MessageKey.EMAIL_ALREADY_USED_ERROR);
|
||||
} else {
|
||||
saveNewEmail(auth);
|
||||
}
|
||||
|
@ -57,3 +57,4 @@ email_exists: '&cA recovery email was already sent! You can discard it and send
|
||||
country_banned: '&4Your country is banned from this server!'
|
||||
antibot_auto_enabled: '&4[AntiBotService] AntiBot enabled due to the huge number of connections!'
|
||||
antibot_auto_disabled: '&2[AntiBotService] AntiBot disabled disabled after %m minutes!'
|
||||
email_already_used: '&4The email address is already being used'
|
||||
|
@ -53,6 +53,7 @@ public class AsyncAddEmailTest {
|
||||
PlayerAuth auth = mock(PlayerAuth.class);
|
||||
given(auth.getEmail()).willReturn(null);
|
||||
given(playerCache.getAuth("tester")).willReturn(auth);
|
||||
given(dataSource.isEmailStored("my.mail@example.org")).willReturn(false);
|
||||
|
||||
// when
|
||||
process.process();
|
||||
@ -72,6 +73,7 @@ public class AsyncAddEmailTest {
|
||||
PlayerAuth auth = mock(PlayerAuth.class);
|
||||
given(auth.getEmail()).willReturn("another@mail.tld");
|
||||
given(playerCache.getAuth("my_player")).willReturn(auth);
|
||||
given(dataSource.isEmailStored("some.mail@example.org")).willReturn(false);
|
||||
|
||||
// when
|
||||
process.process();
|
||||
@ -90,6 +92,7 @@ public class AsyncAddEmailTest {
|
||||
PlayerAuth auth = mock(PlayerAuth.class);
|
||||
given(auth.getEmail()).willReturn(null);
|
||||
given(playerCache.getAuth("my_player")).willReturn(auth);
|
||||
given(dataSource.isEmailStored("invalid_mail")).willReturn(false);
|
||||
|
||||
// when
|
||||
process.process();
|
||||
@ -99,6 +102,25 @@ public class AsyncAddEmailTest {
|
||||
verify(playerCache, never()).updatePlayer(any(PlayerAuth.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotAddMailIfAlreadyUsed() {
|
||||
// given
|
||||
AsyncAddEmail process = createProcess("player@mail.tld");
|
||||
given(player.getName()).willReturn("TestName");
|
||||
given(playerCache.isAuthenticated("testname")).willReturn(true);
|
||||
PlayerAuth auth = mock(PlayerAuth.class);
|
||||
given(auth.getEmail()).willReturn(null);
|
||||
given(playerCache.getAuth("testname")).willReturn(auth);
|
||||
given(dataSource.isEmailStored("player@mail.tld")).willReturn(true);
|
||||
|
||||
// when
|
||||
process.process();
|
||||
|
||||
// then
|
||||
verify(messages).send(player, MessageKey.EMAIL_ALREADY_USED_ERROR);
|
||||
verify(playerCache, never()).updatePlayer(any(PlayerAuth.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldShowLoginMessage() {
|
||||
// given
|
||||
|
@ -136,6 +136,25 @@ public class AsyncChangeEmailTest {
|
||||
verify(messages).send(player, MessageKey.INVALID_OLD_EMAIL);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRejectAlreadyUsedEmail() {
|
||||
// given
|
||||
AsyncChangeEmail process = createProcess("old@example.com", "new@example.com");
|
||||
given(player.getName()).willReturn("Username");
|
||||
given(playerCache.isAuthenticated("username")).willReturn(true);
|
||||
PlayerAuth auth = authWithMail("old@example.com");
|
||||
given(playerCache.getAuth("username")).willReturn(auth);
|
||||
given(dataSource.isEmailStored("new@example.com")).willReturn(true);
|
||||
|
||||
// when
|
||||
process.process();
|
||||
|
||||
// then
|
||||
verify(dataSource, never()).updateEmail(any(PlayerAuth.class));
|
||||
verify(playerCache, never()).updatePlayer(any(PlayerAuth.class));
|
||||
verify(messages).send(player, MessageKey.EMAIL_ALREADY_USED_ERROR);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldSendLoginMessage() {
|
||||
// given
|
||||
|
Loading…
Reference in New Issue
Block a user