Confirming Single Login
The next requirement requires the login module to allow a user to be logged in only once. This requirement has two components. The first component is to check to see whether the user is already logged in. The additional method is as follows:
private boolean isLoggedIn() { String username = getUsername(); Connection con = null; try { InitialContext ic = new InitialContext(); DataSource ds = (DataSource) ic.lookup(dsJndiName); con = ds.getConnection(); PreparedStatement ps = con.prepareStatement(getCounterQuery); ps.setString(1, username); ResultSet rs = ps.executeQuery(); return rs.next(); } catch (Exception e) { _log.error("Unexpected error", e); } finally { try { if (con != null) { con.close(); } } catch (Throwable e) { _log.error("Error closing connection", e); } } }
This method will get called at the top of the login() method just after the check to see whether the account is locked. If the user is already logged in, I log that a failed login attempt occurred and then throw a FailedLoginException.
The second part of this requirement is to flag the database that the user is in fact logged in. The code for this is as follows:
private void setUserLoggedIn() { String username = getUsername(); Connection con = null; try { InitialContext ic = new InitialContext(); DataSource ds = (DataSource) ic.lookup(dsJndiName); con = ds.getConnection(); PreparedStatement ps = con.prepareStatement(setLoggedInQuery); ps.setString(1, username); ps.executeUpdate(); } catch (Exception e) { _log.error("Unexpected error", e); } finally { try { if (con != null) { con.close(); } } catch (Throwable e) { _log.error("Error closing connection", e); } } }
This method is called just prior to returning true at the bottom of the login method. In addition to the login method, this is shown at the end of this article in the completed class' source code.