/********************************************************************************* * The contents of this file are subject to the Common Public Attribution * License Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.openemm.org/cpal1.html. The License is based on the Mozilla * Public License Version 1.1 but Sections 14 and 15 have been added to cover * use of software over a computer network and provide for limited attribution * for the Original Developer. In addition, Exhibit A has been modified to be * consistent with Exhibit B. * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for * the specific language governing rights and limitations under the License. * * The Original Code is OpenEMM. * The Original Developer is the Initial Developer. * The Initial Developer of the Original Code is AGNITAS AG. All portions of * the code written by AGNITAS AG are Copyright (c) 2009 AGNITAS AG. All Rights * Reserved. * * Contributor(s): AGNITAS AG. ********************************************************************************/ package org.agnitas.dao.impl; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import javax.sql.DataSource; import org.agnitas.beans.FailedLoginData; import org.agnitas.beans.impl.FailedLoginDataImpl; import org.agnitas.dao.LoginTrackDao; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; /** * DAO implementation for login tracking using a MySQL database. * * @author Markus Dörschmidt */ public class LoginTrackDaoImpl implements LoginTrackDao { /** * Status for a successful login */ public static final int LOGIN_TRACK_STATUS_SUCCESS = 10; /** * Status for a failed login */ public static final int LOGIN_TRACK_STATUS_FAILED = 20; /** * Status for a successful login during lock period */ public static final int LOGIN_TRACK_STATUS_DURING_BLOCK = 40; /** * RowMapper for DB access */ protected final static RowMapper failedLoginDataRowMapper = new FailedLoginDataRowMapper(); protected DataSource dataSource; public void setDataSource( DataSource dataSource) { this.dataSource = dataSource; } /** * Implementation of the RowMapper * * @author Markus Dörschmidt * */ static class FailedLoginDataRowMapper implements RowMapper { @Override public Object mapRow(ResultSet rs, int row) throws SQLException { FailedLoginDataImpl result = new FailedLoginDataImpl(); result.setNumFailedLogins(rs.getInt(1)); result.setLastFailedLoginTimeDifference(rs.getInt(2)); return result; } } @Override public FailedLoginData getFailedLoginData(String ipAddress) { JdbcTemplate template = new JdbcTemplate( dataSource); String sql = "SELECT count(ip_address), ifnull(timestampdiff(second, max(ifnull(creation_date, 0)), now()),0) " + "FROM login_track_tbl " + "WHERE ip_address = ? " + "AND login_status = " + LoginTrackDaoImpl.LOGIN_TRACK_STATUS_FAILED + " " + "AND creation_date > (" + " SELECT ifnull(max(creation_date), 0) " + " FROM login_track_tbl " + " WHERE ip_address = ? " + " AND login_status = " + LoginTrackDaoImpl.LOGIN_TRACK_STATUS_SUCCESS + ")"; List<FailedLoginData> list = (List<FailedLoginData>) template.query(sql, new Object[] { ipAddress, ipAddress }, failedLoginDataRowMapper); if (list.size() == 1) return list.get(0); else return new FailedLoginDataImpl(); // No failed logins found } @Override public void trackFailedLogin(String ipAddress, String username) { trackLoginStatus(ipAddress, username, LoginTrackDaoImpl.LOGIN_TRACK_STATUS_FAILED); } @Override public void trackSuccessfulLogin(String ipAddress, String username) { trackLoginStatus(ipAddress, username, LoginTrackDaoImpl.LOGIN_TRACK_STATUS_SUCCESS); } @Override public void trackLoginDuringBlock(String ipAddress, String username) { trackLoginStatus(ipAddress, username, LoginTrackDaoImpl.LOGIN_TRACK_STATUS_DURING_BLOCK); } /** * Generic method for recording logins. * * @param ipAddress IP address of host * @param username use username in login * @param status login status */ protected void trackLoginStatus(String ipAddress, String username, int status) { JdbcTemplate template = new JdbcTemplate( dataSource); String sql = "INSERT INTO login_track_tbl (ip_address, login_status, username) VALUES (?,?,?)"; template.update(sql, new Object[] { ipAddress, status, username }); } @Override public int deleteOldRecords(int holdBackDays, int maxRecords) { JdbcTemplate template = new JdbcTemplate( dataSource); String sql = "DELETE FROM login_track_tbl WHERE timestampdiff(day, creation_date, now()) > ? LIMIT ?"; return template.update(sql, new Object[] { new Integer(holdBackDays), new Integer(maxRecords) }); } }