package zall.manager; import zall.bean.Folder; import zall.bean.Media; import zall.bean.User; import zall.util.ServletUtil; import zutil.Hasher; import zutil.db.DBConnection; import zutil.log.LogUtil; import javax.servlet.http.*; import java.sql.SQLException; import java.sql.Timestamp; import java.util.logging.Logger; /** * */ public class AuthenticationManager { private static final Logger logger = LogUtil.getLogger(); public static final String SESSION_KEY_USER = "zall_user"; public static final String SESSION_KEY_AUTH_HASH = "zall_ueser_session_hash"; public static final long SESSION_TIMEOUT = 3*24*60*60*1000; // 2 day public static final String COOKIE_KEY_USER_HASH = "zall_auth"; public static final int COOKIE_TIMEOUT = 10*24*60*60; // 10 days /** * Authenticate a username and password and return the associated Uaer object */ public static User authenticate(DBConnection db, String email, String password, HttpServletRequest request, HttpServletResponse response) throws SQLException { User user = User.load(db, email); // Valid email? if( user != null ){ if (user.getPassword().equals(Hasher.MD5(password))) { setUserAuthenticated(db, user, User.AuthType.USER_INPUT, request, response); return user; } else { logger.info("Incorrect password for username: " + user); } } else { logger.info("Incorrect username provided: " + user); } return null; } /** * Uses a cookie to authenticate a user, * * @return a user object or null authentications fails */ public static User authenticate(DBConnection db, HttpServletRequest request, HttpServletResponse response) throws SQLException{ String cookieHash = ServletUtil.getCookieValue(request.getCookies(), SESSION_KEY_AUTH_HASH); if (cookieHash != null) { User user = User.loadByCookieHash(db, cookieHash); if (user != null) { if (request.getRemoteAddr().equals(user.getIpHost()) && user.getLoginDate().getTime() + SESSION_TIMEOUT > System.currentTimeMillis()) { setUserAuthenticated(db, user, User.AuthType.COOKIE, request, response); return user; } else { logger.info("Cookie hash has expired or have incorrect ipHost: " + cookieHash); } } else { logger.info("Cookie hash not associated with any user: " + cookieHash); } } return null; } private static void setUserAuthenticated(DBConnection db, User user, User.AuthType authType, HttpServletRequest request, HttpServletResponse response) throws SQLException { user.setLoginDate(new Timestamp(System.currentTimeMillis())); user.setAuthBy(authType); user.setIpHost(request.getRemoteAddr()); user.setCookieHash(Double.toHexString(Math.random())); user.save(db); setUserSession(user, request.getSession()); if(authType != User.AuthType.COOKIE){ Cookie c = new Cookie(COOKIE_KEY_USER_HASH, user.getCookieHash()); c.setMaxAge(COOKIE_TIMEOUT); response.addCookie(c); } logger.info("User(" + user.getEmail() + ") authenticated by " + user.getAuthBy()); } /** * @return the User associated with the provided session. */ public static User getUserSession(HttpSession session) { return (User) session.getAttribute(SESSION_KEY_USER); } public static void setUserSession(User user, HttpSession session) { session.setAttribute(SESSION_KEY_USER, user); } public static void rmUserSession(HttpSession session) { session.removeAttribute(SESSION_KEY_USER); } /** * @return true if the user has a isValid authentication session */ public static boolean isValid(User user, HttpServletRequest request) { if(user == null) return false; if(!user.isEnabled()) return false; if(user.getCookieHash() == null || user.getCookieHash().isEmpty() ) return false; switch(user.getAuthBy()){ case USER_INPUT: if (!user.isEmailVerified()) return false; case COOKIE: String sessionHash = ServletUtil.getCookieValue(request.getCookies(), SESSION_KEY_AUTH_HASH); return user.getCookieHash().equals(sessionHash) && user.getIpHost().equals(request.getRemoteAddr()); } return false; } /** * @return true if the specified user can edit the media */ public static boolean canEdit(User user, Media target) { return target != null && (user.isSuperUser() || target.getUser().equals(user)); } /** * @return true if the specified user can edit the media */ public static boolean canEdit(User user, Folder target) { return target != null && (user.isSuperUser() || user.equals( target.getUser() )); } /** * @return true if the specified user can edit the profile of the other user */ public static boolean canEdit(User user, User target){ return user.equals( target ) || user.isSuperUser(); } /** * Reset the user authentication. In plain word: logout user. */ public static void reset(DBConnection db, User user) throws SQLException { user.setCookieHash(null); user.save(db); } }