Added some logging and moved cookie stuff to the manager

This commit is contained in:
Ziver Koc 2018-08-04 18:42:46 +02:00
parent 8e56ff406a
commit a4eb5c613d
9 changed files with 255 additions and 244 deletions

View file

@ -7,7 +7,7 @@
<Environment type="java.lang.String" name="ADMIN_EMAIL" value="admin@example.com" /> <Environment type="java.lang.String" name="ADMIN_EMAIL" value="admin@example.com" />
<Environment type="java.lang.String" name="ADMIN_EMAIL_NICE" value="Example.com Admin" /> <Environment type="java.lang.String" name="ADMIN_EMAIL_NICE" value="Example.com Admin" />
<Environment type="java.lang.String" name="SMTP_HOST" value="127.0.0.1" /> <Environment type="java.lang.String" name="SMTP_HOST" value="127.0.0.1" />
<Environment type="java.lang.String" name="DATA_PATH" value="PATH TO DATA FOLDER" /> <Environment type="java.lang.String" name="DATA_PATH" value="C:\\Users\\Ziver\\Desktop\\Downloads\\zallery" />
<Resource <Resource
name="jdbc/mysql" name="jdbc/mysql"
@ -16,7 +16,7 @@
username="zallery" username="zallery"
password="password" password="password"
driverClassName="com.mysql.jdbc.Driver" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://db:3306/zallery" url="jdbc:mysql://localhost:3306/zallery"
maxActive="8" maxActive="8"
maxIdle="4" maxIdle="4"
validationQuery="SELECT 1" validationQuery="SELECT 1"

View file

@ -56,6 +56,9 @@
</library> </library>
</orderEntry> </orderEntry>
<orderEntry type="library" name="Maven: se.koc:zutil:1.0.2-219" level="project" /> <orderEntry type="library" name="Maven: se.koc:zutil:1.0.2-219" level="project" />
<orderEntry type="library" name="Maven: javax.mail:javax.mail-api:1.6.1" level="project" />
<orderEntry type="library" name="Maven: javax.activation:activation:1.1" level="project" />
<orderEntry type="library" name="Maven: se.koc:zutil:1.0.2-219" level="project" />
<orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.2.1" level="project" /> <orderEntry type="library" name="Maven: commons-fileupload:commons-fileupload:1.2.1" level="project" />
<orderEntry type="library" name="Maven: commons-io:commons-io:2.5" level="project" /> <orderEntry type="library" name="Maven: commons-io:commons-io:2.5" level="project" />
<orderEntry type="library" name="Maven: dom4j:dom4j:1.6.1" level="project" /> <orderEntry type="library" name="Maven: dom4j:dom4j:1.6.1" level="project" />

View file

