package zall.bean; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Timestamp; import java.util.List; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import zall.Zallery; import zutil.Hasher; import zutil.db.DBConnection; import zutil.db.bean.DBBean; import zutil.db.bean.DBBeanSQLResultHandler; import zutil.db.bean.DBBean.*; import zutil.db.handler.SimpleSQLResult; @DBTable("User") public class User extends DBBean{ public enum AuthType{ USER_INPUT, COOKIE, FACEBOOK } public static final long SESSION_TIMEOUT = 1000*60*60*24*3; // 3day ttl protected String name; protected String email; protected boolean emailVerified; protected String password; protected String facebookUid; // Date protected Timestamp loginDate; protected transient Timestamp prevLoginDate; // security protected transient AuthType authBy; protected String sessionId; protected String ipHost; protected String sessionHash; protected boolean superUser; protected boolean enabled; public static User load(DBConnection db, Long id) throws SQLException{ return load(db, User.class, id); } public static List load(DBConnection db) throws SQLException{ PreparedStatement sql = db.getPreparedStatement("SELECT * FROM User"); return DBConnection.exec(sql, DBBeanSQLResultHandler.createList(User.class, db)); } /** * Uses normal user and password to get user object, * this function will save the bean * * @param db is the DB connection * @param email is the email of the user * @param password is the password of the user * @param request is the HTTP request object * @return The user object or null if non where found * @throws SQLException */ public static User load(HttpServletRequest request, HttpServletResponse response, DBConnection db, String email, String password ) throws SQLException{ if( password==null || password.isEmpty() || password.equalsIgnoreCase("null")) return null; PreparedStatement sql = db.getPreparedStatement( "SELECT * FROM User WHERE email=? AND password=? LIMIT 1"); sql.setString(1, email); sql.setString(2, Hasher.MD5( password )); User user = DBConnection.exec(sql, DBBeanSQLResultHandler.create(User.class, db)); if( user != null ){ user.registerOnHost(request, response, db, true ); user.save(db); user.setAuthBy( AuthType.USER_INPUT ); } return user; } public static List loadSuperUsers(DBConnection db) throws SQLException { PreparedStatement sql = db.getPreparedStatement( "SELECT * FROM User WHERE superUser=1"); return DBConnection.exec(sql, DBBeanSQLResultHandler.createList(User.class, db)); } /** * Uses a cookie value to get the user object, * this function will save the bean * * @param db is the DB connection * @param hash is the cookie hash * @param request is the HTTP request object * @return The user object or null if non where found * @throws SQLException */ public static User loadByCookie(HttpServletRequest request, DBConnection db, String hash ) throws SQLException{ PreparedStatement sql = db.getPreparedStatement( "SELECT * FROM User WHERE sessionHash=? LIMIT 1"); sql.setString(1, hash); User user = DBConnection.exec(sql, DBBeanSQLResultHandler.create(User.class, db)); if( user != null && user.ipHost.equals( request.getLocalName() ) && user.loginDate.getTime()+SESSION_TIMEOUT > System.currentTimeMillis() ){ user.prevLoginDate = user.loginDate; user.loginDate = new Timestamp( System.currentTimeMillis() ); user.save(db); user.setAuthBy( AuthType.COOKIE ); return user; } return null; } /** * Uses Facebook user id to get a user object, * this function will save the bean * * @param db is the DB connection * @param uid is the Facebook UID(user id) * @return The user object or null if non where found */ public static User loadByFacebook(HttpServletRequest request, HttpServletResponse response, DBConnection db, String uid ) throws SQLException{ PreparedStatement sql = db.getPreparedStatement( "SELECT * FROM User WHERE facebookUid=? LIMIT 1"); sql.setString(1, uid); User user = DBConnection.exec(sql, DBBeanSQLResultHandler.create(User.class, db)); if( user != null ){ user.registerOnHost(request, response, db, false); user.save(db); user.setAuthBy( AuthType.FACEBOOK ); } return user; } public static boolean emailExists(String email, DBConnection db) throws SQLException{ PreparedStatement sql = db.getPreparedStatement( "SELECT email FROM User WHERE email=? LIMIT 1"); sql.setString(1, email); String tmp = DBConnection.exec(sql, new SimpleSQLResult()); return tmp != null; } public User(){ // Default values emailVerified = false; superUser = false; enabled = false; } /** * Registers the User to the Host machine that sent the request, * this method alters the bean, so a call to save() is recommended * * @param db is the DB connection * @param request is the request from the Host/Client * @throws SQLException */ public void registerOnHost(HttpServletRequest request, HttpServletResponse response, DBConnection db, boolean cookie) throws SQLException{ prevLoginDate = loginDate; loginDate = new Timestamp( System.currentTimeMillis() ); sessionId = request.getSession().getId(); ipHost = request.getLocalName(); sessionHash = Hasher.MD5( ""+sessionId+ipHost+loginDate+password ); if( cookie ){ Cookie c = new Cookie("sessionHash", sessionHash ); c.setMaxAge(5*24*60*60); // 5 days response.addCookie( c ); } } public void logout(HttpServletResponse response) { Cookie cookie = new Cookie( "sessionHash", null); cookie.setMaxAge( 0 ); response.addCookie( cookie ); } public boolean valid(HttpServletRequest request){ if( !this.isEnabled() ) return false; switch( authBy ){ case USER_INPUT: if( !this.isEmailVerified() ) return false; case COOKIE: return ( sessionHash.equals( Zallery.getCookieValue(request.getCookies(), "sessionHash")) || loginDate.getTime()+1000 > System.currentTimeMillis() ) && ipHost.equals( request.getLocalName() ) && loginDate.getTime()+SESSION_TIMEOUT > System.currentTimeMillis(); case FACEBOOK: return true; } return false; } public boolean verifyEmail(String hash) { return emailVerified = getEmailVerificationHash().equals(hash); } public String getEmailVerificationHash(){ return Hasher.MD5( "##helloWorld-->2011"+email+name+password ); } public Timestamp getLoginDate() { if( loginDate == null ) loginDate = new Timestamp(0); return loginDate; } public void setLoginDate(Timestamp loginDate) { this.loginDate = loginDate; } public Timestamp getPrevLoginDate() { if( loginDate == null ) loginDate = new Timestamp(0); return prevLoginDate; } public void setPrevLoginDate(Timestamp prevLoginDate) { this.prevLoginDate = prevLoginDate; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { if( this.email != null && this.email.equals(email) ) return; emailVerified = false; this.email = email; } public String getPassword() { return password; } public void setPassword(String password) { this.password = Hasher.MD5( password ); } public boolean equalsPassword( String pass ){ return Hasher.MD5( pass ).equals( password ); } public String getSessionId() { return sessionId; } public void setSessionId(String sessionId) { this.sessionId = sessionId; } public String getIpHost() { return ipHost; } public void setIpHost(String ipHost) { this.ipHost = ipHost; } public String getSessionHash() { return sessionHash; } public void setFacebookUid(String uid) { facebookUid = uid; } public String getFacebookUid(){ return facebookUid; } public boolean isSuperUser(){ return superUser; } public void setSuperUser(boolean superuser){ this.superUser = superuser; } public boolean isEnabled(){ return enabled; } public void setEnabled(boolean enabled){ this.enabled = enabled; } public boolean isEmailVerified(){ return emailVerified; } public void setEmailVerified(boolean verified){ this.emailVerified = verified; } public void setAuthBy(AuthType authBy){ this.authBy = authBy; } public AuthType getAuthBy(){ return authBy; } public boolean equals(User u){ return u != null && this.getId() == u.getId(); } /** * @return true if the specified user can edit the media */ public boolean canEdit(Media target) { return target != null && (this.isSuperUser() || target.getUser().equals(this)); } public boolean canEdit(Folder target) { return target != null && (this.isSuperUser() || this.equals( target.getUser() )); } public boolean canEdit(User target){ return this.equals( target ) || this.superUser; } }