package com.ubx1.pdpscanner.server.services;
import java.sql.ResultSet;
import javax.servlet.http.HttpSession;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.ubx1.pdpscanner.client.services.UserService;
import com.ubx1.pdpscanner.server.database.BCrypt;
import com.ubx1.pdpscanner.server.database.MySQLConnection;
import com.ubx1.pdpscanner.shared.exceptions.BadLoginException;
import com.ubx1.pdpscanner.shared.exceptions.BadPasswordException;
import com.ubx1.pdpscanner.shared.exceptions.BadUsernameException;
import com.ubx1.pdpscanner.shared.exceptions.InvalidSessionException;
import com.ubx1.pdpscanner.shared.validation.Validator;
/**
* The user service implementation
*
* @author wbraik
*
*/
public class UserServiceImpl extends RemoteServiceServlet implements
UserService {
private static final long serialVersionUID = 1L;
/**
* Log the user in after verifying that the username exists and the password
* is valid
*
* @param username
* the username
* @param password
* the password
* @return a unique session Id
* @throws BadLoginException
*/
public String logIn(String username, String password) throws Exception {
/*
* Login validation
*/
Validator.validateLogin(username, password);
MySQLConnection conn = new MySQLConnection();
conn.connect();
username = "'" + username + "'";
ResultSet rs = conn.SQLSelect("SELECT * FROM users WHERE username = "
+ username + " LIMIT 1");
if (rs.next()) {
String passwordHash = rs.getString("password");
if (BCrypt.checkpw(password, passwordHash)) {
String id = String.valueOf(rs.getInt("id"));
String name = rs.getString("name");
String email = rs.getString("email");
String cell = rs.getString("cell");
if (rs.wasNull())
cell = null;
String creationDate = rs.getDate("creation_date").toString();
conn.disconnect();
HttpSession userSession = getThreadLocalRequest().getSession();
userSession.setAttribute("id", id);
userSession.setAttribute("name", name);
userSession.setAttribute("email", email);
userSession.setAttribute("cell", cell);
userSession.setAttribute("creationDate", creationDate);
System.out.println("User session created.");
return null;
} else {
conn.disconnect();
throw new BadLoginException(username, password,
"Incorrect password");
}
}
// Username does not exist
else {
conn.disconnect();
throw new BadLoginException(username, password,
"Incorrect username");
}
}
/**
* Register a new user into the database
*
* @param username
* the new user's username
* @param password
* the new user's password
* @return a null String object
* @throws Exception
*/
public String signUp(String name, String email, String username,
String password, String cell, String creationDate) throws Exception {
/*
* Signup validation
*/
Validator.validateSignUp(name, email, username, password, password,
cell);
MySQLConnection conn = new MySQLConnection();
conn.connect();
ResultSet rs = conn.SQLSelect("SELECT * FROM users");
// Check username unicity
while (rs.next()) {
String s = rs.getString("username");
if (s.equals(username)) {
throw new BadUsernameException(username,
"Username already exists");
}
}
String passwordHash = BCrypt.hashpw(password, BCrypt.gensalt());
// Prepare insert sql statement
name = "'" + name + "'";
email = "'" + email + "'";
username = "'" + username + "'";
passwordHash = "'" + passwordHash + "'";
if (!cell.isEmpty())
cell = "'" + cell + "'";
else
cell = "NULL";
creationDate = "'" + creationDate + "'";
// Insert new user
conn.SQLUpdate("INSERT INTO users (name,email,username,password,cell,creation_date)"
+ " VALUES ("
+ name
+ ","
+ email
+ ","
+ username
+ ","
+ passwordHash + "," + cell + "," + creationDate + ")");
conn.disconnect();
return null;
}
/**
* Check whether the current user's session is still valid
*/
public String checkSessionValidity() throws Exception {
if (getThreadLocalRequest().isRequestedSessionIdValid()) {
return null;
} else
throw new Exception("Session was *NOT* validated on the server : "
+ "login required!");
}
/**
* Destroy the current user session
*/
@Override
public String logOut() throws Exception {
getThreadLocalRequest().getSession().invalidate();
System.out.println("User session destroyed.");
return null;
}
/**
* Check the current user's password against this password
*/
@Override
public String checkPasswordValidity(String password) throws Exception {
int userId;
if (getThreadLocalRequest().isRequestedSessionIdValid()) {
userId = Integer.parseInt((String) getThreadLocalRequest()
.getSession().getAttribute("id"));
} else {
throw new InvalidSessionException();
}
MySQLConnection conn = new MySQLConnection();
conn.connect();
ResultSet rs = conn.SQLSelect("SELECT password FROM users WHERE id="
+ userId);
if (rs.next()) {
String dbPasswordHash = rs.getString("password");
conn.disconnect();
if (BCrypt.checkpw(password, dbPasswordHash)) {
return null;
} else {
throw new BadPasswordException(password, "Incorrect password");
}
} else {
conn.disconnect();
throw new Exception("Could not find user with ID " + userId);
}
}
/**
* Update the user's password
*/
@Override
public String updatePassword(String newPassword) throws Exception {
int userId;
if (getThreadLocalRequest().isRequestedSessionIdValid()) {
userId = Integer.parseInt((String) getThreadLocalRequest()
.getSession().getAttribute("id"));
} else {
throw new InvalidSessionException();
}
MySQLConnection conn = new MySQLConnection();
conn.connect();
newPassword = "'" + BCrypt.hashpw(newPassword, BCrypt.gensalt()) + "'";
conn.SQLUpdate("UPDATE users SET password=" + newPassword
+ " WHERE id=" + userId);
conn.disconnect();
return null;
}
}