@ -61,8 +61,6 @@ CREATE TABLE `User` (
`email` varchar(50) DEFAULT NULL, `email` varchar(50) DEFAULT NULL,
`emailVerified` tinyint(1) NOT NULL, `emailVerified` tinyint(1) NOT NULL,
`password` varchar(32) DEFAULT NULL, `password` varchar(32) DEFAULT NULL,
`facebookUid` varchar(12) DEFAULT NULL,
`sessionId` varchar(32) DEFAULT NULL,
`ipHost` varchar(20) DEFAULT NULL, `ipHost` varchar(20) DEFAULT NULL,
`loginDate` datetime DEFAULT NULL, `loginDate` datetime DEFAULT NULL,
`sessionHash` varchar(32) DEFAULT NULL, `sessionHash` varchar(32) DEFAULT NULL,

View file

@ -44,7 +44,7 @@ public class Zallery extends HttpServlet{
try { try {
Context context = new InitialContext(); Context context = new InitialContext();
// Check if Zallery has been properly configured // Check if Zallery has been properly configured
if ("PATH TO DATA FOLDER".equals(context.lookup("java:comp/env/DATA_PATH"))) if (((String) context.lookup("java:comp/env/DATA_PATH")).isEmpty())
throw new ServletException("Zallery has not been properly configured, set proper configuration in Zallery.xml context file."); throw new ServletException("Zallery has not been properly configured, set proper configuration in Zallery.xml context file.");
WEBSITE_NAME = (String)context.lookup("java:comp/env/WEBSITE_NAME"); WEBSITE_NAME = (String)context.lookup("java:comp/env/WEBSITE_NAME");
@ -72,7 +72,7 @@ public class Zallery extends HttpServlet{
try { try {
return new DBConnection("jdbc/mysql"); return new DBConnection("jdbc/mysql");
} catch (Exception e) { } catch (Exception e) {
throw new ServletException(e); throw new ServletException("Was unable to initialize DB connection", e);
} }
} }

View file

@ -20,173 +20,180 @@ import zutil.log.LogUtil;
import zall.Zallery; import zall.Zallery;
@DBTable("Folder") @DBTable("Folder")
public class Folder extends DBBean{ public class Folder extends DBBean {
private static final Logger logger = LogUtil.getLogger(); private static final Logger logger = LogUtil.getLogger();
private transient String name; private transient String name;
protected long user = -1; protected long user = -1;
protected transient User userInstance; protected transient User userInstance;
private String path; private String path;
protected Folder parent; protected Folder parent;
protected Timestamp date; protected Timestamp date;
private boolean isPrivate; private boolean isPrivate;
public static Folder load(DBConnection db, Long id) throws SQLException {
return load(db, Folder.class, id);
}
public static Folder load(DBConnection db, Long id) throws SQLException{ public static List<Folder> loadSubFolders(DBConnection db, Folder folder, User requestingUser) throws SQLException {
return load(db, Folder.class, id); PreparedStatement sql = db.getPreparedStatement("SELECT * FROM Folder WHERE parent=? AND (isPrivate=0 OR user=? OR ?)");
} sql.setLong(1, folder.getId());
public static List<Folder> loadSubFolders(DBConnection db, Folder folder, User requestingUser) throws SQLException{ sql.setLong(2, folder.user);
PreparedStatement sql = db.getPreparedStatement("SELECT * FROM Folder WHERE parent=? AND (isPrivate=0 OR user=? OR ?)"); sql.setBoolean(3, requestingUser.isSuperUser());
sql.setLong(1, folder.getId()); return DBConnection.exec(sql, DBBeanSQLResultHandler.createList(Folder.class, db));
sql.setLong(2, folder.user); }
sql.setBoolean(3, requestingUser.isSuperUser());
return DBConnection.exec(sql, DBBeanSQLResultHandler.createList(Folder.class, db));
}
public static Folder loadRoot(DBConnection db, User user) throws SQLException{ public static Folder loadRoot(DBConnection db, User user) throws SQLException {
PreparedStatement sql = db.getPreparedStatement("SELECT * FROM Folder WHERE path=? AND (isPrivate=0 OR user=? OR ?)"); PreparedStatement sql = db.getPreparedStatement("SELECT * FROM Folder WHERE path=? AND (isPrivate=0 OR user=? OR ?)");
sql.setString(1, "/"); sql.setString(1, "/");
sql.setLong(2, user.getId()); sql.setLong(2, user.getId());
sql.setBoolean(3, user.isSuperUser()); sql.setBoolean(3, user.isSuperUser());
return DBConnection.exec(sql, DBBeanSQLResultHandler.create(Folder.class, db)); return DBConnection.exec(sql, DBBeanSQLResultHandler.create(Folder.class, db));
} }
public static Folder load(DBConnection db, String path, User user) throws SQLException{ public static Folder load(DBConnection db, String path, User user) throws SQLException {
PreparedStatement sql = db.getPreparedStatement("SELECT * FROM Folder WHERE path=? AND user=?"); PreparedStatement sql = db.getPreparedStatement("SELECT * FROM Folder WHERE path=? AND user=?");
sql.setString(1, path); sql.setString(1, path);
sql.setLong(2, user.getId()); sql.setLong(2, user.getId());
return DBConnection.exec(sql, DBBeanSQLResultHandler.create(Folder.class, db)); return DBConnection.exec(sql, DBBeanSQLResultHandler.create(Folder.class, db));
} }
public static List<Folder> load(DBConnection db, User user) throws SQLException{ public static List<Folder> load(DBConnection db, User user) throws SQLException {
if( user.getId() == null ) if (user.getId() == null)
return Collections.emptyList(); return Collections.emptyList();
PreparedStatement sql = db.getPreparedStatement("SELECT * FROM Folder WHERE user=?"); PreparedStatement sql = db.getPreparedStatement("SELECT * FROM Folder WHERE user=?");
sql.setLong(1, user.getId() ); sql.setLong(1, user.getId());
return DBConnection.exec(sql, DBBeanSQLResultHandler.createList(Folder.class, db)); return DBConnection.exec(sql, DBBeanSQLResultHandler.createList(Folder.class, db));
} }
public Folder(){ public Folder() {
date = new Timestamp( System.currentTimeMillis() ); date = new Timestamp(System.currentTimeMillis());
} }
public String getName(){ public String getName() {
if(name == null){ if (name == null) {
String[] tmp = path.split("/"); String[] tmp = path.split("/");
name = tmp[tmp.length-1]; name = tmp[tmp.length - 1];
} }
String userName = getUser() != null ? getUser().getName() : "UNKNOWN"; String userName = getUser() != null ? getUser().getName() : "UNKNOWN";
String tmp = name.replaceAll("\\{NAME\\}", userName); String tmp = name.replaceAll("\\{NAME\\}", userName);
return tmp; return tmp;
} }
public User getUser(){
if (userInstance == null) { public User getUser() {
try { if (userInstance == null) {
try {
DBConnection db = Zallery.getDB(); DBConnection db = Zallery.getDB();
userInstance = User.load(db, user); userInstance = User.load(db, user);
db.close(); db.close();
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.WARNING, null, e); logger.log(Level.WARNING, null, e);
} }
} }
return userInstance; return userInstance;
} }
public void setUser(User user){
this.user = user.getId();
this.userInstance = null;
}
public boolean isPrivate(){
return isPrivate;
}
public void setPrivate(boolean priv){
this.isPrivate = priv;
}
public String getPath(){
String tmp = path.replaceAll("\\{NAME\\}", getUser().getName());
return tmp;
}
public void setName(String name){
this.name = name;
if( parent.path.endsWith("/") )
this.path = parent.path+name;
else
this.path = parent.path+"/"+name;
}
public void setParent(Folder parent){
if( this.parent != parent ){
this.parent = parent;
//parent.addSubFolder( this );
if( parent.path.endsWith("/") )
this.path = parent.path+name;
else
this.path = parent.path+"/"+name;
}
}
public Folder getParent(){
return parent;
}
public Timestamp getDate(){ public void setUser(User user) {
this.user = user.getId();
this.userInstance = null;
}
public boolean isPrivate() {
return isPrivate;
}
public void setPrivate(boolean priv) {
this.isPrivate = priv;
}
public String getPath() {
String tmp = path.replaceAll("\\{NAME\\}", getUser().getName());
return tmp;
}
public void setName(String name) {
this.name = name;
if (parent.path.endsWith("/"))
this.path = parent.path + name;
else
this.path = parent.path + "/" + name;
}
public void setParent(Folder parent) {
if (this.parent != parent) {
this.parent = parent;
//parent.addSubFolder( this );
if (parent.path.endsWith("/"))
this.path = parent.path + name;
else
this.path = parent.path + "/" + name;
}
}
public Folder getParent() {
return parent;
}
public Timestamp getDate() {
return date; return date;
} }
/** /**
* @param filename is the name of the file * @return a File object that points to the physical file on the disk,
* @param size specifies the size of the image * or null if the user or the filename is null
* @return a File object that points to the physical file on the disk, * @param filename is the name of the file
* or null if the user or the filename is null * @param size specifies the size of the image
*/ */
public File getFile(String filename, Image.Size size){ public File getFile(String filename, Image.Size size) {
// Zallery not initialized. // Zallery not initialized.
while( Zallery.DATA_PATH.isEmpty() ){ if (Zallery.DATA_PATH.isEmpty()) {
logger.warning("Zallery not initialized or DATA_PATH not set!"); throw new NullPointerException("Zallery not initialized yet or DATA_PATH not set!");
return null; }
}
if( user < 0 || filename == null ) if (user < 0 || filename == null)
return null; return null;
StringBuilder tmp = new StringBuilder(); StringBuilder tmp = new StringBuilder();
// Get the Root path of the given size // Get the Root path of the given size
tmp.append( Zallery.DATA_PATH ); tmp.append(Zallery.DATA_PATH);
if( tmp.charAt(tmp.length()-1) != File.separatorChar ) if (tmp.charAt(tmp.length() - 1) != File.separatorChar)
tmp.append( File.separatorChar ); tmp.append(File.separatorChar);
tmp.append( size.toString() ); tmp.append(size.toString());
if( path.charAt(0) != '/' ) if (path.charAt(0) != '/')
tmp.append( File.separatorChar ); tmp.append(File.separatorChar);
// Add UserID and this folders path // Add UserID and this folders path
String tmp_path = path.replaceAll("\\{NAME\\}", ""+user); String tmp_path = path.replaceAll("\\{NAME\\}", "" + user);
tmp_path = tmp_path.replaceAll("/", Matcher.quoteReplacement(File.separator)); tmp_path = tmp_path.replaceAll("/", Matcher.quoteReplacement(File.separator));
tmp.append( tmp_path ); tmp.append(tmp_path);
// check if folder exists or else create it // check if folder exists or else create it
File folder = new File(tmp.toString()); File folder = new File(tmp.toString());
if( !folder.exists() ) if (!folder.exists())
if( !folder.mkdirs() ){ if (!folder.mkdirs()) {
logger.warning("Unable to create new folders: '"+folder+"'"); logger.warning("Unable to create new folders: '" + folder + "'");
throw new RuntimeException("Unable to create new folders: '"+folder+"'"); throw new RuntimeException("Unable to create new folders: '" + folder + "'");
} }
// Add the filename // Add the filename
if( tmp.charAt(tmp.length()-1) != File.separatorChar ) if (tmp.charAt(tmp.length() - 1) != File.separatorChar)
tmp.append( File.separatorChar ); tmp.append(File.separatorChar);
tmp.append(filename); tmp.append(filename);
logger.finest( "File path: "+tmp.toString() ); logger.finest("File path: " + tmp.toString());
return new File(tmp.toString()); return new File(tmp.toString());
} }
public static Folder genRoot(){ public static Folder genRoot() {
Folder root = new Folder(); Folder root = new Folder();
root.parent = null; root.parent = null;
root.path = "/"; root.path = "/";
return root; return root;
} }
public boolean isEmpty(DBConnection db) throws SQLException { public boolean isEmpty(DBConnection db) throws SQLException {
return Folder.loadSubFolders(db, this, getUser()).isEmpty() && Media.load(db, this).isEmpty(); return Folder.loadSubFolders(db, this, getUser()).isEmpty() && Media.load(db, this).isEmpty();
} }
} }

View file

@ -5,10 +5,6 @@ import java.sql.SQLException;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.List; import java.util.List;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import zutil.Hasher; import zutil.Hasher;
import zutil.db.DBConnection; import zutil.db.DBConnection;
import zutil.db.bean.DBBean; import zutil.db.bean.DBBean;
@ -16,8 +12,8 @@ import zutil.db.bean.DBBeanSQLResultHandler;
import zutil.db.bean.DBBean.*; import zutil.db.bean.DBBean.*;
@DBTable("User") @DBTable("User")
public class User extends DBBean{ public class User extends DBBean {
public enum AuthType{ public enum AuthType {
USER_INPUT, COOKIE USER_INPUT, COOKIE
} }
@ -29,19 +25,18 @@ public class User extends DBBean{
protected Timestamp loginDate; protected Timestamp loginDate;
// security // security
protected transient AuthType authBy; protected transient AuthType authBy;
protected String sessionId;
protected String ipHost; protected String ipHost;
protected String sessionHash; protected String cookieHash;
protected boolean superUser; protected boolean superUser;
protected boolean enabled; protected boolean enabled;
public static User load(DBConnection db, Long id) throws SQLException{ public static User load(DBConnection db, Long id) throws SQLException {
return load(db, User.class, id); return load(db, User.class, id);
} }
public static List<User> load(DBConnection db) throws SQLException{ public static List<User> load(DBConnection db) throws SQLException {
PreparedStatement sql = db.getPreparedStatement("SELECT * FROM User"); PreparedStatement sql = db.getPreparedStatement("SELECT * FROM User");
return DBConnection.exec(sql, DBBeanSQLResultHandler.createList(User.class, db)); return DBConnection.exec(sql, DBBeanSQLResultHandler.createList(User.class, db));
} }
@ -50,9 +45,9 @@ public class User extends DBBean{
* Uses normal user and password to get user object, * Uses normal user and password to get user object,
* this function will save the bean * this function will save the bean
* *
* @return the user object or null if non where found * @return the user object or null if non where found
*/ */
public static User load(DBConnection db, String email) throws SQLException{ public static User load(DBConnection db, String email) throws SQLException {
PreparedStatement sql = db.getPreparedStatement( PreparedStatement sql = db.getPreparedStatement(
"SELECT * FROM User WHERE email=? LIMIT 1"); "SELECT * FROM User WHERE email=? LIMIT 1");
sql.setString(1, email); sql.setString(1, email);
@ -73,71 +68,53 @@ public class User extends DBBean{
* *
* @return the user object or null if non where found * @return the user object or null if non where found
*/ */
public static User loadBySessionHash(DBConnection db, String hash) throws SQLException{ public static User loadByCookieHash(DBConnection db, String hash) throws SQLException {
PreparedStatement sql = db.getPreparedStatement( PreparedStatement sql = db.getPreparedStatement(
"SELECT * FROM User WHERE sessionHash=? LIMIT 1"); "SELECT * FROM User WHERE cookieHash=? LIMIT 1");
sql.setString(1, hash); sql.setString(1, hash);
return DBConnection.exec(sql, DBBeanSQLResultHandler.create(User.class, db)); return DBConnection.exec(sql, DBBeanSQLResultHandler.create(User.class, db));
} }
public User() {
public User(){
// Default values // Default values
emailVerified = false; emailVerified = false;
superUser = false; superUser = false;
enabled = 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{
loginDate = new Timestamp( System.currentTimeMillis() );
sessionId = request.getSession().getId();
ipHost = request.getRemoteAddr();
sessionHash = generateSessionHash();
if( cookie ){
Cookie c = new Cookie("sessionHash", sessionHash );
c.setMaxAge(5*24*60*60); // 5 days
response.addCookie( c );
}
}
public boolean verifyEmail(String hash) { public boolean verifyEmail(String hash) {
return emailVerified = generateEmailVerificationHash().equals(hash); return emailVerified = generateEmailVerificationHash().equals(hash);
} }
public String generateEmailVerificationHash(){
return Hasher.MD5( "##helloWorld-->2011"+email+name+password ); public String generateEmailVerificationHash() {
return Hasher.MD5("##helloWorld-->2011" + email + name + password);
} }
public Timestamp getLoginDate() { public Timestamp getLoginDate() {
if( loginDate == null ) if (loginDate == null)
loginDate = new Timestamp(0); loginDate = new Timestamp(0);
return loginDate; return loginDate;
} }
public void setLoginDate(Timestamp loginDate) { public void setLoginDate(Timestamp loginDate) {
this.loginDate = loginDate; this.loginDate = loginDate;
} }
public void setAuthBy(AuthType authBy){ public void setAuthBy(AuthType authBy) {
this.authBy = authBy; this.authBy = authBy;
} }
public AuthType getAuthBy(){
public AuthType getAuthBy() {
return authBy; return authBy;
} }
public String getName() { public String getName() {
return name; return name;
} }
public void setName(String name) { public void setName(String name) {
this.name = name; this.name = name;
} }
@ -145,65 +122,64 @@ public class User extends DBBean{
public String getEmail() { public String getEmail() {
return email; return email;
} }
public void setEmail(String email) { public void setEmail(String email) {
if( this.email != null && this.email.equals(email) ) if (this.email != null && this.email.equals(email))
return; return;
emailVerified = false; emailVerified = false;
this.email = email; this.email = email;
} }
public boolean isEmailVerified(){
public boolean isEmailVerified() {
return emailVerified; return emailVerified;
} }
public void setEmailVerified(boolean verified){
public void setEmailVerified(boolean verified) {
this.emailVerified = verified; this.emailVerified = verified;
} }
public String getPassword() { public String getPassword() {
return password; return password;
} }
public void setPassword(String password) { public void setPassword(String password) {
this.password = Hasher.MD5( password ); this.password = Hasher.MD5(password);
} }
public String getSessionId() { public String getCookieHash() {
return sessionId; return cookieHash;
} }
public void setSessionId(String sessionId) {
this.sessionId = sessionId; public void setCookieHash(String cookieHash) {
} this.cookieHash = cookieHash;
public String getSessionHash() {
return sessionHash;
}
public void setSessionHash(String sessionHash) {
this.sessionHash = sessionHash;
}
public String generateSessionHash(){
return Hasher.MD5( ""+sessionId+ipHost+loginDate+password );
} }
public String getIpHost() { public String getIpHost() {
return ipHost; return ipHost;
} }
public void setIpHost(String ipHost) { public void setIpHost(String ipHost) {
this.ipHost = ipHost; this.ipHost = ipHost;
} }
public boolean isSuperUser(){ public boolean isSuperUser() {
return superUser; return superUser;
} }
public void setSuperUser(boolean superUser){
public void setSuperUser(boolean superUser) {
this.superUser = superUser; this.superUser = superUser;
} }
public boolean isEnabled(){ public boolean isEnabled() {
return enabled; return enabled;
} }
public void setEnabled(boolean enabled){
public void setEnabled(boolean enabled) {
this.enabled = enabled; this.enabled = enabled;
} }
public boolean equals(User u){ public boolean equals(User u) {
return u != null && getId() == u.getId(); return u != null && getId().equals(u.getId());
} }
} }

View file

@ -4,17 +4,20 @@ import zall.bean.User;
import zall.manager.AuthenticationManager; import zall.manager.AuthenticationManager;
import zall.page.LoginServlet; import zall.page.LoginServlet;
import zall.page.RegisterServlet; import zall.page.RegisterServlet;
import zutil.log.LogUtil;
import javax.servlet.*; import javax.servlet.*;
import javax.servlet.annotation.WebFilter; import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.io.IOException; import java.io.IOException;
import java.util.logging.Logger;
/** /**
* This filter will check if user is isValid if not will redirect to /login page * This filter will check if user is isValid if not will redirect to /login page
*/ */
@WebFilter(urlPatterns = "/") @WebFilter(urlPatterns = "/")
public class AuthenticationFilter implements Filter { public class AuthenticationFilter implements Filter {
private static final Logger logger = LogUtil.getLogger();
@Override @Override
public void init(FilterConfig filterConfig) { } public void init(FilterConfig filterConfig) { }
@ -28,9 +31,11 @@ public class AuthenticationFilter implements Filter {
if (requestURI.equals(LoginServlet.URI) || if (requestURI.equals(LoginServlet.URI) ||
requestURI.equals(RegisterServlet.URI) || requestURI.equals(RegisterServlet.URI) ||
AuthenticationManager.isValid(user, (HttpServletRequest) request)) { AuthenticationManager.isValid(user, (HttpServletRequest) request)) {
logger.finest("User already authenticated, continuing filter chain.");
chain.doFilter(request, response); chain.doFilter(request, response);
} else { } else {
// do not continue the filter pipeline forward to login page // do not continue the filter pipeline forward to login page
logger.fine("User not authenticated, redirecting to login page.");
request.getRequestDispatcher(LoginServlet.URI).forward(request, response); request.getRequestDispatcher(LoginServlet.URI).forward(request, response);
} }
} }

View file

@ -8,8 +8,7 @@ import zutil.Hasher;
import zutil.db.DBConnection; import zutil.db.DBConnection;
import zutil.log.LogUtil; import zutil.log.LogUtil;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.*;
import javax.servlet.http.HttpSession;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -23,21 +22,27 @@ public class AuthenticationManager {
public static final String SESSION_KEY_USER = "zall_user"; public static final String SESSION_KEY_USER = "zall_user";
public static final String SESSION_KEY_AUTH_HASH = "zall_ueser_session_hash"; public static final String SESSION_KEY_AUTH_HASH = "zall_ueser_session_hash";
public static final long SESSION_TIMEOUT = 1000*60*60*24*3; // 3day 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 * Authenticate a username and password and return the associated Uaer object
*/ */
public static User authenticate(DBConnection db, String email, String password) throws SQLException { public static User authenticate(DBConnection db, String email, String password, HttpServletRequest request, HttpServletResponse response) throws SQLException {
User user = User.load(db, email); User user = User.load(db, email);
// Valid email? // Valid email?
if( user != null ){ if( user != null ){
if (user.getPassword().equals(Hasher.MD5(password))) { if (user.getPassword().equals(Hasher.MD5(password))) {
userAuthenticated(db, user, User.AuthType.USER_INPUT); setUserAuthenticated(db, user, User.AuthType.USER_INPUT, request, response);
return user; return user;
} else {
logger.info("Incorrect password for username: " + user);
} }
} else {
logger.info("Incorrect username provided: " + user);
} }
return null; return null;
} }
@ -47,24 +52,41 @@ public class AuthenticationManager {
* *
* @return a user object or null authentications fails * @return a user object or null authentications fails
*/ */
public static User authenticate(DBConnection db, HttpServletRequest request) throws SQLException{ public static User authenticate(DBConnection db, HttpServletRequest request, HttpServletResponse response) throws SQLException{
String sessionHash = ServletUtil.getCookieValue(request.getCookies(), SESSION_KEY_AUTH_HASH); String cookieHash = ServletUtil.getCookieValue(request.getCookies(), SESSION_KEY_AUTH_HASH);
User user = User.loadBySessionHash(db, sessionHash); if (cookieHash != null) {
User user = User.loadByCookieHash(db, cookieHash);
if( user != null && if (user != null) {
user.getIpHost().equals(request.getRemoteAddr()) && if (request.getRemoteAddr().equals(user.getIpHost()) &&
user.getLoginDate().getTime() + SESSION_TIMEOUT > System.currentTimeMillis()){ user.getLoginDate().getTime() + SESSION_TIMEOUT > System.currentTimeMillis()) {
userAuthenticated(db, user, User.AuthType.COOKIE); setUserAuthenticated(db, user, User.AuthType.COOKIE, request, response);
return user; 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; return null;
} }
private static void userAuthenticated(DBConnection db, User user, User.AuthType authType) throws SQLException { private static void setUserAuthenticated(DBConnection db, User user, User.AuthType authType, HttpServletRequest request, HttpServletResponse response) throws SQLException {
user.setLoginDate(new Timestamp(System.currentTimeMillis())); user.setLoginDate(new Timestamp(System.currentTimeMillis()));
user.setAuthBy(authType); user.setAuthBy(authType);
user.setIpHost(request.getRemoteAddr());
user.setCookieHash(Double.toHexString(Math.random()));
user.save(db); user.save(db);
logger.info("User(" + user.getName() + ") authenticated by " + user.getAuthBy());
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());
} }
/** /**
@ -88,7 +110,7 @@ public class AuthenticationManager {
return false; return false;
if(!user.isEnabled()) if(!user.isEnabled())
return false; return false;
if(user.getSessionHash() == null || user.getSessionHash().isEmpty() ) if(user.getCookieHash() == null || user.getCookieHash().isEmpty() )
return false; return false;
switch(user.getAuthBy()){ switch(user.getAuthBy()){
@ -96,7 +118,7 @@ public class AuthenticationManager {
if (!user.isEmailVerified()) return false; if (!user.isEmailVerified()) return false;
case COOKIE: case COOKIE:
String sessionHash = ServletUtil.getCookieValue(request.getCookies(), SESSION_KEY_AUTH_HASH); String sessionHash = ServletUtil.getCookieValue(request.getCookies(), SESSION_KEY_AUTH_HASH);
return user.getSessionHash().equals(sessionHash) && return user.getCookieHash().equals(sessionHash) &&
user.getIpHost().equals(request.getRemoteAddr()); user.getIpHost().equals(request.getRemoteAddr());
} }
return false; return false;
@ -126,7 +148,7 @@ public class AuthenticationManager {
* Reset the user authentication. In plain word: logout user. * Reset the user authentication. In plain word: logout user.
*/ */
public static void reset(DBConnection db, User user) throws SQLException { public static void reset(DBConnection db, User user) throws SQLException {
user.setSessionHash(null); user.setCookieHash(null);
user.save(db); user.save(db);
} }

View file

@ -30,12 +30,13 @@ public class LoginServlet extends ZalleryServlet {
// Authenticate with cookies // Authenticate with cookies
if (user == null) if (user == null)
user = AuthenticationManager.authenticate(db, request); user = AuthenticationManager.authenticate(db, request, response);
// Forward user // Forward user
if (user != null) { if (user != null) {
include(JSP_FILE, request, response); include(JSP_FILE, request, response);
} else { } else {
logger.fine("User(" + user.getEmail() + ") already authenticated, forwarding to gallery.");
redirect(GalleryServlet.URI, request, response); redirect(GalleryServlet.URI, request, response);
} }
} }
@ -45,14 +46,13 @@ public class LoginServlet extends ZalleryServlet {
UserMessage msgs = UserMessage.getUserMessage(request.getSession()); UserMessage msgs = UserMessage.getUserMessage(request.getSession());
User user = AuthenticationManager.authenticate(db, User user = AuthenticationManager.authenticate(db,
request.getParameter("email"), request.getParameter("email"),
request.getParameter("password")); request.getParameter("password"),
request, response);
// Successful login // Successful login
if (user != null) { if (user != null) {
user.registerOnHost(request, response, db, true ); logger.fine("Authenticated user(" + user.getEmail() + ") successfully, forwarding to gallery.");
AuthenticationManager.setUserSession(user, request.getSession()); forward(GalleryServlet.URI, request, response);
forward("/", request, response);
} }
// Failed login // Failed login
else { else {