package games.strategy.engine.lobby.server.userDB; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.util.Date; import java.util.logging.Level; import java.util.logging.Logger; import games.strategy.util.Tuple; /** * Utilitiy class to create/read/delete banned usernames (there is no update). */ public class BannedUsernameController { private static final Logger s_logger = Logger.getLogger(BannedUsernameController.class.getName()); /** * Ban the username permanently. */ public void addBannedUsername(final String username) { addBannedUsername(username, null); } /** * Ban the given username. If banTill is not null, the ban will expire when banTill is reached. * * <p> * If this username is already banned, this call will update the ban_end. * </p> */ public void addBannedUsername(final String username, final Date banTill) { if (isUsernameBanned(username).getFirst()) { removeBannedUsername(username); } Timestamp banTillTs = null; if (banTill != null) { banTillTs = new Timestamp(banTill.getTime()); } s_logger.fine("Banning username:" + username); final Connection con = Database.getConnection(); try { final PreparedStatement ps = con.prepareStatement("insert into banned_usernames (username, ban_till) values (?, ?)"); ps.setString(1, username); ps.setTimestamp(2, banTillTs); ps.execute(); ps.close(); con.commit(); } catch (final SQLException sqle) { if (sqle.getErrorCode() == 30000) { // this is ok // the username is banned as expected s_logger.info("Tried to create duplicate banned username:" + username + " error:" + sqle.getMessage()); return; } s_logger.log(Level.SEVERE, "Error inserting banned username:" + username, sqle); throw new IllegalStateException(sqle.getMessage()); } finally { DbUtil.closeConnection(con); } } public void removeBannedUsername(final String username) { s_logger.fine("Removing banned username:" + username); final Connection con = Database.getConnection(); try { final PreparedStatement ps = con.prepareStatement("delete from banned_usernames where username = ?"); ps.setString(1, username); ps.execute(); ps.close(); con.commit(); } catch (final SQLException sqle) { s_logger.log(Level.SEVERE, "Error deleting banned username:" + username, sqle); throw new IllegalStateException(sqle.getMessage()); } finally { DbUtil.closeConnection(con); } } /** * Is the given username banned? This may have the side effect of removing from the * database any username's whose ban has expired. */ public Tuple<Boolean, Timestamp> isUsernameBanned(final String username) { boolean found = false; boolean expired = false; Timestamp banTill = null; final String sql = "select username, ban_till from banned_usernames where username = ?"; final Connection con = Database.getConnection(); try { final PreparedStatement ps = con.prepareStatement(sql); ps.setString(1, username); final ResultSet rs = ps.executeQuery(); found = rs.next(); // If the ban has expired, allow the username if (found) { banTill = rs.getTimestamp(2); if (banTill != null && banTill.getTime() < System.currentTimeMillis()) { s_logger.fine("Ban expired for:" + username); expired = true; } } rs.close(); ps.close(); } catch (final SQLException sqle) { s_logger.info("Error for testing banned username existence:" + username + " error:" + sqle.getMessage()); throw new IllegalStateException(sqle.getMessage()); } finally { DbUtil.closeConnection(con); } if (expired) { removeBannedUsername(username); return Tuple.of(false, banTill); } return Tuple.of(found, banTill); } }